Skip to content

Commit

Permalink
Deprecate original STK500 v1 protocol in favour of optiboot and Ardui…
Browse files Browse the repository at this point in the history
…no 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.
  • Loading branch information
stefanrueger committed Jul 24, 2022
1 parent 29c6645 commit 3d06457
Showing 1 changed file with 22 additions and 20 deletions.
42 changes: 22 additions & 20 deletions src/stk500.c
Original file line number Diff line number Diff line change
Expand Up @@ -805,27 +805,28 @@ 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"
"n = %u\n"
"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
Expand Down Expand Up @@ -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) {
Expand All @@ -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
Expand Down

0 comments on commit 3d06457

Please sign in to comment.