From 3d06457a1614a2247efc846b8e73788cb8585978 Mon Sep 17 00:00:00 2001 From: Stefan Rueger Date: Sun, 24 Jul 2022 20:18:15 +0100 Subject: [PATCH] Deprecate original STK500 v1 protocol in favour of optiboot and Arduino as ISP For paged read/write early AVRDUDE implementations of the STK500 v1 protocol communicated a word address (below a_div=2) or byte address (a_div=1) based on the following code irrespective of which memories were used: if(m->op[AVR_OP_LOADPAGE_LO] || m->op[AVR_OP_READ_LO]) a_div = 2; else a_div = 1; This turned out to be a bug: it really should have been a_div=2 for flash and a_div=1 for eeprom. At the time presumably no one noted because Atmel was at the cusp of replacing their FW 1.x with FW 2 (and the STK500 v2 protocol). It seems that the world (optiboot, Arduino as ISP, ...) has compensated for the bug by assuming AVRDUDE sends *all* eeprom addresses as word addresses. Actually these programmers overcompensated for the bug because for six out of the 146 known SPI programmable parts with eeprom and page size > 1, AVRDUDE would still send the eeprom addresses as byte addresses (ATmega8 ATmega8A ATmega64 ATmega64A ATmega128 ATmega128A) owing to above code. It makes no sense to correct the bug now seeing that virtually no one uses the old 2005 STK 500 v1 firmware. This commit now follows optiboot, Arduino as ISP and other projects, and simply sends all addresses for paged read or write as word addresses. There are no longer (little known) exceptions for ATmega8 et al that surprised some optiboot etc users. --- src/stk500.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/stk500.c b/src/stk500.c index 084bbec8..27334297 100644 --- a/src/stk500.c +++ b/src/stk500.c @@ -805,19 +805,20 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, if (strcmp(m->desc, "flash") == 0) { memtype = 'F'; - } - else if (strcmp(m->desc, "eeprom") == 0) { + a_div = 2; + } else if (strcmp(m->desc, "eeprom") == 0) { memtype = 'E'; - } - else { + /* + * The STK original 500 v1 protocol actually expects a_div = 1, but the + * v1.x FW of the STK500 kit has been superseded by v2 FW in the mid + * 2000s. Since optiboot, arduino as ISP and others assume a_div = 2, + * better use that. See https://github.com/avrdudes/avrdude/issues/967 + */ + a_div = 2; + } else { return -2; } - if ((m->op[AVR_OP_LOADPAGE_LO]) || (m->op[AVR_OP_READ_LO])) - a_div = 2; - else - a_div = 1; - n = addr + n_bytes; #if 0 avrdude_message(MSG_INFO, "n_bytes = %d\n" @@ -825,7 +826,7 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, "a_div = %d\n" "page_size = %d\n", n_bytes, n, a_div, page_size); -#endif +#endif for (; addr < n; addr += block_size) { // MIB510 uses fixed blocks size of 256 bytes @@ -872,7 +873,7 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, progname, Resp_STK_INSYNC, buf[0]); return -4; } - + if (stk500_recv(pgm, buf, 1) < 0) return -1; if (buf[0] != Resp_STK_OK) { @@ -899,19 +900,20 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, if (strcmp(m->desc, "flash") == 0) { memtype = 'F'; - } - else if (strcmp(m->desc, "eeprom") == 0) { + a_div = 2; + } else if (strcmp(m->desc, "eeprom") == 0) { memtype = 'E'; - } - else { + /* + * The STK original 500 v1 protocol actually expects a_div = 1, but the + * v1.x FW of the STK500 kit has been superseded by v2 FW in the mid + * 2000s. Since optiboot, arduino as ISP and others assume a_div = 2, + * better use that. See https://github.com/avrdudes/avrdude/issues/967 + */ + a_div = 2; + } else { return -2; } - if ((m->op[AVR_OP_LOADPAGE_LO]) || (m->op[AVR_OP_READ_LO])) - a_div = 2; - else - a_div = 1; - n = addr + n_bytes; for (; addr < n; addr += block_size) { // MIB510 uses fixed blocks size of 256 bytes