mirror of
https://github.com/avrdudes/avrdude.git
synced 2026-09-22 09:06:23 +03:00
Merge pull request #1345 from MCUdude/more-extra-parameters
Add `-xvtarg`, `-xvaref` and `-xfosc` extended parameters
This commit is contained in:
@@ -1185,14 +1185,20 @@ bits before, and
|
||||
bits after the target AVR, respectively.
|
||||
Each AVR unit within the chain shifts by 4 bits.
|
||||
Other JTAG units might require a different bit shift count.
|
||||
.El
|
||||
.Pp
|
||||
The PICkit 4 and the Power Debugger also supports high-voltage UPDI programming.
|
||||
This is used to enable a UPDI pin that has previously been set to RESET or
|
||||
GPIO mode. High-voltage UPDI can be utilized by using an extended parameter:
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar hvupdi
|
||||
Enable high-voltage UPDI initialization for targets that supports this.
|
||||
.Nm Power Debugger and Pickit 4 only
|
||||
.sp 0.5
|
||||
High-voltage UPDI programming is used to enable a UPDI pin that has previously
|
||||
been set to RESET or GPIO mode. Use
|
||||
.Ar -xhvupdi
|
||||
to enable high-voltage UPDI initialization for targets that supports this.
|
||||
.It Ar vtarg=VALUE, vtarg
|
||||
.Nm Power Debugger only
|
||||
.sp 0.5
|
||||
The voltage generator can be enabled by setting a target voltage.
|
||||
The current set-voltage can be read by
|
||||
.Ar -xvtarg
|
||||
alone.
|
||||
.It Ar help
|
||||
Show help menu and exit.
|
||||
.El
|
||||
@@ -1228,6 +1234,51 @@ Also note that the smaller Xplained Nano boards does not have a target power swi
|
||||
.It Ar help
|
||||
Show help menu and exit.
|
||||
.El
|
||||
.It Ar Curiosity Nano
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar vtarg=VALUE, vtarg
|
||||
The generated on-board target voltage can be changed by specifying a new voltage.
|
||||
The current set-voltage can be read by
|
||||
.Ar -xvtarg
|
||||
alone.
|
||||
.It Ar help
|
||||
Show help menu and exit.
|
||||
.El
|
||||
.It Ar STK500
|
||||
.It Ar STK600
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar vtarg=VALUE, vtarg
|
||||
The generated on-board target voltage can be changed by specifying a new voltage.
|
||||
The current set-voltage can be read by
|
||||
.Ar -xvtarg
|
||||
alone.
|
||||
.It Ar fosc=VALUE[MHz|M|kHz|k|Hz], fosc
|
||||
Set the programmable oscillator frequency. The current frequency can be read by
|
||||
.Ar -xfosc
|
||||
alone.
|
||||
.It Ar varef=VALUE, varef
|
||||
The generated on-board analog reference voltage can be changed by specifying
|
||||
a new reference voltage. The current reference voltage can be read by
|
||||
.Ar -xvaref
|
||||
alone.
|
||||
.It Ar varef[0,1]=VALUE, varef[0,1]
|
||||
.Nm STK600 only
|
||||
.sp 0.5
|
||||
The generated on-board analog reference voltage for channel 0 or channel 1 can
|
||||
be changed by specifying a new reference voltage.
|
||||
The current reference voltage can be read by
|
||||
.Ar -xvaref0
|
||||
or
|
||||
.Ar -xvaref1
|
||||
alone.
|
||||
.It Ar attemps[=<1..99>]
|
||||
.Nm STK500V1 only
|
||||
.sp 0.5
|
||||
Specify how many connection retry attemps to perform before exiting.
|
||||
Defaults to 10 if not specified.
|
||||
.It Ar help
|
||||
Show help menu and exit.
|
||||
.El
|
||||
.It Ar AVR910
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar devcode=VALUE
|
||||
@@ -1260,6 +1311,8 @@ Show help menu and exit.
|
||||
.It Ar attemps[=<1..99>]
|
||||
Specify how many connection retry attemps to perform before exiting.
|
||||
Defaults to 10 if not specified.
|
||||
.It Ar help
|
||||
Show help menu and exit.
|
||||
.El
|
||||
.It Ar Urclock
|
||||
.Bl -tag -offset indent -width indent
|
||||
@@ -1534,14 +1587,6 @@ line.
|
||||
.It Ar help
|
||||
Show help menu and exit.
|
||||
.El
|
||||
.It Ar STK500
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar attemps[=<1..99>]
|
||||
Specify how many connection retry attemps to perform before exiting.
|
||||
Defaults to 10 if not specified.
|
||||
.It Ar help
|
||||
Show help menu and exit.
|
||||
.El
|
||||
.It Ar serialupdi
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar rtsdtr=low,high
|
||||
@@ -1563,6 +1608,7 @@ the CS line being managed outside the application.
|
||||
.It Ar help
|
||||
Show help menu and exit.
|
||||
.El
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -offset indent -width /dev/ppi0XXX
|
||||
.It Pa /dev/ppi0
|
||||
|
||||
@@ -71,6 +71,10 @@
|
||||
# # - HAS_VTARG_SWITCH: Programer has a programmable target power switch
|
||||
# # - HAS_VTARG_ADJ: Programmer has an adjustable target power source that can
|
||||
# # be controlled with Avrdude
|
||||
# # - HAS_FOSC_ADJ: Programmer has a programable frequency generator that
|
||||
# # can clock an AVR directly through its XTAL1 pin
|
||||
# # - HAS_VAREF_ADJ: Programmer has an adjustable analog reference voltage that
|
||||
# # can be controlled with Avrdude
|
||||
# #
|
||||
# # (3) Not all programmer types can process a list of PIDs
|
||||
#
|
||||
@@ -1285,6 +1289,7 @@ programmer
|
||||
desc = "Atmel STK500";
|
||||
type = "stk500generic";
|
||||
prog_modes = PM_ISP;
|
||||
extra_features = HAS_VTARG_ADJ | HAS_VTARG_READ | HAS_FOSC_ADJ | HAS_VAREF_ADJ;
|
||||
connection_type = serial;
|
||||
;
|
||||
|
||||
@@ -1297,6 +1302,7 @@ programmer
|
||||
desc = "Atmel STK500 version 1.x firmware";
|
||||
type = "stk500";
|
||||
prog_modes = PM_ISP;
|
||||
extra_features = HAS_VTARG_ADJ | HAS_VTARG_READ | HAS_FOSC_ADJ | HAS_VAREF_ADJ;
|
||||
connection_type = serial;
|
||||
;
|
||||
|
||||
@@ -1321,6 +1327,7 @@ programmer
|
||||
desc = "Atmel STK500 version 2.x firmware";
|
||||
type = "stk500v2";
|
||||
prog_modes = PM_TPI | PM_ISP;
|
||||
extra_features = HAS_VTARG_ADJ | HAS_VTARG_READ | HAS_FOSC_ADJ | HAS_VAREF_ADJ;
|
||||
connection_type = serial;
|
||||
;
|
||||
|
||||
@@ -1333,6 +1340,7 @@ programmer
|
||||
desc = "Atmel STK500 v2 in parallel programming mode";
|
||||
type = "stk500pp";
|
||||
prog_modes = PM_HVPP;
|
||||
extra_features = HAS_VTARG_ADJ | HAS_VTARG_READ | HAS_FOSC_ADJ | HAS_VAREF_ADJ;
|
||||
connection_type = serial;
|
||||
;
|
||||
|
||||
@@ -1345,6 +1353,7 @@ programmer
|
||||
desc = "Atmel STK500 v2 in high-voltage serial programming mode";
|
||||
type = "stk500hvsp";
|
||||
prog_modes = PM_HVSP;
|
||||
extra_features = HAS_VTARG_ADJ | HAS_VTARG_READ | HAS_FOSC_ADJ | HAS_VAREF_ADJ;
|
||||
connection_type = serial;
|
||||
;
|
||||
|
||||
@@ -1357,7 +1366,7 @@ programmer
|
||||
desc = "Atmel STK600";
|
||||
type = "stk600";
|
||||
prog_modes = PM_TPI | PM_ISP | PM_PDI;
|
||||
extra_features = HAS_VTARG_ADJ | HAS_VTARG_READ;
|
||||
extra_features = HAS_VTARG_ADJ | HAS_VTARG_READ | HAS_FOSC_ADJ | HAS_VAREF_ADJ;
|
||||
connection_type = usb;
|
||||
;
|
||||
|
||||
@@ -1370,7 +1379,7 @@ programmer
|
||||
desc = "Atmel STK600 in parallel programming mode";
|
||||
type = "stk600pp";
|
||||
prog_modes = PM_HVPP;
|
||||
extra_features = HAS_VTARG_ADJ | HAS_VTARG_READ;
|
||||
extra_features = HAS_VTARG_ADJ | HAS_VTARG_READ | HAS_FOSC_ADJ | HAS_VAREF_ADJ;
|
||||
connection_type = usb;
|
||||
;
|
||||
|
||||
@@ -1383,7 +1392,7 @@ programmer
|
||||
desc = "Atmel STK600 in high-voltage serial programming mode";
|
||||
type = "stk600hvsp";
|
||||
prog_modes = PM_HVSP;
|
||||
extra_features = HAS_VTARG_ADJ | HAS_VTARG_READ;
|
||||
extra_features = HAS_VTARG_ADJ | HAS_VTARG_READ | HAS_FOSC_ADJ | HAS_VAREF_ADJ;
|
||||
connection_type = usb;
|
||||
;
|
||||
|
||||
|
||||
50
src/config.c
50
src/config.c
@@ -336,26 +336,28 @@ TOKEN *new_constant(const char *con) {
|
||||
|
||||
tkn->value.type = V_NUM;
|
||||
tkn->value.number =
|
||||
!strcmp("PM_SPM", con)? PM_SPM:
|
||||
!strcmp("PM_TPI", con)? PM_TPI:
|
||||
!strcmp("PM_ISP", con)? PM_ISP:
|
||||
!strcmp("PM_PDI", con)? PM_PDI:
|
||||
!strcmp("PM_UPDI", con)? PM_UPDI:
|
||||
!strcmp("PM_HVSP", con)? PM_HVSP:
|
||||
!strcmp("PM_HVPP", con)? PM_HVPP:
|
||||
!strcmp("PM_debugWIRE", con)? PM_debugWIRE:
|
||||
!strcmp("PM_JTAG", con)? PM_JTAG:
|
||||
!strcmp("PM_JTAGmkI", con)? PM_JTAGmkI:
|
||||
!strcmp("PM_XMEGAJTAG", con)? PM_XMEGAJTAG:
|
||||
!strcmp("PM_AVR32JTAG", con)? PM_AVR32JTAG:
|
||||
!strcmp("PM_aWire", con)? PM_aWire:
|
||||
!strcmp("HAS_SUFFER", con)? HAS_SUFFER:
|
||||
!strcmp("HAS_VTARG_SWITCH", con)? HAS_VTARG_SWITCH:
|
||||
!strcmp("HAS_VTARG_ADJ", con)? HAS_VTARG_ADJ:
|
||||
!strcmp("HAS_VTARG_READ", con)? HAS_VTARG_READ:
|
||||
!strcmp("pseudo", con)? 2:
|
||||
!strcmp("yes", con) || !strcmp("true", con)? 1:
|
||||
!strcmp("no", con) || !strcmp("false", con)? 0:
|
||||
str_eq(con, "PM_SPM")? PM_SPM:
|
||||
str_eq(con, "PM_TPI")? PM_TPI:
|
||||
str_eq(con, "PM_ISP")? PM_ISP:
|
||||
str_eq(con, "PM_PDI")? PM_PDI:
|
||||
str_eq(con, "PM_UPDI")? PM_UPDI:
|
||||
str_eq(con, "PM_HVSP")? PM_HVSP:
|
||||
str_eq(con, "PM_HVPP")? PM_HVPP:
|
||||
str_eq(con, "PM_debugWIRE")? PM_debugWIRE:
|
||||
str_eq(con, "PM_JTAG")? PM_JTAG:
|
||||
str_eq(con, "PM_JTAGmkI")? PM_JTAGmkI:
|
||||
str_eq(con, "PM_XMEGAJTAG")? PM_XMEGAJTAG:
|
||||
str_eq(con, "PM_AVR32JTAG")? PM_AVR32JTAG:
|
||||
str_eq(con, "PM_aWire")? PM_aWire:
|
||||
str_eq(con, "HAS_SUFFER")? HAS_SUFFER:
|
||||
str_eq(con, "HAS_VTARG_SWITCH")? HAS_VTARG_SWITCH:
|
||||
str_eq(con, "HAS_VTARG_ADJ")? HAS_VTARG_ADJ:
|
||||
str_eq(con, "HAS_VTARG_READ")? HAS_VTARG_READ:
|
||||
str_eq(con, "HAS_FOSC_ADJ")? HAS_FOSC_ADJ:
|
||||
str_eq(con, "HAS_VAREF_ADJ")? HAS_VAREF_ADJ:
|
||||
str_eq(con, "pseudo")? 2:
|
||||
str_eq(con, "yes") || str_eq(con, "true")? 1:
|
||||
str_eq(con, "no") || str_eq(con, "false")? 0:
|
||||
(assigned = 0);
|
||||
|
||||
if(!assigned) {
|
||||
@@ -495,7 +497,7 @@ const char *cache_string(const char *p) {
|
||||
hs = hstrings[h] = (char **) cfg_realloc("cache_string()", NULL, (16+1)*sizeof**hstrings);
|
||||
|
||||
for(k=0; hs[k]; k++)
|
||||
if(*p == *hs[k] && !strcmp(p, hs[k]))
|
||||
if(*p == *hs[k] && str_eq(p, hs[k]))
|
||||
return hs[k];
|
||||
|
||||
if(k && k%16 == 0)
|
||||
@@ -520,7 +522,7 @@ COMMENT *locate_comment(const LISTID comments, const char *where, int rhs) {
|
||||
if(comments)
|
||||
for(LNODEID ln=lfirst(comments); ln; ln=lnext(ln)) {
|
||||
COMMENT *n = ldata(ln);
|
||||
if(n && rhs == n->rhs && n->kw && strcmp(where, n->kw) == 0)
|
||||
if(n && rhs == n->rhs && n->kw && str_eq(where, n->kw))
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -563,7 +565,7 @@ void capture_comment_str(const char *com, int lineno) {
|
||||
|
||||
// Capture assignments (keywords left of =) and associate comments to them
|
||||
void capture_lvalue_kw(const char *kw, int lineno) {
|
||||
if(!strcmp(kw, "memory")) { // Push part comments and start memory comments
|
||||
if(str_eq(kw, "memory")) { // Push part comments and start memory comments
|
||||
if(!cfg_pushed) { // config_gram.y pops the part comments
|
||||
cfg_pushed = 1;
|
||||
cfg_pushedcomms = cfg_strctcomms;
|
||||
@@ -571,7 +573,7 @@ void capture_lvalue_kw(const char *kw, int lineno) {
|
||||
}
|
||||
}
|
||||
|
||||
if(!strcmp(kw, "programmer") || !strcmp(kw, "part") || !strcmp(kw, "memory"))
|
||||
if(str_eq(kw, "programmer") || str_eq(kw, "part") || str_eq(kw, "memory"))
|
||||
kw = "*"; // Show comment before programmer/part/memory
|
||||
|
||||
if(lkw)
|
||||
|
||||
@@ -256,6 +256,10 @@ static char *extra_features_str(int m) {
|
||||
strcat(mode, " | HAS_VTARG_ADJ");
|
||||
if(m & HAS_VTARG_READ)
|
||||
strcat(mode, " | HAS_VTARG_READ");
|
||||
if(m & HAS_FOSC_ADJ)
|
||||
strcat(mode, " | HAS_FOSC_ADJ");
|
||||
if(m & HAS_VAREF_ADJ)
|
||||
strcat(mode, " | HAS_VAREF_ADJ");
|
||||
|
||||
return mode + (mode[1] == 0? 0: 4);
|
||||
}
|
||||
|
||||
@@ -940,14 +940,19 @@ after, @var{BB} bits before, and @var{BA} bits after the target AVR,
|
||||
respectively.
|
||||
Each AVR unit within the chain shifts by 4 bits.
|
||||
Other JTAG units might require a different bit shift count.
|
||||
@end table
|
||||
|
||||
The PICkit 4 and the Power Debugger also supports high-voltage UPDI programming.
|
||||
This is used to enable a UPDI pin that has previously been set to RESET or
|
||||
GPIO mode. High-voltage UPDI can be utilized by using an extended parameter:
|
||||
@table @code
|
||||
@item @samp{hvupdi}
|
||||
Enable high-voltage UPDI initialization for targets that supports this.
|
||||
@var{Power Debugger and Pickit 4 only}
|
||||
@*
|
||||
High-voltage UPDI programming is used to enable a UPDI pin that has previously
|
||||
been set to RESET or GPIO mode. Use @samp{-xhvupdi} to enable high-voltage UPDI
|
||||
initialization for supported targets.
|
||||
|
||||
@item @samp{vtarg=VALUE, vtarg}
|
||||
@var{Power Debugger only}
|
||||
@*
|
||||
The voltage generator can be enabled by setting a target voltage.
|
||||
The current set-voltage can be read by @samp{-xvtarg} alone.
|
||||
|
||||
@item @samp{help}
|
||||
Show help menu and exit.
|
||||
@@ -988,6 +993,51 @@ Also note that the smaller Xplained Nano boards does not have a target power swi
|
||||
Show help menu and exit.
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} Curiosity Nano
|
||||
@item Curiosity Nano
|
||||
|
||||
The Curiosity Nano board accepts the following extended parameter:
|
||||
@table @code
|
||||
@item @samp{vtarg=VALUE, vtarg}
|
||||
The generated on-board target voltage can be changed by specifying a new voltage.
|
||||
The current set-voltage can be read by @samp{-xvtarg} alone.
|
||||
@item @samp{help}
|
||||
Show help menu and exit.
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} STK500
|
||||
@cindex @code{-x} STK600
|
||||
@item STK500
|
||||
@item STK600
|
||||
|
||||
The STK500 and STK600 boards accept the following extended parameters:
|
||||
@table @code
|
||||
@item @samp{vtarg=VALUE, vtarg}
|
||||
The generated on-board target voltage can be changed by specifying a new voltage.
|
||||
The current set-voltage can be read by @samp{-xvtarg} alone.
|
||||
@item @samp{fosc=VALUE[MHz|M|kHz|k|Hz], fosc}
|
||||
Set the programmable oscillator frequency in MHz, kHz or Hz.
|
||||
The current frequency can be read by @samp{-xfosc} alone.
|
||||
@item @samp{varef=VALUE, varef}
|
||||
The generated on-board analog reference voltage can be changed by specifying
|
||||
a new reference voltage. The current reference voltage can be read by
|
||||
@samp{-xvaref} alone.
|
||||
@item @samp{varef[0,1]=VALUE, varef[0,1]}
|
||||
@var{STK600 only}
|
||||
@*
|
||||
The generated on-board analog reference voltage for channel 0 or channel 1 can
|
||||
be changed by specifying a new reference voltage.
|
||||
The current reference voltage can be read by @samp{-xvaref0} or
|
||||
@samp{-xvaref1} alone.
|
||||
@item @samp{attemps[=<1..99>]}
|
||||
@var{STK500V1 only}
|
||||
@*
|
||||
Specify how many connection retry attemps to perform before exiting.
|
||||
Defaults to 10 if not specified.
|
||||
@item @samp{help}
|
||||
Show help menu and exit.
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} AVR910
|
||||
@item AVR910
|
||||
|
||||
|
||||
167
src/jtag3.c
167
src/jtag3.c
@@ -84,6 +84,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;
|
||||
|
||||
/* Function to set the appropriate clock parameter */
|
||||
int (*set_sck)(const PROGRAMMER *, unsigned char *);
|
||||
};
|
||||
@@ -1099,7 +1104,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
if (PDATA(pgm)->set_sck(pgm, parm) < 0)
|
||||
return -1;
|
||||
}
|
||||
jtag3_print_parms1(pgm, progbuf, stderr);
|
||||
|
||||
if (conn == PARM3_CONN_JTAG) {
|
||||
pmsg_notice2("jtag3_initialize(): "
|
||||
"trying to set JTAG daisy-chain info to %d,%d,%d,%d\n",
|
||||
@@ -1109,6 +1114,9 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (verbose && quell_progress < 2)
|
||||
jtag3_print_parms1(pgm, progbuf, stderr);
|
||||
|
||||
// Read or write SUFFER register
|
||||
if (PDATA(pgm)->suffer_get || PDATA(pgm)->suffer_set) {
|
||||
// Read existing SUFFER value
|
||||
@@ -1144,6 +1152,26 @@ static int 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(pgm, 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(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) {
|
||||
msg_warning("Cannot set target voltage %.2fV\n", PDATA(pgm)->vtarg_data);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set device descriptor data */
|
||||
if ((p->prog_modes & PM_PDI)) {
|
||||
struct xmega_device_desc xd;
|
||||
@@ -1528,6 +1556,29 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
// Get target voltage
|
||||
else if(str_eq(extended_param, "vtarg")) {
|
||||
PDATA(pgm)->vtarg_get = true;
|
||||
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);
|
||||
@@ -1541,6 +1592,10 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
|
||||
msg_error(" -xvtarg_switch Read on-board target voltage switch state\n");
|
||||
msg_error(" -xvtarg_switch=<0..1> Set on-board target voltage switch state\n");
|
||||
}
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ) {
|
||||
msg_error(" -xvtarg Read on-board target supply voltage\n");
|
||||
msg_error(" -xvtarg=<arg> Set on-board target supply voltage\n");
|
||||
}
|
||||
msg_error (" -xhelp Show this help menu and exit\n");
|
||||
exit(0);
|
||||
}
|
||||
@@ -2496,7 +2551,7 @@ void jtag3_display(const PROGRAMMER *pgm, const char *p) {
|
||||
msg_info("%sICE HW version : %d\n", p, parms[0]);
|
||||
msg_info("%sICE FW version : %d.%02d (rel. %d)\n", p, parms[1], parms[2],
|
||||
(parms[3] | (parms[4] << 8)));
|
||||
msg_info("%sSerial number : %s", p, sn);
|
||||
msg_info("%sSerial number : %s\n", p, sn);
|
||||
free(resp);
|
||||
}
|
||||
|
||||
@@ -2509,6 +2564,39 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) {
|
||||
return;
|
||||
msg_info("%sVtarget : %.2f V\n", p, b2_to_u16(buf)/1000.0);
|
||||
|
||||
// Print clocks if programmer typ is not 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;
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, &prog_mode[1], 1) < 0)
|
||||
return;
|
||||
if (prog_mode[0] == PARM3_CONN_JTAG) {
|
||||
if (prog_mode[1] == PARM3_ARCH_XMEGA) {
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, buf, 2) < 0)
|
||||
return;
|
||||
if (b2_to_u16(buf) > 0)
|
||||
fmsg_out(fp, "%sJTAG clk Xmega : %u kHz\n", p, b2_to_u16(buf));
|
||||
} else {
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0)
|
||||
return;
|
||||
if (b2_to_u16(buf) > 0)
|
||||
fmsg_out(fp, "%sJTAG clk prog. : %u kHz\n", p, b2_to_u16(buf));
|
||||
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_DEBUG, buf, 2) < 0)
|
||||
return;
|
||||
if (b2_to_u16(buf) > 0)
|
||||
fmsg_out(fp, "%sJTAG clk debug : %u kHz\n", p, b2_to_u16(buf));
|
||||
}
|
||||
}
|
||||
else if (prog_mode[0] == PARM3_CONN_PDI || prog_mode[0] == PARM3_CONN_UPDI) {
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, buf, 2) < 0)
|
||||
return;
|
||||
if (b2_to_u16(buf) > 0)
|
||||
fmsg_out(fp, "%sPDI/UPDI clk : %u kHz\n", p, b2_to_u16(buf));
|
||||
}
|
||||
}
|
||||
|
||||
// Print features unique to the Power Debugger
|
||||
for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) {
|
||||
if(str_starts(ldata(ln), "powerdebugger")) {
|
||||
@@ -2579,39 +2667,6 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Print clocks if programmer typ is not TPI
|
||||
if (strcmp(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;
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, &prog_mode[1], 1) < 0)
|
||||
return;
|
||||
if (prog_mode[0] == PARM3_CONN_JTAG) {
|
||||
if (prog_mode[1] == PARM3_ARCH_XMEGA) {
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, buf, 2) < 0)
|
||||
return;
|
||||
if (b2_to_u16(buf) > 0)
|
||||
fmsg_out(fp, "%sJTAG clk Xmega : %u kHz\n", p, b2_to_u16(buf));
|
||||
} else {
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0)
|
||||
return;
|
||||
if (b2_to_u16(buf) > 0)
|
||||
fmsg_out(fp, "%sJTAG clk prog. : %u kHz\n", p, b2_to_u16(buf));
|
||||
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_DEBUG, buf, 2) < 0)
|
||||
return;
|
||||
if (b2_to_u16(buf) > 0)
|
||||
fmsg_out(fp, "%sJTAG clk debug : %u kHz\n", p, b2_to_u16(buf));
|
||||
}
|
||||
}
|
||||
else if (prog_mode[0] == PARM3_CONN_PDI || prog_mode[0] == PARM3_CONN_UPDI) {
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, buf, 2) < 0)
|
||||
return;
|
||||
if (b2_to_u16(buf) > 0)
|
||||
fmsg_out(fp, "%sPDI/UPDI clk : %u kHz\n", p, b2_to_u16(buf));
|
||||
}
|
||||
}
|
||||
fmsg_out(fp, "\n");
|
||||
}
|
||||
|
||||
@@ -2761,6 +2816,29 @@ static int jtag3_initialize_tpi(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
unsigned char* resp;
|
||||
int status;
|
||||
|
||||
// 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(pgm, 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(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) {
|
||||
msg_warning("Cannot set target voltage %.2fV\n", PDATA(pgm)->vtarg_data);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose && quell_progress < 2)
|
||||
jtag3_print_parms1(pgm, progbuf, stderr);
|
||||
|
||||
pmsg_notice2("jtag3_initialize_tpi() start\n");
|
||||
|
||||
cmd[0] = XPRG_CMD_ENTER_PROGMODE;
|
||||
@@ -2785,8 +2863,6 @@ static int jtag3_initialize_tpi(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
return -1;
|
||||
free(resp);
|
||||
|
||||
jtag3_print_parms1(pgm, progbuf, stderr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3100,6 +3176,9 @@ void jtag3_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->page_size = 256;
|
||||
pgm->flag = PGM_FL_IS_JTAG;
|
||||
|
||||
/*
|
||||
* hardware dependent functions
|
||||
*/
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ)
|
||||
pgm->set_vtarget = jtag3_set_vtarget;
|
||||
}
|
||||
@@ -3129,11 +3208,15 @@ void jtag3_dw_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->paged_write = jtag3_paged_write;
|
||||
pgm->paged_load = jtag3_paged_load;
|
||||
pgm->print_parms = jtag3_print_parms;
|
||||
pgm->parseextparams = jtag3_parseextparms;
|
||||
pgm->setup = jtag3_setup;
|
||||
pgm->teardown = jtag3_teardown;
|
||||
pgm->page_size = 256;
|
||||
pgm->flag = PGM_FL_IS_DW;
|
||||
|
||||
/*
|
||||
* hardware dependent functions
|
||||
*/
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ)
|
||||
pgm->set_vtarget = jtag3_set_vtarget;
|
||||
}
|
||||
@@ -3165,11 +3248,15 @@ void jtag3_pdi_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->page_erase = jtag3_page_erase;
|
||||
pgm->print_parms = jtag3_print_parms;
|
||||
pgm->set_sck_period = jtag3_set_sck_period;
|
||||
pgm->parseextparams = jtag3_parseextparms;
|
||||
pgm->setup = jtag3_setup;
|
||||
pgm->teardown = jtag3_teardown;
|
||||
pgm->page_size = 256;
|
||||
pgm->flag = PGM_FL_IS_PDI;
|
||||
|
||||
/*
|
||||
* hardware dependent functions
|
||||
*/
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ)
|
||||
pgm->set_vtarget = jtag3_set_vtarget;
|
||||
}
|
||||
@@ -3183,7 +3270,6 @@ void jtag3_updi_initpgm(PROGRAMMER *pgm) {
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->initialize = jtag3_initialize;
|
||||
pgm->parseextparams = jtag3_parseextparms;
|
||||
pgm->display = jtag3_display;
|
||||
pgm->enable = jtag3_enable;
|
||||
pgm->disable = jtag3_disable;
|
||||
@@ -3202,6 +3288,7 @@ void jtag3_updi_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->page_erase = jtag3_page_erase;
|
||||
pgm->print_parms = jtag3_print_parms;
|
||||
pgm->set_sck_period = jtag3_set_sck_period;
|
||||
pgm->parseextparams = jtag3_parseextparms;
|
||||
pgm->setup = jtag3_setup;
|
||||
pgm->teardown = jtag3_teardown;
|
||||
pgm->page_size = 256;
|
||||
@@ -3209,6 +3296,9 @@ void jtag3_updi_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->unlock = jtag3_unlock_erase_key;
|
||||
pgm->read_sib = jtag3_read_sib;
|
||||
|
||||
/*
|
||||
* hardware dependent functions
|
||||
*/
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ)
|
||||
pgm->set_vtarget = jtag3_set_vtarget;
|
||||
}
|
||||
@@ -3238,6 +3328,7 @@ void jtag3_tpi_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->paged_write = jtag3_paged_write_tpi;
|
||||
pgm->paged_load = jtag3_paged_load_tpi;
|
||||
pgm->print_parms = jtag3_print_parms;
|
||||
pgm->parseextparams = jtag3_parseextparms;
|
||||
pgm->setup = jtag3_setup;
|
||||
pgm->teardown = jtag3_teardown;
|
||||
pgm->page_size = 256;
|
||||
|
||||
@@ -145,7 +145,7 @@ SIGN [+-]
|
||||
|
||||
|
||||
(?x: PM_(SPM|TPI|ISP|PDI|UPDI|HVSP|HVPP|debugWIRE|JTAG|JTAGmkI|XMEGAJTAG|AVR32JTAG|aWire) |
|
||||
HAS_(SUFFER|VTARG_SWITCH|VTARG_ADJ|VTARG_READ) |
|
||||
HAS_(SUFFER|VTARG_SWITCH|VTARG_ADJ|VTARG_READ|FOSC_ADJ|VAREF_ADJ) |
|
||||
yes|no|pseudo | true|false ) { /* Constants */
|
||||
yylval = new_constant(yytext);
|
||||
return TKN_NUMBER;
|
||||
|
||||
@@ -215,6 +215,8 @@ typedef struct opcode {
|
||||
#define HAS_VTARG_SWITCH 2
|
||||
#define HAS_VTARG_ADJ 4
|
||||
#define HAS_VTARG_READ 8
|
||||
#define HAS_FOSC_ADJ 16
|
||||
#define HAS_VAREF_ADJ 32
|
||||
|
||||
#define AVR_FAMILYIDLEN 7
|
||||
#define AVR_SIBLEN 16
|
||||
|
||||
215
src/stk500.c
215
src/stk500.c
@@ -45,6 +45,18 @@
|
||||
#define STK500_XTAL 7372800U
|
||||
#define MAX_SYNC_ATTEMPTS 10
|
||||
|
||||
static double f_to_kHz_MHz(double f, const char **unit) {
|
||||
if (f > 1e6) {
|
||||
f /= 1e6;
|
||||
*unit = "MHz";
|
||||
} else if (f > 1e3) {
|
||||
f /= 1000;
|
||||
*unit = "kHz";
|
||||
} else
|
||||
*unit = "Hz";
|
||||
return f;
|
||||
}
|
||||
|
||||
static int stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value);
|
||||
static int stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value);
|
||||
static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp);
|
||||
@@ -557,6 +569,73 @@ static int stk500_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 int vtarg_read;
|
||||
stk500_getparm(pgm, Parm_STK_VTARGET, &vtarg_read);
|
||||
if (PDATA(pgm)->vtarg_get)
|
||||
msg_info("Target voltage value read as %.2fV\n", (vtarg_read / 10.0));
|
||||
// Write target voltage value
|
||||
else {
|
||||
msg_info("Changing target voltage from %.2f to %.2fV\n", (vtarg_read / 10.0), PDATA(pgm)->vtarg_data);
|
||||
if(pgm->set_vtarget(pgm, PDATA(pgm)->vtarg_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Read or write analog reference voltage
|
||||
if (PDATA(pgm)->varef_get || PDATA(pgm)->varef_set) {
|
||||
// Read current analog reference voltage
|
||||
unsigned int varef_read;
|
||||
stk500_getparm(pgm, Parm_STK_VADJUST, &varef_read);
|
||||
if (PDATA(pgm)->varef_get)
|
||||
msg_info("Analog reference voltage value read as %.2fV\n", (varef_read / 10.0));
|
||||
// Write analog reference voltage
|
||||
else {
|
||||
msg_info("Changing analog reference voltage from %.2f to %.2fV\n",
|
||||
(varef_read / 10.0), PDATA(pgm)->varef_data);
|
||||
if(pgm->set_varef(pgm, 0, PDATA(pgm)->varef_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Read or write clock generator frequency
|
||||
if (PDATA(pgm)->fosc_get || PDATA(pgm)->fosc_set) {
|
||||
// Read current target voltage set value
|
||||
unsigned int osc_pscale;
|
||||
unsigned int osc_cmatch;
|
||||
const char *unit_get = {"Hz"};
|
||||
double f_get = 0.0;
|
||||
stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &osc_pscale);
|
||||
stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch);
|
||||
if(osc_pscale) {
|
||||
int prescale = 1;
|
||||
f_get = STK500_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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return pgm->program_enable(pgm, p);
|
||||
}
|
||||
|
||||
@@ -570,17 +649,122 @@ static int stk500_parseextparms(const PROGRAMMER *pgm, const LISTID extparms)
|
||||
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
||||
extended_param = ldata(ln);
|
||||
|
||||
if (sscanf(extended_param, "attempts=%2d", &attempts) == 1) {
|
||||
PDATA(pgm)->retry_attempts = attempts;
|
||||
pmsg_info("setting number of retry attempts to %d\n", attempts);
|
||||
continue;
|
||||
}
|
||||
if (sscanf(extended_param, "attempts=%2d", &attempts) == 1) {
|
||||
PDATA(pgm)->retry_attempts = attempts;
|
||||
pmsg_info("setting number of retry attempts to %d\n", attempts);
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
// Get target voltage
|
||||
else if(str_eq(extended_param, "vtarg")) {
|
||||
PDATA(pgm)->vtarg_get = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (str_starts(extended_param, "varef")) {
|
||||
if (pgm->extra_features & HAS_VAREF_ADJ) {
|
||||
int sscanf_success = 0;
|
||||
double varef_set_val = 0;
|
||||
// Get new analog reference voltage for channel 0
|
||||
if (str_starts(extended_param, "varef=")) {
|
||||
sscanf_success = sscanf(extended_param, "varef=%lf", &varef_set_val);
|
||||
PDATA(pgm)->varef_set = true;
|
||||
}
|
||||
// Get new analog reference voltage for channel 0
|
||||
else if(str_starts(extended_param, "varef0=")) {
|
||||
sscanf_success = sscanf(extended_param, "varef0=%lf", &varef_set_val);
|
||||
PDATA(pgm)->varef_set = true;
|
||||
}
|
||||
// Get current analog reference voltage for channel 0
|
||||
else if(str_eq(extended_param, "varef") || str_eq(extended_param, "varef0")) {
|
||||
PDATA(pgm)->varef_get = true;
|
||||
continue;
|
||||
}
|
||||
// Set analog reference voltage
|
||||
if (PDATA(pgm)->varef_set) {
|
||||
PDATA(pgm)->varef_data = (double)((int)(varef_set_val * 100 + .5)) / 100;
|
||||
if (sscanf_success < 1 || varef_set_val < 0) {
|
||||
pmsg_error("invalid varef value '%s'\n", extended_param);
|
||||
PDATA(pgm)->varef_set = false;
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (str_starts(extended_param, "fosc")) {
|
||||
if (pgm->extra_features & HAS_VAREF_ADJ) {
|
||||
// Set clock generator frequency
|
||||
if (str_starts(extended_param, "fosc=")) {
|
||||
char fosc_str[16] = {0};
|
||||
int sscanf_success = sscanf(extended_param, "fosc=%10s", fosc_str);
|
||||
if (sscanf_success < 1) {
|
||||
pmsg_error("invalid fosc value '%s'\n", extended_param);
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
char *endp;
|
||||
double v = strtod(fosc_str, &endp);
|
||||
if (endp == fosc_str){
|
||||
if (str_eq(fosc_str, "off"))
|
||||
PDATA(pgm)->fosc_data = 0.0;
|
||||
else {
|
||||
pmsg_error("cannot parse fosc value %s\n", fosc_str);
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*endp == 'm' || *endp == 'M')
|
||||
PDATA(pgm)->fosc_data = v * 1e6;
|
||||
else if (*endp == 'k' || *endp == 'K')
|
||||
PDATA(pgm)->fosc_data = v * 1e3;
|
||||
PDATA(pgm)->fosc_set = true;
|
||||
continue;
|
||||
}
|
||||
// Get clock generator frequency
|
||||
else if(str_eq(extended_param, "fosc")) {
|
||||
PDATA(pgm)->fosc_get = true;
|
||||
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);
|
||||
msg_error(" -xattempts=<arg> Specify no. connection retry attempts\n");
|
||||
msg_error(" -xhelp Show this help menu and exit\n");
|
||||
msg_error(" -xattempts=<arg> Specify no. connection retry attempts\n");
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ) {
|
||||
msg_error(" -xvtarg Read target supply voltage\n");
|
||||
msg_error(" -xvtarg=<arg> Set target supply voltage\n");
|
||||
}
|
||||
if (pgm->extra_features & HAS_VAREF_ADJ) {
|
||||
msg_error(" -xvaref Read analog reference voltage\n");
|
||||
msg_error(" -xvaref=<arg> Set analog reference voltage\n");
|
||||
}
|
||||
if (pgm->extra_features & HAS_FOSC_ADJ) {
|
||||
msg_error(" -xfosc Read oscillator clock frequency\n");
|
||||
msg_error(" -xfosc=<arg>[M|k]|off Set oscillator clock frequency\n");
|
||||
}
|
||||
msg_error(" -xhelp Show this help menu and exit\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -966,7 +1150,7 @@ static int stk500_set_vtarget(const PROGRAMMER *pgm, double v) {
|
||||
}
|
||||
|
||||
if (uaref > utarg) {
|
||||
pmsg_error("reducing V[aref] from %.1f to %.1f\n", uaref / 10.0, v);
|
||||
pmsg_warning("reducing V[aref] from %.1f to %.1f\n", uaref / 10.0, v);
|
||||
if (stk500_setparm(pgm, Parm_STK_VADJUST, utarg) != 0)
|
||||
return -1;
|
||||
}
|
||||
@@ -1282,7 +1466,6 @@ void stk500_initpgm(PROGRAMMER *pgm) {
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->initialize = stk500_initialize;
|
||||
pgm->parseextparams = stk500_parseextparms;
|
||||
pgm->display = stk500_display;
|
||||
pgm->enable = stk500_enable;
|
||||
pgm->disable = stk500_disable;
|
||||
@@ -1300,11 +1483,19 @@ void stk500_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->paged_write = stk500_paged_write;
|
||||
pgm->paged_load = stk500_paged_load;
|
||||
pgm->print_parms = stk500_print_parms;
|
||||
pgm->set_vtarget = stk500_set_vtarget;
|
||||
pgm->set_varef = stk500_set_varef;
|
||||
pgm->set_fosc = stk500_set_fosc;
|
||||
pgm->set_sck_period = stk500_set_sck_period;
|
||||
pgm->parseextparams = stk500_parseextparms;
|
||||
pgm->setup = stk500_setup;
|
||||
pgm->teardown = stk500_teardown;
|
||||
pgm->page_size = 256;
|
||||
|
||||
/*
|
||||
* hardware dependent functions
|
||||
*/
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ)
|
||||
pgm->set_vtarget = stk500_set_vtarget;
|
||||
if (pgm->extra_features & HAS_VAREF_ADJ)
|
||||
pgm->set_varef = stk500_set_varef;
|
||||
if (pgm->extra_features & HAS_FOSC_ADJ)
|
||||
pgm->set_fosc = stk500_set_fosc;
|
||||
}
|
||||
|
||||
15
src/stk500.h
15
src/stk500.h
@@ -42,6 +42,21 @@ struct pdata {
|
||||
unsigned char ext_addr_byte; // Record ext-addr byte set in the target device (if used)
|
||||
int retry_attempts; // Number of connection attempts provided by the user
|
||||
int xbeeResetPin; // Piggy back variable used by xbee programmmer
|
||||
|
||||
// Get/set flags for adjustable target voltage
|
||||
bool vtarg_get;
|
||||
bool vtarg_set;
|
||||
double vtarg_data;
|
||||
|
||||
// Get/set flags for adjustable analog reference voltage
|
||||
bool varef_get;
|
||||
bool varef_set;
|
||||
double varef_data;
|
||||
|
||||
// Get/set flags for programmable clock generator
|
||||
bool fosc_get;
|
||||
bool fosc_set;
|
||||
double fosc_data;
|
||||
};
|
||||
|
||||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||
|
||||
516
src/stk500v2.c
516
src/stk500v2.c
@@ -377,6 +377,28 @@ 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 double
|
||||
f_to_kHz_MHz(double f, const char **unit)
|
||||
{
|
||||
if (f > 1e6) {
|
||||
f /= 1e6;
|
||||
*unit = "MHz";
|
||||
} else if (f > 1e3) {
|
||||
f /= 1000;
|
||||
*unit = "kHz";
|
||||
} else
|
||||
*unit = "Hz";
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
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");
|
||||
@@ -1223,6 +1245,109 @@ static int stk500v2_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
// stk600_setup_isp(pgm); [moved to pgm->enable()]
|
||||
}
|
||||
|
||||
// Read or write target voltage
|
||||
if (PDATA(pgm)->vtarg_get || PDATA(pgm)->vtarg_set) {
|
||||
// Read current target voltage set value
|
||||
unsigned char vtarg_read;
|
||||
stk500v2_getparm(pgm, PARAM_VTARGET, &vtarg_read);
|
||||
if (PDATA(pgm)->vtarg_get)
|
||||
msg_info("Target voltage value read as %.2fV\n", (vtarg_read / 10.0));
|
||||
// Write target voltage value
|
||||
else {
|
||||
msg_info("Changing target voltage from %.2f to %.2fV\n", (vtarg_read / 10.0), PDATA(pgm)->vtarg_data);
|
||||
if(pgm->set_vtarget(pgm, PDATA(pgm)->vtarg_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Read or write analog reference voltage
|
||||
if (PDATA(pgm)->varef_get || PDATA(pgm)->varef_set) {
|
||||
if(PDATA(pgm)->pgmtype == PGMTYPE_STK500) {
|
||||
// STK500: Read current analog reference voltage
|
||||
unsigned char varef_read;
|
||||
stk500v2_getparm(pgm, PARAM_VADJUST, &varef_read);
|
||||
if (PDATA(pgm)->varef_get)
|
||||
msg_info("Analog reference voltage value read as %.2fV\n", (varef_read / 10.0));
|
||||
// STK500: Write analog reference voltage
|
||||
else {
|
||||
msg_info("Changing analog reference voltage from %.2f to %.2fV\n",
|
||||
(varef_read / 10.0), PDATA(pgm)->varef_data);
|
||||
if(pgm->set_varef(pgm, 0, PDATA(pgm)->varef_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
} else if(PDATA(pgm)->pgmtype == PGMTYPE_STK600) {
|
||||
// STK600: Read current target voltage set value
|
||||
unsigned int varef_read;
|
||||
stk500v2_getparm2(pgm, PDATA(pgm)->varef_channel == 0 ? PARAM2_AREF0 : PARAM2_AREF1, &varef_read);
|
||||
if (PDATA(pgm)->varef_get)
|
||||
msg_info("Analog reference channel %d voltage read as %.2fV\n", PDATA(pgm)->varef_channel, (varef_read / 100.0));
|
||||
// STK600: Write target voltage value for channel n
|
||||
else {
|
||||
msg_info("Changing analog reference channel %d voltage from %.2f to %.2fV\n",
|
||||
PDATA(pgm)->varef_channel, (varef_read / 100.0), PDATA(pgm)->varef_data);
|
||||
if(pgm->set_varef(pgm, PDATA(pgm)->varef_channel, PDATA(pgm)->varef_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
unsigned char osc_cmatch;
|
||||
const char *unit_get = {"Hz"};
|
||||
double f_get = 0.0;
|
||||
stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale);
|
||||
stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch);
|
||||
if(osc_pscale) {
|
||||
int prescale = 1;
|
||||
f_get = STK500V2_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);
|
||||
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;
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Examine the avrpart's memory definitions, and initialize the page
|
||||
* caches. For devices/memory that are not page oriented, treat
|
||||
@@ -1350,6 +1475,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);
|
||||
|
||||
/*
|
||||
@@ -1415,6 +1560,109 @@ static int stk500hv_initialize(const PROGRAMMER *pgm, const AVRPART *p, enum hvm
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read or write target voltage
|
||||
if (PDATA(pgm)->vtarg_get || PDATA(pgm)->vtarg_set) {
|
||||
// Read current target voltage set value
|
||||
unsigned char vtarg_read;
|
||||
stk500v2_getparm(pgm, PARAM_VTARGET, &vtarg_read);
|
||||
if (PDATA(pgm)->vtarg_get)
|
||||
msg_info("Target voltage value read as %.2fV\n", (vtarg_read / 10.0));
|
||||
// Write target voltage value
|
||||
else {
|
||||
msg_info("Changing target voltage from %.2f to %.2fV\n", (vtarg_read / 10.0), PDATA(pgm)->vtarg_data);
|
||||
if(pgm->set_vtarget(pgm, PDATA(pgm)->vtarg_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Read or write analog reference voltage
|
||||
if (PDATA(pgm)->varef_get || PDATA(pgm)->varef_set) {
|
||||
if(PDATA(pgm)->pgmtype == PGMTYPE_STK500) {
|
||||
// STK500: Read current analog reference voltage
|
||||
unsigned char varef_read;
|
||||
stk500v2_getparm(pgm, PARAM_VADJUST, &varef_read);
|
||||
if (PDATA(pgm)->varef_get)
|
||||
msg_info("Analog reference voltage value read as %.2fV\n", (varef_read / 10.0));
|
||||
// STK500: Write analog reference voltage
|
||||
else {
|
||||
msg_info("Changing analog reference voltage from %.2f to %.2fV\n",
|
||||
(varef_read / 10.0), PDATA(pgm)->varef_data);
|
||||
if(pgm->set_varef(pgm, 0, PDATA(pgm)->varef_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
} else if(PDATA(pgm)->pgmtype == PGMTYPE_STK600) {
|
||||
// STK600: Read current target voltage set value
|
||||
unsigned int varef_read;
|
||||
stk500v2_getparm2(pgm, PDATA(pgm)->varef_channel == 0 ? PARAM2_AREF0 : PARAM2_AREF1, &varef_read);
|
||||
if (PDATA(pgm)->varef_get)
|
||||
msg_info("Analog reference channel %d voltage read as %.2fV\n", PDATA(pgm)->varef_channel, (varef_read / 100.0));
|
||||
// STK600: Write target voltage value for channel n
|
||||
else {
|
||||
msg_info("Changing analog reference channel %d voltage from %.2f to %.2fV\n",
|
||||
PDATA(pgm)->varef_channel, (varef_read / 100.0), PDATA(pgm)->varef_data);
|
||||
if(pgm->set_varef(pgm, PDATA(pgm)->varef_channel, PDATA(pgm)->varef_data) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
unsigned char osc_cmatch;
|
||||
const char *unit_get = {"Hz"};
|
||||
double f_get = 0.0;
|
||||
stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale);
|
||||
stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch);
|
||||
if(osc_pscale) {
|
||||
int prescale = 1;
|
||||
f_get = STK500V2_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);
|
||||
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;
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Examine the avrpart's memory definitions, and initialize the page
|
||||
* caches. For devices/memory that are not page oriented, treat
|
||||
@@ -1563,6 +1811,157 @@ static void stk500v2_enable(PROGRAMMER *pgm, const AVRPART *p) {
|
||||
return;
|
||||
}
|
||||
|
||||
static int stk500v2_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
|
||||
LNODEID ln;
|
||||
const char *extended_param;
|
||||
int rv = 0;
|
||||
|
||||
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
||||
extended_param = ldata(ln);
|
||||
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
// Get target voltage
|
||||
else if(str_eq(extended_param, "vtarg")) {
|
||||
PDATA(pgm)->vtarg_get = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (str_starts(extended_param, "varef")) {
|
||||
if (pgm->extra_features & HAS_VAREF_ADJ) {
|
||||
int sscanf_success = 0;
|
||||
double varef_set_val = 0;
|
||||
// Get new analog reference voltage for channel 0
|
||||
if (str_starts(extended_param, "varef=")) {
|
||||
sscanf_success = sscanf(extended_param, "varef=%lf", &varef_set_val);
|
||||
PDATA(pgm)->varef_channel = 0;
|
||||
PDATA(pgm)->varef_set = true;
|
||||
}
|
||||
// Get new analog reference voltage for channel 0
|
||||
else if(str_starts(extended_param, "varef0=")) {
|
||||
sscanf_success = sscanf(extended_param, "varef0=%lf", &varef_set_val);
|
||||
PDATA(pgm)->varef_channel = 0;
|
||||
PDATA(pgm)->varef_set = true;
|
||||
}
|
||||
// Get new analog reference voltage for channel 1
|
||||
else if (str_starts(extended_param, "varef1=") && str_contains(pgm->type, "STK600")) {
|
||||
sscanf_success = sscanf(extended_param, "varef1=%lf", &varef_set_val);
|
||||
PDATA(pgm)->varef_channel = 1;
|
||||
PDATA(pgm)->varef_set = true;
|
||||
}
|
||||
// Get current analog reference voltage for channel 0
|
||||
else if(str_eq(extended_param, "varef") || str_eq(extended_param, "varef0")) {
|
||||
PDATA(pgm)->varef_get = true;
|
||||
PDATA(pgm)->varef_channel = 0;
|
||||
continue;
|
||||
}
|
||||
// Get current analog reference voltage for channel 1
|
||||
else if(str_eq(extended_param, "varef1") && str_contains(pgm->type, "STK600")) {
|
||||
PDATA(pgm)->varef_get = true;
|
||||
PDATA(pgm)->varef_channel = 1;
|
||||
continue;
|
||||
}
|
||||
// Set analog reference voltage
|
||||
if (PDATA(pgm)->varef_set) {
|
||||
PDATA(pgm)->varef_data = (double)((int)(varef_set_val * 100 + .5)) / 100;
|
||||
if (sscanf_success < 1 || varef_set_val < 0) {
|
||||
pmsg_error("invalid varef value '%s'\n", extended_param);
|
||||
PDATA(pgm)->varef_set = false;
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (str_starts(extended_param, "fosc")) {
|
||||
if (pgm->extra_features & HAS_VAREF_ADJ) {
|
||||
// Set clock generator frequency
|
||||
if (str_starts(extended_param, "fosc=")) {
|
||||
char fosc_str[16] = {0};
|
||||
int sscanf_success = sscanf(extended_param, "fosc=%10s", fosc_str);
|
||||
if (sscanf_success < 1) {
|
||||
pmsg_error("invalid fosc value '%s'\n", extended_param);
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
char *endp;
|
||||
double v = strtod(fosc_str, &endp);
|
||||
if (endp == fosc_str){
|
||||
if (str_eq(fosc_str, "off"))
|
||||
PDATA(pgm)->fosc_data = 0.0;
|
||||
else {
|
||||
pmsg_error("cannot parse fosc value %s\n", fosc_str);
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*endp == 'm' || *endp == 'M')
|
||||
PDATA(pgm)->fosc_data = v * 1e6;
|
||||
else if (*endp == 'k' || *endp == 'K')
|
||||
PDATA(pgm)->fosc_data = v * 1e3;
|
||||
PDATA(pgm)->fosc_set = true;
|
||||
continue;
|
||||
}
|
||||
// Get clock generator frequency
|
||||
else if(str_eq(extended_param, "fosc")) {
|
||||
PDATA(pgm)->fosc_get = true;
|
||||
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);
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ) {
|
||||
msg_error(" -xvtarg Read target supply voltage\n");
|
||||
msg_error(" -xvtarg=<arg> Set target supply voltage\n");
|
||||
}
|
||||
if (pgm->extra_features & HAS_VAREF_ADJ) {
|
||||
if (str_contains(pgm->type, "STK500")) {
|
||||
msg_error(" -xvaref Read analog reference voltage\n");
|
||||
msg_error(" -xvaref=<arg> Set analog reference voltage\n");
|
||||
}
|
||||
else if (str_contains(pgm->type, "STK600")) {
|
||||
msg_error(" -xvaref Read channel 0 analog reference voltage\n");
|
||||
msg_error(" -xvaref0 Alias for -xvaref\n");
|
||||
msg_error(" -xvaref1 Read channel 1 analog reference voltage\n");
|
||||
msg_error(" -xvaref=<arg> Set channel 0 analog reference voltage\n");
|
||||
msg_error(" -xvaref0=<arg> Alias for -xvaref=<arg>\n");
|
||||
msg_error(" -xvaref1=<arg> Set channel 1 analog reference voltage\n");
|
||||
}
|
||||
}
|
||||
if (pgm->extra_features & HAS_FOSC_ADJ) {
|
||||
msg_error(" -xfosc Read oscillator clock frequency\n");
|
||||
msg_error(" -xfosc=<arg>[M|k]|off Set oscillator clock frequency\n");
|
||||
}
|
||||
msg_error(" -xhelp Show this help menu and exit\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pmsg_error("invalid extended parameter '%s'\n", extended_param);
|
||||
rv = -1;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int stk500v2_jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
|
||||
LNODEID ln;
|
||||
const char *extended_param;
|
||||
@@ -1619,6 +2018,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);
|
||||
@@ -1628,6 +2050,10 @@ static int stk500v2_jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extp
|
||||
msg_error(" -xvtarg_switch Read on-board target voltage switch state\n");
|
||||
msg_error(" -xvtarg_switch=<0..1> Set on-board target voltage switch state\n");
|
||||
}
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ) {
|
||||
msg_error(" -xvtarg Read on-board target supply voltage\n");
|
||||
msg_error(" -xvtarg=<arg> Set on-board target supply voltage\n");
|
||||
}
|
||||
msg_error (" -xhelp Show this help menu and exit\n");
|
||||
exit(0);
|
||||
}
|
||||
@@ -2925,7 +3351,6 @@ static int stk600_set_vtarget(const PROGRAMMER *pgm, double v) {
|
||||
unsigned char utarg;
|
||||
unsigned int uaref;
|
||||
int rv;
|
||||
|
||||
utarg = (unsigned)((v + 0.049) * 10);
|
||||
|
||||
if (stk500v2_getparm2(pgm, PARAM2_AREF0, &uaref) != 0) {
|
||||
@@ -3206,7 +3631,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);
|
||||
@@ -3214,20 +3638,6 @@ static void stk500v2_display(const PROGRAMMER *pgm, const char *p) {
|
||||
return;
|
||||
}
|
||||
|
||||
static double
|
||||
f_to_kHz_MHz(double f, const char **unit)
|
||||
{
|
||||
if (f > 1e6) {
|
||||
f /= 1e6;
|
||||
*unit = "MHz";
|
||||
} else if (f > 1e3) {
|
||||
f /= 1000;
|
||||
*unit = "kHz";
|
||||
} else
|
||||
*unit = "Hz";
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
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
|
||||
@@ -3301,7 +3711,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);
|
||||
}
|
||||
@@ -4280,14 +4690,14 @@ static void stk600_setup_xprog(PROGRAMMER * pgm)
|
||||
*/
|
||||
static void stk600_setup_isp(PROGRAMMER * pgm)
|
||||
{
|
||||
pgm->program_enable = stk500v2_program_enable;
|
||||
pgm->disable = stk500v2_disable;
|
||||
pgm->read_byte = stk500isp_read_byte;
|
||||
pgm->write_byte = stk500isp_write_byte;
|
||||
pgm->paged_load = stk500v2_paged_load;
|
||||
pgm->paged_write = stk500v2_paged_write;
|
||||
pgm->page_erase = stk500v2_page_erase;
|
||||
pgm->chip_erase = stk500v2_chip_erase;
|
||||
pgm->program_enable = stk500v2_program_enable;
|
||||
pgm->disable = stk500v2_disable;
|
||||
pgm->read_byte = stk500isp_read_byte;
|
||||
pgm->write_byte = stk500isp_write_byte;
|
||||
pgm->paged_load = stk500v2_paged_load;
|
||||
pgm->paged_write = stk500v2_paged_write;
|
||||
pgm->page_erase = stk500v2_page_erase;
|
||||
pgm->chip_erase = stk500v2_chip_erase;
|
||||
}
|
||||
|
||||
const char stk500v2_desc[] = "Atmel STK500 Version 2.x firmware";
|
||||
@@ -4317,14 +4727,22 @@ void stk500v2_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->paged_load = stk500v2_paged_load;
|
||||
pgm->page_erase = stk500v2_page_erase;
|
||||
pgm->print_parms = stk500v2_print_parms;
|
||||
pgm->set_vtarget = stk500v2_set_vtarget;
|
||||
pgm->set_varef = stk500v2_set_varef;
|
||||
pgm->set_fosc = stk500v2_set_fosc;
|
||||
pgm->set_sck_period = stk500v2_set_sck_period;
|
||||
pgm->perform_osccal = stk500v2_perform_osccal;
|
||||
pgm->parseextparams = stk500v2_parseextparms;
|
||||
pgm->setup = stk500v2_setup;
|
||||
pgm->teardown = stk500v2_teardown;
|
||||
pgm->page_size = 256;
|
||||
|
||||
/*
|
||||
* hardware dependent functions
|
||||
*/
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ)
|
||||
pgm->set_vtarget = stk500v2_set_vtarget;
|
||||
if (pgm->extra_features & HAS_VAREF_ADJ)
|
||||
pgm->set_varef = stk500v2_set_varef;
|
||||
if (pgm->extra_features & HAS_FOSC_ADJ)
|
||||
pgm->set_fosc = stk500v2_set_fosc;
|
||||
}
|
||||
|
||||
const char stk500pp_desc[] = "Atmel STK500 V2 in parallel programming mode";
|
||||
@@ -4352,13 +4770,21 @@ void stk500pp_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->paged_write = stk500pp_paged_write;
|
||||
pgm->paged_load = stk500pp_paged_load;
|
||||
pgm->print_parms = stk500v2_print_parms;
|
||||
pgm->set_vtarget = stk500v2_set_vtarget;
|
||||
pgm->set_varef = stk500v2_set_varef;
|
||||
pgm->set_fosc = stk500v2_set_fosc;
|
||||
pgm->set_sck_period = stk500v2_set_sck_period;
|
||||
pgm->parseextparams = stk500v2_parseextparms;
|
||||
pgm->setup = stk500v2_setup;
|
||||
pgm->teardown = stk500v2_teardown;
|
||||
pgm->page_size = 256;
|
||||
|
||||
/*
|
||||
* hardware dependent functions
|
||||
*/
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ)
|
||||
pgm->set_vtarget = stk500v2_set_vtarget;
|
||||
if (pgm->extra_features & HAS_VAREF_ADJ)
|
||||
pgm->set_varef = stk500v2_set_varef;
|
||||
if (pgm->extra_features & HAS_FOSC_ADJ)
|
||||
pgm->set_fosc = stk500v2_set_fosc;
|
||||
}
|
||||
|
||||
const char stk500hvsp_desc[] = "Atmel STK500 V2 in high-voltage serial programming mode";
|
||||
@@ -4386,13 +4812,21 @@ void stk500hvsp_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->paged_write = stk500hvsp_paged_write;
|
||||
pgm->paged_load = stk500hvsp_paged_load;
|
||||
pgm->print_parms = stk500v2_print_parms;
|
||||
pgm->set_vtarget = stk500v2_set_vtarget;
|
||||
pgm->set_varef = stk500v2_set_varef;
|
||||
pgm->set_fosc = stk500v2_set_fosc;
|
||||
pgm->set_sck_period = stk500v2_set_sck_period;
|
||||
pgm->parseextparams = stk500v2_parseextparms;
|
||||
pgm->setup = stk500v2_setup;
|
||||
pgm->teardown = stk500v2_teardown;
|
||||
pgm->page_size = 256;
|
||||
|
||||
/*
|
||||
* hardware dependent functions
|
||||
*/
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ)
|
||||
pgm->set_vtarget = stk500v2_set_vtarget;
|
||||
if (pgm->extra_features & HAS_VAREF_ADJ)
|
||||
pgm->set_varef = stk500v2_set_varef;
|
||||
if (pgm->extra_features & HAS_FOSC_ADJ)
|
||||
pgm->set_fosc = stk500v2_set_fosc;
|
||||
}
|
||||
|
||||
const char stk500v2_jtagmkII_desc[] = "Atmel JTAG ICE mkII in ISP mode";
|
||||
@@ -4487,9 +4921,6 @@ void stk500v2_dragon_pp_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->paged_write = stk500pp_paged_write;
|
||||
pgm->paged_load = stk500pp_paged_load;
|
||||
pgm->print_parms = stk500v2_print_parms;
|
||||
pgm->set_vtarget = stk500v2_set_vtarget;
|
||||
pgm->set_varef = stk500v2_set_varef;
|
||||
pgm->set_fosc = stk500v2_set_fosc;
|
||||
pgm->set_sck_period = stk500v2_set_sck_period_mk2;
|
||||
pgm->setup = stk500v2_jtagmkII_setup;
|
||||
pgm->teardown = stk500v2_jtagmkII_teardown;
|
||||
@@ -4521,9 +4952,6 @@ void stk500v2_dragon_hvsp_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->paged_write = stk500hvsp_paged_write;
|
||||
pgm->paged_load = stk500hvsp_paged_load;
|
||||
pgm->print_parms = stk500v2_print_parms;
|
||||
pgm->set_vtarget = stk500v2_set_vtarget;
|
||||
pgm->set_varef = stk500v2_set_varef;
|
||||
pgm->set_fosc = stk500v2_set_fosc;
|
||||
pgm->set_sck_period = stk500v2_set_sck_period_mk2;
|
||||
pgm->setup = stk500v2_jtagmkII_setup;
|
||||
pgm->teardown = stk500v2_jtagmkII_teardown;
|
||||
@@ -4562,6 +4990,7 @@ void stk600_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->set_fosc = stk600_set_fosc;
|
||||
pgm->set_sck_period = stk600_set_sck_period;
|
||||
pgm->perform_osccal = stk500v2_perform_osccal;
|
||||
pgm->parseextparams = stk500v2_parseextparms;
|
||||
pgm->setup = stk500v2_setup;
|
||||
pgm->teardown = stk500v2_teardown;
|
||||
pgm->page_size = 256;
|
||||
@@ -4596,6 +5025,7 @@ void stk600pp_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->set_varef = stk600_set_varef;
|
||||
pgm->set_fosc = stk600_set_fosc;
|
||||
pgm->set_sck_period = stk600_set_sck_period;
|
||||
pgm->parseextparams = stk500v2_parseextparms;
|
||||
pgm->setup = stk500v2_setup;
|
||||
pgm->teardown = stk500v2_teardown;
|
||||
pgm->page_size = 256;
|
||||
@@ -4630,6 +5060,7 @@ void stk600hvsp_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->set_varef = stk600_set_varef;
|
||||
pgm->set_fosc = stk600_set_fosc;
|
||||
pgm->set_sck_period = stk600_set_sck_period;
|
||||
pgm->parseextparams = stk500v2_parseextparms;
|
||||
pgm->setup = stk500v2_setup;
|
||||
pgm->teardown = stk500v2_teardown;
|
||||
pgm->page_size = 256;
|
||||
@@ -4644,7 +5075,6 @@ void stk500v2_jtag3_initpgm(PROGRAMMER *pgm) {
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->initialize = stk500v2_jtag3_initialize;
|
||||
pgm->parseextparams = stk500v2_jtag3_parseextparms;
|
||||
pgm->display = stk500v2_display;
|
||||
pgm->enable = stk500v2_enable;
|
||||
pgm->disable = stk500v2_jtag3_disable;
|
||||
@@ -4665,10 +5095,14 @@ void stk500v2_jtag3_initpgm(PROGRAMMER *pgm) {
|
||||
pgm->print_parms = stk500v2_print_parms;
|
||||
pgm->set_sck_period = stk500v2_jtag3_set_sck_period;
|
||||
pgm->perform_osccal = stk500v2_perform_osccal;
|
||||
pgm->parseextparams = stk500v2_jtag3_parseextparms;
|
||||
pgm->setup = stk500v2_jtag3_setup;
|
||||
pgm->teardown = stk500v2_jtag3_teardown;
|
||||
pgm->page_size = 256;
|
||||
|
||||
/*
|
||||
* hardware dependent functions
|
||||
*/
|
||||
if (pgm->extra_features & HAS_VTARG_ADJ)
|
||||
pgm->set_vtarget = jtag3_set_vtarget;
|
||||
}
|
||||
|
||||
@@ -280,6 +280,22 @@ 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;
|
||||
|
||||
/* Get/set flags for adjustable analog reference voltage */
|
||||
bool varef_get;
|
||||
bool varef_set;
|
||||
int varef_channel;
|
||||
double varef_data;
|
||||
|
||||
/* Get/set flags for programmable clock generator */
|
||||
bool fosc_get;
|
||||
bool fosc_set;
|
||||
double fosc_data;
|
||||
|
||||
const AVRPART *lastpart;
|
||||
|
||||
/* Start address of Xmega boot area */
|
||||
|
||||
Reference in New Issue
Block a user