Implement STK500 (v2) HVSP mode.
* stk500v2.c: Add new functions for HVSP support. * stk500v2.h: Add prototype for the stk500hvsp programmer. * avrpart.h: Add fields to struct avrpart for new features. * config_gram.y: Extend the configuration syntax for new features required for HVSP support. * lexer.l: (Ditto.) * avrdude.conf.in: Add HVSP support for ATtiny13 and ATtiny45 as an example. * avrdude.1: Document stk500hvsp. * doc/avrdude.texi: (Ditto.) git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@595 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
e963f38753
commit
dbf083fb4d
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2006-07-21 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Implement STK500 (v2) HVSP mode.
|
||||
* stk500v2.c: Add new functions for HVSP support.
|
||||
* stk500v2.h: Add prototype for the stk500hvsp programmer.
|
||||
* avrpart.h: Add fields to struct avrpart for new features.
|
||||
* config_gram.y: Extend the configuration syntax for new
|
||||
features required for HVSP support.
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: Add HVSP support for ATtiny13 and
|
||||
ATtiny45 as an example.
|
||||
* avrdude.1: Document stk500hvsp.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2006-07-21 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrpart.c: Print the very verbose memory details only
|
||||
|
|
|
@ -99,8 +99,9 @@ Atmel's STK500 programmer is also supported and connects to a serial
|
|||
port.
|
||||
Both, firmware versions 1.x and 2.x can be handled, but require a
|
||||
different programmer type specification (by now).
|
||||
Using firmware version 2, parallel programming is also supported
|
||||
(programmer type stk500pp).
|
||||
Using firmware version 2, high-voltage programming is also supported,
|
||||
both parallel and serial
|
||||
(programmer types stk500pp and stk500hvsp).
|
||||
.Pp
|
||||
The simple serial programmer described in Atmel's application note
|
||||
AVR910, and the bootloader described in Atmel's application note
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
# programmer
|
||||
# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
||||
# desc = <description> ; # quoted string
|
||||
# type = par | stk500 | stk500v2 | stk500pp | avr910 | jtagmki | jtagmkii; # programmer type
|
||||
# type = par | stk500 | stk500v2 | stk500pp | stk500hvsp |
|
||||
# avr910 | jtagmki | jtagmkii; # programmer type
|
||||
# baudrate = <num> ; # baudrate for avr910-programmer
|
||||
# vcc = <num1> [, <num2> ... ] ; # pin number(s)
|
||||
# reset = <num> ; # pin number
|
||||
|
@ -50,7 +51,7 @@
|
|||
# # STK500v2 parameters, to be taken from Atmel's XML files
|
||||
# timeout = <num> ;
|
||||
# stabdelay = <num> ;
|
||||
# cmdexdelay = <num> ;
|
||||
# cmdexedelay = <num> ;
|
||||
# synchloops = <num> ;
|
||||
# bytedelay = <num> ;
|
||||
# pollvalue = <num> ;
|
||||
|
@ -62,22 +63,26 @@
|
|||
# delay = <num> ;
|
||||
# blocksize = <num> ;
|
||||
# readsize = <num> ;
|
||||
# # STK500v2 parallel programming parameters, from XML
|
||||
# pp_controlstack = <num>, <num>, ...;
|
||||
# ppenterstabdelay = <num>;
|
||||
# progmodedelay = <num>;
|
||||
# hvspcmdexedelay = <num> ;
|
||||
# # STK500v2 HV programming parameters, from XML
|
||||
# pp_controlstack = <num>, <num>, ...; # PP only
|
||||
# hvsp_controlstack = <num>, <num>, ...; # HVSP only
|
||||
# hventerstabdelay = <num>;
|
||||
# progmodedelay = <num>; # PP only
|
||||
# latchcycles = <num>;
|
||||
# togglevtg = <num>;
|
||||
# poweroffdelay = <num>;
|
||||
# resetdelayms = <num>;
|
||||
# resetdelayus = <num>;
|
||||
# ppleavestabdelay = <num>;
|
||||
# hvleavestabdelay = <num>;
|
||||
# resetdelay = <num>;
|
||||
# chiperasepulsewidth = <num>;
|
||||
# synchcycles = <num>; # HVSP only
|
||||
# chiperasepulsewidth = <num>; # PP only
|
||||
# chiperasepolltimeout = <num>;
|
||||
# programfusepulsewidth = <num>;
|
||||
# chiperasetime = <num>; # HVSP only
|
||||
# programfusepulsewidth = <num>; # PP only
|
||||
# programfusepolltimeout = <num>;
|
||||
# programlockpulsewidth = <num>;
|
||||
# programlockpulsewidth = <num>; # PP only
|
||||
# programlockpolltimeout = <num>;
|
||||
# # JTAG ICE mkII parameters, also from XML files
|
||||
# allowfullpagebitstream = <yes/no> ;
|
||||
|
@ -281,6 +286,12 @@ programmer
|
|||
type = stk500pp;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "stk500hvsp";
|
||||
desc = "Atmel STK500 V2 in high-voltage serial programming mode";
|
||||
type = stk500hvsp;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "avr910";
|
||||
desc = "Atmel Low Cost Serial Programmer";
|
||||
|
@ -721,8 +732,30 @@ part
|
|||
postdelay = 1;
|
||||
pollmethod = 1;
|
||||
|
||||
hvsp_controlstack =
|
||||
0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
|
||||
0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
|
||||
0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
|
||||
0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
|
||||
hventerstabdelay = 100;
|
||||
progmodedelay = 0;
|
||||
hvspcmdexedelay = 0;
|
||||
synchcycles = 6;
|
||||
latchcycles = 1;
|
||||
togglevtg = 1;
|
||||
poweroffdelay = 25;
|
||||
resetdelayms = 0;
|
||||
resetdelayus = 90;
|
||||
hvleavestabdelay = 100;
|
||||
resetdelay = 25;
|
||||
chiperasepolltimeout = 40;
|
||||
chiperasetime = 0;
|
||||
programfusepolltimeout = 25;
|
||||
programlockpolltimeout = 25;
|
||||
|
||||
memory "eeprom"
|
||||
size = 64;
|
||||
page_size = 4;
|
||||
min_write_delay = 4000;
|
||||
max_write_delay = 4000;
|
||||
readback_p1 = 0xff;
|
||||
|
@ -1624,14 +1657,14 @@ part
|
|||
0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
|
||||
0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
|
||||
0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
|
||||
ppenterstabdelay = 100;
|
||||
hventerstabdelay = 100;
|
||||
progmodedelay = 0;
|
||||
latchcycles = 0;
|
||||
togglevtg = 0;
|
||||
poweroffdelay = 0;
|
||||
resetdelayms = 0;
|
||||
resetdelayus = 0;
|
||||
ppleavestabdelay = 15;
|
||||
hvleavestabdelay = 15;
|
||||
resetdelay = 15;
|
||||
chiperasepulsewidth = 15;
|
||||
chiperasepolltimeout = 0;
|
||||
|
@ -2412,14 +2445,14 @@ part
|
|||
0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
|
||||
0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
|
||||
0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
|
||||
ppenterstabdelay = 100;
|
||||
hventerstabdelay = 100;
|
||||
progmodedelay = 100;
|
||||
latchcycles = 6;
|
||||
togglevtg = 0;
|
||||
poweroffdelay = 0;
|
||||
resetdelayms = 0;
|
||||
resetdelayus = 0;
|
||||
ppleavestabdelay = 15;
|
||||
hvleavestabdelay = 15;
|
||||
resetdelay = 15;
|
||||
chiperasepulsewidth = 0;
|
||||
chiperasepolltimeout = 10;
|
||||
|
@ -5876,8 +5909,30 @@ part
|
|||
postdelay = 1;
|
||||
pollmethod = 1;
|
||||
|
||||
hvsp_controlstack =
|
||||
0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
|
||||
0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
|
||||
0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
|
||||
0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
|
||||
hventerstabdelay = 100;
|
||||
progmodedelay = 0;
|
||||
hvspcmdexedelay = 0;
|
||||
synchcycles = 6;
|
||||
latchcycles = 1;
|
||||
togglevtg = 1;
|
||||
poweroffdelay = 25;
|
||||
resetdelayms = 0;
|
||||
resetdelayus = 50;
|
||||
hvleavestabdelay = 100;
|
||||
resetdelay = 25;
|
||||
chiperasepolltimeout = 40;
|
||||
chiperasetime = 0;
|
||||
programfusepolltimeout = 25;
|
||||
programlockpolltimeout = 25;
|
||||
|
||||
memory "eeprom"
|
||||
size = 256;
|
||||
page_size = 4;
|
||||
min_write_delay = 4000;
|
||||
max_write_delay = 4500;
|
||||
readback_p1 = 0xff;
|
||||
|
|
33
avrpart.h
33
avrpart.h
|
@ -121,21 +121,24 @@ typedef struct avrpart {
|
|||
enum ctl_stack_t ctl_stack_type; /* what to use the ctl stack for */
|
||||
unsigned char controlstack[CTL_STACK_SIZE]; /* stk500v2 PP/HVSP ctl stack */
|
||||
|
||||
int ppenterstabdelay; /* stk500 v2 pp mode parameter */
|
||||
int progmodedelay; /* stk500 v2 pp mode parameter */
|
||||
int latchcycles; /* stk500 v2 pp mode parameter */
|
||||
int togglevtg; /* stk500 v2 pp mode parameter */
|
||||
int poweroffdelay; /* stk500 v2 pp mode parameter */
|
||||
int resetdelayms; /* stk500 v2 pp mode parameter */
|
||||
int resetdelayus; /* stk500 v2 pp mode parameter */
|
||||
int ppleavestabdelay; /* stk500 v2 pp mode parameter */
|
||||
int resetdelay; /* stk500 v2 pp mode parameter */
|
||||
int chiperasepulsewidth; /* stk500 v2 pp mode parameter */
|
||||
int chiperasepolltimeout; /* stk500 v2 pp mode parameter */
|
||||
int programfusepulsewidth; /* stk500 v2 pp mode parameter */
|
||||
int programfusepolltimeout; /* stk500 v2 pp mode parameter */
|
||||
int programlockpulsewidth; /* stk500 v2 pp mode parameter */
|
||||
int programlockpolltimeout; /* stk500 v2 pp mode parameter */
|
||||
int hventerstabdelay; /* stk500 v2 hv mode parameter */
|
||||
int progmodedelay; /* stk500 v2 hv mode parameter */
|
||||
int latchcycles; /* stk500 v2 hv mode parameter */
|
||||
int togglevtg; /* stk500 v2 hv mode parameter */
|
||||
int poweroffdelay; /* stk500 v2 hv mode parameter */
|
||||
int resetdelayms; /* stk500 v2 hv mode parameter */
|
||||
int resetdelayus; /* stk500 v2 hv mode parameter */
|
||||
int hvleavestabdelay; /* stk500 v2 hv mode parameter */
|
||||
int resetdelay; /* stk500 v2 hv mode parameter */
|
||||
int chiperasepulsewidth; /* stk500 v2 hv mode parameter */
|
||||
int chiperasepolltimeout; /* stk500 v2 hv mode parameter */
|
||||
int chiperasetime; /* stk500 v2 hv mode parameter */
|
||||
int programfusepulsewidth; /* stk500 v2 hv mode parameter */
|
||||
int programfusepolltimeout; /* stk500 v2 hv mode parameter */
|
||||
int programlockpulsewidth; /* stk500 v2 hv mode parameter */
|
||||
int programlockpolltimeout; /* stk500 v2 hv mode parameter */
|
||||
int synchcycles; /* stk500 v2 hv mode parameter */
|
||||
int hvspcmdexedelay; /* stk500 v2 xml file parameter */
|
||||
|
||||
unsigned char idr; /* JTAG ICE mkII XML file parameter */
|
||||
unsigned char rampz; /* JTAG ICE mkII XML file parameter */
|
||||
|
|
|
@ -121,6 +121,7 @@ static int parse_cmdbits(OPCODE * op);
|
|||
%token K_SIGNATURE
|
||||
%token K_SIZE
|
||||
%token K_STK500
|
||||
%token K_STK500HVSP
|
||||
%token K_STK500PP
|
||||
%token K_STK500V2
|
||||
%token K_AVR910
|
||||
|
@ -138,6 +139,7 @@ static int parse_cmdbits(OPCODE * op);
|
|||
%token K_TIMEOUT
|
||||
%token K_STABDELAY
|
||||
%token K_CMDEXEDELAY
|
||||
%token K_HVSPCMDEXEDELAY
|
||||
%token K_SYNCHLOOPS
|
||||
%token K_BYTEDELAY
|
||||
%token K_POLLVALUE
|
||||
|
@ -149,25 +151,29 @@ static int parse_cmdbits(OPCODE * op);
|
|||
%token K_DELAY
|
||||
%token K_BLOCKSIZE
|
||||
%token K_READSIZE
|
||||
/* PP mode */
|
||||
%token K_PPENTERSTABDELAY
|
||||
/* HV mode */
|
||||
%token K_HVENTERSTABDELAY
|
||||
%token K_PROGMODEDELAY
|
||||
%token K_LATCHCYCLES
|
||||
%token K_TOGGLEVTG
|
||||
%token K_POWEROFFDELAY
|
||||
%token K_RESETDELAYMS
|
||||
%token K_RESETDELAYUS
|
||||
%token K_PPLEAVESTABDELAY
|
||||
%token K_HVLEAVESTABDELAY
|
||||
%token K_RESETDELAY
|
||||
%token K_SYNCHCYCLES
|
||||
%token K_HVCMDEXEDELAY
|
||||
|
||||
%token K_CHIPERASEPULSEWIDTH
|
||||
%token K_CHIPERASEPOLLTIMEOUT
|
||||
%token K_CHIPERASETIME
|
||||
%token K_PROGRAMFUSEPULSEWIDTH
|
||||
%token K_PROGRAMFUSEPOLLTIMEOUT
|
||||
%token K_PROGRAMLOCKPULSEWIDTH
|
||||
%token K_PROGRAMLOCKPOLLTIMEOUT
|
||||
|
||||
%token K_PP_CONTROLSTACK
|
||||
%token K_HVSP_CONTROLSTACK
|
||||
|
||||
/* JTAG ICE mkII specific parameters */
|
||||
%token K_ALLOWFULLPAGEBITSTREAM /*
|
||||
|
@ -372,6 +378,12 @@ prog_parm :
|
|||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK500HVSP {
|
||||
{
|
||||
stk500hvsp_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK500PP {
|
||||
{
|
||||
stk500pp_initpgm(current_prog);
|
||||
|
@ -614,6 +626,48 @@ part_parm :
|
|||
}
|
||||
} |
|
||||
|
||||
K_HVSP_CONTROLSTACK TKN_EQUAL num_list {
|
||||
{
|
||||
TOKEN * t;
|
||||
unsigned nbytes;
|
||||
int ok;
|
||||
|
||||
if (current_part->ctl_stack_type != CTL_STACK_NONE)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: error at line %d of %s: "
|
||||
"control stack already defined\n",
|
||||
progname, lineno, infile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
current_part->ctl_stack_type = CTL_STACK_HVSP;
|
||||
nbytes = 0;
|
||||
ok = 1;
|
||||
|
||||
while (lsize(number_list)) {
|
||||
t = lrmv_n(number_list, 1);
|
||||
if (nbytes < CTL_STACK_SIZE)
|
||||
{
|
||||
current_part->controlstack[nbytes] = t->value.number;
|
||||
nbytes++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = 0;
|
||||
}
|
||||
free_token(t);
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: Warning: line %d of %s: "
|
||||
"too many bytes in control stack\n",
|
||||
progname, lineno, infile);
|
||||
}
|
||||
}
|
||||
} |
|
||||
|
||||
K_CHIP_ERASE_DELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->chip_erase_delay = $3->value.number;
|
||||
|
@ -660,6 +714,12 @@ part_parm :
|
|||
free_token($3);
|
||||
} |
|
||||
|
||||
K_HVSPCMDEXEDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->hvspcmdexedelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_SYNCHLOOPS TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->synchloops = $3->value.number;
|
||||
|
@ -702,9 +762,9 @@ part_parm :
|
|||
free_token($3);
|
||||
} |
|
||||
|
||||
K_PPENTERSTABDELAY TKN_EQUAL TKN_NUMBER
|
||||
K_HVENTERSTABDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->ppenterstabdelay = $3->value.number;
|
||||
current_part->hventerstabdelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
|
@ -744,9 +804,9 @@ part_parm :
|
|||
free_token($3);
|
||||
} |
|
||||
|
||||
K_PPLEAVESTABDELAY TKN_EQUAL TKN_NUMBER
|
||||
K_HVLEAVESTABDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->ppleavestabdelay = $3->value.number;
|
||||
current_part->hvleavestabdelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
|
@ -768,6 +828,12 @@ part_parm :
|
|||
free_token($3);
|
||||
} |
|
||||
|
||||
K_CHIPERASETIME TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->chiperasetime = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_PROGRAMFUSEPULSEWIDTH TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->programfusepulsewidth = $3->value.number;
|
||||
|
@ -792,6 +858,12 @@ part_parm :
|
|||
free_token($3);
|
||||
} |
|
||||
|
||||
K_SYNCHCYCLES TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->synchcycles = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_HAS_JTAG TKN_EQUAL yesno
|
||||
{
|
||||
if ($3->primary == K_YES)
|
||||
|
|
|
@ -499,6 +499,10 @@ STK200
|
|||
@itemx stk500
|
||||
Atmel STK500
|
||||
|
||||
@itemx stk500hvsp
|
||||
Atmel STK500 in high-voltage serial programming mode
|
||||
(version 2.x firmware only)
|
||||
|
||||
@itemx stk500pp
|
||||
Atmel STK500 in parallel programming mode (version 2.x
|
||||
firmware only)
|
||||
|
@ -1898,7 +1902,7 @@ programming works, and is documented that way in the Atmel AVR
|
|||
datasheets.
|
||||
In order to successfully program the EEPROM that way, a prior chip
|
||||
erase (with the EESAVE fuse unprogrammed) is required.
|
||||
This also applies to the STK500 in parallel programming mode.
|
||||
This also applies to the STK500 in high-voltage programming mode.
|
||||
|
||||
|
||||
@end itemize
|
||||
|
|
9
lexer.l
9
lexer.l
|
@ -171,6 +171,7 @@ signature { yylval=NULL; return K_SIGNATURE; }
|
|||
size { yylval=NULL; return K_SIZE; }
|
||||
spmcr { yylval=NULL; return K_SPMCR; }
|
||||
stk500 { yylval=NULL; return K_STK500; }
|
||||
stk500hvsp { yylval=NULL; return K_STK500HVSP; }
|
||||
stk500pp { yylval=NULL; return K_STK500PP; }
|
||||
stk500v2 { yylval=NULL; return K_STK500V2; }
|
||||
stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
|
||||
|
@ -181,6 +182,7 @@ vfyled { yylval=NULL; return K_VFYLED; }
|
|||
timeout { yylval=NULL; return K_TIMEOUT; }
|
||||
stabdelay { yylval=NULL; return K_STABDELAY; }
|
||||
cmdexedelay { yylval=NULL; return K_CMDEXEDELAY; }
|
||||
hvspcmdexedelay { yylval=NULL; return K_HVSPCMDEXEDELAY; }
|
||||
synchloops { yylval=NULL; return K_SYNCHLOOPS; }
|
||||
bytedelay { yylval=NULL; return K_BYTEDELAY; }
|
||||
pollvalue { yylval=NULL; return K_POLLVALUE; }
|
||||
|
@ -193,17 +195,20 @@ delay { yylval=NULL; return K_DELAY; }
|
|||
blocksize { yylval=NULL; return K_BLOCKSIZE; }
|
||||
readsize { yylval=NULL; return K_READSIZE; }
|
||||
pp_controlstack { yylval=NULL; return K_PP_CONTROLSTACK; }
|
||||
ppenterstabdelay { yylval=NULL; return K_PPENTERSTABDELAY; }
|
||||
hvsp_controlstack { yylval=NULL; return K_HVSP_CONTROLSTACK; }
|
||||
hventerstabdelay { yylval=NULL; return K_HVENTERSTABDELAY; }
|
||||
progmodedelay { yylval=NULL; return K_PROGMODEDELAY; }
|
||||
latchcycles { yylval=NULL; return K_LATCHCYCLES; }
|
||||
togglevtg { yylval=NULL; return K_TOGGLEVTG; }
|
||||
poweroffdelay { yylval=NULL; return K_POWEROFFDELAY; }
|
||||
resetdelayms { yylval=NULL; return K_RESETDELAYMS; }
|
||||
resetdelayus { yylval=NULL; return K_RESETDELAYUS; }
|
||||
ppleavestabdelay { yylval=NULL; return K_PPLEAVESTABDELAY; }
|
||||
hvleavestabdelay { yylval=NULL; return K_HVLEAVESTABDELAY; }
|
||||
resetdelay { yylval=NULL; return K_RESETDELAY; }
|
||||
synchcycles { yylval=NULL; return K_SYNCHCYCLES; }
|
||||
chiperasepulsewidth { yylval=NULL; return K_CHIPERASEPULSEWIDTH; }
|
||||
chiperasepolltimeout { yylval=NULL; return K_CHIPERASEPOLLTIMEOUT; }
|
||||
chiperasetime { yylval=NULL; return K_CHIPERASETIME; }
|
||||
programfusepulsewidth { yylval=NULL; return K_PROGRAMFUSEPULSEWIDTH; }
|
||||
programfusepolltimeout { yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; }
|
||||
programlockpulsewidth { yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; }
|
||||
|
|
339
stk500v2.c
339
stk500v2.c
|
@ -68,6 +68,11 @@
|
|||
#define DEBUGRECV(format,args...)
|
||||
#endif
|
||||
|
||||
enum hvmode
|
||||
{
|
||||
PPMODE, HVSPMODE
|
||||
};
|
||||
|
||||
|
||||
extern int verbose;
|
||||
extern char * progname;
|
||||
|
@ -399,11 +404,11 @@ static int stk500v2_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
|||
}
|
||||
|
||||
|
||||
static int stk500pp_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
static int stk500hv_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4])
|
||||
{
|
||||
|
||||
fprintf(stderr, "%s: stk500pp_command(): no direct SPI supported for PP mode\n",
|
||||
fprintf(stderr, "%s: stk500hv_command(): no direct SPI supported for PP mode\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
@ -439,18 +444,24 @@ static int stk500v2_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|||
}
|
||||
|
||||
/*
|
||||
* issue the 'chip erase' command to the AVR device, parallel mode
|
||||
* issue the 'chip erase' command to the AVR device, generic HV mode
|
||||
*/
|
||||
static int stk500pp_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
static int stk500hv_chip_erase(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
|
||||
{
|
||||
int result;
|
||||
unsigned char buf[3];
|
||||
|
||||
pgm->pgm_led(pgm, ON);
|
||||
|
||||
buf[0] = CMD_CHIP_ERASE_PP;
|
||||
buf[1] = p->chiperasepulsewidth;
|
||||
buf[2] = p->chiperasepolltimeout;
|
||||
if (mode == PPMODE) {
|
||||
buf[0] = CMD_CHIP_ERASE_PP;
|
||||
buf[1] = p->chiperasepulsewidth;
|
||||
buf[2] = p->chiperasepolltimeout;
|
||||
} else {
|
||||
buf[0] = CMD_CHIP_ERASE_HVSP;
|
||||
buf[1] = p->chiperasepolltimeout;
|
||||
buf[2] = p->chiperasetime;
|
||||
}
|
||||
result = stk500v2_command(pgm, buf, 3, sizeof(buf));
|
||||
usleep(p->chip_erase_delay);
|
||||
pgm->initialize(pgm, p);
|
||||
|
@ -460,6 +471,22 @@ static int stk500pp_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* issue the 'chip erase' command to the AVR device, parallel mode
|
||||
*/
|
||||
static int stk500pp_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
return stk500hv_chip_erase(pgm, p, PPMODE);
|
||||
}
|
||||
|
||||
/*
|
||||
* issue the 'chip erase' command to the AVR device, HVSP mode
|
||||
*/
|
||||
static int stk500hvsp_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
return stk500hv_chip_erase(pgm, p, HVSPMODE);
|
||||
}
|
||||
|
||||
/*
|
||||
* issue the 'program enable' command to the AVR device
|
||||
*/
|
||||
|
@ -477,7 +504,7 @@ static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
|||
buf[1] = p->timeout;
|
||||
buf[2] = p->stabdelay;
|
||||
buf[3] = p->cmdexedelay;
|
||||
buf[4] = p->synchloops;
|
||||
buf[4] = p->synchcycles;
|
||||
buf[5] = p->bytedelay;
|
||||
buf[6] = p->pollvalue;
|
||||
buf[7] = p->pollindex;
|
||||
|
@ -494,7 +521,7 @@ static int stk500pp_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
|||
unsigned char buf[16];
|
||||
|
||||
buf[0] = CMD_ENTER_PROGMODE_PP;
|
||||
buf[1] = p->ppenterstabdelay;
|
||||
buf[1] = p->hventerstabdelay;
|
||||
buf[2] = p->progmodedelay;
|
||||
buf[3] = p->latchcycles;
|
||||
buf[4] = p->togglevtg;
|
||||
|
@ -505,6 +532,26 @@ static int stk500pp_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
|||
return stk500v2_command(pgm, buf, 8, sizeof(buf));
|
||||
}
|
||||
|
||||
/*
|
||||
* issue the 'program enable' command to the AVR device, HVSP mode
|
||||
*/
|
||||
static int stk500hvsp_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
|
||||
buf[0] = CMD_ENTER_PROGMODE_HVSP;
|
||||
buf[1] = p->hventerstabdelay;
|
||||
buf[2] = p->hvspcmdexedelay;
|
||||
buf[3] = p->synchcycles;
|
||||
buf[4] = p->latchcycles;
|
||||
buf[5] = p->togglevtg;
|
||||
buf[6] = p->poweroffdelay;
|
||||
buf[7] = p->resetdelayms;
|
||||
buf[8] = p->resetdelayus;
|
||||
|
||||
return stk500v2_command(pgm, buf, 9, sizeof(buf));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
@ -517,20 +564,22 @@ static int stk500v2_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|||
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands, parallel mode
|
||||
* initialize the AVR device and prepare it to accept commands, generic HV mode
|
||||
*/
|
||||
static int stk500pp_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
static int stk500hv_initialize(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
|
||||
{
|
||||
unsigned char buf[CTL_STACK_SIZE + 1];
|
||||
int result;
|
||||
LNODEID ln;
|
||||
AVRMEM * m;
|
||||
|
||||
if (p->ctl_stack_type != CTL_STACK_PP) {
|
||||
if (p->ctl_stack_type != (mode == PPMODE? CTL_STACK_PP: CTL_STACK_HVSP)) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500pp_initialize(): "
|
||||
"parallel programming control stack not defined for part \"%s\"\n",
|
||||
progname, p->desc);
|
||||
"%s: stk500hv_initialize(): "
|
||||
"%s programming control stack not defined for part \"%s\"\n",
|
||||
progname,
|
||||
(mode == PPMODE? "parallel": "high-voltage serial"),
|
||||
p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -582,6 +631,21 @@ static int stk500pp_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|||
return pgm->program_enable(pgm, p);
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands, PP mode
|
||||
*/
|
||||
static int stk500pp_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
return stk500hv_initialize(pgm, p, PPMODE);
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands, HVSP mode
|
||||
*/
|
||||
static int stk500hvsp_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
return stk500hv_initialize(pgm, p, HVSPMODE);
|
||||
}
|
||||
|
||||
static void stk500v2_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
|
@ -603,7 +667,10 @@ static void stk500v2_disable(PROGRAMMER * pgm)
|
|||
return;
|
||||
}
|
||||
|
||||
static void stk500pp_disable(PROGRAMMER * pgm)
|
||||
/*
|
||||
* Leave programming mode, generic HV mode
|
||||
*/
|
||||
static void stk500hv_disable(PROGRAMMER * pgm, enum hvmode mode)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
int result;
|
||||
|
@ -613,15 +680,15 @@ static void stk500pp_disable(PROGRAMMER * pgm)
|
|||
free(eeprom_pagecache);
|
||||
eeprom_pagecache = NULL;
|
||||
|
||||
buf[0] = CMD_LEAVE_PROGMODE_PP;
|
||||
buf[1] = 15; // p->ppleavestabdelay;
|
||||
buf[0] = mode == PPMODE? CMD_LEAVE_PROGMODE_PP: CMD_LEAVE_PROGMODE_HVSP;
|
||||
buf[1] = 15; // p->hvleavestabdelay;
|
||||
buf[2] = 15; // p->resetdelay;
|
||||
|
||||
result = stk500v2_command(pgm, buf, 3, sizeof(buf));
|
||||
|
||||
if (result < 0 || buf[1] != STATUS_CMD_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500pp_disable(): "
|
||||
"%s: stk500hv_disable(): "
|
||||
"failed to leave programming mode, got 0x%02x\n",
|
||||
progname,buf[1]);
|
||||
exit(1);
|
||||
|
@ -630,6 +697,22 @@ static void stk500pp_disable(PROGRAMMER * pgm)
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Leave programming mode, PP mode
|
||||
*/
|
||||
static void stk500pp_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
stk500hv_disable(pgm, PPMODE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Leave programming mode, HVSP mode
|
||||
*/
|
||||
static void stk500hvsp_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
stk500hv_disable(pgm, HVSPMODE);
|
||||
}
|
||||
|
||||
static void stk500v2_enable(PROGRAMMER * pgm)
|
||||
{
|
||||
return;
|
||||
|
@ -715,8 +798,12 @@ static int stk500v2_loadaddr(PROGRAMMER * pgm, unsigned int addr)
|
|||
}
|
||||
|
||||
|
||||
static int stk500pp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value)
|
||||
/*
|
||||
* Read a single byte, generic HV mode
|
||||
*/
|
||||
static int stk500hv_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value,
|
||||
enum hvmode mode)
|
||||
{
|
||||
int result, cmdlen = 2;
|
||||
char buf[266];
|
||||
|
@ -725,14 +812,11 @@ static int stk500pp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
unsigned char *cache_ptr = NULL;
|
||||
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: stk500pp_read_byte(.., %s, 0x%lx, ...)\n",
|
||||
fprintf(stderr, "%s: stk500hv_read_byte(.., %s, 0x%lx, ...)\n",
|
||||
progname, mem->desc, addr);
|
||||
|
||||
if (stk500pp_program_enable(pgm, p) < 0)
|
||||
return -1;
|
||||
|
||||
if (strcmp(mem->desc, "flash") == 0) {
|
||||
buf[0] = CMD_READ_FLASH_PP;
|
||||
buf[0] = mode == PPMODE? CMD_READ_FLASH_PP: CMD_READ_FLASH_HVSP;
|
||||
cmdlen = 3;
|
||||
pagesize = mem->page_size;
|
||||
if (pagesize == 0)
|
||||
|
@ -751,7 +835,7 @@ static int stk500pp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
use_ext_addr = (1U << 31);
|
||||
}
|
||||
} else if (strcmp(mem->desc, "eeprom") == 0) {
|
||||
buf[0] = CMD_READ_EEPROM_PP;
|
||||
buf[0] = mode == PPMODE? CMD_READ_EEPROM_PP: CMD_READ_EEPROM_HVSP;
|
||||
cmdlen = 3;
|
||||
pagesize = mem->page_size;
|
||||
if (pagesize == 0)
|
||||
|
@ -761,24 +845,24 @@ static int stk500pp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
cache_ptr = eeprom_pagecache;
|
||||
} else if (strcmp(mem->desc, "lfuse") == 0 ||
|
||||
strcmp(mem->desc, "fuse") == 0) {
|
||||
buf[0] = CMD_READ_FUSE_PP;
|
||||
buf[0] = mode == PPMODE? CMD_READ_FUSE_PP: CMD_READ_FUSE_HVSP;
|
||||
addr = 0;
|
||||
} else if (strcmp(mem->desc, "hfuse") == 0) {
|
||||
buf[0] = CMD_READ_FUSE_PP;
|
||||
buf[0] = mode == PPMODE? CMD_READ_FUSE_PP: CMD_READ_FUSE_HVSP;
|
||||
addr = 1;
|
||||
} else if (strcmp(mem->desc, "efuse") == 0) {
|
||||
buf[0] = CMD_READ_FUSE_PP;
|
||||
buf[0] = mode == PPMODE? CMD_READ_FUSE_PP: CMD_READ_FUSE_HVSP;
|
||||
addr = 2;
|
||||
} else if (strcmp(mem->desc, "lock") == 0) {
|
||||
buf[0] = CMD_READ_LOCK_PP;
|
||||
buf[0] = mode == PPMODE? CMD_READ_LOCK_PP: CMD_READ_LOCK_HVSP;
|
||||
} else if (strcmp(mem->desc, "calibration") == 0) {
|
||||
buf[0] = CMD_READ_OSCCAL_PP;
|
||||
buf[0] = mode == PPMODE? CMD_READ_OSCCAL_PP: CMD_READ_OSCCAL_HVSP;
|
||||
} else if (strcmp(mem->desc, "signature") == 0) {
|
||||
buf[0] = CMD_READ_SIGNATURE_PP;
|
||||
buf[0] = mode == PPMODE? CMD_READ_SIGNATURE_PP: CMD_READ_SIGNATURE_HVSP;
|
||||
}
|
||||
|
||||
/*
|
||||
* In parallel mode, we have to use paged reads for flash and
|
||||
* In HV mode, we have to use paged reads for flash and
|
||||
* EEPROM, and cache the results in a page cache.
|
||||
*
|
||||
* Page cache validation is based on "{flash,eeprom}_pageaddr"
|
||||
|
@ -803,14 +887,14 @@ static int stk500pp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
}
|
||||
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: stk500pp_read_byte(): Sending read memory command: ",
|
||||
fprintf(stderr, "%s: stk500hv_read_byte(): Sending read memory command: ",
|
||||
progname);
|
||||
|
||||
result = stk500v2_command(pgm, buf, cmdlen, sizeof(buf));
|
||||
|
||||
if (result < 0 || buf[1] != STATUS_CMD_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500pp_read_byte(): "
|
||||
"%s: stk500hv_read_byte(): "
|
||||
"timeout/error communicating with programmer (status %d)\n",
|
||||
progname, result);
|
||||
return -1;
|
||||
|
@ -827,8 +911,30 @@ static int stk500pp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data)
|
||||
/*
|
||||
* Read a single byte, PP mode
|
||||
*/
|
||||
static int stk500pp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
return stk500hv_read_byte(pgm, p, mem, addr, value, PPMODE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a single byte, HVSP mode
|
||||
*/
|
||||
static int stk500hvsp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
return stk500hv_read_byte(pgm, p, mem, addr, value, HVSPMODE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write one byte, generic HV mode
|
||||
*/
|
||||
static int stk500hv_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data,
|
||||
enum hvmode mode)
|
||||
{
|
||||
int result, cmdlen, timeout = 0, pulsewidth = 0;
|
||||
char buf[266];
|
||||
|
@ -837,14 +943,11 @@ static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
unsigned char *cache_ptr = NULL;
|
||||
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: stk500pp_write_byte(.., %s, 0x%lx, ...)\n",
|
||||
fprintf(stderr, "%s: stk500hv_write_byte(.., %s, 0x%lx, ...)\n",
|
||||
progname, mem->desc, addr);
|
||||
|
||||
if (stk500pp_program_enable(pgm, p) < 0)
|
||||
return -1;
|
||||
|
||||
if (strcmp(mem->desc, "flash") == 0) {
|
||||
buf[0] = CMD_PROGRAM_FLASH_PP;
|
||||
buf[0] = mode == PPMODE? CMD_PROGRAM_FLASH_PP: CMD_PROGRAM_FLASH_HVSP;
|
||||
pagesize = mem->page_size;
|
||||
if (pagesize == 0)
|
||||
pagesize = 2;
|
||||
|
@ -862,7 +965,7 @@ static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
use_ext_addr = (1U << 31);
|
||||
}
|
||||
} else if (strcmp(mem->desc, "eeprom") == 0) {
|
||||
buf[0] = CMD_PROGRAM_EEPROM_PP;
|
||||
buf[0] = mode == PPMODE? CMD_PROGRAM_EEPROM_PP: CMD_PROGRAM_EEPROM_HVSP;
|
||||
pagesize = mem->page_size;
|
||||
if (pagesize == 0)
|
||||
pagesize = 1;
|
||||
|
@ -871,27 +974,27 @@ static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
cache_ptr = eeprom_pagecache;
|
||||
} else if (strcmp(mem->desc, "lfuse") == 0 ||
|
||||
strcmp(mem->desc, "fuse") == 0) {
|
||||
buf[0] = CMD_PROGRAM_FUSE_PP;
|
||||
buf[0] = mode == PPMODE? CMD_PROGRAM_FUSE_PP: CMD_PROGRAM_FUSE_HVSP;
|
||||
addr = 0;
|
||||
pulsewidth = p->programfusepulsewidth;
|
||||
timeout = p->programfusepolltimeout;
|
||||
} else if (strcmp(mem->desc, "hfuse") == 0) {
|
||||
buf[0] = CMD_PROGRAM_FUSE_PP;
|
||||
buf[0] = mode == PPMODE? CMD_PROGRAM_FUSE_PP: CMD_PROGRAM_FUSE_HVSP;
|
||||
addr = 1;
|
||||
pulsewidth = p->programfusepulsewidth;
|
||||
timeout = p->programfusepolltimeout;
|
||||
} else if (strcmp(mem->desc, "efuse") == 0) {
|
||||
buf[0] = CMD_PROGRAM_FUSE_PP;
|
||||
buf[0] = mode == PPMODE? CMD_PROGRAM_FUSE_PP: CMD_PROGRAM_FUSE_HVSP;
|
||||
addr = 2;
|
||||
pulsewidth = p->programfusepulsewidth;
|
||||
timeout = p->programfusepolltimeout;
|
||||
} else if (strcmp(mem->desc, "lock") == 0) {
|
||||
buf[0] = CMD_PROGRAM_LOCK_PP;
|
||||
buf[0] = mode == PPMODE? CMD_PROGRAM_LOCK_PP: CMD_PROGRAM_LOCK_HVSP;
|
||||
pulsewidth = p->programlockpulsewidth;
|
||||
timeout = p->programlockpolltimeout;
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"%s: stk500pp_write_byte(): "
|
||||
"%s: stk500hv_write_byte(): "
|
||||
"unsupported memory type: %s\n",
|
||||
progname, mem->desc);
|
||||
return -1;
|
||||
|
@ -900,7 +1003,7 @@ static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
cmdlen = 5 + pagesize;
|
||||
|
||||
/*
|
||||
* In parallel mode, we have to use paged writes for flash and
|
||||
* In HV mode, we have to use paged writes for flash and
|
||||
* EEPROM. As both, flash and EEPROM cells can only be programmed
|
||||
* from `1' to `0' bits (even EEPROM does not support auto-erase in
|
||||
* parallel mode), we just pre-fill the page cache with 0xff, so all
|
||||
|
@ -938,19 +1041,24 @@ static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
} else {
|
||||
buf[1] = addr;
|
||||
buf[2] = data;
|
||||
buf[3] = pulsewidth;
|
||||
buf[4] = timeout;
|
||||
if (mode == PPMODE) {
|
||||
buf[3] = pulsewidth;
|
||||
buf[4] = timeout;
|
||||
} else {
|
||||
buf[3] = timeout;
|
||||
cmdlen--;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: stk500pp_write_byte(): Sending write memory command: ",
|
||||
fprintf(stderr, "%s: stk500hv_write_byte(): Sending write memory command: ",
|
||||
progname);
|
||||
|
||||
result = stk500v2_command(pgm, buf, cmdlen, sizeof(buf));
|
||||
|
||||
if (result < 0 || buf[1] != STATUS_CMD_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500pp_write_byte(): "
|
||||
"%s: stk500hv_write_byte(): "
|
||||
"timeout/error communicating with programmer (status %d)\n",
|
||||
progname, result);
|
||||
return -1;
|
||||
|
@ -964,6 +1072,25 @@ static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write one byte, PP mode
|
||||
*/
|
||||
static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data)
|
||||
{
|
||||
return stk500hv_write_byte(pgm, p, mem, addr, data, PPMODE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write one byte, HVSP mode
|
||||
*/
|
||||
static int stk500hvsp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data)
|
||||
{
|
||||
return stk500hv_write_byte(pgm, p, mem, addr, data, HVSPMODE);
|
||||
}
|
||||
|
||||
|
||||
static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
|
@ -1096,14 +1223,18 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
return n_bytes;
|
||||
}
|
||||
|
||||
static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
/*
|
||||
* Write pages of flash/EEPROM, generic HV mode
|
||||
*/
|
||||
static int stk500hv_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes,
|
||||
enum hvmode mode)
|
||||
{
|
||||
unsigned int addr, block_size, last_addr, hiaddr, addrshift, use_ext_addr;
|
||||
unsigned char commandbuf[5], buf[266];
|
||||
int result;
|
||||
|
||||
DEBUG("STK500V2: stk500pp_paged_write(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
|
||||
DEBUG("STK500V2: stk500hv_paged_write(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
|
||||
|
||||
hiaddr = UINT_MAX;
|
||||
addrshift = 0;
|
||||
|
@ -1113,7 +1244,7 @@ static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
if (strcmp(m->desc, "flash") == 0) {
|
||||
addrshift = 1;
|
||||
flash_pageaddr = (unsigned long)-1L;
|
||||
commandbuf[0] = CMD_PROGRAM_FLASH_PP;
|
||||
commandbuf[0] = mode == PPMODE? CMD_PROGRAM_FLASH_PP: CMD_PROGRAM_FLASH_HVSP;
|
||||
/*
|
||||
* If bit 31 is set, this indicates that the following read/write
|
||||
* operation will be performed on a memory that is larger than
|
||||
|
@ -1125,7 +1256,7 @@ static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
}
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
eeprom_pageaddr = (unsigned long)-1L;
|
||||
commandbuf[0] = CMD_PROGRAM_EEPROM_PP;
|
||||
commandbuf[0] = mode == PPMODE? CMD_PROGRAM_EEPROM_PP: CMD_PROGRAM_EEPROM_HVSP;
|
||||
}
|
||||
/*
|
||||
* Synthesize the mode byte. This is simpler than adding yet
|
||||
|
@ -1158,7 +1289,7 @@ static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
|
||||
DEBUG("block_size at addr %d is %d\n",addr,block_size);
|
||||
|
||||
if (commandbuf[0] == CMD_PROGRAM_FLASH_PP) {
|
||||
if (addrshift == 1) {
|
||||
if (stk500v2_is_page_empty(addr, block_size, m->buf)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1180,7 +1311,7 @@ static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
|
||||
result = stk500v2_command(pgm, buf, page_size + 5, sizeof(buf));
|
||||
if (buf[1] != STATUS_CMD_OK) {
|
||||
fprintf(stderr, "%s: stk500pp_paged_write: write command failed with %d\n",
|
||||
fprintf(stderr, "%s: stk500hv_paged_write: write command failed with %d\n",
|
||||
progname, buf[1]);
|
||||
return -1;
|
||||
}
|
||||
|
@ -1189,6 +1320,24 @@ static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
return n_bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write pages of flash/EEPROM, PP mode
|
||||
*/
|
||||
static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
return stk500hv_paged_write(pgm, p, m, page_size, n_bytes, PPMODE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write pages of flash/EEPROM, HVSP mode
|
||||
*/
|
||||
static int stk500hvsp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
return stk500hv_paged_write(pgm, p, m, page_size, n_bytes, HVSPMODE);
|
||||
}
|
||||
|
||||
static int stk500v2_is_page_empty(unsigned int address, int page_size,
|
||||
const unsigned char *buf)
|
||||
{
|
||||
|
@ -1293,14 +1442,18 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
}
|
||||
|
||||
|
||||
static int stk500pp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
/*
|
||||
* Read pages of flash/EEPROM, generic HV mode
|
||||
*/
|
||||
static int stk500hv_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes,
|
||||
enum hvmode mode)
|
||||
{
|
||||
unsigned int addr, block_size, hiaddr, addrshift, use_ext_addr;
|
||||
unsigned char commandbuf[3], buf[266];
|
||||
int result;
|
||||
|
||||
DEBUG("STK500V2: stk500pp_paged_load(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
|
||||
DEBUG("STK500V2: stk500hv_paged_load(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
|
||||
|
||||
page_size = m->readsize;
|
||||
|
||||
|
@ -1310,7 +1463,7 @@ static int stk500pp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
|
||||
// determine which command is to be used
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
commandbuf[0] = CMD_READ_FLASH_PP;
|
||||
commandbuf[0] = mode == PPMODE? CMD_READ_FLASH_PP: CMD_READ_FLASH_HVSP;
|
||||
addrshift = 1;
|
||||
/*
|
||||
* If bit 31 is set, this indicates that the following read/write
|
||||
|
@ -1323,7 +1476,7 @@ static int stk500pp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
}
|
||||
}
|
||||
else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
commandbuf[0] = CMD_READ_EEPROM_PP;
|
||||
commandbuf[0] = mode == PPMODE? CMD_READ_EEPROM_PP: CMD_READ_EEPROM_HVSP;
|
||||
}
|
||||
|
||||
for (addr = 0; addr < n_bytes; addr += page_size) {
|
||||
|
@ -1349,7 +1502,7 @@ static int stk500pp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
|
||||
result = stk500v2_command(pgm, buf, 3, sizeof(buf));
|
||||
if (buf[1] != STATUS_CMD_OK) {
|
||||
fprintf(stderr, "%s: stk500pp_paged_load: read command failed with %d\n",
|
||||
fprintf(stderr, "%s: stk500hv_paged_load: read command failed with %d\n",
|
||||
progname, buf[1]);
|
||||
return -1;
|
||||
}
|
||||
|
@ -1366,6 +1519,24 @@ static int stk500pp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
return n_bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read pages of flash/EEPROM, PP mode
|
||||
*/
|
||||
static int stk500pp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
return stk500hv_paged_load(pgm, p, m, page_size, n_bytes, PPMODE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read pages of flash/EEPROM, HVSP mode
|
||||
*/
|
||||
static int stk500hvsp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
return stk500hv_paged_load(pgm, p, m, page_size, n_bytes, HVSPMODE);
|
||||
}
|
||||
|
||||
|
||||
static int stk500v2_set_vtarget(PROGRAMMER * pgm, double v)
|
||||
{
|
||||
|
@ -1746,7 +1917,7 @@ void stk500pp_initpgm(PROGRAMMER * pgm)
|
|||
pgm->disable = stk500pp_disable;
|
||||
pgm->program_enable = stk500pp_program_enable;
|
||||
pgm->chip_erase = stk500pp_chip_erase;
|
||||
pgm->cmd = stk500pp_cmd;
|
||||
pgm->cmd = stk500hv_cmd;
|
||||
pgm->open = stk500v2_open;
|
||||
pgm->close = stk500v2_close;
|
||||
|
||||
|
@ -1764,3 +1935,35 @@ void stk500pp_initpgm(PROGRAMMER * pgm)
|
|||
pgm->set_sck_period = stk500v2_set_sck_period;
|
||||
pgm->page_size = 256;
|
||||
}
|
||||
|
||||
void stk500hvsp_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "STK500HVSP");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->initialize = stk500hvsp_initialize;
|
||||
pgm->display = stk500v2_display;
|
||||
pgm->enable = stk500v2_enable;
|
||||
pgm->disable = stk500hvsp_disable;
|
||||
pgm->program_enable = stk500hvsp_program_enable;
|
||||
pgm->chip_erase = stk500hvsp_chip_erase;
|
||||
pgm->cmd = stk500hv_cmd;
|
||||
pgm->open = stk500v2_open;
|
||||
pgm->close = stk500v2_close;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
pgm->read_byte = stk500hvsp_read_byte;
|
||||
pgm->write_byte = stk500hvsp_write_byte;
|
||||
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->page_size = 256;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define stk500v2_h__
|
||||
|
||||
void stk500v2_initpgm (PROGRAMMER * pgm);
|
||||
void stk500hvsp_initpgm (PROGRAMMER * pgm);
|
||||
void stk500pp_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue