diff --git a/src/jtagmkI.c b/src/jtagmkI.c index e920534b9..513019319 100644 --- a/src/jtagmkI.c +++ b/src/jtagmkI.c @@ -1075,6 +1075,37 @@ static int jtagmkI_set_sck_period(const PROGRAMMER *pgm, double v) { } +static int jtagmkI_get_sck_period(const PROGRAMMER *pgm, double *v) { + unsigned char dur = 0; + if (jtagmkI_getparm(pgm, PARM_CLOCK, &dur) < 0) + return -1; + if (dur == JTAG_BITRATE_1_MHz) + *v = 1e6; + else if (dur == JTAG_BITRATE_500_kHz) + *v = 500e3; + else if (dur == JTAG_BITRATE_250_kHz) + *v = 250e3; + else if (dur == JTAG_BITRATE_125_kHz) + *v = 125e3; + else { // something went wrong + pmsg_error("wrong JTAG_BITRATE ID %02X\n", dur); + return -1; + } + return 0; +} + + +static int jtagmkI_get_vtarget(const PROGRAMMER *pgm, double *v) { + unsigned char vtarget = 0; + if (jtagmkI_getparm(pgm, PARM_OCD_VTARGET, &vtarget) < 0) { + pmsg_error("jtagmkI_getparm PARM_OCD_VTARGET failed\n"); + return -1; + } + *v = 6.25 * (unsigned)vtarget / 255.0; + return 0; +} + + /* * Read an emulator parameter. The result is exactly one byte, * multi-byte parameters get two different parameter names for @@ -1148,8 +1179,8 @@ static void jtagmkI_display(const PROGRAMMER *pgm, const char *p) { if (jtagmkI_getparm(pgm, PARM_HW_VERSION, &hw) < 0 || jtagmkI_getparm(pgm, PARM_SW_VERSION, &fw) < 0) return; - msg_info("%sICE HW version : 0x%02x\n", p, hw); - msg_info("%sICE FW version : 0x%02x\n", p, fw); + msg_info("%sICE HW version : 0x%02x\n", p, hw); + msg_info("%sICE FW version : 0x%02x\n", p, fw); jtagmkI_print_parms1(pgm, p, stderr); @@ -1158,7 +1189,8 @@ static void jtagmkI_display(const PROGRAMMER *pgm, const char *p) { static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { - unsigned char vtarget, jtag_clock; + unsigned char jtag_clock = 0; + double vtarget = 0; const char *clkstr; double clk; @@ -1192,9 +1224,9 @@ static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) } if (pgm->extra_features & HAS_VTARG_READ) { - if (jtagmkI_getparm(pgm, PARM_OCD_VTARGET, &vtarget) < 0) + if (jtagmkI_get_vtarget(pgm, &vtarget) < 0) return; - fmsg_out(fp, "%sVtarget : %.1f V\n", p, 6.25 * (unsigned)vtarget / 255.0); + fmsg_out(fp, "%sVtarget : %.1f V\n", p, vtarget); } fmsg_out(fp, "%sJTAG clock : %s (%.1f us)\n", p, clkstr, 1.0e6 / clk); @@ -1232,7 +1264,11 @@ void jtagmkI_initpgm(PROGRAMMER *pgm) { pgm->paged_load = jtagmkI_paged_load; pgm->print_parms = jtagmkI_print_parms; pgm->set_sck_period = jtagmkI_set_sck_period; + pgm->get_sck_period = jtagmkI_get_sck_period; pgm->setup = jtagmkI_setup; pgm->teardown = jtagmkI_teardown; pgm->page_size = 256; + if (pgm->extra_features & HAS_VTARG_READ) { + pgm->get_vtarget = jtagmkI_get_vtarget; + } } diff --git a/src/libavrdude.h b/src/libavrdude.h index ebf343f4e..434a9bb2a 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -992,9 +992,13 @@ typedef struct programmer_t { int (*term_keep_alive)(const struct programmer_t *pgm, const AVRPART *p); void (*print_parms) (const struct programmer_t *pgm, FILE *fp); int (*set_vtarget) (const struct programmer_t *pgm, double v); + int (*get_vtarget) (const struct programmer_t *pgm, double *v); int (*set_varef) (const struct programmer_t *pgm, unsigned int chan, double v); + int (*get_varef) (const struct programmer_t *pgm, unsigned int chan, double *v); int (*set_fosc) (const struct programmer_t *pgm, double v); + int (*get_fosc) (const struct programmer_t *pgm, double *v); int (*set_sck_period) (const struct programmer_t *pgm, double v); + int (*get_sck_period) (const struct programmer_t *pgm, double *v); int (*setpin) (const struct programmer_t *pgm, int pinfunc, int value); int (*getpin) (const struct programmer_t *pgm, int pinfunc); int (*highpulsepin) (const struct programmer_t *pgm, int pinfunc); diff --git a/src/pgm.c b/src/pgm.c index 1557720b0..3e4ad392e 100644 --- a/src/pgm.c +++ b/src/pgm.c @@ -146,9 +146,13 @@ PROGRAMMER *pgm_new(void) { pgm->term_keep_alive= NULL; pgm->print_parms = NULL; pgm->set_vtarget = NULL; + pgm->get_vtarget = NULL; pgm->set_varef = NULL; + pgm->get_varef = NULL; pgm->set_fosc = NULL; + pgm->get_fosc = NULL; pgm->set_sck_period = NULL; + pgm->get_sck_period = NULL; pgm->setpin = NULL; pgm->getpin = NULL; pgm->highpulsepin = NULL; diff --git a/src/stk500.c b/src/stk500.c index 4d2eee5a6..aafcccf42 100644 --- a/src/stk500.c +++ b/src/stk500.c @@ -1190,13 +1190,29 @@ static int stk500_set_vtarget(const PROGRAMMER *pgm, double v) { if (uaref > utarg) { pmsg_warning("reducing V[aref] from %.1f to %.1f\n", uaref / 10.0, v); - if ((rc = stk500_setparm(pgm, Parm_STK_VADJUST, utarg)) != 0) + if ((rc = stk500_setparm(pgm, Parm_STK_VADJUST, utarg)) != 0) { + pmsg_error("cannot set V[aref]\n"); return rc; + } } return stk500_setparm(pgm, Parm_STK_VTARGET, utarg); } +static int stk500_get_vtarget(const PROGRAMMER *pgm, double *v) { + unsigned utarg = 0; + int rv; + + if ((rv = stk500_getparm(pgm, Parm_STK_VTARGET, &utarg)) != 0) { + pmsg_error("cannot obtain V[target]\n"); + return rv; + } + + *v = utarg / 10.0; + return 0; +} + + static int stk500_set_varef(const PROGRAMMER *pgm, unsigned int chan /* unused */, double v) { @@ -1214,7 +1230,25 @@ static int stk500_set_varef(const PROGRAMMER *pgm, unsigned int chan /* unused * "V[target] = %.1f\n", utarg/10.0); return -1; } - return stk500_setparm(pgm, Parm_STK_VADJUST, uaref); + + if ((rc = stk500_setparm(pgm, Parm_STK_VADJUST, uaref)) < 0) + pmsg_error("cannot set V[aref]\n"); + return rc; +} + + +static int stk500_get_varef(const PROGRAMMER *pgm, unsigned int chan /* unused */, + double *v) { + unsigned uaref = 0; + int rv; + + if ((rv = stk500_getparm(pgm, Parm_STK_VADJUST, &uaref)) != 0) { + pmsg_error("cannot obtain V[aref]\n"); + return rv; + } + + *v = uaref / 10.0; + return 0; } @@ -1224,7 +1258,7 @@ static int stk500_set_fosc(const PROGRAMMER *pgm, double v) { 1, 8, 32, 64, 128, 256, 1024 }; size_t idx; - int rc; + int rc = 0; prescale = cmatch = 0; if (v > 0.0) { @@ -1252,15 +1286,45 @@ static int stk500_set_fosc(const PROGRAMMER *pgm, double v) { } } if (idx == sizeof(ps) / sizeof(ps[0])) { - pmsg_warning("f = %u Hz too low, %u Hz min\n", fosc, PDATA(pgm)->xtal / (256 * 1024 * 2)); - return -1; + pmsg_warning("f = %u Hz too low, using %u Hz\n", fosc, PDATA(pgm)->xtal / (256 * 1024 * 2)); + prescale = idx; + cmatch = 255; } } - if ((rc = stk500_setparm(pgm, Parm_STK_OSC_PSCALE, prescale)) != 0 - || (rc = stk500_setparm(pgm, Parm_STK_OSC_CMATCH, cmatch)) != 0) + if ((rc = stk500_setparm(pgm, Parm_STK_OSC_PSCALE, prescale)) != 0 ) { + pmsg_error("cannot set Parm_STK_OSC_PSCALE\n"); return rc; - + } + + if ((rc = stk500_setparm(pgm, Parm_STK_OSC_CMATCH, cmatch)) != 0) { + pmsg_error("cannot set Parm_STK_OSC_CMATCH\n"); + return rc; + } + + return 0; +} + + +static int stk500_get_fosc(const PROGRAMMER *pgm, double *v) { + unsigned prescale=0, cmatch=0; + static unsigned ps[] = { + 1, 8, 32, 64, 128, 256, 1024 + }; + int rc; + + if ((rc = stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &prescale)) != 0) { + pmsg_error("cannot get Parm_STK_OSC_PSCALE\n"); + return rc; +} + + if ((rc = stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &cmatch)) != 0) { + pmsg_error("cannot get Parm_STK_OSC_CMATCH\n"); + return rc; + } + + *v = !prescale ? 0 : PDATA(pgm)->xtal / ((cmatch + 1) * 2 * ps[prescale - 1]); + return 0; } @@ -1275,11 +1339,12 @@ static int stk500_set_fosc(const PROGRAMMER *pgm, double v) { static int stk500_set_sck_period(const PROGRAMMER *pgm, double v) { int dur; double min, max; + int rv = 0; min = 8.0 / PDATA(pgm)->xtal; max = 255 * min; dur = v / min + 0.5; - + if (v < min) { dur = 1; pmsg_warning("p = %.1f us too small, using %.1f us\n", @@ -1289,8 +1354,25 @@ static int stk500_set_sck_period(const PROGRAMMER *pgm, double v) { pmsg_warning("p = %.1f us too large, using %.1f us\n", v/1e-6, dur*min/1e-6); } - - return stk500_setparm(pgm, Parm_STK_SCK_DURATION, dur); + + if ((rv = stk500_setparm(pgm, Parm_STK_SCK_DURATION, dur)) < 0) { + pmsg_error("cannot set Parm_STK_SCK_DURATION\n"); + return rv; + } + return 0; +} + + +static int stk500_get_sck_period(const PROGRAMMER *pgm, double *v) { + unsigned dur; + int rv = 0; + + if ((rv = stk500_getparm(pgm, Parm_STK_SCK_DURATION, &dur)) < 0) { + pmsg_error("cannot obtain Parm_STK_SCK_DURATION\n"); + return rv; + } + *v = dur * 8.0 / PDATA(pgm)->xtal; + return 0; } @@ -1535,6 +1617,7 @@ void stk500_initpgm(PROGRAMMER *pgm) { pgm->paged_load = stk500_paged_load; pgm->print_parms = stk500_print_parms; pgm->set_sck_period = stk500_set_sck_period; + pgm->get_sck_period = stk500_get_sck_period; pgm->parseextparams = stk500_parseextparms; pgm->setup = stk500_setup; pgm->teardown = stk500_teardown; @@ -1545,8 +1628,14 @@ void stk500_initpgm(PROGRAMMER *pgm) { */ if (pgm->extra_features & HAS_VTARG_ADJ) pgm->set_vtarget = stk500_set_vtarget; - if (pgm->extra_features & HAS_VAREF_ADJ) + if (pgm->extra_features & HAS_VTARG_READ) + pgm->get_vtarget = stk500_get_vtarget; + if (pgm->extra_features & HAS_VAREF_ADJ) { pgm->set_varef = stk500_set_varef; - if (pgm->extra_features & HAS_FOSC_ADJ) + pgm->get_varef = stk500_get_varef; + } + if (pgm->extra_features & HAS_FOSC_ADJ) { pgm->set_fosc = stk500_set_fosc; + pgm->get_fosc = stk500_get_fosc; + } } diff --git a/src/stk500v2.c b/src/stk500v2.c index 1c4bac138..9d7e9e47d 100644 --- a/src/stk500v2.c +++ b/src/stk500v2.c @@ -70,6 +70,7 @@ #include "jtag3_private.h" #define STK500V2_XTAL 7372800U +#define SCRATCHMONKEY_XTAL 16000000U // Timeout (in seconds) for waiting for serial response #define SERIAL_TIMEOUT 2 @@ -280,6 +281,12 @@ static double stk500v2_sck_to_us(const PROGRAMMER *pgm, unsigned char dur); static int stk500v2_set_sck_period_mk2(const PROGRAMMER *pgm, double v); static int stk600_set_sck_period(const PROGRAMMER *pgm, double v); +static double stk500v2_fosc_value(const PROGRAMMER *pgm); +static double stk500v2_vtarget_value(const PROGRAMMER *pgm); +static double stk500v2_varef_value(const PROGRAMMER *pgm); +static double stk600_varef_0_value(const PROGRAMMER *pgm); +static double stk600_varef_1_value(const PROGRAMMER *pgm); +static double stk500v2_sck_duration_value(const PROGRAMMER *pgm); static void stk600_setup_xprog(PROGRAMMER *pgm); static void stk600_setup_isp(PROGRAMMER *pgm); @@ -294,7 +301,7 @@ void stk500v2_setup(PROGRAMMER * pgm) memset(pgm->cookie, 0, sizeof(struct pdata)); PDATA(pgm)->command_sequence = 1; PDATA(pgm)->boot_start = ULONG_MAX; - PDATA(pgm)->xtal = STK500V2_XTAL; + PDATA(pgm)->xtal = str_starts(pgmid, "scratchmonkey") ? SCRATCHMONKEY_XTAL : STK500V2_XTAL; } static void stk500v2_jtagmkII_setup(PROGRAMMER * pgm) @@ -1307,50 +1314,11 @@ static int stk500v2_initialize(const PROGRAMMER *pgm, const AVRPART *p) { // Read or write clock generator frequency if (PDATA(pgm)->fosc_get || PDATA(pgm)->fosc_set) { - if(PDATA(pgm)->pgmtype == PGMTYPE_STK500) { - // Read current target voltage set value - unsigned char osc_pscale = 0; - unsigned char osc_cmatch = 0; + if(PDATA(pgm)->pgmtype == PGMTYPE_STK500 || PDATA(pgm)->pgmtype == PGMTYPE_STK600) { const char *unit_get = {"Hz"}; - double f_get = 0.0; - int rv = 0; - if ((rv = stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale)) < 0 - || (rv = stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch)) < 0) - return rv; - if(osc_pscale) { - int prescale = 1; - f_get = PDATA(pgm)->xtal / 2; - switch (osc_pscale) { - case 2: prescale = 8; break; - case 3: prescale = 32; break; - case 4: prescale = 64; break; - case 5: prescale = 128; break; - case 6: prescale = 256; break; - case 7: prescale = 1024; break; - } - f_get /= prescale; - f_get /= (osc_cmatch + 1); + double f_get = stk500v2_fosc_value(pgm); + if (f_get) f_get = f_to_kHz_MHz(f_get, &unit_get); - } - if (PDATA(pgm)->fosc_get) - msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get); - // Write target voltage value - else { - const char *unit_set; - double f_set = f_to_kHz_MHz(PDATA(pgm)->fosc_data, &unit_set); - msg_info("Changing oscillator frequency from %.3f %s to %.3f %s\n", f_get, unit_get, f_set, unit_set); - if(pgm->set_fosc(pgm, PDATA(pgm)->fosc_data) < 0) - return -1; - } - } else if(PDATA(pgm)->pgmtype == PGMTYPE_STK600) { - // Read current target voltage set value - unsigned int clock_conf = 0; - stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf); - unsigned int oct = (clock_conf & 0xf000) >> 12u; - unsigned int dac = (clock_conf & 0x0ffc) >> 2u; - double f_get = pow(2, (double)oct) * 2078.0 / (2 - (double)dac / 1024.0); - const char *unit_get = {"Hz"}; - f_get = f_to_kHz_MHz(f_get, &unit_get); if (PDATA(pgm)->fosc_get) msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get); // Write new osc freq @@ -3243,6 +3211,12 @@ static int stk500v2_set_vtarget(const PROGRAMMER *pgm, double v) { } +static int stk500v2_get_vtarget(const PROGRAMMER *pgm, double *v) { + *v = stk500v2_vtarget_value(pgm); + return 0; +} + + static int stk500v2_set_varef(const PROGRAMMER *pgm, unsigned int chan /* unused */, double v) { @@ -3263,6 +3237,14 @@ static int stk500v2_set_varef(const PROGRAMMER *pgm, unsigned int chan /* unused } +static int stk500v2_get_varef(const PROGRAMMER *pgm, unsigned int chan /* unused */, + double *v) +{ + *v = stk500v2_varef_value(pgm); + return 0; +} + + static int stk500v2_set_fosc(const PROGRAMMER *pgm, double v) { int fosc; unsigned char prescale, cmatch; @@ -3312,6 +3294,13 @@ static int stk500v2_set_fosc(const PROGRAMMER *pgm, double v) { return 0; } + +static int stk500v2_get_fosc(const PROGRAMMER *pgm, double *v) { + *v = stk500v2_fosc_value(pgm); + return 0; +} + + /* The list of SCK frequencies supported by the AVRISP mkII, as listed * in AVR069 */ static double avrispmkIIfreqs[] = { @@ -3411,6 +3400,12 @@ static int stk500v2_set_sck_period(const PROGRAMMER *pgm, double v) { return stk500v2_setparm(pgm, PARAM_SCK_DURATION, dur); } +static int stk500v2_get_sck_period(const PROGRAMMER *pgm, double *v) { + *v = stk500v2_sck_duration_value(pgm) / 1e6; + return 0; +} + + static double stk500v2_sck_to_us(const PROGRAMMER *pgm, unsigned char dur) { double x; @@ -3712,77 +3707,175 @@ static void stk500v2_display(const PROGRAMMER *pgm, const char *p) { } -static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { - unsigned char vtarget = 0, vadjust = 0, osc_pscale = 0, osc_cmatch = 0, sck_duration =0; //XXX 0 is not correct, check caller - unsigned int sck_stk600, clock_conf, dac, oct, varef; - unsigned char vtarget_jtag[4]; +static double stk500v2_vtarget_value(const PROGRAMMER *pgm) { + if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) { + unsigned char vtarget_jtag[4]; + memset(vtarget_jtag, 0, sizeof vtarget_jtag); + PROGRAMMER *pgmcp = pgm_dup(pgm); + pgmcp->cookie = PDATA(pgm)->chained_pdata; + jtagmkII_getparm(pgmcp, PAR_OCD_VTARGET, vtarget_jtag); + pgm_free(pgmcp); + return b2_to_u16(vtarget_jtag) / 1000.0; + } + + if (PDATA(pgm)->pgmtype != PGMTYPE_JTAGICE3) { + unsigned char vtarget = 0; + stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget); + return vtarget / 10.0; + } + + return 0; +} + + +static double stk500v2_sck_duration_value(const PROGRAMMER *pgm) { + unsigned char sck_duration = 0; + unsigned int sck_stk600 = 0; + + switch (PDATA(pgm)->pgmtype) { + case PGMTYPE_STK500: + stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration); + return stk500v2_sck_to_us(pgm, sck_duration); + + case PGMTYPE_AVRISP_MKII: + case PGMTYPE_JTAGICE_MKII: + stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration); + return 1.0e6 / avrispmkIIfreqs[sck_duration]; + + case PGMTYPE_JTAGICE3: + { + unsigned char cmd[4]; + cmd[0] = CMD_GET_SCK; + if (stk500v2_jtag3_send(pgm, cmd, 1) >= 0 && stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) { + unsigned int sck = cmd[1] | (cmd[2] << 8); + return (1E6 / (1000.0 * sck)); + } + return 0; + } + + case PGMTYPE_STK600: + stk500v2_getparm2(pgm, PARAM2_SCK_DURATION, &sck_stk600); + return (sck_stk600 + 1) / 8.0; + + default: + return sck_duration * 8.0e6 / PDATA(pgm)->xtal + 0.05; + } + return 0; +} + + +static double stk500v2_varef_value(const PROGRAMMER *pgm) { + unsigned char vadjust = 0; + if (stk500v2_getparm(pgm, PARAM_VADJUST, &vadjust) < 0) + return 0; + return vadjust / 10.0; +} + + +static double stk600_varef_0_value(const PROGRAMMER *pgm) { + unsigned int varef = 0; + if (stk500v2_getparm2(pgm, PARAM2_AREF0, &varef) < 0) + return 0; + return varef / 100.0; +} + + +static double stk600_varef_1_value(const PROGRAMMER *pgm) { + unsigned int varef = 0; + if (stk500v2_getparm2(pgm, PARAM2_AREF1, &varef) < 0) + return 0; + return varef / 100.0; +} + + +static double stk500v2_fosc_value(const PROGRAMMER *pgm) { + unsigned char osc_pscale = 0, osc_cmatch = 0, sck_duration = 0; + unsigned int clock_conf = 0, dac, oct; int prescale; + double fosc = 0.0; + + switch (PDATA(pgm)->pgmtype) { + case PGMTYPE_STK500: + if (stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale) < 0) + return 0.0; + if (stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch) < 0) + return 0.0; + if (osc_pscale == 0) + return 0.0; + + prescale = 1; + fosc = PDATA(pgm)->xtal / 2; + + switch (osc_pscale) { + case 2: prescale = 8; break; + case 3: prescale = 32; break; + case 4: prescale = 64; break; + case 5: prescale = 128; break; + case 6: prescale = 256; break; + case 7: prescale = 1024; break; + } + fosc /= prescale; + fosc /= (osc_cmatch + 1); + return fosc; + + case PGMTYPE_AVRISP_MKII: + case PGMTYPE_JTAGICE_MKII: + if (stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration) < 0) + return 0.0; + return 1e6 / avrispmkIIfreqs[sck_duration]; + + case PGMTYPE_STK600: + if (stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf) < 0) + return 0.0; + oct = (clock_conf & 0xf000) >> 12u; + dac = (clock_conf & 0x0ffc) >> 2u; + fosc = pow(2, (double)oct) * 2078.0 / (2 - (double)dac / 1024.0); + return fosc; + + default: + return 0.0; + } +} + + +static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { double f; + int decimals; const char *unit; - int decimals = 6; - - memset(vtarget_jtag, 0, sizeof vtarget_jtag); if (pgm->extra_features & HAS_VTARG_READ) { - if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) { - PROGRAMMER *pgmcp = pgm_dup(pgm); - pgmcp->cookie = PDATA(pgm)->chained_pdata; - jtagmkII_getparm(pgmcp, PAR_OCD_VTARGET, vtarget_jtag); - pgm_free(pgmcp); - fmsg_out(fp, "%sVtarget : %.1f V\n", p, b2_to_u16(vtarget_jtag) / 1000.0); - } else if (PDATA(pgm)->pgmtype != PGMTYPE_JTAGICE3) { - stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget); - fmsg_out(fp, "%sVtarget : %.1f V\n", p, vtarget / 10.0); - } + fmsg_out(fp, "%sVtarget : %.1f V\n", p, stk500v2_vtarget_value(pgm)); } switch (PDATA(pgm)->pgmtype) { case PGMTYPE_STK500: - stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration); if (pgm->extra_features & HAS_VAREF_ADJ) { - stk500v2_getparm(pgm, PARAM_VADJUST, &vadjust); - fmsg_out(fp, "%sVaref : %.1f V\n", p, vadjust / 10.0); + fmsg_out(fp, "%sVaref : %.1f V\n", p, stk500v2_varef_value(pgm)); } if (pgm->extra_features & HAS_FOSC_ADJ) { - stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale); - stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch); fmsg_out(fp, "%sOscillator : ", p); - if (osc_pscale == 0) + f = stk500v2_fosc_value(pgm); + if (f == 0.0) fmsg_out(fp, "Off\n"); else { - prescale = 1; - f = PDATA(pgm)->xtal / 2; - - switch (osc_pscale) { - case 2: prescale = 8; break; - case 3: prescale = 32; break; - case 4: prescale = 64; break; - case 5: prescale = 128; break; - case 6: prescale = 256; break; - case 7: prescale = 1024; break; - } - f /= prescale; - f /= (osc_cmatch + 1); decimals = get_decimals(f); f = f_to_kHz_MHz(f, &unit); fmsg_out(fp, "%.*f %s\n", decimals, f, unit); } } + // SCK duration is always available fmsg_out(fp, "%sSCK period : %.1f us\n", p, - stk500v2_sck_to_us(pgm, sck_duration)); - - //const char *unit; + stk500v2_sck_duration_value(pgm)); + // XTAL frequency is always available double f = PDATA(pgm)->xtal; decimals = get_decimals(f); f = f_to_kHz_MHz(f, &unit); fmsg_out(fp, "%sXTAL frequency : %.*f %s\n", p, decimals, f, unit); - break; + break; case PGMTYPE_AVRISP_MKII: case PGMTYPE_JTAGICE_MKII: - stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration); - fmsg_out(fp, "%sSCK period : %.2f us\n", p, - 1000000 / avrispmkIIfreqs[sck_duration]); + fmsg_out(fp, "%sSCK period : %.1f us\n", p, stk500v2_sck_duration_value(pgm)); break; case PGMTYPE_JTAGICE3: @@ -3791,7 +3884,7 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp cmd[0] = CMD_GET_SCK; if (stk500v2_jtag3_send(pgm, cmd, 1) >= 0 && stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) { unsigned int sck = cmd[1] | (cmd[2] << 8); - fmsg_out(fp, "%sSCK period : %.2f us\n", p, (1E6 / (1000.0 * sck))); + fmsg_out(fp, "%sSCK period : %.1f us\n", p, (1E6 / (1000.0 * sck))); } PROGRAMMER *pgmcp = pgm_dup(pgm); pgmcp->cookie = PDATA(pgm)->chained_pdata; @@ -3806,26 +3899,19 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp case PGMTYPE_STK600: if (pgm->extra_features & HAS_VAREF_ADJ) { - stk500v2_getparm2(pgm, PARAM2_AREF0, &varef); - fmsg_out(fp, "%sVaref 0 : %.2f V\n", p, varef / 100.0); - stk500v2_getparm2(pgm, PARAM2_AREF1, &varef); - fmsg_out(fp, "%sVaref 1 : %.2f V\n", p, varef / 100.0); + fmsg_out(fp, "%sVaref 0 : %.2f V\n", p, stk600_varef_0_value(pgm)); + fmsg_out(fp, "%sVaref 1 : %.2f V\n", p, stk600_varef_1_value(pgm)); } - stk500v2_getparm2(pgm, PARAM2_SCK_DURATION, &sck_stk600); - fmsg_out(fp, "%sSCK period : %.2f us\n", p, (sck_stk600 + 1) / 8.0); + fmsg_out(fp, "%sSCK period : %.1f us\n", p, stk500v2_sck_duration_value(pgm)); if (pgm->extra_features & HAS_FOSC_ADJ) { - stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf); - oct = (clock_conf & 0xf000) >> 12u; - dac = (clock_conf & 0x0ffc) >> 2u; - f = pow(2, (double)oct) * 2078.0 / (2 - (double)dac / 1024.0); + f = stk500v2_sck_duration_value(pgm); f = f_to_kHz_MHz(f, &unit); fmsg_out(fp, "%sOscillator : %.3f %s\n", p, f, unit); } break; default: - fmsg_out(fp, "%sSCK period : %.1f us\n", p, - sck_duration * 8.0e6 / PDATA(pgm)->xtal + 0.0499); + fmsg_out(fp, "%sSCK period : %.1f us\n", p, stk500v2_sck_duration_value(pgm)); break; } @@ -4826,6 +4912,7 @@ void stk500v2_initpgm(PROGRAMMER *pgm) { pgm->page_erase = NULL; pgm->print_parms = stk500v2_print_parms; pgm->set_sck_period = stk500v2_set_sck_period; + pgm->get_sck_period = stk500v2_get_sck_period; pgm->perform_osccal = stk500v2_perform_osccal; pgm->parseextparams = stk500v2_parseextparms; pgm->setup = stk500v2_setup; @@ -4837,10 +4924,16 @@ void stk500v2_initpgm(PROGRAMMER *pgm) { */ if (pgm->extra_features & HAS_VTARG_ADJ) pgm->set_vtarget = stk500v2_set_vtarget; - if (pgm->extra_features & HAS_VAREF_ADJ) + if (pgm->extra_features & HAS_VTARG_READ) + pgm->get_vtarget = stk500v2_get_vtarget; + if (pgm->extra_features & HAS_VAREF_ADJ) { pgm->set_varef = stk500v2_set_varef; - if (pgm->extra_features & HAS_FOSC_ADJ) + pgm->get_varef = stk500v2_get_varef; + } + if (pgm->extra_features & HAS_FOSC_ADJ) { pgm->set_fosc = stk500v2_set_fosc; + pgm->get_fosc = stk500v2_get_fosc; + } } const char stk500pp_desc[] = "Atmel STK500 V2 in parallel programming mode"; diff --git a/src/term.c b/src/term.c index 96d1ee7fb..36892ae74 100644 --- a/src/term.c +++ b/src/term.c @@ -105,10 +105,10 @@ struct command cmd[] = { { "part", cmd_part, _fo(open), "display the current part information" }, { "send", cmd_send, _fo(cmd), "send a raw command to the programmer" }, { "parms", cmd_parms, _fo(print_parms), "display useful parameters" }, - { "vtarg", cmd_vtarg, _fo(set_vtarget), "set the target voltage" }, - { "varef", cmd_varef, _fo(set_varef), "set the analog reference voltage" }, - { "fosc", cmd_fosc, _fo(set_fosc), "set the oscillator frequency" }, - { "sck", cmd_sck, _fo(set_sck_period), "set the SCK period" }, + { "vtarg", cmd_vtarg, _fo(set_vtarget), "set or get the target voltage" }, + { "varef", cmd_varef, _fo(set_varef), "set or get the analog reference voltage" }, + { "fosc", cmd_fosc, _fo(set_fosc), "set or get the oscillator frequency" }, + { "sck", cmd_sck, _fo(set_sck_period), "set or get the SCK period" }, { "spi", cmd_spi, _fo(setpin), "enter direct SPI mode" }, { "pgm", cmd_pgm, _fo(setpin), "return to programming mode" }, { "verbose", cmd_verbose, _fo(open), "display or set -v verbosity level" }, @@ -1681,9 +1681,18 @@ static int cmd_parms(const PROGRAMMER *pgm, const AVRPART *p, int argc, char *ar static int cmd_vtarg(const PROGRAMMER *pgm, const AVRPART *p, int argc, char *argv[]) { int rc; - double v; + double v = 0; char *endp; + if (argc == 1 && pgm->get_vtarget){ // no parameter: query vtarg if fkt exists + if ((rc = pgm->get_vtarget(pgm, &v)) != 0) { + pmsg_error("(vtarg) unable to get V[target] (rc = %d)\n", rc); + return -3; + } + term_out("Vtarget = %.1f V\n", v); + return 0; + } + if(argc != 2 || (argc > 1 && str_eq(argv[1], "-?"))) { msg_error( "Syntax: vtarg \n" @@ -1706,9 +1715,25 @@ static int cmd_vtarg(const PROGRAMMER *pgm, const AVRPART *p, int argc, char *ar static int cmd_fosc(const PROGRAMMER *pgm, const AVRPART *p, int argc, char *argv[]) { int rc; - double v; + double v = 0; char *endp; + if (argc == 1 && pgm->get_fosc) { // query fosc + if ((rc = pgm->get_fosc(pgm, &v)) != 0) { + pmsg_error("(fosc) unable to get oscillator frequency (rc = %d)\n", rc); + return -3; + } + if (v >= 1e6) + term_out("fosc = %.6f MHz\n", v / 1e6); + else if (v >= 1e3) + term_out("fosc = %.3f kHz\n", v / 1e3); + else if (v) + term_out("fosc = %.0f Hz\n", v); + else + term_out("fosc off\n"); + return 0; + } + if(argc != 2 || (argc > 1 && str_eq(argv[1], "-?"))) { msg_error( "Syntax: fosc [M|k] | off\n" @@ -1742,6 +1767,15 @@ static int cmd_sck(const PROGRAMMER *pgm, const AVRPART *p, int argc, char *argv double v; char *endp; + if (argc == 1 && pgm->get_sck_period){ + if ((rc = pgm->get_sck_period(pgm, &v)) != 0) { + pmsg_error("(fosc) unable to get sck period (rc = %d)\n", rc); + return -3; + } + term_out("SCK period = %.1f us\n", v * 1e6 ); + return 0; + } + if(argc != 2 || (argc > 1 && str_eq(argv[1], "-?"))) { msg_error( "Syntax: sck \n" @@ -1769,6 +1803,15 @@ static int cmd_varef(const PROGRAMMER *pgm, const AVRPART *p, int argc, char *ar double v; char *endp; + if (argc == 1 && pgm->get_varef) { // varef w/o parameter returns value of channel 0 + if ((rc = pgm->get_varef(pgm, 0, &v)) != 0) { + pmsg_error("(varef) unable to get V[aref] (rc = %d)\n", rc); + return -3; + } + term_out("Varef = %.1f V\n", v); + return 0; + } + if (argc < 2 || argc > 3 || (argc > 1 && str_eq(argv[1], "-?"))) { msg_error( "Syntax: varef [channel] \n"