Xmega page erase implementation for JTAGICEmkII

* jtagmkII.c: Handle flash pages sizes > 256 bytes, implement
page_erase() method
* avrdude.conf.in: Change flash pagesize for all Xmega devices
to 512 bytes
* avr.c: Implement auto_erase, using page_erase if available
* avr.h: Remove unused parameters from avr_read(), replace
unused parameter in avr_write)() by auto_erase
* stk500v2.c: Handle flash page sizes > 256 bytes
* update.c (do_op): Handle new updateflags parameter
* main.c: Implement auto_erase as page_erase if possible
* update.h (enum updateflags): New enum
* pgm.h (struct programmer_t): Add page_erase method



git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1089 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Joerg Wunsch 2012-05-04 10:02:30 +00:00
parent 36ca4dce5c
commit b9a38193a0
11 changed files with 265 additions and 104 deletions

View File

@ -1,3 +1,19 @@
2012-05-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Xmega page erase implementation for JTAGICEmkII
* jtagmkII.c: Handle flash pages sizes > 256 bytes, implement
page_erase() method
* avrdude.conf.in: Change flash pagesize for all Xmega devices
to 512 bytes
* avr.c: Implement auto_erase, using page_erase if available
* avr.h: Remove unused parameters from avr_read(), replace
unused parameter in avr_write)() by auto_erase
* stk500v2.c: Handle flash page sizes > 256 bytes
* update.c (do_op): Handle new updateflags parameter
* main.c: Implement auto_erase as page_erase if possible
* update.h (enum updateflags): New enum
* pgm.h (struct programmer_t): Add page_erase method
2012-04-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de> 2012-04-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* jtagmkII.c (jtagmkII_paged_load, jtagmkII_paged_write): fix bug * jtagmkII.c (jtagmkII_paged_load, jtagmkII_paged_write): fix bug

3
NEWS
View File

@ -86,6 +86,9 @@ Current:
Xmega devices, and "flash" for everything else. This ensures Xmega devices, and "flash" for everything else. This ensures
the bootloader is not touched. the bootloader is not touched.
* For programmers that support it, the default erase method is a
page erase now, rather than a chip erase (Xmega only).
* Programmers and parts lists * Programmers and parts lists
They are now sorted at output with '-c ?'/'-p ?'. (patch #7671: They are now sorted at output with '-c ?'/'-p ?'. (patch #7671:

10
avr.c
View File

@ -213,7 +213,7 @@ int avr_mem_hiaddr(AVRMEM * mem)
* Return the number of bytes read, or < 0 if an error occurs. * Return the number of bytes read, or < 0 if an error occurs.
*/ */
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
AVRPART * v, int verb) AVRPART * v)
{ {
unsigned long i, lastaddr; unsigned long i, lastaddr;
unsigned char cmd[4]; unsigned char cmd[4];
@ -718,7 +718,7 @@ int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
* Return the number of bytes written, or -1 if an error occurs. * Return the number of bytes written, or -1 if an error occurs.
*/ */
int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
int verb) int auto_erase)
{ {
int rc; int rc;
int newpage, page_tainted, flush_page, do_write; int newpage, page_tainted, flush_page, do_write;
@ -813,6 +813,10 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
break; break;
} }
if (need_write) { if (need_write) {
rc = 0;
if (auto_erase)
rc = pgm->page_erase(pgm, p, m, pageaddr);
if (rc >= 0)
rc = pgm->paged_write(pgm, p, m, m->page_size, pageaddr, m->page_size); rc = pgm->paged_write(pgm, p, m, m->page_size, pageaddr, m->page_size);
if (rc < 0) if (rc < 0)
/* paged write failed, fall back to byte-at-a-time write below */ /* paged write failed, fall back to byte-at-a-time write below */
@ -925,7 +929,7 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p)
int rc; int rc;
report_progress (0,1,"Reading"); report_progress (0,1,"Reading");
rc = avr_read(pgm, p, "signature", 0, 0); rc = avr_read(pgm, p, "signature", 0);
if (rc < 0) { if (rc < 0) {
fprintf(stderr, fprintf(stderr,
"%s: error reading signature data for part \"%s\", rc=%d\n", "%s: error reading signature data for part \"%s\", rc=%d\n",

5
avr.h
View File

@ -41,8 +41,7 @@ int avr_tpi_poll_nvmbsy(PROGRAMMER *pgm);
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value); unsigned long addr, unsigned char * value);
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, AVRPART * v, int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, AVRPART * v);
int verbose);
int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr); unsigned long addr);
@ -54,7 +53,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data); unsigned long addr, unsigned char data);
int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
int verbose); int auto_erase);
int avr_signature(PROGRAMMER * pgm, AVRPART * p); int avr_signature(PROGRAMMER * pgm, AVRPART * p);

View File

@ -12291,14 +12291,14 @@ part
memory "prodsig" memory "prodsig"
size = 0x200; size = 0x200;
offset = 0x8e0200; offset = 0x8e0200;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "usersig" memory "usersig"
size = 0x200; size = 0x200;
offset = 0x8e0400; offset = 0x8e0400;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
@ -12358,28 +12358,28 @@ part parent ".xmega"
memory "application" memory "application"
size = 0x00010000; size = 0x00010000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "apptable" memory "apptable"
size = 0x00001000; size = 0x00001000;
offset = 0x0080f000; offset = 0x0080f000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "boot" memory "boot"
size = 0x00001000; size = 0x00001000;
offset = 0x00810000; offset = 0x00810000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "flash" memory "flash"
size = 0x00011000; size = 0x00011000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
@ -12408,28 +12408,28 @@ part parent ".xmega"
memory "application" memory "application"
size = 0x00020000; size = 0x00020000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "apptable" memory "apptable"
size = 0x00002000; size = 0x00002000;
offset = 0x0081e000; offset = 0x0081e000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "boot" memory "boot"
size = 0x00002000; size = 0x00002000;
offset = 0x00820000; offset = 0x00820000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "flash" memory "flash"
size = 0x00022000; size = 0x00022000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
@ -12468,28 +12468,28 @@ part parent ".xmega"
memory "application" memory "application"
size = 0x00030000; size = 0x00030000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "apptable" memory "apptable"
size = 0x00002000; size = 0x00002000;
offset = 0x0082e000; offset = 0x0082e000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "boot" memory "boot"
size = 0x00002000; size = 0x00002000;
offset = 0x00830000; offset = 0x00830000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "flash" memory "flash"
size = 0x00032000; size = 0x00032000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
@ -12518,28 +12518,28 @@ part parent ".xmega"
memory "application" memory "application"
size = 0x00040000; size = 0x00040000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "apptable" memory "apptable"
size = 0x00002000; size = 0x00002000;
offset = 0x0083e000; offset = 0x0083e000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "boot" memory "boot"
size = 0x00002000; size = 0x00002000;
offset = 0x00840000; offset = 0x00840000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "flash" memory "flash"
size = 0x00042000; size = 0x00042000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
@ -12618,14 +12618,14 @@ part parent ".xmega"
memory "application" memory "application"
size = 0x00004000; size = 0x00004000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "apptable" memory "apptable"
size = 0x00001000; size = 0x00001000;
offset = 0x00803000; offset = 0x00803000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
@ -12639,7 +12639,7 @@ part parent ".xmega"
memory "flash" memory "flash"
size = 0x00005000; size = 0x00005000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
@ -12668,28 +12668,28 @@ part parent ".xmega"
memory "application" memory "application"
size = 0x00008000; size = 0x00008000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "apptable" memory "apptable"
size = 0x00001000; size = 0x00001000;
offset = 0x00807000; offset = 0x00807000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "boot" memory "boot"
size = 0x00001000; size = 0x00001000;
offset = 0x00808000; offset = 0x00808000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "flash" memory "flash"
size = 0x00009000; size = 0x00009000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
@ -12738,28 +12738,28 @@ part parent ".xmega"
memory "application" memory "application"
size = 0x00004000; size = 0x00004000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "apptable" memory "apptable"
size = 0x00001000; size = 0x00001000;
offset = 0x00803000; offset = 0x00803000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "boot" memory "boot"
size = 0x00001000; size = 0x00001000;
offset = 0x00804000; offset = 0x00804000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "flash" memory "flash"
size = 0x00005000; size = 0x00005000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
; ;
@ -12784,28 +12784,28 @@ part parent ".xmega"
memory "application" memory "application"
size = 0x00008000; size = 0x00008000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "apptable" memory "apptable"
size = 0x00001000; size = 0x00001000;
offset = 0x00807000; offset = 0x00807000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "boot" memory "boot"
size = 0x00001000; size = 0x00001000;
offset = 0x00808000; offset = 0x00808000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "flash" memory "flash"
size = 0x00009000; size = 0x00009000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
; ;
@ -12830,7 +12830,7 @@ part parent ".xmega"
memory "application" memory "application"
size = 0x00010000; size = 0x00010000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
@ -12844,14 +12844,14 @@ part parent ".xmega"
memory "boot" memory "boot"
size = 0x00001000; size = 0x00001000;
offset = 0x00810000; offset = 0x00810000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
memory "flash" memory "flash"
size = 0x00011000; size = 0x00011000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
; ;
@ -12876,7 +12876,7 @@ part parent ".xmega"
memory "application" memory "application"
size = 0x00020000; size = 0x00020000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
@ -12886,7 +12886,7 @@ part parent ".xmega"
# XML file also says it's 8 KiB, use this. # XML file also says it's 8 KiB, use this.
size = 0x00002000; size = 0x00002000;
offset = 0x0081e000; offset = 0x0081e000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
@ -12900,7 +12900,7 @@ part parent ".xmega"
memory "flash" memory "flash"
size = 0x00022000; size = 0x00022000;
offset = 0x0800000; offset = 0x0800000;
page_size = 0x100; page_size = 0x200;
readsize = 0x100; readsize = 0x100;
; ;
; ;

View File

@ -993,10 +993,13 @@ static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
m = ldata(ln); m = ldata(ln);
if (strcmp(m->desc, "flash") == 0) { if (strcmp(m->desc, "flash") == 0) {
if (m->page_size > 256)
PDATA(pgm)->flash_pagesize = 256;
else
PDATA(pgm)->flash_pagesize = m->page_size; PDATA(pgm)->flash_pagesize = m->page_size;
u32_to_b4(sendbuf.dd.ulFlashSize, m->size); u32_to_b4(sendbuf.dd.ulFlashSize, m->size);
u16_to_b2(sendbuf.dd.uiFlashPageSize, PDATA(pgm)->flash_pagesize); u16_to_b2(sendbuf.dd.uiFlashPageSize, m->page_size);
u16_to_b2(sendbuf.dd.uiFlashpages, m->size / PDATA(pgm)->flash_pagesize); u16_to_b2(sendbuf.dd.uiFlashpages, m->size / m->page_size);
if (p->flags & AVRPART_HAS_DW) { if (p->flags & AVRPART_HAS_DW) {
memcpy(sendbuf.dd.ucFlashInst, p->flash_instr, FLASH_INSTR_SIZE); memcpy(sendbuf.dd.ucFlashInst, p->flash_instr, FLASH_INSTR_SIZE);
memcpy(sendbuf.dd.ucEepromInst, p->eeprom_instr, EEPROM_INSTR_SIZE); memcpy(sendbuf.dd.ucEepromInst, p->eeprom_instr, EEPROM_INSTR_SIZE);
@ -1061,8 +1064,11 @@ static void jtagmkII_set_xmega_params(PROGRAMMER * pgm, AVRPART * p)
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
m = ldata(ln); m = ldata(ln);
if (strcmp(m->desc, "flash") == 0) { if (strcmp(m->desc, "flash") == 0) {
if (m->page_size > 256)
PDATA(pgm)->flash_pagesize = 256;
else
PDATA(pgm)->flash_pagesize = m->page_size; PDATA(pgm)->flash_pagesize = m->page_size;
u16_to_b2(sendbuf.dd.flash_page_size, m->page_size * 2); u16_to_b2(sendbuf.dd.flash_page_size, m->page_size);
} else if (strcmp(m->desc, "eeprom") == 0) { } else if (strcmp(m->desc, "eeprom") == 0) {
sendbuf.dd.eeprom_page_size = m->page_size; sendbuf.dd.eeprom_page_size = m->page_size;
u16_to_b2(sendbuf.dd.eeprom_size, m->size); u16_to_b2(sendbuf.dd.eeprom_size, m->size);
@ -1366,6 +1372,15 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
return -1; return -1;
} }
/*
* If this is an ATxmega device in JTAG mode, change the emulator
* mode from JTAG to JTAG_XMEGA.
*/
if ((pgm->flag & PGM_FL_IS_JTAG) &&
(p->flags & AVRPART_HAS_PDI)) {
if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG_XMEGA) < 0)
return -1;
}
/* /*
* Must set the device descriptor before entering programming mode. * Must set the device descriptor before entering programming mode.
*/ */
@ -1381,8 +1396,6 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
*/ */
if ((pgm->flag & PGM_FL_IS_JTAG) && if ((pgm->flag & PGM_FL_IS_JTAG) &&
(p->flags & AVRPART_HAS_PDI)) { (p->flags & AVRPART_HAS_PDI)) {
if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG_XMEGA) < 0)
return -1;
/* /*
* Find out where the border between application and boot area * Find out where the border between application and boot area
* is. * is.
@ -1394,6 +1407,16 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
"%s: jtagmkII_initialize(): Cannot locate \"flash\" and \"boot\" memories in description\n", "%s: jtagmkII_initialize(): Cannot locate \"flash\" and \"boot\" memories in description\n",
progname); progname);
} else { } else {
if (PDATA(pgm)->fwver < 0x700) {
/* V7+ firmware does not need this anymore */
unsigned char par[4];
u32_to_b4(par, flashmem->offset);
(void) jtagmkII_setparm(pgm, PAR_PDI_OFFSET_START, par);
u32_to_b4(par, bootmem->offset);
(void) jtagmkII_setparm(pgm, PAR_PDI_OFFSET_END, par);
}
PDATA(pgm)->boot_start = bootmem->offset - flashmem->offset; PDATA(pgm)->boot_start = bootmem->offset - flashmem->offset;
} }
} }
@ -1856,6 +1879,107 @@ void jtagmkII_close(PROGRAMMER * pgm)
pgm->fd.ifd = -1; pgm->fd.ifd = -1;
} }
static int jtagmkII_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int addr)
{
unsigned char cmd[6];
unsigned char *resp;
int status, tries;
long otimeout = serial_recv_timeout;
if (verbose >= 2)
fprintf(stderr, "%s: jtagmkII_page_erase(.., %s, 0x%x)\n",
progname, m->desc, addr);
if (!(p->flags & AVRPART_HAS_PDI)) {
fprintf(stderr, "%s: jtagmkII_page_erase: not an Xmega device\n",
progname);
return -1;
}
if ((pgm->flag & PGM_FL_IS_DW)) {
fprintf(stderr, "%s: jtagmkII_page_erase: not applicable to debugWIRE\n",
progname);
return -1;
}
if (jtagmkII_program_enable(pgm) < 0)
return -1;
cmd[0] = CMND_XMEGA_ERASE;
if (strcmp(m->desc, "flash") == 0) {
if (jtagmkII_memtype(pgm, p, addr) == MTYPE_FLASH)
cmd[1] = XMEGA_ERASE_APP_PAGE;
else
cmd[1] = XMEGA_ERASE_BOOT_PAGE;
} else if (strcmp(m->desc, "eeprom") == 0) {
cmd[1] = XMEGA_ERASE_EEPROM_PAGE;
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
cmd[1] = XMEGA_ERASE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
cmd[1] = XMEGA_ERASE_BOOT_PAGE;
} else {
cmd[1] = XMEGA_ERASE_APP_PAGE;
}
serial_recv_timeout = 100;
/*
* Don't use jtagmkII_memaddr() here. While with all other
* commands, firmware 7+ doesn't require the NVM offsets being
* applied, the erase page commands make an exception, and do
* require the NVM offsets as part of the (page) address.
*/
u32_to_b4(cmd + 2, addr + m->offset);
tries = 0;
retry:
if (verbose >= 2)
fprintf(stderr, "%s: jtagmkII_page_erase(): "
"Sending xmega erase command: ",
progname);
jtagmkII_send(pgm, cmd, sizeof cmd);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
if (verbose >= 1)
fprintf(stderr,
"%s: jtagmkII_page_erase(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
if (tries++ < 4) {
serial_recv_timeout *= 2;
goto retry;
}
fprintf(stderr,
"%s: jtagmkII_page_erase(): fatal timeout/"
"error communicating with programmer (status %d)\n",
progname, status);
serial_recv_timeout = otimeout;
return -1;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
fprintf(stderr, "0x%02x (%d bytes msg)\n", resp[0], status);
if (resp[0] != RSP_OK) {
fprintf(stderr,
"%s: jtagmkII_page_erase(): "
"bad response to xmega erase command: %s\n",
progname, jtagmkII_get_rc(resp[0]));
free(resp);
serial_recv_timeout = otimeout;
return -1;
}
free(resp);
serial_recv_timeout = otimeout;
return 0;
}
static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size, unsigned int page_size,
unsigned int addr, unsigned int n_bytes) unsigned int addr, unsigned int n_bytes)
@ -1864,7 +1988,6 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int maxaddr = addr + n_bytes; unsigned int maxaddr = addr + n_bytes;
unsigned char *cmd; unsigned char *cmd;
unsigned char *resp; unsigned char *resp;
unsigned char par[4];
int status, tries, dynamic_memtype = 0; int status, tries, dynamic_memtype = 0;
long otimeout = serial_recv_timeout; long otimeout = serial_recv_timeout;
@ -1876,24 +1999,17 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return -1; return -1;
if (page_size == 0) page_size = 256; if (page_size == 0) page_size = 256;
else if (page_size > 256) page_size = 256;
if ((cmd = malloc(page_size + 10)) == NULL) { if ((cmd = malloc(page_size + 10)) == NULL) {
fprintf(stderr, "%s: jtagmkII_paged_write(): Out of memory\n", fprintf(stderr, "%s: jtagmkII_paged_write(): Out of memory\n",
progname); progname);
return -1; return -1;
} }
if ( p->flags & AVRPART_HAS_PDI )
{
u32_to_b4( par, m->offset );
(void) jtagmkII_setparm( pgm, PAR_PDI_OFFSET_START, par );
u32_to_b4( par, m->offset + m->size );
(void) jtagmkII_setparm( pgm, PAR_PDI_OFFSET_END, par );
}
cmd[0] = CMND_WRITE_MEMORY; cmd[0] = CMND_WRITE_MEMORY;
if (strcmp(m->desc, "flash") == 0) { if (strcmp(m->desc, "flash") == 0) {
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L; PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
page_size = PDATA(pgm)->flash_pagesize;
cmd[1] = jtagmkII_memtype(pgm, p, addr); cmd[1] = jtagmkII_memtype(pgm, p, addr);
if (p->flags & AVRPART_HAS_PDI) if (p->flags & AVRPART_HAS_PDI)
/* dynamically decide between flash/boot memtype */ /* dynamically decide between flash/boot memtype */
@ -1916,7 +2032,6 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
} }
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE; cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
page_size = PDATA(pgm)->eeprom_pagesize;
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) { } else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
cmd[1] = MTYPE_USERSIG; cmd[1] = MTYPE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) { } else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
@ -2136,8 +2251,11 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
addr += mem->offset; addr += mem->offset;
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE; cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE;
if (strcmp(mem->desc, "flash") == 0) { if (strcmp(mem->desc, "flash") == 0 ||
pagesize = mem->page_size; strcmp(mem->desc, "application") == 0 ||
strcmp(mem->desc, "apptable") == 0 ||
strcmp(mem->desc, "boot") == 0) {
pagesize = PDATA(pgm)->flash_pagesize;
paddr = addr & ~(pagesize - 1); paddr = addr & ~(pagesize - 1);
paddr_ptr = &PDATA(pgm)->flash_pageaddr; paddr_ptr = &PDATA(pgm)->flash_pageaddr;
cache_ptr = PDATA(pgm)->flash_pagecache; cache_ptr = PDATA(pgm)->flash_pagecache;
@ -3771,6 +3889,7 @@ void jtagmkII_initpgm(PROGRAMMER * pgm)
*/ */
pgm->paged_write = jtagmkII_paged_write; pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load; pgm->paged_load = jtagmkII_paged_load;
pgm->page_erase = jtagmkII_page_erase;
pgm->print_parms = jtagmkII_print_parms; pgm->print_parms = jtagmkII_print_parms;
pgm->set_sck_period = jtagmkII_set_sck_period; pgm->set_sck_period = jtagmkII_set_sck_period;
pgm->parseextparams = jtagmkII_parseextparms; pgm->parseextparams = jtagmkII_parseextparms;
@ -3837,6 +3956,7 @@ void jtagmkII_pdi_initpgm(PROGRAMMER * pgm)
*/ */
pgm->paged_write = jtagmkII_paged_write; pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load; pgm->paged_load = jtagmkII_paged_load;
pgm->page_erase = jtagmkII_page_erase;
pgm->print_parms = jtagmkII_print_parms; pgm->print_parms = jtagmkII_print_parms;
pgm->setup = jtagmkII_setup; pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown; pgm->teardown = jtagmkII_teardown;
@ -3869,6 +3989,7 @@ void jtagmkII_dragon_initpgm(PROGRAMMER * pgm)
*/ */
pgm->paged_write = jtagmkII_paged_write; pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load; pgm->paged_load = jtagmkII_paged_load;
pgm->page_erase = jtagmkII_page_erase;
pgm->print_parms = jtagmkII_print_parms; pgm->print_parms = jtagmkII_print_parms;
pgm->set_sck_period = jtagmkII_set_sck_period; pgm->set_sck_period = jtagmkII_set_sck_period;
pgm->parseextparams = jtagmkII_parseextparms; pgm->parseextparams = jtagmkII_parseextparms;
@ -3969,6 +4090,7 @@ void jtagmkII_dragon_pdi_initpgm(PROGRAMMER * pgm)
*/ */
pgm->paged_write = jtagmkII_paged_write; pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load; pgm->paged_load = jtagmkII_paged_load;
pgm->page_erase = jtagmkII_page_erase;
pgm->print_parms = jtagmkII_print_parms; pgm->print_parms = jtagmkII_print_parms;
pgm->setup = jtagmkII_setup; pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown; pgm->teardown = jtagmkII_teardown;

37
main.c
View File

@ -315,11 +315,8 @@ int main(int argc, char * argv [])
/* options / operating mode variables */ /* options / operating mode variables */
int erase; /* 1=erase chip, 0=don't */ int erase; /* 1=erase chip, 0=don't */
int calibrate; /* 1=calibrate RC oscillator, 0=don't */ int calibrate; /* 1=calibrate RC oscillator, 0=don't */
int auto_erase; /* 0=never erase unless explicity told to do
so, 1=erase if we are going to program flash */
char * port; /* device port (/dev/xxx) */ char * port; /* device port (/dev/xxx) */
int terminal; /* 1=enter terminal mode, 0=don't */ int terminal; /* 1=enter terminal mode, 0=don't */
int nowrite; /* don't actually write anything to the chip */
int verify; /* perform a verify operation */ int verify; /* perform a verify operation */
char * exitspecs; /* exit specs string from command line */ char * exitspecs; /* exit specs string from command line */
char * programmer; /* programmer id */ char * programmer; /* programmer id */
@ -336,6 +333,7 @@ int main(int argc, char * argv [])
int silentsafe; /* Don't ask about fuses, 1=silent, 0=normal */ int silentsafe; /* Don't ask about fuses, 1=silent, 0=normal */
int init_ok; /* Device initialization worked well */ int init_ok; /* Device initialization worked well */
int is_open; /* Device open succeeded */ int is_open; /* Device open succeeded */
enum updateflags uflags = UF_AUTO_ERASE; /* Flags for do_op() */
unsigned char safemode_lfuse = 0xff; unsigned char safemode_lfuse = 0xff;
unsigned char safemode_hfuse = 0xff; unsigned char safemode_hfuse = 0xff;
unsigned char safemode_efuse = 0xff; unsigned char safemode_efuse = 0xff;
@ -397,11 +395,9 @@ int main(int argc, char * argv [])
port = NULL; port = NULL;
erase = 0; erase = 0;
calibrate = 0; calibrate = 0;
auto_erase = 1;
p = NULL; p = NULL;
ovsigck = 0; ovsigck = 0;
terminal = 0; terminal = 0;
nowrite = 0;
verify = 1; /* on by default */ verify = 1; /* on by default */
quell_progress = 0; quell_progress = 0;
exitspecs = NULL; exitspecs = NULL;
@ -508,11 +504,12 @@ int main(int argc, char * argv [])
break; break;
case 'D': /* disable auto erase */ case 'D': /* disable auto erase */
auto_erase = 0; uflags &= ~UF_AUTO_ERASE;
break; break;
case 'e': /* perform a chip erase */ case 'e': /* perform a chip erase */
erase = 1; erase = 1;
uflags &= ~UF_AUTO_ERASE;
break; break;
case 'E': case 'E':
@ -524,7 +521,7 @@ int main(int argc, char * argv [])
break; break;
case 'n': case 'n':
nowrite = 1; uflags |= UF_NOWRITE;
break; break;
case 'O': /* perform RC oscillator calibration */ case 'O': /* perform RC oscillator calibration */
@ -844,7 +841,6 @@ int main(int argc, char * argv [])
if(p->flags & AVRPART_AVR32) { if(p->flags & AVRPART_AVR32) {
safemode = 0; safemode = 0;
auto_erase = 0;
} }
if(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) { if(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) {
@ -1131,26 +1127,39 @@ int main(int argc, char * argv [])
} }
} }
if ((erase == 0) && (auto_erase == 1)) { if (uflags & UF_AUTO_ERASE) {
if ((p->flags & AVRPART_HAS_PDI) && pgm->page_erase != NULL &&
lsize(updates) > 0) {
if (quell_progress < 2) {
fprintf(stderr,
"%s: NOTE: Programmer supports page erase for Xmega devices.\n"
"%sEach page will be erased before programming it, but no chip erase is performed.\n"
"%sTo disable page erases, specify the -D option; for a chip-erase, use the -e option.\n",
progname, progbuf, progbuf);
}
} else {
AVRMEM * m; AVRMEM * m;
const char *memname = (p->flags & AVRPART_HAS_PDI)? "application": "flash";
for (ln=lfirst(updates); ln; ln=lnext(ln)) { for (ln=lfirst(updates); ln; ln=lnext(ln)) {
upd = ldata(ln); upd = ldata(ln);
m = avr_locate_mem(p, upd->memtype); m = avr_locate_mem(p, upd->memtype);
if (m == NULL) if (m == NULL)
continue; continue;
if ((strcasecmp(m->desc, "flash") == 0) && (upd->op == DEVICE_WRITE)) { if ((strcasecmp(m->desc, memname) == 0) && (upd->op == DEVICE_WRITE)) {
erase = 1; erase = 1;
uflags &= ~UF_AUTO_ERASE;
if (quell_progress < 2) { if (quell_progress < 2) {
fprintf(stderr, fprintf(stderr,
"%s: NOTE: FLASH memory has been specified, an erase cycle " "%s: NOTE: \"%s\" memory has been specified, an erase cycle "
"will be performed\n" "will be performed\n"
"%sTo disable this feature, specify the -D option.\n", "%sTo disable this feature, specify the -D option.\n",
progname, progbuf); progname, memname, progbuf);
} }
break; break;
} }
} }
} }
}
/* /*
* Display cycle count, if and only if it is not set later on. * Display cycle count, if and only if it is not set later on.
@ -1199,7 +1208,7 @@ int main(int argc, char * argv [])
* erase the chip's flash and eeprom memories, this is required * erase the chip's flash and eeprom memories, this is required
* before the chip can accept new programming * before the chip can accept new programming
*/ */
if (nowrite) { if (uflags & UF_NOWRITE) {
fprintf(stderr, fprintf(stderr,
"%s: conflicting -e and -n options specified, NOT erasing chip\n", "%s: conflicting -e and -n options specified, NOT erasing chip\n",
progname); progname);
@ -1230,7 +1239,7 @@ int main(int argc, char * argv [])
for (ln=lfirst(updates); ln; ln=lnext(ln)) { for (ln=lfirst(updates); ln; ln=lnext(ln)) {
upd = ldata(ln); upd = ldata(ln);
rc = do_op(pgm, p, upd, nowrite); rc = do_op(pgm, p, upd, uflags);
if (rc) { if (rc) {
exitrc = 1; exitrc = 1;
break; break;

2
pgm.h
View File

@ -109,6 +109,8 @@ typedef struct programmer_t {
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m, int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size, unsigned int baseaddr, unsigned int page_size, unsigned int baseaddr,
unsigned int n_bytes); unsigned int n_bytes);
int (*page_erase) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
unsigned int baseaddr);
void (*write_setup) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m); void (*write_setup) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
int (*write_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m, int (*write_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char value); unsigned long addr, unsigned char value);

View File

@ -1171,8 +1171,12 @@ static int stk500hv_initialize(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
m = ldata(ln); m = ldata(ln);
if (strcmp(m->desc, "flash") == 0) { if (strcmp(m->desc, "flash") == 0) {
if (m->page_size > 0) if (m->page_size > 0) {
if (m->page_size > 256)
PDATA(pgm)->flash_pagesize = 256;
else
PDATA(pgm)->flash_pagesize = m->page_size; PDATA(pgm)->flash_pagesize = m->page_size;
}
} else if (strcmp(m->desc, "eeprom") == 0) { } else if (strcmp(m->desc, "eeprom") == 0) {
if (m->page_size > 0) if (m->page_size > 0)
PDATA(pgm)->eeprom_pagesize = m->page_size; PDATA(pgm)->eeprom_pagesize = m->page_size;
@ -1456,9 +1460,7 @@ static int stk500hv_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
if (strcmp(mem->desc, "flash") == 0) { if (strcmp(mem->desc, "flash") == 0) {
buf[0] = mode == PPMODE? CMD_READ_FLASH_PP: CMD_READ_FLASH_HVSP; buf[0] = mode == PPMODE? CMD_READ_FLASH_PP: CMD_READ_FLASH_HVSP;
cmdlen = 3; cmdlen = 3;
pagesize = mem->page_size; pagesize = PDATA(pgm)->flash_pagesize;
if (pagesize == 0)
pagesize = 2;
paddr = addr & ~(pagesize - 1); paddr = addr & ~(pagesize - 1);
paddr_ptr = &PDATA(pgm)->flash_pageaddr; paddr_ptr = &PDATA(pgm)->flash_pageaddr;
cache_ptr = PDATA(pgm)->flash_pagecache; cache_ptr = PDATA(pgm)->flash_pagecache;
@ -1587,9 +1589,7 @@ static int stk500hv_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
if (strcmp(mem->desc, "flash") == 0) { if (strcmp(mem->desc, "flash") == 0) {
buf[0] = mode == PPMODE? CMD_PROGRAM_FLASH_PP: CMD_PROGRAM_FLASH_HVSP; buf[0] = mode == PPMODE? CMD_PROGRAM_FLASH_PP: CMD_PROGRAM_FLASH_HVSP;
pagesize = mem->page_size; pagesize = PDATA(pgm)->flash_pagesize;
if (pagesize == 0)
pagesize = 2;
paddr = addr & ~(pagesize - 1); paddr = addr & ~(pagesize - 1);
paddr_ptr = &PDATA(pgm)->flash_pageaddr; paddr_ptr = &PDATA(pgm)->flash_pageaddr;
cache_ptr = PDATA(pgm)->flash_pagecache; cache_ptr = PDATA(pgm)->flash_pagecache;

View File

@ -216,7 +216,7 @@ void free_update(UPDATE * u)
} }
int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite) int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags flags)
{ {
struct avrpart * v; struct avrpart * v;
AVRMEM * mem; AVRMEM * mem;
@ -239,7 +239,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite)
progname, mem->desc); progname, mem->desc);
} }
report_progress(0,1,"Reading"); report_progress(0,1,"Reading");
rc = avr_read(pgm, p, upd->memtype, 0, 1); rc = avr_read(pgm, p, upd->memtype, 0);
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
progname, mem->desc, rc); progname, mem->desc, rc);
@ -288,9 +288,9 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite)
progname, mem->desc, size); progname, mem->desc, size);
} }
if (!nowrite) { if (!(flags & UF_NOWRITE)) {
report_progress(0,1,"Writing"); report_progress(0,1,"Writing");
rc = avr_write(pgm, p, upd->memtype, size, 1); rc = avr_write(pgm, p, upd->memtype, size, (flags & UF_AUTO_ERASE) != 0);
report_progress(1,1,NULL); report_progress(1,1,NULL);
} }
else { else {
@ -346,7 +346,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite)
} }
report_progress (0,1,"Reading"); report_progress (0,1,"Reading");
rc = avr_read(pgm, p, upd->memtype, v, 1); rc = avr_read(pgm, p, upd->memtype, v);
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
progname, mem->desc, rc); progname, mem->desc, rc);

View File

@ -29,6 +29,12 @@ enum {
DEVICE_VERIFY DEVICE_VERIFY
}; };
enum updateflags {
UF_NONE = 0,
UF_NOWRITE = 1,
UF_AUTO_ERASE = 2,
};
typedef struct update_t { typedef struct update_t {
char * memtype; char * memtype;
@ -47,7 +53,7 @@ extern UPDATE * new_update(int op, char * memtype, int filefmt,
char * filename); char * filename);
extern void free_update(UPDATE * upd); extern void free_update(UPDATE * upd);
extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd,
int nowrite); enum updateflags flags);
#ifdef __cplusplus #ifdef __cplusplus
} }