From 84b633e41d1993ac5fcf813619644f283635db8c Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Thu, 23 Nov 2006 07:07:06 +0000 Subject: [PATCH] Implement EEPROM access through debugWire. * jtagmkII.c: Extend the jtagmkII_read_byte() and jtagmkII_write_byte() methods to handle EEPROM through debugWire. * avrpart.h: Implement the "flash instruction" parameter. * config_gram.y: (Ditto.) * lexer.l: (Ditto.) * avrdude.conf.in: (Ditto.) * avrdude.1: Document the EEPROM access through dW. * doc/avrdude.texi: (Ditto.) * tools/get-dw-params.xsl: Extend to extract the flash instruction field. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@693 81a1dc3b-b13d-400b-aceb-764788c761c2 --- ChangeLog | 15 +++++++++++ avrdude.1 | 4 +-- avrdude.conf.in | 48 ++++++++++++++++++++++++++++++++++ avrpart.h | 2 ++ config_gram.y | 33 +++++++++++++++++++++++ doc/avrdude.texi | 4 +-- jtagmkII.c | 58 +++++++++++++++++++++++++---------------- lexer.l | 1 + tools/get-dw-params.xsl | 11 +++++++- 9 files changed, 148 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 04a271a5..4f1a1558 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2006-11-23 Joerg Wunsch + + Implement EEPROM access through debugWire. + * jtagmkII.c: Extend the jtagmkII_read_byte() and + jtagmkII_write_byte() methods to handle EEPROM through + debugWire. + * avrpart.h: Implement the "flash instruction" parameter. + * config_gram.y: (Ditto.) + * lexer.l: (Ditto.) + * avrdude.conf.in: (Ditto.) + * avrdude.1: Document the EEPROM access through dW. + * doc/avrdude.texi: (Ditto.) + * tools/get-dw-params.xsl: Extend to extract the flash + instruction field. + 2006-11-23 Joerg Wunsch * avr.c (avr_read, avr_write): if the paged access returns a diff --git a/avrdude.1 b/avrdude.1 index f5f8de26..9491ae63 100644 --- a/avrdude.1 +++ b/avrdude.1 @@ -722,8 +722,8 @@ DebugWire mode is initiated by activating the fuse, and then power-cycling the target. While this mode is mainly intented for debugging/emulation, it also offers limited programming capabilities. -Effectively, the only memory area that can be read or programmed -in this mode is the flash ROM. +Effectively, the only memory areas that can be read or programmed +in this mode are flash ROM and EEPROM. It is also possible to read out the signature. All other memory areas cannot be accessed. There is no diff --git a/avrdude.conf.in b/avrdude.conf.in index 200ae942..05d6b83f 100644 --- a/avrdude.conf.in +++ b/avrdude.conf.in @@ -965,6 +965,9 @@ part desc = "ATtiny13"; has_debugwire = yes; flash_instr = 0xB4, 0x0E, 0x1E; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x0E, 0xB4, 0x0E, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; stk500_devcode = 0x14; signature = 0x1e 0x90 0x07; chip_erase_delay = 4000; @@ -5915,6 +5918,9 @@ part desc = "ATTINY261"; has_debugwire = yes; flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; # stk500_devcode = 0x21; # avr910_devcode = 0x5e; signature = 0x1e 0x91 0x0c; @@ -6101,6 +6107,9 @@ part desc = "ATTINY461"; has_debugwire = yes; flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; # stk500_devcode = 0x21; # avr910_devcode = 0x5e; signature = 0x1e 0x92 0x08; @@ -6287,6 +6296,9 @@ part desc = "ATTINY861"; has_debugwire = yes; flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; # stk500_devcode = 0x21; # avr910_devcode = 0x5e; signature = 0x1e 0x93 0x0d; @@ -6472,6 +6484,9 @@ part desc = "ATMEGA48"; has_debugwire = yes; flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; stk500_devcode = 0x59; # avr910_devcode = 0x; signature = 0x1e 0x92 0x05; @@ -6656,6 +6671,9 @@ part desc = "ATMEGA88"; has_debugwire = yes; flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; stk500_devcode = 0x73; # avr910_devcode = 0x; signature = 0x1e 0x93 0x0a; @@ -6839,6 +6857,9 @@ part desc = "ATMEGA168"; has_debugwire = yes; flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; stk500_devcode = 0x86; # avr910_devcode = 0x; signature = 0x1e 0x94 0x06; @@ -7024,6 +7045,9 @@ part desc = "ATtiny2313"; has_debugwire = yes; flash_instr = 0xB2, 0x0F, 0x1F; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; stk500_devcode = 0x23; ## Use the ATtiny26 devcode: avr910_devcode = 0x5e; @@ -7208,6 +7232,9 @@ part desc = "AT90PWM2"; has_debugwire = yes; flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; stk500_devcode = 0x65; ## avr910_devcode = ?; signature = 0x1e 0x93 0x81; @@ -7389,6 +7416,9 @@ part desc = "AT90PWM3"; has_debugwire = yes; flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; stk500_devcode = 0x65; ## avr910_devcode = ?; signature = 0x1e 0x93 0x81; @@ -7568,6 +7598,9 @@ part desc = "ATtiny25"; has_debugwire = yes; flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; ## no STK500 devcode in XML file, use the ATtiny45 one stk500_devcode = 0x14; ## avr910_devcode = ?; @@ -7745,6 +7778,9 @@ part desc = "ATtiny45"; has_debugwire = yes; flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; stk500_devcode = 0x14; ## avr910_devcode = ?; ## Try the AT90S2313 devcode: @@ -7921,6 +7957,9 @@ part desc = "ATtiny85"; has_debugwire = yes; flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; ## no STK500 devcode in XML file, use the ATtiny45 one stk500_devcode = 0x14; ## avr910_devcode = ?; @@ -9050,6 +9089,9 @@ part desc = "ATtiny24"; has_debugwire = yes; flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; ## no STK500 devcode in XML file, use the ATtiny45 one stk500_devcode = 0x14; ## avr910_devcode = ?; @@ -9229,6 +9271,9 @@ part desc = "ATtiny44"; has_debugwire = yes; flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; ## no STK500 devcode in XML file, use the ATtiny45 one stk500_devcode = 0x14; ## avr910_devcode = ?; @@ -9408,6 +9453,9 @@ part desc = "ATtiny84"; has_debugwire = yes; flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; ## no STK500 devcode in XML file, use the ATtiny45 one stk500_devcode = 0x14; ## avr910_devcode = ?; diff --git a/avrpart.h b/avrpart.h index 2e5bc48d..747b3495 100644 --- a/avrpart.h +++ b/avrpart.h @@ -95,6 +95,7 @@ typedef struct opcode { #define AVR_IDLEN 32 #define CTL_STACK_SIZE 32 #define FLASH_INSTR_SIZE 3 +#define EEPROM_INSTR_SIZE 20 typedef struct avrpart { char desc[AVR_DESCLEN]; /* long part name */ char id[AVR_IDLEN]; /* short part name */ @@ -123,6 +124,7 @@ 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 */ unsigned char flash_instr[FLASH_INSTR_SIZE]; /* flash instructions (debugWire, JTAG) */ + unsigned char eeprom_instr[EEPROM_INSTR_SIZE]; /* EEPROM instructions (debugWire, JTAG) */ int hventerstabdelay; /* stk500 v2 hv mode parameter */ int progmodedelay; /* stk500 v2 hv mode parameter */ diff --git a/config_gram.y b/config_gram.y index 185e4725..b182f200 100644 --- a/config_gram.y +++ b/config_gram.y @@ -202,6 +202,7 @@ static int parse_cmdbits(OPCODE * op); %token K_SPMCR /* address of SPMC[S]R in memory space */ %token K_EECR /* address of EECR in memory space */ %token K_FLASH_INSTR /* flash instructions */ +%token K_EEPROM_INSTR /* EEPROM instructions */ %token TKN_COMMA %token TKN_EQUAL @@ -751,6 +752,38 @@ part_parm : } } | + K_EEPROM_INSTR TKN_EQUAL num_list { + { + TOKEN * t; + unsigned nbytes; + int ok; + + nbytes = 0; + ok = 1; + + while (lsize(number_list)) { + t = lrmv_n(number_list, 1); + if (nbytes < EEPROM_INSTR_SIZE) + { + current_part->eeprom_instr[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 EEPROM instructions\n", + progname, lineno, infile); + } + } + } | + K_CHIP_ERASE_DELAY TKN_EQUAL TKN_NUMBER { current_part->chip_erase_delay = $3->value.number; diff --git a/doc/avrdude.texi b/doc/avrdude.texi index 472a323f..18c69c15 100644 --- a/doc/avrdude.texi +++ b/doc/avrdude.texi @@ -1944,8 +1944,8 @@ DebugWire mode is initiated by activating the @var{DWEN} fuse, and then power-cycling the target. While this mode is mainly intented for debugging/emulation, it also offers limited programming capabilities. -Effectively, the only memory area that can be read or programmed -in this mode is the flash ROM. +Effectively, the only memory areas that can be read or programmed +in this mode are flash ROM and EEPROM. It is also possible to read out the signature. All other memory areas cannot be accessed. There is no diff --git a/jtagmkII.c b/jtagmkII.c index f65552d1..8a42174b 100644 --- a/jtagmkII.c +++ b/jtagmkII.c @@ -846,8 +846,10 @@ static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p) u32_to_b4(sendbuf.dd.ulFlashSize, m->size); u16_to_b2(sendbuf.dd.uiFlashPageSize, flash_pagesize); u16_to_b2(sendbuf.dd.uiFlashpages, m->size / flash_pagesize); - 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.ucEepromInst, p->eeprom_instr, EEPROM_INSTR_SIZE); + } } else if (strcmp(m->desc, "eeprom") == 0) { sendbuf.dd.ucEepromPageSize = eeprom_pagesize = m->page_size; } @@ -1660,13 +1662,16 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, paddr_ptr = &flash_pageaddr; cache_ptr = flash_pagecache; } else if (strcmp(mem->desc, "eeprom") == 0) { - cmd[1] = MTYPE_EEPROM_PAGE; - pagesize = mem->page_size; - paddr = addr & ~(pagesize - 1); - paddr_ptr = &eeprom_pageaddr; - cache_ptr = eeprom_pagecache; - if (pgm->flag & PGM_FL_IS_DW) - unsupp = 1; + if (pgm->flag & PGM_FL_IS_DW) { + /* debugWire cannot use page access for EEPROM */ + cmd[1] = MTYPE_EEPROM; + } else { + cmd[1] = MTYPE_EEPROM_PAGE; + pagesize = mem->page_size; + paddr = addr & ~(pagesize - 1); + paddr_ptr = &eeprom_pageaddr; + cache_ptr = eeprom_pagecache; + } } else if (strcmp(mem->desc, "lfuse") == 0) { cmd[1] = MTYPE_FUSE_BITS; addr = 0; @@ -1716,7 +1721,6 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, default: fprintf(stderr, "%s: illegal address %lu for signature memory\n", progname, addr); - *value = 42; return -1; } return 0; @@ -1776,6 +1780,8 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, "%s: jtagmkII_read_byte(): " "fatal timeout/error communicating with programmer (status %d)\n", progname, status); + if (status < 0) + resp = 0; goto fail; } if (verbose >= 3) { @@ -1811,7 +1817,7 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, { unsigned char cmd[11]; unsigned char *resp = NULL, writedata; - int status, tries, need_progmode = 1; + int status, tries, need_progmode = 1, unsupp = 0; if (verbose >= 2) fprintf(stderr, "%s: jtagmkII_write_byte(.., %s, 0x%lx, ...)\n", @@ -1823,6 +1829,8 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, cmd[1] = MTYPE_SPM; need_progmode = 0; flash_pageaddr = (unsigned long)-1L; + if (pgm->flag & PGM_FL_IS_DW) + unsupp = 1; } else if (strcmp(mem->desc, "eeprom") == 0) { cmd[1] = MTYPE_EEPROM; need_progmode = 0; @@ -1830,20 +1838,35 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, } else if (strcmp(mem->desc, "lfuse") == 0) { cmd[1] = MTYPE_FUSE_BITS; addr = 0; + if (pgm->flag & PGM_FL_IS_DW) + unsupp = 1; } else if (strcmp(mem->desc, "hfuse") == 0) { cmd[1] = MTYPE_FUSE_BITS; addr = 1; + if (pgm->flag & PGM_FL_IS_DW) + unsupp = 1; } else if (strcmp(mem->desc, "efuse") == 0) { cmd[1] = MTYPE_FUSE_BITS; addr = 2; + if (pgm->flag & PGM_FL_IS_DW) + unsupp = 1; } else if (strcmp(mem->desc, "lock") == 0) { cmd[1] = MTYPE_LOCK_BITS; + if (pgm->flag & PGM_FL_IS_DW) + unsupp = 1; } else if (strcmp(mem->desc, "calibration") == 0) { cmd[1] = MTYPE_OSCCAL_BYTE; + if (pgm->flag & PGM_FL_IS_DW) + unsupp = 1; } else if (strcmp(mem->desc, "signature") == 0) { cmd[1] = MTYPE_SIGN_JTAG; + if (pgm->flag & PGM_FL_IS_DW) + unsupp = 1; } + if (unsupp) + return -1; + if (need_progmode) { if (jtagmkII_program_enable(pgm) < 0) return -1; @@ -1902,17 +1925,6 @@ fail: } -static int jtagmkII_write_byte_dw(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, - unsigned long addr, unsigned char data) -{ - - fprintf(stderr, - "%s: jtagmkII_write_byte_dw(): no single-byte writes supported in debugWire\n", - progname); - - return -1; -} - /* * Set the JTAG clock. The actual frequency is quite a bit of * guesswork, based on the values claimed by AVR Studio. Inside the @@ -2172,7 +2184,7 @@ void jtagmkII_dw_initpgm(PROGRAMMER * pgm) pgm->open = jtagmkII_open_dw; pgm->close = jtagmkII_close; pgm->read_byte = jtagmkII_read_byte; - pgm->write_byte = jtagmkII_write_byte_dw; + pgm->write_byte = jtagmkII_write_byte; /* * optional functions @@ -2230,7 +2242,7 @@ void jtagmkII_dragon_dw_initpgm(PROGRAMMER * pgm) pgm->open = jtagmkII_dragon_open_dw; pgm->close = jtagmkII_close; pgm->read_byte = jtagmkII_read_byte; - pgm->write_byte = jtagmkII_write_byte_dw; + pgm->write_byte = jtagmkII_write_byte; /* * optional functions diff --git a/lexer.l b/lexer.l index 22a35dda..94e6c7ac 100644 --- a/lexer.l +++ b/lexer.l @@ -224,6 +224,7 @@ programfusepolltimeout { yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; } programlockpulsewidth { yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; } programlockpolltimeout { yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; } flash_instr { yylval=NULL; return K_FLASH_INSTR; } +eeprom_instr { yylval=NULL; return K_EEPROM_INSTR; } dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; } io { yylval=new_token(K_IO); return K_IO; } diff --git a/tools/get-dw-params.xsl b/tools/get-dw-params.xsl index e5cb7987..3561db91 100644 --- a/tools/get-dw-params.xsl +++ b/tools/get-dw-params.xsl @@ -40,6 +40,8 @@ select="translate(/AVRPART/ADMIN/PART_NAME, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" /> + @@ -63,6 +65,13 @@ ; + eeprom_instr = + + + + + ; + @@ -118,7 +127,7 @@ - , + , ,