Hi list,
I have subscribed in order to report/discuss an issue with avrdude, and one
working solution. Apologies if this is not the preferred way. Also I am
aware it is possible I may have mis-diagnosed.
In brief:
When programming the ATMega2560 using an stk500 (v1) compatible ISP, avrdude
doesn't set the extended address byte in the target device. As a result it
cannot be certain whether it is programming above or below the 128K bytes
threshold. One manifestation of this is reports of verify errors at 0x1e000
when programming the Mega2560 bootloader using the ArduinoISP. A patch that
resolves this is attached - modifying the stk500 code to set the extended
byte when necessary.
More details:
The stk500 v1 protocol only allows 2 bytes for the (word) address, so with
this type of programmer, flash >128K has to be handled specially (within
avrdude). Since stk500 also does not include a dedicated means to set the
extended addr byte, it has to be done using cmd-universal direct to the
target SPI.
The stk500 programming process has been studied in detail with a logic
analyser, capturing Tx, Rx and all SPI signals for the whole 90s of a
bootloader programming cycle on the Mega2560. Nowhere is the ext-addr-byte
set. When the whole of flash is read for the verify, whichever half is
presently set in the target device is actually read through twice. On my test
unit, this was always the upper half, so the bootloader appears to
avrdude-read 'ghosted' at the top of the lower half of flash as well as at
the top of the upper half. This gives the verify error. It is in this case
not possible to read or write the real lower half of flash.
At present I have continued to use avrdude 5.11.1 as 6.0.1 doesn't build
(separate issue) but I don't see any indication that the ext addr has been
identified and resolved in the later release - please correct me if it has.
The patch here for stk500.c adds an extended address byte cmd for any device
where the flash size >128K, and sets it initially and when a 128K boundary is
crossed. With these changes the bootloader program completes without errors,
and it is clear from the analyser that the correct memory locations are now
being accessed. This is not necessarily a 'final' patch, but should apply to
6.01 cleanly.
This could be fixed in other different ways - and may be better pushed up the
layers in avrdude into avr.c; I am posting for your comments, awareness etc.
If there is important info missed, ask and I will try to respond.
Hope this is useful,
Regards
Alan
--- stk500-orig.c 2011-09-15 15:37:04.000000000 +0100
+++ stk500.c 2013-12-06 22:45:30.000000000 +0000
@@ -689,14 +689,31 @@
}
-static int stk500_loadaddr(PROGRAMMER * pgm, unsigned int addr)
+static int stk500_loadaddr(PROGRAMMER * pgm, unsigned int addr, char ext_addr)
{
unsigned char buf[16];
int tries;
+ static unsigned char prev_ext_byte = 0xff; /* Ensures it is set first time */
+ unsigned char ext_byte;
tries = 0;
retry:
tries++;
+
+ /* To support flash > 64K words the correct Extended Address Byte has to be programmed. Use cmnd-universal */
+ if (ext_addr) {
+ ext_byte = (addr >> 16) & 0xff;
+ if (ext_byte != prev_ext_byte) {
+ /* 'Load Extended Address Byte' 0x4d,0x00 see Atmel datasheets, 'Serial Programming Instructions' */
+ buf[0] = 0x4d;
+ buf[1] = 0x00;
+ buf[2] = ext_byte;
+ buf[3] = 0x00;
+ stk500_cmd(pgm, buf, buf);
+ prev_ext_byte = ext_byte;
+ }
+ }
+
buf[0] = Cmnd_STK_LOAD_ADDRESS;
buf[1] = addr & 0xff;
buf[2] = (addr >> 8) & 0xff;
@@ -751,6 +768,7 @@
unsigned int n;
unsigned int i;
int flash;
+ char use_ext_addr = 0;
if (page_size == 0) {
// MIB510 uses page size of 256 bytes
@@ -765,6 +783,9 @@
if (strcmp(m->desc, "flash") == 0) {
memtype = 'F';
flash = 1;
+ /* To support flash > 128K (64K words) use an Extended Address Byte */
+ if (m->size > 131072)
+ use_ext_addr = 1;
}
else if (strcmp(m->desc, "eeprom") == 0) {
memtype = 'E';
@@ -822,7 +843,7 @@
tries = 0;
retry:
tries++;
- stk500_loadaddr(pgm, addr/a_div);
+ stk500_loadaddr(pgm, addr/a_div, use_ext_addr);
/* build command block and avoid multiple send commands as it leads to a crash
of the silabs usb serial driver on mac os x */
@@ -895,9 +916,13 @@
int tries;
unsigned int n;
int block_size;
+ char use_ext_addr = 0;
if (strcmp(m->desc, "flash") == 0) {
memtype = 'F';
+ /* To support flash > 128K (64K words) use an Extended Address Byte */
+ if (m->size > 131072)
+ use_ext_addr = 1;
}
else if (strcmp(m->desc, "eeprom") == 0) {
memtype = 'E';
@@ -939,7 +964,7 @@
tries = 0;
retry:
tries++;
- stk500_loadaddr(pgm, addr/a_div);
+ stk500_loadaddr(pgm, addr/a_div, use_ext_addr);
buf[0] = Cmnd_STK_READ_PAGE;
buf[1] = (block_size >> 8) & 0xff;
buf[2] = block_size & 0xff;
_______________________________________________
avrdude-dev mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/avrdude-dev