diff --git a/ChangeLog b/ChangeLog index 36ea7f2e..dc73cde8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2006-07-19 Joerg Wunsch + + * stk500v2.c: Add more parameters for PP mode. Fix the + non-paged write operations for old AVRs. + * lexer.l: Add more parameters for PP mode. + * config_gram.y: (Ditto.) + * avrpart.h: (Ditto.) + * avrdude.conf.in: Use the new PP mode parameters; add PP mode + definitions for AT90S8515. + 2006-07-19 Joerg Wunsch * stk500v2.c: Hide stk500v2_set_sck_period_mk2() behind an #if diff --git a/avrdude.conf.in b/avrdude.conf.in index c4542d31..53b1e21a 100644 --- a/avrdude.conf.in +++ b/avrdude.conf.in @@ -1602,6 +1602,27 @@ part postdelay = 1; pollmethod = 0; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + ppenterstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + ppleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + memory "eeprom" size = 512; min_write_delay = 4000; @@ -2383,6 +2404,12 @@ part resetdelayus = 0; ppleavestabdelay = 15; resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; idr = 0x31; spmcr = 0x57; diff --git a/avrpart.h b/avrpart.h index ab09e4d4..18f0325f 100644 --- a/avrpart.h +++ b/avrpart.h @@ -130,6 +130,12 @@ typedef struct avrpart { int resetdelayus; /* stk500 v2 pp mode parameter */ int ppleavestabdelay; /* stk500 v2 pp mode parameter */ int resetdelay; /* stk500 v2 pp mode parameter */ + int chiperasepulsewidth; /* stk500 v2 pp mode parameter */ + int chiperasepolltimeout; /* stk500 v2 pp mode parameter */ + int programfusepulsewidth; /* stk500 v2 pp mode parameter */ + int programfusepolltimeout; /* stk500 v2 pp mode parameter */ + int programlockpulsewidth; /* stk500 v2 pp mode parameter */ + int programlockpolltimeout; /* stk500 v2 pp mode parameter */ unsigned char idr; /* JTAG ICE mkII XML file parameter */ unsigned char rampz; /* JTAG ICE mkII XML file parameter */ diff --git a/config_gram.y b/config_gram.y index 2464dc8d..e3cbfd85 100644 --- a/config_gram.y +++ b/config_gram.y @@ -160,6 +160,13 @@ static int parse_cmdbits(OPCODE * op); %token K_PPLEAVESTABDELAY %token K_RESETDELAY +%token K_CHIPERASEPULSEWIDTH +%token K_CHIPERASEPOLLTIMEOUT +%token K_PROGRAMFUSEPULSEWIDTH +%token K_PROGRAMFUSEPOLLTIMEOUT +%token K_PROGRAMLOCKPULSEWIDTH +%token K_PROGRAMLOCKPOLLTIMEOUT + %token K_PP_CONTROLSTACK /* JTAG ICE mkII specific parameters */ @@ -749,6 +756,42 @@ part_parm : free_token($3); } | + K_CHIPERASEPULSEWIDTH TKN_EQUAL TKN_NUMBER + { + current_part->chiperasepulsewidth = $3->value.number; + free_token($3); + } | + + K_CHIPERASEPOLLTIMEOUT TKN_EQUAL TKN_NUMBER + { + current_part->chiperasepolltimeout = $3->value.number; + free_token($3); + } | + + K_PROGRAMFUSEPULSEWIDTH TKN_EQUAL TKN_NUMBER + { + current_part->programfusepulsewidth = $3->value.number; + free_token($3); + } | + + K_PROGRAMFUSEPOLLTIMEOUT TKN_EQUAL TKN_NUMBER + { + current_part->programfusepolltimeout = $3->value.number; + free_token($3); + } | + + K_PROGRAMLOCKPULSEWIDTH TKN_EQUAL TKN_NUMBER + { + current_part->programlockpulsewidth = $3->value.number; + free_token($3); + } | + + K_PROGRAMLOCKPOLLTIMEOUT TKN_EQUAL TKN_NUMBER + { + current_part->programlockpolltimeout = $3->value.number; + free_token($3); + } | + K_HAS_JTAG TKN_EQUAL yesno { if ($3->primary == K_YES) diff --git a/lexer.l b/lexer.l index 5bba2c5f..2b66e701 100644 --- a/lexer.l +++ b/lexer.l @@ -202,6 +202,12 @@ resetdelayms { yylval=NULL; return K_RESETDELAYMS; } resetdelayus { yylval=NULL; return K_RESETDELAYUS; } ppleavestabdelay { yylval=NULL; return K_PPLEAVESTABDELAY; } resetdelay { yylval=NULL; return K_RESETDELAY; } +chiperasepulsewidth { yylval=NULL; return K_CHIPERASEPULSEWIDTH; } +chiperasepolltimeout { yylval=NULL; return K_CHIPERASEPOLLTIMEOUT; } +programfusepulsewidth { yylval=NULL; return K_PROGRAMFUSEPULSEWIDTH; } +programfusepolltimeout { yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; } +programlockpulsewidth { yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; } +programlockpolltimeout { yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; } dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; } diff --git a/stk500v2.c b/stk500v2.c index b53ffef9..0cf92b4b 100644 --- a/stk500v2.c +++ b/stk500v2.c @@ -449,8 +449,8 @@ static int stk500pp_chip_erase(PROGRAMMER * pgm, AVRPART * p) pgm->pgm_led(pgm, ON); buf[0] = CMD_CHIP_ERASE_PP; - buf[1] = 0; /* pulseWidth */ - buf[2] = 5; /* pollTimeout */ + buf[1] = p->chiperasepulsewidth; + buf[2] = p->chiperasepolltimeout; result = stk500v2_command(pgm, buf, 3, sizeof(buf)); usleep(p->chip_erase_delay); pgm->initialize(pgm, p); @@ -557,9 +557,11 @@ static int stk500pp_initialize(PROGRAMMER * pgm, AVRPART * p) for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { m = ldata(ln); if (strcmp(m->desc, "flash") == 0) { - flash_pagesize = m->page_size; + if (m->page_size > 0) + flash_pagesize = m->page_size; } else if (strcmp(m->desc, "eeprom") == 0) { - eeprom_pagesize = m->page_size; + if (m->page_size > 0) + eeprom_pagesize = m->page_size; } } free(flash_pagecache); @@ -757,7 +759,8 @@ static int stk500pp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, paddr = addr & ~(pagesize - 1); paddr_ptr = &eeprom_pageaddr; cache_ptr = eeprom_pagecache; - } else if (strcmp(mem->desc, "lfuse") == 0) { + } else if (strcmp(mem->desc, "lfuse") == 0 || + strcmp(mem->desc, "fuse") == 0) { buf[0] = CMD_READ_FUSE_PP; addr = 0; } else if (strcmp(mem->desc, "hfuse") == 0) { @@ -827,7 +830,7 @@ static int stk500pp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, unsigned long addr, unsigned char data) { - int result, cmdlen; + int result, cmdlen, timeout = 0, pulsewidth = 0; char buf[266]; unsigned long paddr = 0UL, *paddr_ptr = NULL; unsigned int pagesize = 0, use_ext_addr = 0, addrshift = 0; @@ -866,17 +869,26 @@ static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, paddr = addr & ~(pagesize - 1); paddr_ptr = &eeprom_pageaddr; cache_ptr = eeprom_pagecache; - } else if (strcmp(mem->desc, "lfuse") == 0) { + } else if (strcmp(mem->desc, "lfuse") == 0 || + strcmp(mem->desc, "fuse") == 0) { buf[0] = CMD_PROGRAM_FUSE_PP; addr = 0; + pulsewidth = p->programfusepulsewidth; + timeout = p->programfusepolltimeout; } else if (strcmp(mem->desc, "hfuse") == 0) { buf[0] = CMD_PROGRAM_FUSE_PP; addr = 1; + pulsewidth = p->programfusepulsewidth; + timeout = p->programfusepolltimeout; } else if (strcmp(mem->desc, "efuse") == 0) { buf[0] = CMD_PROGRAM_FUSE_PP; addr = 2; + pulsewidth = p->programfusepulsewidth; + timeout = p->programfusepolltimeout; } else if (strcmp(mem->desc, "lock") == 0) { buf[0] = CMD_PROGRAM_LOCK_PP; + pulsewidth = p->programlockpulsewidth; + timeout = p->programlockpolltimeout; } else { fprintf(stderr, "%s: stk500pp_write_byte(): " @@ -913,9 +925,11 @@ static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, * pretend we don't know any better. ;-) Bit 0 is set if this is * a paged memory, which means it has a page size of more than 2. */ - buf[3] = stk500v2_mode_for_pagesize(pagesize) | 0x80 | 0x40; - if (pagesize > 2) + buf[3] = 0x80 | 0x40; + if (pagesize > 2) { + buf[3] |= stk500v2_mode_for_pagesize(pagesize); buf[3] |= 0x01; + } buf[4] = mem->delay; memcpy(buf + 5, cache_ptr, pagesize); @@ -924,8 +938,8 @@ static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, } else { buf[1] = addr; buf[2] = data; - buf[3] = 0; /* pulseWidth */ - buf[4] = 5; /* pollTimeout */ + buf[3] = pulsewidth; + buf[4] = timeout; } if (verbose >= 2) @@ -1091,7 +1105,6 @@ static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, DEBUG("STK500V2: stk500pp_paged_write(..,%s,%d,%d)\n",m->desc,page_size,n_bytes); - if (page_size == 0) page_size = 256; hiaddr = UINT_MAX; addrshift = 0; use_ext_addr = 0; @@ -1124,9 +1137,15 @@ static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, * don't know any better. ;-) Finally, we set bit 0 to say this is * a paged memory, after all, that's why we got here at all. */ - commandbuf[3] = stk500v2_mode_for_pagesize(page_size) | 0x80 | 0x40 | 0x01; + commandbuf[3] = 0x80 | 0x40; + if (page_size > 2) { + commandbuf[3] |= stk500v2_mode_for_pagesize(page_size); + commandbuf[3] |= 0x01; + } commandbuf[4] = m->delay; + if (page_size == 0) page_size = 256; + last_addr = UINT_MAX; /* impossible address */ for (addr = 0; addr < n_bytes; addr += page_size) {