diff --git a/src/jtag3.c b/src/jtag3.c index 080244d2..015845eb 100644 --- a/src/jtag3.c +++ b/src/jtag3.c @@ -2556,8 +2556,12 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { unsigned char prog_mode[2]; unsigned char buf[3]; + if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0) + return; + msg_info("%sVtarget : %.2f V\n", p, b2_to_u16(buf)/1000.0); + // Print clocks if programmer typ is not TPI - if (strcmp(pgm->type, "JTAGICE3_TPI")) { + if (!str_eq(pgm->type, "JTAGICE3_TPI")) { // Get current programming mode and target type from to determine what data to print if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, prog_mode, 1) < 0) return; @@ -2589,10 +2593,6 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { } } - if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0) - return; - msg_info("%sVtarget : %.2f V\n", p, b2_to_u16(buf)/1000.0); - // Print features unique to the Power Debugger for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) { if(str_starts(ldata(ln), "powerdebugger")) { @@ -2663,7 +2663,6 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { break; } } - fmsg_out(fp, "\n"); } @@ -2813,6 +2812,9 @@ static int jtag3_initialize_tpi(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char* resp; int status; + if (verbose && quell_progress < 2) + jtag3_print_parms1(pgm, progbuf, stderr); + pmsg_notice2("jtag3_initialize_tpi() start\n"); cmd[0] = XPRG_CMD_ENTER_PROGMODE; diff --git a/src/stk500v2.c b/src/stk500v2.c index d1015c0b..c5b7daa2 100644 --- a/src/stk500v2.c +++ b/src/stk500v2.c @@ -377,6 +377,13 @@ b2_to_u16(unsigned char *b) return l; } +static void +u16_to_b2(unsigned char *b, unsigned short l) +{ + b[0] = l & 0xff; + b[1] = (l >> 8) & 0xff; +} + static int stk500v2_send_mk2(const PROGRAMMER *pgm, unsigned char *data, size_t len) { if (serial_send(&pgm->fd, data, len) != 0) { pmsg_error("unable to send command to serial port\n"); @@ -1350,6 +1357,26 @@ static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { } } + // Read or write target voltage + if (PDATA(pgm)->vtarg_get || PDATA(pgm)->vtarg_set) { + // Read current target voltage set value + unsigned char buf[2]; + if (jtag3_getparm(pgmcp, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, 2) < 0) + return -1; + double vtarg_read = b2_to_u16(buf) / 1000.0; + if (PDATA(pgm)->vtarg_get) + msg_info("Target voltage value read as %.2fV\n", vtarg_read); + // Write target voltage value + else { + u16_to_b2(buf, (unsigned)(PDATA(pgm)->vtarg_data * 1000)); + msg_info("Changing target voltage from %.2f to %.2fV\n", vtarg_read, PDATA(pgm)->vtarg_data); + if (jtag3_setparm(pgmcp, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) { + msg_warning("Cannot set target voltage %.2fV\n", PDATA(pgm)->vtarg_data); + return -1; + } + } + } + free(pgmcp); /* @@ -1619,6 +1646,29 @@ static int stk500v2_jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extp } } + else if (str_starts(extended_param, "vtarg")) { + if (pgm->extra_features & HAS_VTARG_ADJ) { + // Set target voltage + if (str_starts(extended_param, "vtarg=") ) { + double vtarg_set_val = 0; + int sscanf_success = sscanf(extended_param, "vtarg=%lf", &vtarg_set_val); + PDATA(pgm)->vtarg_data = (double)((int)(vtarg_set_val * 100 + .5)) / 100; + if (sscanf_success < 1 || vtarg_set_val < 0) { + pmsg_error("invalid vtarg value '%s'\n", extended_param); + rv = -1; + break; + } + PDATA(pgm)->vtarg_set = true; + } + // Get target voltage + else if(str_eq(extended_param, "vtarg")) + PDATA(pgm)->vtarg_get = true; + else + break; + continue; + } + } + else if (str_eq(extended_param, "help")) { char *prg = (char *)ldata(lfirst(pgm->id)); msg_error("%s -c %s extended options:\n", progname, prg); @@ -3206,7 +3256,6 @@ static void stk500v2_display(const PROGRAMMER *pgm, const char *p) { PROGRAMMER *pgmcp = pgm_dup(pgm); pgmcp->cookie = PDATA(pgm)->chained_pdata; jtag3_display(pgmcp, p); - msg_info("\n"); pgm_free(pgmcp); } stk500v2_print_parms1(pgm, p, stderr); @@ -3301,7 +3350,7 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp 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))); + ladd(pgmcp->id, cfg_strdup("stk500v2_display()", ldata(ln))); jtag3_print_parms1(pgmcp, p, fp); pgm_free(pgmcp); } diff --git a/src/stk500v2_private.h b/src/stk500v2_private.h index b58cc5b4..f2c27b44 100644 --- a/src/stk500v2_private.h +++ b/src/stk500v2_private.h @@ -280,6 +280,11 @@ struct pdata bool vtarg_switch_set; unsigned char vtarg_switch_data[2]; + /* Get/set flags for adjustable target voltage */ + bool vtarg_get; + bool vtarg_set; + double vtarg_data; + const AVRPART *lastpart; /* Start address of Xmega boot area */