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
This commit is contained in:
Joerg Wunsch 2006-11-23 07:07:06 +00:00
parent 946810fb81
commit 84b633e41d
9 changed files with 148 additions and 28 deletions

View File

@ -1,3 +1,18 @@
2006-11-23 Joerg Wunsch <j@uriah.heep.sax.de>
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 <j@uriah.heep.sax.de>
* avr.c (avr_read, avr_write): if the paged access returns a

View File

@ -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

View File

@ -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 = ?;

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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; }

View File

@ -40,6 +40,8 @@
select="translate(/AVRPART/ADMIN/PART_NAME,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="ucEepromInst"
select="//AVRPART/ICE_SETTINGS/JTAGICEmkII/ucEepromInst" />
<xsl:variable name="ucFlashInst"
select="//AVRPART/ICE_SETTINGS/JTAGICEmkII/ucFlashInst" />
@ -63,6 +65,13 @@
</xsl:call-template>
<xsl:text>;&#010;</xsl:text>
<xsl:text> eeprom_instr = </xsl:text>
<xsl:call-template name="format-hex">
<xsl:with-param name="arg" select="$ucEepromInst" />
<xsl:with-param name="count" select="0" />
</xsl:call-template>
<xsl:text>;&#010;</xsl:text>
</xsl:if> <!-- JTAGICEmkII uses debugWire -->
</xsl:template>
@ -118,7 +127,7 @@
<xsl:value-of select="substring($arg, 1, 4)" />
<xsl:choose>
<xsl:when test="$count mod 8 = 7">
<xsl:text>,&#010;&#009; </xsl:text>
<xsl:text>,&#010;&#009; </xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>, </xsl:text>