Implement TPI mode for AVRISPmkII/STK600.
Add ATtiny4/5/9/10 to avrdude.conf.in. Document TPI and new device support. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@916 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
24e0a12960
commit
46715b4296
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2_private.h: Implement TPI mode for AVRISPmkII/STK600
|
||||
* config_gram.y: (Dito.)
|
||||
* avrpart.h: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* avrdude.conf.in: Add ATtiny4/5/9/10
|
||||
* avrdude.1: Document TPI and new device support.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2010-01-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by clint fisher:
|
||||
|
|
5
NEWS
5
NEWS
|
@ -11,12 +11,17 @@ Current:
|
|||
|
||||
- AVR32A0512 (JTAGMKII only)
|
||||
- ATmega32U4
|
||||
- ATtiny4
|
||||
- ATtiny5
|
||||
- ATtiny9
|
||||
- ATtiny10
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- BusPirate
|
||||
- Arduino
|
||||
- JTAGICEmkII and AVR Dragon in PDI mode (ATxmega devices)
|
||||
- STK600 and AVRISP mkII in TPI mode (ATtiny4/5/9/10)
|
||||
|
||||
* Bugfixes
|
||||
|
||||
|
|
10
avrdude.1
10
avrdude.1
|
@ -119,6 +119,7 @@ below for details.
|
|||
Atmel's STK600 programmer is supported in ISP and high-voltage
|
||||
programming modes, and connects through the USB.
|
||||
For ATxmega devices, the STK600 is supported in PDI mode.
|
||||
For ATtiny4/5/9/10 devices, the STK600 and AVRISP mkII are supported in TPI mode.
|
||||
.Pp
|
||||
The simple serial programmer described in Atmel's application note
|
||||
AVR910, and the bootloader described in Atmel's application note
|
||||
|
@ -256,20 +257,24 @@ pwm2 AT90PWM2
|
|||
pwm2b AT90PWM2B
|
||||
pwm3 AT90PWM3
|
||||
pwm3b AT90PWM3B
|
||||
t12 ATtiny12
|
||||
t10 ATtiny10
|
||||
t12 ATtiny12 (***)
|
||||
t13 ATtiny13
|
||||
t15 ATtiny15
|
||||
t2313 ATtiny2313
|
||||
t25 ATtiny25
|
||||
t26 ATtiny26
|
||||
t261 ATtiny261
|
||||
t4 ATtiny4
|
||||
t44 ATtiny44
|
||||
t45 ATtiny45
|
||||
t461 ATtiny461
|
||||
t5 ATtiny5
|
||||
t84 ATtiny84
|
||||
t85 ATtiny85
|
||||
t861 ATtiny861
|
||||
t88 ATtiny88
|
||||
t9 ATtiny9
|
||||
ucr2 AT32uca0512
|
||||
usb1286 ATmega1286
|
||||
usb1287 ATmega1287
|
||||
|
@ -299,6 +304,9 @@ The AT90S2323 and ATtiny22 use the same algorithm.
|
|||
Flash addressing above 128 KB is not supported by all
|
||||
programming hardware. Known to work are jtag2, stk500v2,
|
||||
and bit-bang programmers.
|
||||
.It "(***)"
|
||||
The ATtiny11 uses the same algorithm, but can only be
|
||||
programmed in high-voltage serial mode.
|
||||
.El
|
||||
.It Fl b Ar baudrate
|
||||
Override the RS-232 connection baud rate specified in the respective
|
||||
|
|
164
avrdude.conf.in
164
avrdude.conf.in
|
@ -39,6 +39,8 @@
|
|||
# desc = <description> ; # quoted string
|
||||
# has_jtag = <yes/no> ; # part has JTAG i/f
|
||||
# has_debugwire = <yes/no> ; # part has debugWire i/f
|
||||
# has_pdi = <yes/no> ; # part has PDI i/f
|
||||
# has_tpi = <yes/no> ; # part has TPI i/f
|
||||
# devicecode = <num> ; # deprecated, use stk500_devcode
|
||||
# stk500_devcode = <num> ; # numeric
|
||||
# avr910_devcode = <num> ; # numeric
|
||||
|
@ -185,7 +187,7 @@
|
|||
# http://www.atmel.com/atmel/acrobat/doc2525.pdf
|
||||
#
|
||||
|
||||
#define ATTINY10 0x10
|
||||
#define ATTINY10 0x10 /* the _old_ one that never existed! */
|
||||
#define ATTINY11 0x11
|
||||
#define ATTINY12 0x12
|
||||
#define ATTINY15 0x13
|
||||
|
@ -15316,3 +15318,163 @@ part
|
|||
;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATtiny4
|
||||
#------------------------------------------------------------
|
||||
|
||||
part
|
||||
id = "t4";
|
||||
desc = "ATtiny4";
|
||||
signature = 0x1e 0x8f 0x0a;
|
||||
has_tpi = yes;
|
||||
|
||||
memory "flash"
|
||||
size = 512;
|
||||
offset = 0x4000;
|
||||
page_size = 16;
|
||||
blocksize = 128;
|
||||
;
|
||||
|
||||
memory "signature"
|
||||
size = 3;
|
||||
offset = 0x3fc0;
|
||||
;
|
||||
|
||||
memory "fuse"
|
||||
size = 1;
|
||||
offset = 0x3f40;
|
||||
blocksize = 4;
|
||||
;
|
||||
|
||||
memory "calibration"
|
||||
size = 1;
|
||||
offset = 0x3f80;
|
||||
;
|
||||
|
||||
memory "lockbits"
|
||||
size = 1;
|
||||
offset = 0x3f00;
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATtiny5
|
||||
#------------------------------------------------------------
|
||||
|
||||
part
|
||||
id = "t5";
|
||||
desc = "ATtiny5";
|
||||
signature = 0x1e 0x8f 0x09;
|
||||
has_tpi = yes;
|
||||
|
||||
memory "flash"
|
||||
size = 512;
|
||||
offset = 0x4000;
|
||||
page_size = 16;
|
||||
blocksize = 128;
|
||||
;
|
||||
|
||||
memory "signature"
|
||||
size = 3;
|
||||
offset = 0x3fc0;
|
||||
;
|
||||
|
||||
memory "fuse"
|
||||
size = 1;
|
||||
offset = 0x3f40;
|
||||
blocksize = 4;
|
||||
;
|
||||
|
||||
memory "calibration"
|
||||
size = 1;
|
||||
offset = 0x3f80;
|
||||
;
|
||||
|
||||
memory "lockbits"
|
||||
size = 1;
|
||||
offset = 0x3f00;
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATtiny9
|
||||
#------------------------------------------------------------
|
||||
|
||||
part
|
||||
id = "t8";
|
||||
desc = "ATtiny9";
|
||||
signature = 0x1e 0x90 0x08;
|
||||
has_tpi = yes;
|
||||
|
||||
memory "flash"
|
||||
size = 1024;
|
||||
offset = 0x4000;
|
||||
page_size = 16;
|
||||
blocksize = 128;
|
||||
;
|
||||
|
||||
memory "signature"
|
||||
size = 3;
|
||||
offset = 0x3fc0;
|
||||
;
|
||||
|
||||
memory "fuse"
|
||||
size = 1;
|
||||
offset = 0x3f40;
|
||||
blocksize = 4;
|
||||
;
|
||||
|
||||
memory "calibration"
|
||||
size = 1;
|
||||
offset = 0x3f80;
|
||||
;
|
||||
|
||||
memory "lockbits"
|
||||
size = 1;
|
||||
offset = 0x3f00;
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATtiny10
|
||||
#------------------------------------------------------------
|
||||
|
||||
part
|
||||
id = "t10";
|
||||
desc = "ATtiny10";
|
||||
signature = 0x1e 0x90 0x03;
|
||||
has_tpi = yes;
|
||||
|
||||
memory "flash"
|
||||
size = 1024;
|
||||
offset = 0x4000;
|
||||
page_size = 16;
|
||||
blocksize = 128;
|
||||
;
|
||||
|
||||
memory "signature"
|
||||
size = 3;
|
||||
offset = 0x3fc0;
|
||||
;
|
||||
|
||||
memory "fuse"
|
||||
size = 1;
|
||||
offset = 0x3f40;
|
||||
blocksize = 4;
|
||||
;
|
||||
|
||||
memory "calibration"
|
||||
size = 1;
|
||||
offset = 0x3f80;
|
||||
;
|
||||
|
||||
memory "lockbits"
|
||||
size = 1;
|
||||
offset = 0x3f00;
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ typedef struct opcode {
|
|||
#define AVRPART_AVR32 0x0100 /* part is in AVR32 family */
|
||||
#define AVRPART_INIT_SMC 0x0200 /* part will undergo chip erase */
|
||||
#define AVRPART_WRITE 0x0400 /* at least one write operation specified */
|
||||
#define AVRPART_HAS_TPI 0x0800 /* part has TPI i/f rather than ISP (ATtiny4/5/9/10) */
|
||||
|
||||
#define AVR_DESCLEN 64
|
||||
#define AVR_IDLEN 32
|
||||
|
|
|
@ -211,6 +211,7 @@ static int parse_cmdbits(OPCODE * op);
|
|||
%token K_HAS_JTAG /* MCU has JTAG i/f. */
|
||||
%token K_HAS_DW /* MCU has debugWire i/f. */
|
||||
%token K_HAS_PDI /* MCU has PDI i/f rather than ISP (ATxmega). */
|
||||
%token K_HAS_TPI /* MCU has TPI i/f rather than ISP (ATtiny4/5/9/10). */
|
||||
%token K_IDR /* address of OCD register in IO space */
|
||||
%token K_IS_AVR32 /* chip is in the avr32 family */
|
||||
%token K_RAMPZ /* address of RAMPZ reg. in IO space */
|
||||
|
@ -1078,6 +1079,16 @@ part_parm :
|
|||
free_token($3);
|
||||
} |
|
||||
|
||||
K_HAS_TPI TKN_EQUAL yesno
|
||||
{
|
||||
if ($3->primary == K_YES)
|
||||
current_part->flags |= AVRPART_HAS_TPI;
|
||||
else if ($3->primary == K_NO)
|
||||
current_part->flags &= ~AVRPART_HAS_TPI;
|
||||
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_IS_AVR32 TKN_EQUAL yesno
|
||||
{
|
||||
if ($3->primary == K_YES)
|
||||
|
|
|
@ -350,20 +350,24 @@ Currently, the following MCU types are understood:
|
|||
@item @code{pwm2b} @tab AT90PWM2B
|
||||
@item @code{pwm3} @tab AT90PWM3
|
||||
@item @code{pwm3b} @tab AT90PWM3B
|
||||
@item @code{t12} @tab ATtiny12
|
||||
@item @code{t10} @tab ATtiny10
|
||||
@item @code{t12} @tab ATtiny12 (***)
|
||||
@item @code{t13} @tab ATtiny13
|
||||
@item @code{t15} @tab ATtiny15
|
||||
@item @code{t2313} @tab ATtiny2313
|
||||
@item @code{t25} @tab ATtiny25
|
||||
@item @code{t26} @tab ATtiny26
|
||||
@item @code{t261} @tab ATtiny261
|
||||
@item @code{t4} @tab ATtiny4
|
||||
@item @code{t44} @tab ATtiny44
|
||||
@item @code{t45} @tab ATtiny45
|
||||
@item @code{t461} @tab ATtiny461
|
||||
@item @code{t5} @tab ATtiny5
|
||||
@item @code{t84} @tab ATtiny84
|
||||
@item @code{t85} @tab ATtiny85
|
||||
@item @code{t861} @tab ATtiny861
|
||||
@item @code{t88} @tab ATtiny88
|
||||
@item @code{t9} @tab ATtiny9
|
||||
@item @code{ucr2} @tab AT32uca0512
|
||||
@item @code{usb1286} @tab ATmega1286
|
||||
@item @code{usb1287} @tab ATmega1287
|
||||
|
@ -393,6 +397,10 @@ Currently, the following MCU types are understood:
|
|||
programming hardware. Known to work are jtag2, stk500v2,
|
||||
and bit-bang programmers.
|
||||
|
||||
(***)
|
||||
The ATtiny11 uses the same algorithm, but can only be
|
||||
programmed in high-voltage serial mode.
|
||||
|
||||
@item -b @var{baudrate}
|
||||
Override the RS-232 connection baud rate specified in the respective
|
||||
programmer's entry of the configuration file.
|
||||
|
@ -440,7 +448,8 @@ Atmel AppNote AVR911 AVROSP (an alias for avr109)
|
|||
@item @code{avrisp} @tab
|
||||
Atmel AVR ISP (an alias for stk500)
|
||||
@item @code{avrisp2} @tab
|
||||
Atmel AVR ISP mkII (alias for stk500v2)
|
||||
Atmel AVR ISP mkII in ISP mode, in PDI mode for ATxmega devices, or
|
||||
in TPI mode for ATtiny4/5/9/10
|
||||
@item @code{avrispmkII} @tab
|
||||
Atmel AVR ISP mkII (alias for stk500v2)
|
||||
@item @code{avrispv2} @tab
|
||||
|
@ -540,7 +549,8 @@ Atmel STK500, running a version 1.x firmware
|
|||
@item @code{stk500v2} @tab
|
||||
Atmel STK500, running a version 2.x firmware
|
||||
@item @code{stk600} @tab
|
||||
Atmel STK600 in ISP mode, or in PDI mode for ATxmega devices
|
||||
Atmel STK600 in ISP mode, in PDI mode for ATxmega devices, or
|
||||
in TPI mode for ATtiny4/5/9/10
|
||||
@item @code{stk600hvsp} @tab
|
||||
Atmel STK600 in high-voltage serial programming mode
|
||||
@item @code{stk600pp} @tab
|
||||
|
@ -2335,6 +2345,66 @@ This sequence is automatically initiated by using the JTAG ICE mkII
|
|||
or AVR Dragon in ISP mode, when they detect that ISP mode cannot be
|
||||
entered.
|
||||
|
||||
@item
|
||||
Problem: I want to use my JTAG ICE mkII or AVR Dragon to program an
|
||||
Xmega device through PDI. The documentation tells me to use the
|
||||
@emph{XMEGA PDI adapter for JTAGICE mkII} that is supposed to ship
|
||||
with the kit, yet I don't have it.
|
||||
|
||||
Solution: Use the following pin mapping:
|
||||
|
||||
@multitable @columnfractions .2 .2 .2 .2
|
||||
@item @strong{JTAGICE} @tab @strong{Target} @tab @strong{Squid cab-} @tab @strong{PDI}
|
||||
@item @strong{mkII probe} @tab @strong{pins} @tab @strong{le colors} @tab @strong{header}
|
||||
@item 1 (TCK) @tab @tab Black @tab
|
||||
@item 2 (GND) @tab GND @tab White @tab 6
|
||||
@item 3 (TDO) @tab @tab Grey @tab
|
||||
@item 4 (VTref) @tab VTref @tab Purple @tab 2
|
||||
@item 5 (TMS) @tab @tab Blue @tab
|
||||
@item 6 (nSRST) @tab PDI_CLK @tab Green @tab 5
|
||||
@item 7 (N.C.) @tab @tab Yellow @tab
|
||||
@item 8 (nTRST) @tab @tab Orange @tab
|
||||
@item 9 (TDI) @tab PDI_DATA @tab Red @tab 1
|
||||
@item 10 (GND) @tab @tab Brown @tab
|
||||
@end multitable
|
||||
|
||||
|
||||
@item
|
||||
Problem: I want to use my AVRISP mkII to program an
|
||||
ATtiny4/5/9/10 device through TPI. How to connect the pins?
|
||||
|
||||
Solution: Use the following pin mapping:
|
||||
|
||||
@multitable @columnfractions .2 .2 .2
|
||||
@item @strong{AVRISP} @tab @strong{Target} @tab @strong{ATtiny}
|
||||
@item @strong{connector} @tab @strong{pins} @tab @strong{pin #}
|
||||
@item 1 (MISO) @tab TPIDATA @tab 1
|
||||
@item 2 (VTref) @tab Vcc @tab 5
|
||||
@item 3 (SCK) @tab TPICLK @tab 3
|
||||
@item 4 (MOSI) @tab @tab
|
||||
@item 5 (RESET) @tab /RESET @tab 6
|
||||
@item 6 (GND) @tab GND @tab 2
|
||||
@end multitable
|
||||
|
||||
@item
|
||||
Problem: My ATtiny4/5/9/10 reads out fine, but any attempt to program
|
||||
it (through TPI) fails. Instead, the memory retains the old contents.
|
||||
|
||||
Solution: Mind the limited programming supply voltage range of these
|
||||
devices.
|
||||
|
||||
In-circuit programming through TPI is only guaranteed by the datasheet
|
||||
at Vcc = 5 V.
|
||||
|
||||
@item
|
||||
Problem: My ATxmega@dots{}A1/A2/A3 cannot be programmed through PDI with
|
||||
my AVR Dragon. Programming through a JTAG ICE mkII works though, as does
|
||||
programming through JTAG.
|
||||
|
||||
Solution: None by this time (2010 Q1).
|
||||
|
||||
It is said that the AVR Dragon can only program devices from the A4
|
||||
Xmega sub-family.
|
||||
|
||||
@end itemize
|
||||
|
||||
|
|
1
lexer.l
1
lexer.l
|
@ -149,6 +149,7 @@ flash { yylval=NULL; return K_FLASH; }
|
|||
has_jtag { yylval=NULL; return K_HAS_JTAG; }
|
||||
has_debugwire { yylval=NULL; return K_HAS_DW; }
|
||||
has_pdi { yylval=NULL; return K_HAS_PDI; }
|
||||
has_tpi { yylval=NULL; return K_HAS_TPI; }
|
||||
id { yylval=NULL; return K_ID; }
|
||||
idr { yylval=NULL; return K_IDR; }
|
||||
is_avr32 { yylval=NULL; return K_IS_AVR32; }
|
||||
|
|
2
main.c
2
main.c
|
@ -730,7 +730,7 @@ int main(int argc, char * argv [])
|
|||
auto_erase = 0;
|
||||
}
|
||||
|
||||
if(p->flags & AVRPART_HAS_PDI) {
|
||||
if(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) {
|
||||
safemode = 0;
|
||||
}
|
||||
|
||||
|
|
200
stk500v2.c
200
stk500v2.c
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2005 Erik Walthinsen
|
||||
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2006 David Moore
|
||||
* Copyright (C) 2006,2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
* Copyright (C) 2006,2007,2010 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -1100,7 +1100,7 @@ static int stk500v2_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|||
if ((PDATA(pgm)->pgmtype == PGMTYPE_STK600 ||
|
||||
PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
|
||||
PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) != 0
|
||||
&& (p->flags & AVRPART_HAS_PDI) != 0) {
|
||||
&& (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) != 0) {
|
||||
/*
|
||||
* This is an ATxmega device, must use XPROG protocol for the
|
||||
* remaining actions.
|
||||
|
@ -2409,9 +2409,11 @@ static int stk600_set_vtarget(PROGRAMMER * pgm, double v)
|
|||
* Vtarget on the STK600 can only be adjusted while not being in
|
||||
* programming mode.
|
||||
*/
|
||||
pgm->disable(pgm);
|
||||
if (PDATA(pgm)->lastpart)
|
||||
pgm->disable(pgm);
|
||||
rv = stk500v2_setparm(pgm, PARAM_VTARGET, utarg);
|
||||
pgm->program_enable(pgm, PDATA(pgm)->lastpart);
|
||||
if (PDATA(pgm)->lastpart)
|
||||
pgm->program_enable(pgm, PDATA(pgm)->lastpart);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -3044,73 +3046,107 @@ static int stk600_xprog_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
|||
unsigned char buf[16];
|
||||
unsigned int eepagesize = 42;
|
||||
unsigned int nvm_base;
|
||||
AVRMEM *mem;
|
||||
AVRMEM *mem = NULL;
|
||||
int use_tpi;
|
||||
|
||||
if (p->nvm_base == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_program_enable(): no nvm_base parameter for XPROG device\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if ((mem = avr_locate_mem(p, "eeprom")) != NULL) {
|
||||
if (mem->page_size == 0) {
|
||||
use_tpi = (p->flags & AVRPART_HAS_TPI) != 0;
|
||||
|
||||
if (!use_tpi) {
|
||||
if (p->nvm_base == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_program_enable(): no EEPROM page_size parameter for XPROG device\n",
|
||||
"%s: stk600_xprog_program_enable(): no nvm_base parameter for PDI device\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
eepagesize = mem->page_size;
|
||||
if ((mem = avr_locate_mem(p, "eeprom")) != NULL) {
|
||||
if (mem->page_size == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_program_enable(): no EEPROM page_size parameter for PDI device\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
eepagesize = mem->page_size;
|
||||
}
|
||||
}
|
||||
|
||||
buf[0] = CMD_XPROG_SETMODE;
|
||||
buf[1] = 0; /* PDI mode */
|
||||
buf[1] = use_tpi? XPRG_MODE_TPI: XPRG_MODE_PDI;
|
||||
if (stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_program_enable(): CMD_XPROG_SETMODE failed\n",
|
||||
progname);
|
||||
"%s: stk600_xprog_program_enable(): CMD_XPROG_SETMODE(XPRG_MODE_%s) failed\n",
|
||||
progname, use_tpi? "TPI": "PDI");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[0] = XPRG_CMD_ENTER_PROGMODE;
|
||||
if (stk600_xprog_command(pgm, buf, 1, 2) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_program_enable(): XPRG_CMD_ENTER_PROGMODE failed\n",
|
||||
"%s: stk600_xprog_program_enable(): XPRG_CMD_ENTER_PROGMODE failed\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[0] = XPRG_CMD_SET_PARAM;
|
||||
buf[1] = XPRG_PARAM_NVMBASE;
|
||||
nvm_base = p->nvm_base;
|
||||
/*
|
||||
* The 0x01000000 appears to be an indication to the programmer
|
||||
* that the respective address is located in IO (i.e., SRAM)
|
||||
* memory address space rather than flash. This is not documented
|
||||
* anywhere in AVR079 but matches what AVR Studio does.
|
||||
*/
|
||||
nvm_base |= 0x01000000;
|
||||
buf[2] = nvm_base >> 24;
|
||||
buf[3] = nvm_base >> 16;
|
||||
buf[4] = nvm_base >> 8;
|
||||
buf[5] = nvm_base;
|
||||
if (stk600_xprog_command(pgm, buf, 6, 2) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_program_enable(): XPRG_CMD_SET_PARAM(XPRG_PARAM_NVMBASE) failed\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if (use_tpi) {
|
||||
/*
|
||||
* Whatever all that might mean, it matches what AVR Studio
|
||||
* does.
|
||||
*/
|
||||
if (stk500v2_setparm_real(pgm, PARAM_DISCHARGEDELAY, 232) < 0)
|
||||
return -1;
|
||||
|
||||
if (mem != NULL) {
|
||||
buf[0] = XPRG_CMD_SET_PARAM;
|
||||
buf[1] = XPRG_PARAM_EEPPAGESIZE;
|
||||
buf[2] = eepagesize >> 8;
|
||||
buf[3] = eepagesize;
|
||||
if (stk600_xprog_command(pgm, buf, 4, 2) < 0) {
|
||||
buf[1] = XPRG_PARAM_TPI_3;
|
||||
buf[2] = 51;
|
||||
if (stk600_xprog_command(pgm, buf, 3, 2) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_program_enable(): XPRG_CMD_SET_PARAM(XPRG_PARAM_EEPPAGESIZE) failed\n",
|
||||
"%s: stk600_xprog_program_enable(): XPRG_CMD_SET_PARAM(XPRG_PARAM_TPI_3) failed\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[0] = XPRG_CMD_SET_PARAM;
|
||||
buf[1] = XPRG_PARAM_TPI_4;
|
||||
buf[2] = 50;
|
||||
if (stk600_xprog_command(pgm, buf, 3, 2) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_program_enable(): XPRG_CMD_SET_PARAM(XPRG_PARAM_TPI_4) failed\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
buf[0] = XPRG_CMD_SET_PARAM;
|
||||
buf[1] = XPRG_PARAM_NVMBASE;
|
||||
nvm_base = p->nvm_base;
|
||||
/*
|
||||
* The 0x01000000 appears to be an indication to the programmer
|
||||
* that the respective address is located in IO (i.e., SRAM)
|
||||
* memory address space rather than flash. This is not documented
|
||||
* anywhere in AVR079 but matches what AVR Studio does.
|
||||
*/
|
||||
nvm_base |= 0x01000000;
|
||||
buf[2] = nvm_base >> 24;
|
||||
buf[3] = nvm_base >> 16;
|
||||
buf[4] = nvm_base >> 8;
|
||||
buf[5] = nvm_base;
|
||||
if (stk600_xprog_command(pgm, buf, 6, 2) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_program_enable(): XPRG_CMD_SET_PARAM(XPRG_PARAM_NVMBASE) failed\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mem != NULL) {
|
||||
buf[0] = XPRG_CMD_SET_PARAM;
|
||||
buf[1] = XPRG_PARAM_EEPPAGESIZE;
|
||||
buf[2] = eepagesize >> 8;
|
||||
buf[3] = eepagesize;
|
||||
if (stk600_xprog_command(pgm, buf, 4, 2) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_program_enable(): XPRG_CMD_SET_PARAM(XPRG_PARAM_EEPPAGESIZE) failed\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -3123,7 +3159,7 @@ static void stk600_xprog_disable(PROGRAMMER * pgm)
|
|||
buf[0] = XPRG_CMD_LEAVE_PROGMODE;
|
||||
if (stk600_xprog_command(pgm, buf, 1, 2) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_program_enable(): XPRG_CMD_LEAVE_PROGMODE failed\n",
|
||||
"%s: stk600_xprog_program_disable(): XPRG_CMD_LEAVE_PROGMODE failed\n",
|
||||
progname);
|
||||
}
|
||||
}
|
||||
|
@ -3131,20 +3167,31 @@ static void stk600_xprog_disable(PROGRAMMER * pgm)
|
|||
static int stk600_xprog_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data)
|
||||
{
|
||||
unsigned char b[10];
|
||||
unsigned char b[9 + 256];
|
||||
int need_erase = 0;
|
||||
unsigned char write_size = 1;
|
||||
unsigned char memcode;
|
||||
|
||||
memset(b, 0, sizeof(b));
|
||||
|
||||
if (strcmp(mem->desc, "flash") == 0) {
|
||||
b[1] = XPRG_MEM_TYPE_APPL;
|
||||
memcode = XPRG_MEM_TYPE_APPL;
|
||||
} else if (strcmp(mem->desc, "boot") == 0) {
|
||||
b[1] = XPRG_MEM_TYPE_BOOT;
|
||||
memcode = XPRG_MEM_TYPE_BOOT;
|
||||
} else if (strcmp(mem->desc, "eeprom") == 0) {
|
||||
b[1] = XPRG_MEM_TYPE_EEPROM;
|
||||
memcode = XPRG_MEM_TYPE_EEPROM;
|
||||
} else if (strcmp(mem->desc, "lockbits") == 0) {
|
||||
b[1] = XPRG_MEM_TYPE_LOCKBITS;
|
||||
memcode = XPRG_MEM_TYPE_LOCKBITS;
|
||||
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
|
||||
b[1] = XPRG_MEM_TYPE_FUSE;
|
||||
memcode = XPRG_MEM_TYPE_FUSE;
|
||||
if (p->flags & AVRPART_HAS_TPI)
|
||||
/*
|
||||
* TPI devices need a mystic erase prior to writing their
|
||||
* fuses.
|
||||
*/
|
||||
need_erase = 1;
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
b[1] = XPRG_MEM_TYPE_USERSIG;
|
||||
memcode = XPRG_MEM_TYPE_USERSIG;
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_write_byte(): unknown memory \"%s\"\n",
|
||||
|
@ -3153,16 +3200,42 @@ static int stk600_xprog_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
}
|
||||
addr += mem->offset;
|
||||
|
||||
if (need_erase) {
|
||||
b[0] = XPRG_CMD_ERASE;
|
||||
b[1] = XPRG_ERASE_CONFIG;
|
||||
b[2] = mem->offset >> 24;
|
||||
b[3] = mem->offset >> 16;
|
||||
b[4] = mem->offset >> 8;
|
||||
b[5] = mem->offset + 1;
|
||||
if (stk600_xprog_command(pgm, b, 6, 2) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_chip_erase(): XPRG_CMD_ERASE(XPRG_ERASE_CONFIG) failed\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI) {
|
||||
/*
|
||||
* Some TPI memories (configuration aka. fuse) require a
|
||||
* larger write block size. We record that as a blocksize in
|
||||
* avrdude.conf.
|
||||
*/
|
||||
if (mem->blocksize != 0)
|
||||
write_size = mem->blocksize;
|
||||
}
|
||||
|
||||
b[0] = XPRG_CMD_WRITE_MEM;
|
||||
b[1] = memcode;
|
||||
b[2] = 0; /* pagemode: non-paged write */
|
||||
b[3] = addr >> 24;
|
||||
b[4] = addr >> 16;
|
||||
b[5] = addr >> 8;
|
||||
b[6] = addr;
|
||||
b[7] = 0;
|
||||
b[8] = 1;
|
||||
b[8] = write_size;
|
||||
b[9] = data;
|
||||
if (stk600_xprog_command(pgm, b, 10, 2) < 0) {
|
||||
if (stk600_xprog_command(pgm, b, 9 + write_size, 2) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_write_byte(): XPRG_CMD_WRITE_MEM failed\n",
|
||||
progname);
|
||||
|
@ -3460,10 +3533,25 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
static int stk600_xprog_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char b[6];
|
||||
AVRMEM *mem;
|
||||
unsigned int addr = 0;
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI) {
|
||||
if ((mem = avr_locate_mem(p, "flash")) == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_chip_erase(): no FLASH definition found for TPI device\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
addr = mem->offset + 1;
|
||||
}
|
||||
|
||||
b[0] = XPRG_CMD_ERASE;
|
||||
b[1] = XPRG_ERASE_CHIP;
|
||||
b[2] = b[3] = b[4] = b[5] = 0;
|
||||
b[2] = addr >> 24;
|
||||
b[3] = addr >> 16;
|
||||
b[4] = addr >> 8;
|
||||
b[5] = addr;
|
||||
if (stk600_xprog_command(pgm, b, 6, 2) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk600_xprog_chip_erase(): XPRG_CMD_ERASE(XPRG_ERASE_CHIP) failed\n",
|
||||
|
|
|
@ -215,6 +215,11 @@
|
|||
#define PARAM2_EC_ID_TABLE_REV 0xC9
|
||||
|
||||
/* STK600 XPROG section */
|
||||
// XPROG modes
|
||||
#define XPRG_MODE_PDI 0
|
||||
#define XPRG_MODE_JTAG 1
|
||||
#define XPRG_MODE_TPI 2
|
||||
|
||||
// XPROG commands
|
||||
#define XPRG_CMD_ENTER_PROGMODE 0x01
|
||||
#define XPRG_CMD_LEAVE_PROGMODE 0x02
|
||||
|
@ -242,6 +247,7 @@
|
|||
#define XPRG_ERASE_BOOT_PAGE 6
|
||||
#define XPRG_ERASE_EEPROM_PAGE 7
|
||||
#define XPRG_ERASE_USERSIG 8
|
||||
#define XPRG_ERASE_CONFIG 9 // TPI only, prepare fuse write
|
||||
|
||||
// Write mode flags
|
||||
#define XPRG_MEM_WRITE_ERASE 0
|
||||
|
@ -263,6 +269,10 @@
|
|||
#define XPRG_PARAM_NVMBASE 0x01
|
||||
// 2-byte page size
|
||||
#define XPRG_PARAM_EEPPAGESIZE 0x02
|
||||
// 1-byte, undocumented TPI param
|
||||
#define XPRG_PARAM_TPI_3 0x03
|
||||
// 1-byte, undocumented TPI param
|
||||
#define XPRG_PARAM_TPI_4 0x04
|
||||
|
||||
// *****************[ STK answer constants ]***************************
|
||||
|
||||
|
|
Loading…
Reference in New Issue