Merge pull request #1105 from MCUdude/power-debugger-features
Support for Power Debugger analog readings in terminal mode
This commit is contained in:
commit
c4cb242823
120
src/jtag3.c
120
src/jtag3.c
|
@ -103,7 +103,7 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
|
||||||
static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
||||||
unsigned long addr, unsigned char data);
|
unsigned long addr, unsigned char data);
|
||||||
static int jtag3_set_sck_period(const PROGRAMMER *pgm, double v);
|
static int jtag3_set_sck_period(const PROGRAMMER *pgm, double v);
|
||||||
static void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p);
|
void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p);
|
||||||
static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
|
static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
|
||||||
unsigned int page_size,
|
unsigned int page_size,
|
||||||
unsigned int addr, unsigned int n_bytes);
|
unsigned int addr, unsigned int n_bytes);
|
||||||
|
@ -2339,7 +2339,7 @@ int jtag3_read_sib(const PROGRAMMER *pgm, const AVRPART *p, char *sib) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jtag3_set_vtarget(const PROGRAMMER *pgm, double v) {
|
int jtag3_set_vtarget(const PROGRAMMER *pgm, double v) {
|
||||||
unsigned uaref, utarg;
|
unsigned uaref, utarg;
|
||||||
unsigned char buf[2];
|
unsigned char buf[2];
|
||||||
|
|
||||||
|
@ -2407,15 +2407,91 @@ static void jtag3_display(const PROGRAMMER *pgm, const char *p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) {
|
void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) {
|
||||||
unsigned char buf[2];
|
unsigned char buf[3];
|
||||||
|
|
||||||
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0)
|
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
avrdude_message(MSG_INFO, "%sVtarget %s: %.2f V\n", p,
|
avrdude_message(MSG_INFO, "%sVtarget %s: %.2f V\n", p,
|
||||||
verbose ? "" : " ", b2_to_u16(buf) / 1000.0);
|
verbose ? "" : " ", b2_to_u16(buf) / 1000.0);
|
||||||
|
|
||||||
|
// Print features unique to the Power Debugger
|
||||||
|
for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) {
|
||||||
|
if(matches(ldata(ln), "powerdebugger")) {
|
||||||
|
short analog_raw_data;
|
||||||
|
|
||||||
|
// Read generator set voltage value (VOUT)
|
||||||
|
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, 2) < 0)
|
||||||
|
return;
|
||||||
|
analog_raw_data = b2_to_u16(buf);
|
||||||
|
avrdude_message(MSG_INFO, "%sVout set %s: %.2f V\n", p,
|
||||||
|
verbose ? "" : " ", analog_raw_data / 1000.0);
|
||||||
|
|
||||||
|
// Read measured generator voltage value (VOUT)
|
||||||
|
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_TSUP_VOLTAGE_MEAS, buf, 2) < 0)
|
||||||
|
return;
|
||||||
|
analog_raw_data = ((buf[0] & 0x0F) << 8) + buf[1];
|
||||||
|
if ((buf[0] & 0xF0) != 0x30)
|
||||||
|
avrdude_message(MSG_INFO, "%s: jtag3_print_parms1(): invalid PARM3_TSUP_VOLTAGE_MEAS data packet format\n", progname);
|
||||||
|
else {
|
||||||
|
if (analog_raw_data & 0x0800)
|
||||||
|
analog_raw_data |= 0xF000;
|
||||||
|
avrdude_message(MSG_INFO, "%sVout measured %s: %.02f V\n", p,
|
||||||
|
verbose ? "" : " ", ((float)analog_raw_data / -200.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read channel A voltage
|
||||||
|
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_ANALOG_A_VOLTAGE, buf, 2) < 0)
|
||||||
|
return;
|
||||||
|
analog_raw_data = ((buf[0] & 0x0F) << 8) + buf[1];
|
||||||
|
if ((buf[0] & 0xF0) != 0x20)
|
||||||
|
avrdude_message(MSG_INFO, "%s: jtag3_print_parms1(): invalid PARM3_ANALOG_A_VOLTAGE data packet format\n", progname);
|
||||||
|
else {
|
||||||
|
if (analog_raw_data & 0x0800)
|
||||||
|
analog_raw_data |= 0xF000;
|
||||||
|
avrdude_message(MSG_INFO, "%sCh A voltage %s: %.03f V\n", p,
|
||||||
|
verbose ? "" : " ", ((float)analog_raw_data / -200.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read channel A current
|
||||||
|
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_ANALOG_A_CURRENT, buf, 3) < 0)
|
||||||
|
return;
|
||||||
|
analog_raw_data = (buf[1] << 8) + buf[2];
|
||||||
|
if (buf[0] != 0x90)
|
||||||
|
avrdude_message(MSG_INFO, "%s: jtag3_print_parms1(): invalid PARM3_ANALOG_A_CURRENT data packet format\n", progname);
|
||||||
|
else
|
||||||
|
avrdude_message(MSG_INFO, "%sCh A current %s: %.3f mA\n", p,
|
||||||
|
verbose ? "" : " ", ((float)analog_raw_data * 0.003472));
|
||||||
|
|
||||||
|
// Read channel B voltage
|
||||||
|
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_ANALOG_B_VOLTAGE, buf, 2) < 0)
|
||||||
|
return;
|
||||||
|
analog_raw_data = ((buf[0] & 0x0F) << 8) + buf[1];
|
||||||
|
if ((buf[0] & 0xF0) != 0x10)
|
||||||
|
avrdude_message(MSG_INFO, "%s: jtag3_print_parms1(): invalid PARM3_ANALOG_B_VOLTAGE data packet format\n", progname);
|
||||||
|
else {
|
||||||
|
if (analog_raw_data & 0x0800)
|
||||||
|
analog_raw_data |= 0xF000;
|
||||||
|
avrdude_message(MSG_INFO, "%sCh B voltage %s: %.03f V\n", p,
|
||||||
|
verbose ? "" : " ", ((float)analog_raw_data / -200.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read channel B current
|
||||||
|
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_ANALOG_B_CURRENT, buf, 3) < 0)
|
||||||
|
return;
|
||||||
|
analog_raw_data = ((buf[0] & 0x0F) << 8) + buf[1];
|
||||||
|
if ((buf[0] & 0xF0) != 0x00)
|
||||||
|
avrdude_message(MSG_INFO, "%s: jtag3_print_parms1(): invalid PARM3_ANALOG_B_CURRENT data packet format\n", progname);
|
||||||
|
else {
|
||||||
|
if (analog_raw_data & 0x0800)
|
||||||
|
analog_raw_data |= 0xF000;
|
||||||
|
avrdude_message(MSG_INFO, "%sCh B current %s: %.3f mA\n", p,
|
||||||
|
verbose ? "" : " ", ((float)analog_raw_data * 0.555556));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0)
|
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -2444,7 +2520,7 @@ static void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (b2_to_u16(buf) > 0) {
|
if (b2_to_u16(buf) > 0) {
|
||||||
avrdude_message(MSG_INFO, "%sPDI/UPDI clock Xmega/megaAVR : %u kHz\n\n", p,
|
avrdude_message(MSG_INFO, "%sPDI/UPDI clock Xmega/megaAVR : %u kHz\n", p,
|
||||||
b2_to_u16(buf));
|
b2_to_u16(buf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2525,6 +2601,13 @@ void jtag3_initpgm(PROGRAMMER *pgm) {
|
||||||
pgm->teardown = jtag3_teardown;
|
pgm->teardown = jtag3_teardown;
|
||||||
pgm->page_size = 256;
|
pgm->page_size = 256;
|
||||||
pgm->flag = PGM_FL_IS_JTAG;
|
pgm->flag = PGM_FL_IS_JTAG;
|
||||||
|
|
||||||
|
for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) {
|
||||||
|
if (matches(ldata(ln), "powerdebugger")) {
|
||||||
|
pgm->set_vtarget = jtag3_set_vtarget;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char jtag3_dw_desc[] = "Atmel JTAGICE3 in debugWire mode";
|
const char jtag3_dw_desc[] = "Atmel JTAGICE3 in debugWire mode";
|
||||||
|
@ -2556,6 +2639,13 @@ void jtag3_dw_initpgm(PROGRAMMER *pgm) {
|
||||||
pgm->teardown = jtag3_teardown;
|
pgm->teardown = jtag3_teardown;
|
||||||
pgm->page_size = 256;
|
pgm->page_size = 256;
|
||||||
pgm->flag = PGM_FL_IS_DW;
|
pgm->flag = PGM_FL_IS_DW;
|
||||||
|
|
||||||
|
for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) {
|
||||||
|
if (matches(ldata(ln), "powerdebugger")) {
|
||||||
|
pgm->set_vtarget = jtag3_set_vtarget;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char jtag3_pdi_desc[] = "Atmel JTAGICE3 in PDI mode";
|
const char jtag3_pdi_desc[] = "Atmel JTAGICE3 in PDI mode";
|
||||||
|
@ -2589,6 +2679,13 @@ void jtag3_pdi_initpgm(PROGRAMMER *pgm) {
|
||||||
pgm->teardown = jtag3_teardown;
|
pgm->teardown = jtag3_teardown;
|
||||||
pgm->page_size = 256;
|
pgm->page_size = 256;
|
||||||
pgm->flag = PGM_FL_IS_PDI;
|
pgm->flag = PGM_FL_IS_PDI;
|
||||||
|
|
||||||
|
for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) {
|
||||||
|
if (matches(ldata(ln), "powerdebugger")) {
|
||||||
|
pgm->set_vtarget = jtag3_set_vtarget;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char jtag3_updi_desc[] = "Atmel JTAGICE3 in UPDI mode";
|
const char jtag3_updi_desc[] = "Atmel JTAGICE3 in UPDI mode";
|
||||||
|
@ -2626,11 +2723,12 @@ void jtag3_updi_initpgm(PROGRAMMER *pgm) {
|
||||||
pgm->unlock = jtag3_unlock_erase_key;
|
pgm->unlock = jtag3_unlock_erase_key;
|
||||||
pgm->read_sib = jtag3_read_sib;
|
pgm->read_sib = jtag3_read_sib;
|
||||||
|
|
||||||
/*
|
for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) {
|
||||||
* enable target voltage adjustment for PKOB/nEDBG boards
|
if (matches(ldata(ln), "powerdebugger") ||
|
||||||
*/
|
matches(ldata(ln), "pkob")) {
|
||||||
if (matches(ldata(lfirst(pgm->id)), "pkobn_updi")) {
|
pgm->set_vtarget = jtag3_set_vtarget;
|
||||||
pgm->set_vtarget = jtag3_set_vtarget;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope,
|
||||||
unsigned char *value, unsigned char length);
|
unsigned char *value, unsigned char length);
|
||||||
int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
|
int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
|
||||||
unsigned char **resp, const char *descr);
|
unsigned char **resp, const char *descr);
|
||||||
|
void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p);
|
||||||
|
int jtag3_set_vtarget(const PROGRAMMER *pgm, double voltage);
|
||||||
extern const char jtag3_desc[];
|
extern const char jtag3_desc[];
|
||||||
extern const char jtag3_dw_desc[];
|
extern const char jtag3_dw_desc[];
|
||||||
extern const char jtag3_pdi_desc[];
|
extern const char jtag3_pdi_desc[];
|
||||||
|
|
|
@ -184,16 +184,24 @@
|
||||||
* precedes each parameter address. There are distinct parameter
|
* precedes each parameter address. There are distinct parameter
|
||||||
* sets for generic and AVR scope.
|
* sets for generic and AVR scope.
|
||||||
*/
|
*/
|
||||||
#define PARM3_HW_VER 0x00 /* section 0, generic scope, 1 byte */
|
#define PARM3_HW_VER 0x00 /* section 0, generic scope, 1 byte */
|
||||||
#define PARM3_FW_MAJOR 0x01 /* section 0, generic scope, 1 byte */
|
#define PARM3_FW_MAJOR 0x01 /* section 0, generic scope, 1 byte */
|
||||||
#define PARM3_FW_MINOR 0x02 /* section 0, generic scope, 1 byte */
|
#define PARM3_FW_MINOR 0x02 /* section 0, generic scope, 1 byte */
|
||||||
#define PARM3_FW_RELEASE 0x03 /* section 0, generic scope, 1 byte;
|
#define PARM3_FW_RELEASE 0x03 /* section 0, generic scope, 1 byte;
|
||||||
* always asked for by Atmel Studio,
|
* always asked for by Atmel Studio,
|
||||||
* but never displayed there */
|
* but never displayed there */
|
||||||
#define PARM3_VTARGET 0x00 /* section 1, generic scope, 2 bytes, in millivolts */
|
|
||||||
#define PARM3_VBUF 0x01 /* section 1, generic scope, 2 bytes, bufferred target voltage reference */
|
#define PARM3_VTARGET 0x00 /* section 1, generic scope, 2 bytes, in millivolts */
|
||||||
#define PARM3_VUSB 0x02 /* section 1, generic scope, 2 bytes, USB voltage */
|
#define PARM3_VBUF 0x01 /* section 1, generic scope, 2 bytes, bufferred target voltage reference */
|
||||||
#define PARM3_VADJUST 0x20 /* section 1, generic scope, 2 bytes, set voltage */
|
#define PARM3_VUSB 0x02 /* section 1, generic scope, 2 bytes, USB voltage */
|
||||||
|
#define PARM3_ANALOG_A_CURRENT 0x10 /* section 1, generic scope, 2 bytes, Ch A current in milliamps, Powerdebugger only */
|
||||||
|
#define PARM3_ANALOG_A_VOLTAGE 0x11 /* section 1, generic scope, 2 bytes, Ch A voltage in millivolts, Powerdebugger only */
|
||||||
|
#define PARM3_ANALOG_B_CURRENT 0x12 /* section 1, generic scope, 2 bytes, Ch B current in milliamps, Powerdebugger only */
|
||||||
|
#define PARM3_ANALOG_B_VOLTAGE 0x13 /* section 1, generic scope, 2 bytes, Ch V voltage in millivolts, Powerdebugger only */
|
||||||
|
#define PARM3_TSUP_VOLTAGE_MEAS 0x14 /* section 1, generic scope, 2 bytes, target voltage measurement in millivolts */
|
||||||
|
#define PARM3_USB_VOLTAGE_MEAS 0x15 /* section 1, generic scope, 2 bytes, USB voltage measurement in millivolts */
|
||||||
|
#define PARM3_VADJUST 0x20 /* section 1, generic scope, 2 bytes, set voltage in millivolts */
|
||||||
|
#define PARM3_ANALOG_STATUS 0x30 /* section 1, generic scope, 2 bytes, analog status */
|
||||||
|
|
||||||
#define PARM3_DEVICEDESC 0x00 /* section 2, memory etc. configuration,
|
#define PARM3_DEVICEDESC 0x00 /* section 2, memory etc. configuration,
|
||||||
* 31 bytes for tiny/mega AVR, 47 bytes
|
* 31 bytes for tiny/mega AVR, 47 bytes
|
||||||
|
|
|
@ -3226,11 +3226,12 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) {
|
||||||
} else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3) {
|
} else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3) {
|
||||||
PROGRAMMER *pgmcp = pgm_dup(pgm);
|
PROGRAMMER *pgmcp = pgm_dup(pgm);
|
||||||
pgmcp->cookie = PDATA(pgm)->chained_pdata;
|
pgmcp->cookie = PDATA(pgm)->chained_pdata;
|
||||||
jtag3_getparm(pgmcp, SCOPE_GENERAL, 1, PARM3_VTARGET, vtarget_jtag, 2);
|
pgmcp->id = lcreat(NULL, 0);
|
||||||
|
// Copy pgm->id contents over to pgmcp->id
|
||||||
|
for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln))
|
||||||
|
ladd(pgmcp->id, cfg_strdup("stk500v2_print_parms1()", ldata(ln)));
|
||||||
|
jtag3_print_parms1(pgmcp, p);
|
||||||
pgm_free(pgmcp);
|
pgm_free(pgmcp);
|
||||||
avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p,
|
|
||||||
b2_to_u16(vtarget_jtag) / 1000.0);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget);
|
stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget);
|
||||||
avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
|
avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
|
||||||
|
@ -3282,7 +3283,7 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) {
|
||||||
if (stk500v2_jtag3_send(pgm, cmd, 1) >= 0 &&
|
if (stk500v2_jtag3_send(pgm, cmd, 1) >= 0 &&
|
||||||
stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) {
|
stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) {
|
||||||
unsigned int sck = cmd[1] | (cmd[2] << 8);
|
unsigned int sck = cmd[1] | (cmd[2] << 8);
|
||||||
avrdude_message(MSG_INFO, "%sSCK period : %.2f us\n", p,
|
avrdude_message(MSG_INFO, "%sSCK period : %.2f us\n", p,
|
||||||
(float)(1E6 / (1000.0 * sck)));
|
(float)(1E6 / (1000.0 * sck)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4681,4 +4682,7 @@ void stk500v2_jtag3_initpgm(PROGRAMMER *pgm) {
|
||||||
pgm->setup = stk500v2_jtag3_setup;
|
pgm->setup = stk500v2_jtag3_setup;
|
||||||
pgm->teardown = stk500v2_jtag3_teardown;
|
pgm->teardown = stk500v2_jtag3_teardown;
|
||||||
pgm->page_size = 256;
|
pgm->page_size = 256;
|
||||||
|
|
||||||
|
if (strcmp(ldata(lfirst(pgm->id)), "powerdebugger_isp") == 0)
|
||||||
|
pgm->set_vtarget = jtag3_set_vtarget;
|
||||||
}
|
}
|
||||||
|
|
|
@ -854,7 +854,7 @@ static int cmd_parms(PROGRAMMER * pgm, struct avrpart * p,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pgm->print_parms(pgm);
|
pgm->print_parms(pgm);
|
||||||
|
terminal_message(MSG_INFO, "\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue