Extend the single-byte algorithm to all devices, both flash and

EEPROM.  (Flash cells must have been erased before though.)
* jtag3.c (jtag3_initialize): OCDEN no longer needs to be
considered; a session with "programming" purpose is sufficient
* jtag3.c (jtag3_write_byte): Use the paged algorithm for all
flash and EEPROM areas, not just Xmega.



git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1209 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
joerg_wunsch 2013-09-06 07:06:13 +00:00
parent 8daa7cecd4
commit 038807958e
2 changed files with 33 additions and 54 deletions

View File

@ -1,3 +1,12 @@
2013-09-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Extend the single-byte algorithm to all devices, both flash and
EEPROM. (Flash cells must have been erased before though.)
* jtag3.c (jtag3_initialize): OCDEN no longer needs to be
considered; a session with "programming" purpose is sufficient
* jtag3.c (jtag3_write_byte): Use the paged algorithm for all
flash and EEPROM areas, not just Xmega.
2013-09-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de> 2013-09-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Fix single-byte EEPROM updates on Xmega: Fix single-byte EEPROM updates on Xmega:

78
jtag3.c
View File

@ -77,17 +77,6 @@ struct pdata
#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) #define PDATA(pgm) ((struct pdata *)(pgm->cookie))
/*
* The OCDEN fuse is bit 7 of the high fuse (hfuse). In order to
* perform memory operations on MTYPE_SPM and MTYPE_EEPROM, OCDEN
* needs to be programmed.
*
* OCDEN should probably rather be defined via the configuration, but
* if this ever changes to a different fuse byte for one MCU, quite
* some code here needs to be generalized anyway.
*/
#define OCDEN (1 << 7)
/* /*
* pgm->flag is marked as "for private use of the programmer". * pgm->flag is marked as "for private use of the programmer".
* The following defines this programmer's use of that field. * The following defines this programmer's use of that field.
@ -695,10 +684,9 @@ static int jtag3_set_sck_mega_jtag(PROGRAMMER *pgm, unsigned char *clk)
*/ */
static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p) static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
{ {
AVRMEM hfuse;
unsigned char conn = 0, parm[4]; unsigned char conn = 0, parm[4];
const char *ifname; const char *ifname;
unsigned char cmd[4], *resp, b; unsigned char cmd[4], *resp;
int status; int status;
/* /*
@ -760,10 +748,7 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, parm, 1) < 0) if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, parm, 1) < 0)
return -1; return -1;
if (p->flags & AVRPART_HAS_PDI) parm[0] = PARM3_SESS_PROGRAMMING;
parm[0] = PARM3_SESS_DEBUGGING; /* to allow for EEPROM writes */
else
parm[0] = PARM3_SESS_PROGRAMMING;
if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_SESS_PURPOSE, parm, 1) < 0) if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_SESS_PURPOSE, parm, 1) < 0)
return -1; return -1;
@ -960,17 +945,6 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
} }
PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
if ((pgm->flag & PGM_FL_IS_JTAG) && !(p->flags & AVRPART_HAS_PDI)) {
strcpy(hfuse.desc, "hfuse");
if (jtag3_read_byte(pgm, p, &hfuse, 1, &b) < 0)
return -1;
if ((b & OCDEN) != 0)
fprintf(stderr,
"%s: jtag3_initialize(): warning: OCDEN fuse not programmed, "
"single-byte EEPROM updates not possible\n",
progname);
}
return 0; return 0;
} }
@ -1583,7 +1557,7 @@ static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned char cmd[14]; unsigned char cmd[14];
unsigned char *resp; unsigned char *resp;
unsigned char *cache_ptr = 0; unsigned char *cache_ptr = 0;
int status, need_progmode = 1, unsupp = 0; int status, unsupp = 0;
unsigned int pagesize = 0; unsigned int pagesize = 0;
if (verbose >= 2) if (verbose >= 2)
@ -1595,15 +1569,12 @@ static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
cmd[2] = 0; cmd[2] = 0;
cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_SPM; cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_SPM;
if (strcmp(mem->desc, "flash") == 0) { if (strcmp(mem->desc, "flash") == 0) {
need_progmode = 0;
cache_ptr = PDATA(pgm)->flash_pagecache; cache_ptr = PDATA(pgm)->flash_pagecache;
pagesize = PDATA(pgm)->flash_pagesize; pagesize = PDATA(pgm)->flash_pagesize;
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L; PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
if (pgm->flag & PGM_FL_IS_DW) if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1; unsupp = 1;
} else if (strcmp(mem->desc, "eeprom") == 0) { } else if (strcmp(mem->desc, "eeprom") == 0) {
cmd[3] = MTYPE_EEPROM;
need_progmode = 0;
cache_ptr = PDATA(pgm)->eeprom_pagecache; cache_ptr = PDATA(pgm)->eeprom_pagecache;
pagesize = PDATA(pgm)->eeprom_pagesize; pagesize = PDATA(pgm)->eeprom_pagesize;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
@ -1646,32 +1617,31 @@ static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
if (unsupp) if (unsupp)
return -1; return -1;
if (need_progmode) { if (pagesize != 0) {
if (jtag3_program_enable(pgm) < 0) /* flash or EEPROM write: use paged algorithm */
unsigned char dummy;
int i;
/* step #1: ensure the page cache is up to date */
if (jtag3_read_byte(pgm, p, mem, addr, &dummy) < 0)
return -1; return -1;
} else { /* step #2: update our value in page cache, and copy
if (( p->flags & AVRPART_HAS_PDI ) != 0) { * cache to mem->buf */
/* flash or EEPROM write on Xmega: use paged algorithm */ cache_ptr[addr & (pagesize - 1)] = data;
/* step #1: ensure the page cache is up to date */ addr &= ~(pagesize - 1); /* page base address */
unsigned char dummy; memcpy(mem->buf + addr, cache_ptr, pagesize);
int i; /* step #3: write back */
if (jtag3_read_byte(pgm, p, mem, addr, &dummy) < 0) i = jtag3_paged_write(pgm, p, mem, pagesize, addr, pagesize);
return -1; if (i < 0)
/* step #2: update our value in page cache, and copy to mem-> */
cache_ptr[addr & (pagesize - 1)] = data;
addr &= ~(pagesize - 1); /* page base address */
memcpy(mem->buf + addr, cache_ptr, pagesize);
/* step #3: write back */
i = jtag3_paged_write(pgm, p, mem, pagesize, addr, pagesize);
if (i < 0)
return -1;
else
return 0;
}
if (jtag3_program_disable(pgm) < 0)
return -1; return -1;
else
return 0;
} }
/* non-paged writes go here */
if (jtag3_program_enable(pgm) < 0)
return -1;
u32_to_b4(cmd + 8, 1); u32_to_b4(cmd + 8, 1);
u32_to_b4(cmd + 4, addr); u32_to_b4(cmd + 4, addr);
cmd[12] = 0; cmd[12] = 0;