avrdudes / avrdude

AVRDUDE is a utility to program AVR microcontrollers
GNU General Public License v2.0
696 stars 136 forks source link

[Regression] Optiboot for "modern AVRs" does not work with upstream version of Avrdude. #1120

Closed MCUdude closed 1 year ago

MCUdude commented 1 year ago

(Probably) related to #1090.

I'm able to upload programs to an ATtiny1616 using optiboot (-c arduino) with Avrdude 6.0 and 7.0, but not the upstream version. I've tracked down the issue to commit https://github.com/avrdudes/avrdude/commit/3d06457a1614a2247efc846b8e73788cb8585978.

The bootloader source code is located here: https://github.com/SpenceKonde/megaTinyCore/tree/master/megaavr/bootloaders/optiboot_x

Here's Avrdude output.

Avrdude 6.3:

$ /Users/hans/Library/Arduino15/packages/DxCore/tools/avrdude/6.3.0-arduino17or18/bin/avrdude -C/Users/hans/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.6.1/avrdude.conf -pattiny1616 -carduino -D -P/dev/cu.usbserial-1410 -b115200 -P/dev/cu.usbserial-1410 -Uflash:w:/var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex:i

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9421 (probably t1616)
avrdude: reading input file "/var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex"
avrdude: writing flash (1278 bytes):

Writing | ################################################## | 100% 0.06s

avrdude: 1278 bytes of flash written
avrdude: verifying flash memory against /var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex:
avrdude: load data flash data from input file /var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex:
avrdude: input file /var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex contains 1278 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.05s

avrdude: verifying ...
avrdude: 1278 bytes of flash verified

avrdude: safemode: Fuses OK (E:FF, H:FF, L:FF)

avrdude done.  Thank you.

Avrdude 7.0:

$ /Users/hans/Library/Arduino15/packages/MegaCoreX/tools/avrdude/7.0.0-arduino2/bin/avrdude -C/Users/hans/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.6.1/avrdude.conf -pattiny1616 -carduino -D -P/dev/cu.usbserial-1410 -b115200 -P/dev/cu.usbserial-1410 -Uflash:w:/var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex:i 

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9421 (probably t1616)
avrdude: reading input file "/var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex"
avrdude: writing flash (1278 bytes):

Writing | ################################################## | 100% 0.06s

avrdude: 1278 bytes of flash written
avrdude: verifying flash memory against /var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex:

Reading | ################################################## | 100% 0.05s

avrdude: 1278 bytes of flash verified

avrdude done.  Thank you.

Upstream version:

$ ./avrdude -C/Users/hans/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.6.1/avrdude.conf -pattiny1616 -carduino -D -P/dev/cu.usbserial-1410 -b115200 -P/dev/cu.usbserial-1410 -Uflash:w:/var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex:i 

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9421 (probably t1616)
avrdude: reading input file /var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex for flash
         with 766 bytes in 1 section within [0x200, 0x4fd]
         using 12 pages and 2 pad bytes
avrdude: writing 766 bytes flash ...

Writing | ################################################## | 100% 0.05s

avrdude: 766 bytes of flash written
avrdude: verifying flash memory against /var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex

Reading | ################################################## | 100% 0.05s

avrdude: verification error, first mismatch at byte 0x0200
         0x04 != 0x3d
avrdude: verification error; content mismatch

avrdude done.  Thank you.

Hex file:

``` :100200003DC000004BC0000049C0000047C00000D6 :1002100045C0000043C0000041C000003FC00000D6 :100220003DC000003BC0000039C0000037C00000E6 :1002300035C0000033C0000031C00000B4C0000071 :100240002DC000002BC0000029C0000027C0000006 :1002500025C0000023C0000021C000001FC0000016 :100260001DC000001BC0000019C0000017C0000026 :1002700015C0000013C0000011C0000011241FBEF3 :10028000CFEFCDBFDFE3DEBF28E3A0E0B8E301C0DE :100290001D92AA30B207E1F7DCD02FC1B1CF9FB7D2 :1002A000F89488E08093840A80918E0A81FFFCCFC5 :1002B00080918D0AE091A20AF091A30A209106385C :1002C0003091073840910838509109389FBF80FF1E :1002D00007C0E730F10520F42F5F3F4F4F4F5F4FCE :1002E000BF0176956795CF01860F911DE62FE695A4 :1002F000E695762F72957F70E71BFF0B67FD3196B1 :10030000E80FF91FA0E3B3E0DFD06E0F7F1F811D60 :10031000911D0895CF92DF92EF92FF92CF93DF93DA :10032000BEDFEB0188EEC82E83E0D82EE12CF12C45 :10033000B6DF6C1B7D0B683E7340A0F0C114D10486 :10034000E104F10439F4DF91CF91FF90EF90DF9059 :10035000CF90089581E0C81AD108E108F108C8518A :10036000DC4FE6CFC114D104E104F10409F7EBCF6F :1003700090E2811111C0909326049091200495FD84 :100380000AC09FB7F89481110AC080913504877F15 :10039000809335049FBF089590932504EECF8091FC :1003A00035048860F5CF1F920F920FB60F9211247B :1003B0002F933F934F935F936F938F939F93AF933D :1003C000BF938091023890910338A0910438B09186 :1003D000053840910038509101389A01205D3C4F1A :1003E000283E63E0360728F0285E33400196A11DC1 :1003F000B11D2093003830930138809302389093D8 :100400000338A0930438B093053880910638909152 :100410000738A0910838B09109380196A11DB11D87 :100420008093063890930738A0930838B093093822 :1004300081E080938D0ABF91AF919F918F916F91D1 :100440005F914F913F912F910F900FBE0F901F9092 :10045000189588ED90E084BF9093610083E58093C8 :1004600002068DE08093050680E280930306E1E0BA :10047000E0930006E093030A9EEF9093260A909380 :10048000270A9BE09093000A2DEF31E02093AE0AFB :100490003093AF0A1092810A90E89093820AE09319 :1004A0008C0A91E19093800A7894E295EE0FF0E047 :1004B000F46081838589877F858B81E059DF2ADF1E :1004C00080E056DF27DFF9CF09D0A59F900DB49FBC :1004D000900DA49F800D911D11240895A29FB0013D :1004E000B39FC001A39F700D811D1124911DB29F68 :0E04F000700D811D1124911D0895F894FFCF09 :0400000300000200F7 :00000001FF ```
mcuee commented 1 year ago

This seems to indicate that optiboot_x is not exactly the same as vanilla optiboot, or maybe it is due to the different memory configuration of the new AVR tiny 0/1/2 part. I am not so sure how to fix this.

One easy solution is to create a new bootloader type optiboot_x as arduino seems to include too many bootloaders with potential different implementations. I am also thinking that we need to the function to be able to define the capability of the bootloaders.

Maybe @stefanrueger has a better idea to differentiate the bootloader implementation.

mcuee commented 1 year ago

Detailed explanation from @SpenceKonde

Not surprised this broke my forks of Optiboot when someone fiddled with it (was that change made to address a complaint?). Arguably the hardest part of porting optiboot to Dx-series parts was figuring out to get AVRdude to use the correct addressing modes. Everything else was relatively straightforward. But DA and DB can have 128k parts. AVRdude uses byte addresses talking to optiboot_x for the tinyAVR parts, while I used a weird trick to fool it into using word addressing for the AVR128Dx parts (see my avrdude.conf from DxCore). If there's a better way that will work with both 6.3 and future 7.x versions please let me know (based on experience, it must be backwards compatible - I can change what's in the avrdude.conf to make it work with whatever new version - or ideally both versions, but I can't say "Yeah from here on out you need a new bootloader binary", people make an unholy stink*) but shrug that was the trick I found to make it work on 6.3 (haven't tested 7.0 - I'm not allowed to look at that until both megaTinyCore and DxCore have stable releases)

* especially the ones who are using tinyAVRs with the updi pin fused to act as reset or I/O and who don't own an HVUPDI programmer (virtually nobody does HV updi. most of microchip's programmers don't even support it as implemented on tinyAVR (and small wonder: you need to have a line at 12v, then go back to sending normal data over it. Even microchip retreated from the shared HV pulse + data line concept on the DD's! So there are two HV UPDI's now :-( The DD's put the pulse on reset, which can be fused as input, but never output (reset sucks when used as output anyway - sub-milliamp current? screw that) and if UPDI is fused as GPIO, then a 12V pulse on reset followed rapidly by a KEY on the (now once more) UPDI line is what you need to do to reprogram it. On a tinyAVR, instead, you power-cycle it, almost immediately put the 12v pulse on the UPDI/Reset/GPIO line... there may or may not be a timeout that you have to send that KEY within on some parts; certainly some parts don't, because multiple people have told me they do it with 12v doorbell batteries and nerves of steel),

mcuee commented 1 year ago

Not surprised this broke my forks of Optiboot when someone fiddled with it (was that change made to address a complaint?).

Indeed that change https://github.com/avrdudes/avrdude/commit/3d06457a1614a2247efc846b8e73788cb8585978 is because of a long standing bug that typical optiboot implemnetation does not follow the stk500v1 exactly.

There were three options to go as per @stefanrueger and in the end the team aligned and went with Option 1 as the Real STK500v1 is dead. Unfortunately optiboot_x got affected because of the change.

  1. Deprecate the "pure" STK500 v1 support and change above code to simply a_div = 2 (accept that the STK500 kit with FW version 1.xx is a dead horse)

  2. Create a new AVRDUDE programmer stk500v1w that imports the stk500 (v1) programmer and change paged access to be always through word addresses. Modify .conf for these programmers to be based on stk200v1w

  3. Change all STK500 derived programmers to swap out their paged memory access functions

SpenceKonde commented 1 year ago

Hm, that problem is about EEPROM, but this bug is reported when uploading to flash. That's the one thing I don't understand here. Why does a change to eeprom impact flash writes?

mcuee commented 1 year ago

Hm, that problem is about EEPROM, but this bug is reported when uploading to flash. That's the one thing I don't understand here. Why does a change to eeprom impact flash writes?

Good point. Maybe @MCUdude and @stefanrueger can help here.

MCUdude commented 1 year ago

If you look closely at the https://github.com/avrdudes/avrdude/commit/3d06457a1614a2247efc846b8e73788cb8585978 diff, you can see that a_div=2; is added to both flash and EEPROM for stk500_paged_load() and stk500_paged_write()

stefanrueger commented 1 year ago

@SpenceKonde I see two solutions (there may be more)

  1. We create a different programmer arduino_x or optiboot_x that sends word or byte addresses just like the arduino programmer did before. (Given all the different bootloaders and derivative programmers it seems pretty much impossible to satisfy every use case with one programmer).

  2. You tell us which byte/word addressing you'd need for which parts and which memories and which access modes (paged or byte-wise), and I look into whether/how that can be implemented in a bespoke optiboot_x programmer that hopefully doesn't need avrdude.conf juggling (you mentioned a "weird trick").

stefanrueger commented 1 year ago

Another possibility without need for a new arduino type programmer would be to treat PDI/UPDI parts differently (assuming that the optiboot_x extension is just for XMEGAs or newer parts with UPDI i/f). That could be done within the current arduino programmer. Still, when doing so, would better address what's needed for the _x extension w/out private avrdude.conf manipulations.

MCUdude commented 1 year ago

It suddenly hit me, @SpenceKonde Optiboot X fork uses the exact same codebase as my own (originally written by @westfw). This mean that this bug also should affect the megaAVR-0 series (ATmega808/809/1608/1609/3208/3209/4808/4809). And in fact, it does!

This means that all Optiboot bootloaders + forks for "modern" AVRs are using a_div=1.

$ ./avrdude -carduino -P /dev/cu.usbserial-1410 -patmega4808 -D -Uflash:w:/var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex:i

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9650 (probably m4808)
avrdude: reading input file /var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex for flash
         with 768 bytes in 1 section within [0x200, 0x4ff]
         using 6 pages and 0 pad bytes
avrdude: writing 768 bytes flash ...

Writing | ################################################## | 100% 0.04s

avrdude: 768 bytes of flash written
avrdude: verifying flash memory against /var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_148565/Blink.ino.hex

Reading | ################################################## | 100% 0.03s

avrdude: verification error, first mismatch at byte 0x0200
         0xd0 != 0x47
avrdude: verification error; content mismatch

avrdude done.  Thank you.
SpenceKonde commented 1 year ago

In that case, optiboot_dx for AVR128DA should be fine

But optiboot_dx for AVR64Dx isn't.

The incantation i have in my avrdude.conf is this:

    memory "flash"
        size      = 0x20000;
        offset    = 0x800000;
        page_size = 0x200;
        readsize  = 0x100;
        load_ext_addr   = "  0   1   0   0      1   1   0   1",
                          "  0   0   0   0      0   0   0   0",
                          "  0   0   0   0      0   0   0 a16",
                          "  0   0   0   0      0   0   0   0";
    ;

Its the load_ext_addr that makes it do adiv = 2 currently it seems.

(Note also that readsize could be up to 0x200, but it is capped artificially by avrdude to 0x100)

stefanrueger commented 1 year ago

@MCUdude and @SpenceKonde OK, so rather than putting into avrdude.conf parameters that are for classic AVRs (readsize is for ISP STK500/STK600, and ISP commands are, well, for the ISP i/f), can I suggest you express which bootloaders expect which type of address for which devices? Ideally dependent on memory type (flash/eeprom/...), interface, memory size, eg,

i/f memory size a_div
UPDI flash >64k 2
UPDI flash <=64k 1
UPDI eeprom all 1
PDI flash all 1
PDI eeprom all 1

Clearly, I have been making this table up, but it's much neater if the code expresses what your bootloaders expect rather than resorting to avrdude.conf trickery.

MCUdude commented 1 year ago

@stefanrueger I can't speak for AVR-Dx'es, but for megaAVR-0's it's supposed to be a_div=1 for both flash and EEPROM.

stefanrueger commented 1 year ago

OK, so, let's wait and hear from @SpenceKonde when his bootloaders need a_div=2 - I assume that's only needed for flash with memory size exceeding 64k and up to 128k and including that. I wonder what people do for ATxmega devices with flash that exceeds 128k?

$ avrdude -p*/d | grep PDI | awk '{ if(strtonum($7) > 2*65536) print; }'
  'ATxmega128C3' =>     [0x1E, 0x97, 0x52, 0x00800000, 0x22000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI'], # /usr/local/etc/avrdude.conf 11942
  'ATxmega128D3' =>     [0x1E, 0x97, 0x48, 0x00800000, 0x22000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI'], # /usr/local/etc/avrdude.conf 11997
  'ATxmega128D4' =>     [0x1E, 0x97, 0x47, 0x00800000, 0x22000, 0x100, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI'], # /usr/local/etc/avrdude.conf 12009
  'ATxmega128A1' =>     [0x1E, 0x97, 0x4C, 0x00800000, 0x22000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12025
  'ATxmega128A1revD' => [0x1E, 0x97, 0x41, 0x00800000, 0x22000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12043
  'ATxmega128A1U' =>    [0x1E, 0x97, 0x4C, 0x00800000, 0x22000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12054
  'ATxmega128A3' =>     [0x1E, 0x97, 0x42, 0x00800000, 0x22000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12066
  'ATxmega128A3U' =>    [0x1E, 0x97, 0x42, 0x00800000, 0x22000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12078
  'ATxmega128A4' =>     [0x1E, 0x97, 0x46, 0x00800000, 0x22000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12091
  'ATxmega128A4U' =>    [0x1E, 0x97, 0x46, 0x00800000, 0x22000, 0x100, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI'], # /usr/local/etc/avrdude.conf 12150
  'ATxmega128B1' =>     [0x1E, 0x97, 0x4D, 0x00800000, 0x22000, 0x100, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12205
  'ATxmega128B3' =>     [0x1E, 0x97, 0x4B, 0x00800000, 0x22000, 0x100, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12266
  'ATxmega192C3' =>     [0x1E, 0x97, 0x51, 0x00800000, 0x32000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI'], # /usr/local/etc/avrdude.conf 12279
  'ATxmega192D3' =>     [0x1E, 0x97, 0x49, 0x00800000, 0x32000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI'], # /usr/local/etc/avrdude.conf 12334
  'ATxmega192A1' =>     [0x1E, 0x97, 0x4E, 0x00800000, 0x32000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12346
  'ATxmega192A3' =>     [0x1E, 0x97, 0x44, 0x00800000, 0x32000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12363
  'ATxmega192A3U' =>    [0x1E, 0x97, 0x44, 0x00800000, 0x32000, 0x200, 0x8c0000, 0x0800, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12375
  'ATxmega256C3' =>     [0x1E, 0x98, 0x46, 0x00800000, 0x42000, 0x200, 0x8c0000, 0x1000, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI'], # /usr/local/etc/avrdude.conf 12387
  'ATxmega256D3' =>     [0x1E, 0x98, 0x44, 0x00800000, 0x42000, 0x200, 0x8c0000, 0x1000, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI'], # /usr/local/etc/avrdude.conf 12442
  'ATxmega256A1' =>     [0x1E, 0x98, 0x46, 0x00800000, 0x42000, 0x200, 0x8c0000, 0x1000, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12454
  'ATxmega256A3' =>     [0x1E, 0x98, 0x42, 0x00800000, 0x42000, 0x200, 0x8c0000, 0x1000, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12470
  'ATxmega256A3U' =>    [0x1E, 0x98, 0x42, 0x00800000, 0x42000, 0x200, 0x8c0000, 0x1000, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12482
  'ATxmega256A3B' =>    [0x1E, 0x98, 0x43, 0x00800000, 0x42000, 0x200, 0x8c0000, 0x1000, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12494
  'ATxmega256A3BU' =>   [0x1E, 0x98, 0x43, 0x00800000, 0x42000, 0x200, 0x8c0000, 0x1000, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI | PM_XMEGAJTAG'], # /usr/local/etc/avrdude.conf 12506
  'ATxmega384C3' =>     [0x1E, 0x98, 0x45, 0x00800000, 0x62000, 0x200, 0x8c0000, 0x1000, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI'], # /usr/local/etc/avrdude.conf 12518
  'ATxmega384D3' =>     [0x1E, 0x98, 0x47, 0x00800000, 0x62000, 0x200, 0x8c0000, 0x1000, 0x020, 0, 0x000, 0x0013, 'PM_SPM | PM_PDI'], # /usr/local/etc/avrdude.conf 12573

Do bootloaders for these devices expect the ISP command for load extended address?

mcuee commented 1 year ago

My test results with optiboot_dx for avr128db48. There is a problem with EEPROM. I will test Flash later.

With current code, the optiboot_dx will fail using PR #1110.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1110v1 -c arduino -P COM6 -b 115200 -p avr128db48 
-qq -U eeprom:w:.\hex2\entest.eep && echo OK
avrdude_pr1110v1.exe: verification error, first mismatch at byte 0x0001
                      0x54 != 0x68
avrdude_pr1110v1.exe: verification error; content mismatch

But with a_div = 1, it will work with PR #1110.

PS C:\work\avr\avrdude_test\avrdude_sr> git diff
diff --git a/src/stk500.c b/src/stk500.c
index 8966747..43e5111 100644
--- a/src/stk500.c
+++ b/src/stk500.c
@@ -793,7 +793,7 @@ static int stk500_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR
      * 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;
+    a_div = 1;
   } else {
     return -2;
   }
@@ -888,7 +888,7 @@ static int stk500_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM
      * 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;
+    a_div = 1;
   } else {
     return -2;
   }

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1110v1mod -c arduino -P COM6 -b 115200 
-p avr128db48 -qq -U eeprom:w:.\hex2\entest.eep && echo OK
OK
WestfW commented 1 year ago

It looks like the root optiboot_x (https://github.com/Optiboot/optiboot) assumes byte-addressable flash, and also that all of flash is mapped into the RAM address space.

That probably means that optiboot_x won't work on chips with more than 48k of FLASH (it was originally written for ATmega4809) or with chips that don't/can't map all of their flash at once (if there are any.) (except for "short" programs, I guess.)

@MCUdude and @SpenceKonde code seems to be the same code.

That rather sucks :-(

optiboot assumes that both flash and eeprom are word-addressed, while optiboot_x assumes that both are byte addressed. Sigh.

    else if(ch == STK_LOAD_ADDRESS) {
      // LOAD ADDRESS
      address.bytes[0] = getch();
      address.bytes[1] = getch();
      // ToDo: will there be mega-0 chips with >128k of RAM?
/*          UPDI chips apparently have byte-addressable FLASH ?
            address.word *= 2; // Convert from word address to byte address
*/
mcuee commented 1 year ago

Indeed optiboot_x and optiboot_dx codes seem to be the same. https://github.com/SpenceKonde/megaTinyCore/blob/master/megaavr/bootloaders/optiboot_x/optiboot_x.c https://github.com/MCUdude/MegaCoreX/blob/master/megaavr/bootloaders/optiboot/optiboot_x.c https://github.com/SpenceKonde/DxCore/blob/master/megaavr/bootloaders/optiboot_dx/optiboot_dx.c

mcuee commented 1 year ago

I wonder what people do for ATxmega devices with flash that exceeds 128k?

Do bootloaders for these devices expect the ISP command for load extended address?

@stefanrueger optiboot_dx does deal with extended address. https://github.com/SpenceKonde/DxCore/blob/master/megaavr/bootloaders/optiboot_dx/optiboot_dx.c#L535-L543

WestfW commented 1 year ago

is a_div determined from the chip type, or a combination of chip and programmer? Certainly it's much more important at the moment that the chips be programmable with the various actual hardware UPDI programmers (and especially the official ones) than with optiboot_x

stefanrueger commented 1 year ago

optiboot assumes that both flash and eeprom are word-addressed

@WestfW That's OK for eeprom with a page size hat exceeds 1. Turns out newer parts with UPDI i/f and some older parts (ATmega161 ATmega163 ATmega8515 ATmega8535 ...) have an eeprom page size of 1, which out of necessity fail when trying to use word addresses for their pages.

@SpenceKonde I can certainly put code in stk500.c that recognises that it services a bootloader for parts with PDI/UPDI interfaces and tries to figure out whether to send byte or word addresses.

Of course, the proper physical STK500 programmer (for which stk500.c was originally written) only handles classic AVR parts and has long since been upgraded to v2 firmware. Nevertheless, happy to "upgrade" the old and venerable stk500.c code to the vagaries of various bootloaders that latch onto this protocol.

mcuee commented 1 year ago

Of course, the proper physical STK500 programmer (for which stk500.c was originally written) only handles classic AVR parts and has long since been upgraded to v2 firmware. Nevertheless, happy to "upgrade" the old and venerable stk500.c code to the vagaries of various bootloaders that latch onto this protocol.

@stefanrueger

When you are at it (upgraing stk500.c code to the bootloaders and things like "Arduino as ISP" programmer), probably you can consider removing the old codes only for the real STK500 hardware programmer.

mcuee commented 1 year ago

is a_div determined from the chip type, or a combination of chip and programmer? Certainly it's much more important at the moment that the chips be programmable with the various actual hardware UPDI programmers (and especially the official ones) than with optiboot_x

We are talking about stk500.c here. The real STK500 only deals with classic AVRs and the V1 FW has been been obsoleted and replaced by V2 FW back in 2006. So we are not talking about any hardware UPDI programmers here.

The hardware UPDI programmers will still work as we are not changing the avrdude.conf parts definitions of the new AVR chips targeted by optiboot_x and optiboot_dx. Rather the change should be in stk500.c (or a new file -- which does not seem to be necessary now).

mcuee commented 1 year ago

My test results with optiboot_dx for avr128db48. There is a problem with EEPROM. I will test Flash later.

DxCore apparently works, but only for the first upload -- the LED blinking works fine as well. The second time it will fail to load.

I am not so sure if this is because of the 8s non-auto-reset problem. I am using Microchip AVR128DB48 Curiosity Nano evaluation board.

click for the details of bootloader burning and blinking LED sketec upload: 1st time good and 2nd time bad ``` :\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\tools\avrdude\6.3.0-arduino17or18/bin/avrdude -CC:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\hardware\megaavr\1.4.10/avrdude.conf -v -pavr128db48 -ccuriosity_updi -Pusb -e -Ufuse0:w:0x00:m -Ufuse1:w:0x00:m -Ufuse5:w:0b11001000:m -Ufuse6:w:0b00001100:m -Ufuse7:w:0x00:m -Ufuse8:w:0x01:m -Uflash:w:C:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\hardware\megaavr\1.4.10/bootloaders/hex/optiboot_dx128_ser3_8sec.hex:i avrdude: Version 6.3-20201216 Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/ Copyright (c) 2007-2014 Joerg Wunsch System wide configuration file is "C:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\hardware\megaavr\1.4.10/avrdude.conf" Using Port : usb Using Programmer : curiosity_updi avrdude: Found CMSIS-DAP compliant device, using EDBG protocol AVR Part : AVR128DB48 Chip Erase delay : 0 us PAGEL : P00 BS2 : P00 RESET disposition : dedicated RETRY pulse : SCK serial program mode : yes parallel program mode : yes Timeout : 0 StabDelay : 0 CmdexeDelay : 0 SyncLoops : 0 ByteDelay : 0 PollIndex : 0 PollValue : 0x00 Memory Detail : Block Poll Page Polled Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00 prodsig 0 0 0 0 no 125 125 0 0 0 0x00 0x00 fuses 0 0 0 0 no 9 16 0 0 0 0x00 0x00 fuse0 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse1 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse2 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse4 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse5 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse6 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse7 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse8 0 0 0 0 no 1 0 0 0 0 0x00 0x00 lock 0 0 0 0 no 4 1 0 0 0 0x00 0x00 data 0 0 0 0 no 0 0 0 0 0 0x00 0x00 flash 0 0 0 0 no 131072 512 0 0 0 0x00 0x00 eeprom 0 0 0 0 no 512 32 0 0 0 0x00 0x00 Programmer Type : JTAGICE3_UPDI Description : Microchip Curiosity in UPDI mode ICE hardware version: 0 ICE firmware version: 1.21 (rel. 37) Serial number : MCHP3372031800001331 Vtarget : 3.31 V JTAG clock megaAVR/program: 0 kHz JTAG clock megaAVR/debug: 0 kHz JTAG clock Xmega: 0 kHz PDI clock Xmega : 100 kHz avrdude: Partial Family_ID returned: "AVR " avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.01s avrdude: Device signature = 0x1e970c (probably avr128db48) avrdude: erasing chip avrdude: reading input file "0x00" avrdude: writing fuse0 (1 bytes): Writing | ################################################## | 100% 0.02s avrdude: 1 bytes of fuse0 written avrdude: verifying fuse0 memory against 0x00: avrdude: load data fuse0 data from input file 0x00: avrdude: input file 0x00 contains 1 bytes avrdude: reading on-chip fuse0 data: Reading | ################################################## | 100% 0.00s avrdude: verifying ... avrdude: 1 bytes of fuse0 verified avrdude: reading input file "0x00" avrdude: writing fuse1 (1 bytes): Writing | ################################################## | 100% 0.02s avrdude: 1 bytes of fuse1 written avrdude: verifying fuse1 memory against 0x00: avrdude: load data fuse1 data from input file 0x00: avrdude: input file 0x00 contains 1 bytes avrdude: reading on-chip fuse1 data: Reading | ################################################## | 100% 0.00s avrdude: verifying ... avrdude: 1 bytes of fuse1 verified avrdude: reading input file "0b11001000" avrdude: writing fuse5 (1 bytes): Writing | ################################################## | 100% 0.02s avrdude: 1 bytes of fuse5 written avrdude: verifying fuse5 memory against 0b11001000: avrdude: load data fuse5 data from input file 0b11001000: avrdude: input file 0b11001000 contains 1 bytes avrdude: reading on-chip fuse5 data: Reading | ################################################## | 100% 0.00s avrdude: verifying ... avrdude: 1 bytes of fuse5 verified avrdude: reading input file "0b00001100" avrdude: writing fuse6 (1 bytes): Writing | ################################################## | 100% 0.02s avrdude: 1 bytes of fuse6 written avrdude: verifying fuse6 memory against 0b00001100: avrdude: load data fuse6 data from input file 0b00001100: avrdude: input file 0b00001100 contains 1 bytes avrdude: reading on-chip fuse6 data: Reading | ################################################## | 100% 0.00s avrdude: verifying ... avrdude: 1 bytes of fuse6 verified avrdude: reading input file "0x00" avrdude: writing fuse7 (1 bytes): Writing | ################################################## | 100% 0.02s avrdude: 1 bytes of fuse7 written avrdude: verifying fuse7 memory against 0x00: avrdude: load data fuse7 data from input file 0x00: avrdude: input file 0x00 contains 1 bytes avrdude: reading on-chip fuse7 data: Reading | ################################################## | 100% 0.01s avrdude: verifying ... avrdude: 1 bytes of fuse7 verified avrdude: reading input file "0x01" avrdude: writing fuse8 (1 bytes): Writing | ################################################## | 100% 0.02s avrdude: 1 bytes of fuse8 written avrdude: verifying fuse8 memory against 0x01: avrdude: load data fuse8 data from input file 0x01: avrdude: input file 0x01 contains 1 bytes avrdude: reading on-chip fuse8 data: Reading | ################################################## | 100% 0.00s avrdude: verifying ... avrdude: 1 bytes of fuse8 verified avrdude: reading input file "C:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\hardware\megaavr\1.4.10/bootloaders/hex/optiboot_dx128_ser3_8sec.hex" avrdude: writing flash (512 bytes): Writing | ################################################## | 100% 0.15s avrdude: 512 bytes of flash written avrdude: verifying flash memory against C:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\hardware\megaavr\1.4.10/bootloaders/hex/optiboot_dx128_ser3_8sec.hex: avrdude: load data flash data from input file C:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\hardware\megaavr\1.4.10/bootloaders/hex/optiboot_dx128_ser3_8sec.hex: avrdude: input file C:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\hardware\megaavr\1.4.10/bootloaders/hex/optiboot_dx128_ser3_8sec.hex contains 512 bytes avrdude: reading on-chip flash data: Reading | ################################################## | 100% 0.09s avrdude: verifying ... avrdude: 512 bytes of flash verified avrdude done. Thank you. C:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\tools\avrdude\6.3.0-arduino17or18/bin/avrdude -CC:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\hardware\megaavr\1.4.10/avrdude.conf -v -pavr128db48 -carduino -D -PCOM6 -b115200 -Uflash:w:C:\Users\xiaof\AppData\Local\Temp\arduino_build_506679/Blink.ino.hex:i avrdude: Version 6.3-20201216 Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/ Copyright (c) 2007-2014 Joerg Wunsch System wide configuration file is "C:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\hardware\megaavr\1.4.10/avrdude.conf" Using Port : COM6 Using Programmer : arduino Overriding Baud Rate : 115200 AVR Part : AVR128DB48 Chip Erase delay : 0 us PAGEL : P00 BS2 : P00 RESET disposition : dedicated RETRY pulse : SCK serial program mode : yes parallel program mode : yes Timeout : 0 StabDelay : 0 CmdexeDelay : 0 SyncLoops : 0 ByteDelay : 0 PollIndex : 0 PollValue : 0x00 Memory Detail : Block Poll Page Polled Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00 prodsig 0 0 0 0 no 125 125 0 0 0 0x00 0x00 fuses 0 0 0 0 no 9 16 0 0 0 0x00 0x00 fuse0 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse1 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse2 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse4 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse5 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse6 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse7 0 0 0 0 no 1 0 0 0 0 0x00 0x00 fuse8 0 0 0 0 no 1 0 0 0 0 0x00 0x00 lock 0 0 0 0 no 4 1 0 0 0 0x00 0x00 data 0 0 0 0 no 0 0 0 0 0 0x00 0x00 flash 0 0 0 0 no 131072 512 0 0 0 0x00 0x00 eeprom 0 0 0 0 no 512 32 0 0 0 0x00 0x00 Programmer Type : Arduino Description : Arduino Hardware Version: 3 Firmware Version: 25.1 Vtarget : 0.3 V Varef : 0.3 V Oscillator : 28.800 kHz SCK period : 3.3 us avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.01s avrdude: Device signature = 0x1e970c (probably avr128db48) avrdude: reading input file "C:\Users\xiaof\AppData\Local\Temp\arduino_build_506679/Blink.ino.hex" avrdude: writing flash (1552 bytes): Writing | ################################################## | 100% 0.18s avrdude: 1552 bytes of flash written avrdude: verifying flash memory against C:\Users\xiaof\AppData\Local\Temp\arduino_build_506679/Blink.ino.hex: avrdude: load data flash data from input file C:\Users\xiaof\AppData\Local\Temp\arduino_build_506679/Blink.ino.hex: avrdude: input file C:\Users\xiaof\AppData\Local\Temp\arduino_build_506679/Blink.ino.hex contains 1552 bytes avrdude: reading on-chip flash data: Reading | ################################################## | 100% 0.13s avrdude: verifying ... avrdude: 1552 bytes of flash verified avrdude done. Thank you. C:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\tools\avrdude\6.3.0-arduino17or18/bin/avrdude -CC:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\hardware\megaavr\1.4.10/avrdude.conf -v -pavr128db48 -carduino -D -PCOM6 -b115200 -Uflash:w:C:\Users\xiaof\AppData\Local\Temp\arduino_build_506679/Blink.ino.hex:i avrdude: Version 6.3-20201216 Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/ Copyright (c) 2007-2014 Joerg Wunsch System wide configuration file is "C:\Users\xiaof\AppData\Local\Arduino15\packages\DxCore\hardware\megaavr\1.4.10/avrdude.conf" Using Port : COM6 Using Programmer : arduino Overriding Baud Rate : 115200 avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00 avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00 avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00 avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00 avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x80 avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00 avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00 avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00 avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00 avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00 avrdude done. Thank you. An error occurred while uploading the sketch ```

But avrdude git main will not even work for one time (flash the bootloader again).

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_git -c arduino -P COM6 -b 115200 -p avr128db48 
-U .\hex2\Blink.ino.avr128db48opti.16c1.mB2.wO.v1410.hex

avrdude_git.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude_git.exe: Device signature = 0x1e970c (probably avr128db48)
avrdude_git.exe: NOTE: "flash" memory has been specified, an erase cycle will be performed
                 To disable this feature, specify the -D option.
avrdude_git.exe: erasing chip
avrdude_git.exe: chip erase instruction not defined for part "AVR128DB48"

avrdude_git.exe done.  Thank you.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_git -c arduino -P COM6 -b 115200 -p avr128db48 
-D -U .\hex2\Blink.ino.avr128db48opti.16c1.mB2.wO.v1410.hex

avrdude_git.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude_git.exe: Device signature = 0x1e970c (probably avr128db48)
avrdude_git.exe: reading input file .\hex2\Blink.ino.avr128db48opti.16c1.mB2.wO.v1410.hex for flash
                 with 1040 bytes in 1 section within [0x200, 0x60f]
                 using 3 pages and 496 pad bytes
avrdude_git.exe: writing 1040 bytes flash ...

Writing | ################################################## | 100% 0.16s

avrdude_git.exe: 1040 bytes of flash written
avrdude_git.exe: verifying flash memory against .\hex2\Blink.ino.avr128db48opti.16c1.mB2.wO.v1410.hex

Reading | ################################################## | 100% 0.12s

avrdude_git.exe: verification error, first mismatch at byte 0x0200
                 0xa9 != 0x79
avrdude_git.exe: verification error; content mismatch

avrdude_git.exe done.  Thank you.

avrdude 7.0 release works fine for one time. So this is inline with @MCUdude's result, there is a regression here for flash.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude7 -C avrdude7.conf -c arduino -P COM6 -b 115200 -p avr128db48 
-D -U .\hex2\Blink.ino.avr128db48opti.16c1.mB2.wO.v1410.hex

avrdude7.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude7.exe: Device signature = 0x1e970c (probably avr128db48)
avrdude7.exe: reading input file ".\hex2\Blink.ino.avr128db48opti.16c1.mB2.wO.v1410.hex"
avrdude7.exe: input file .\hex2\Blink.ino.avr128db48opti.16c1.mB2.wO.v1410.hex auto detected as Intel Hex
avrdude7.exe: writing flash (1552 bytes):

Writing | ################################################## | 100% 0.17s

avrdude7.exe: 1552 bytes of flash written
avrdude7.exe: verifying flash memory against .\hex2\Blink.ino.avr128db48opti.16c1.mB2.wO.v1410.hex:
avrdude7.exe: input file .\hex2\Blink.ino.avr128db48opti.16c1.mB2.wO.v1410.hex auto detected as Intel Hex

Reading | ################################################## | 100% 0.12s

avrdude7.exe: 1552 bytes of flash verified

avrdude7.exe done.  Thank you.

Somehow the PR #1110 EEPROM mod no longer works. I have no idea why. Apparently it does nothing (still read as 0xff).

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1110v1mod.exe -c arduino -P COM6 -b 115200 -p avr128db48 
-U eeprom:w:.\hex2\entest.hex:i

avrdude_pr1110v1mod.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude_pr1110v1mod.exe: Device signature = 0x1e970c (probably avr128db48)
avrdude_pr1110v1mod.exe: reading input file .\hex2\entest.hex for eeprom
avrdude_pr1110v1mod.exe: writing 512 bytes eeprom ...

Writing | ################################################## | 100% 12.29s

avrdude_pr1110v1mod.exe: 512 bytes of eeprom written
avrdude_pr1110v1mod.exe: verifying eeprom memory against .\hex2\entest.hex

Reading | ################################################## | 100% 12.28s

avrdude_pr1110v1mod.exe: verification error, first mismatch at byte 0x0000
                         0xff != 0x54
avrdude_pr1110v1mod.exe: verification error; content mismatch

avrdude_pr1110v1mod.exe done.  Thank you.
mcuee commented 1 year ago

Once I change a_div = 1 for flash, then avrdude seems to work with flash write for optiboot, same as avrdude 7.0 release. So again, this is in line with analysis done here by @MCUdude and @stefanrueger.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1110v1mod2 -c arduino -P COM6 -b 115200 
-p avr128db48 -D -U .\hex2\Blink.ino.avr128db48opti.16c1.mB2.wO.v1410.hex

avrdude_pr1110v1mod2.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude_pr1110v1mod2.exe: Device signature = 0x1e970c (probably avr128db48)
avrdude_pr1110v1mod2.exe: reading input file .\hex2\Blink.ino.avr128db48opti.16c1.mB2.wO.v1410.hex for flash
                          with 1040 bytes in 1 section within [0x200, 0x60f]
                          using 3 pages and 496 pad bytes
avrdude_pr1110v1mod2.exe: writing 1040 bytes flash ...

Writing | ################################################## | 100% 0.17s

avrdude_pr1110v1mod2.exe: 1040 bytes of flash written
avrdude_pr1110v1mod2.exe: verifying flash memory against .\hex2\Blink.ino.avr128db48opti.16c1.mB2.wO.v1410.hex

Reading | ################################################## | 100% 0.13s

avrdude_pr1110v1mod2.exe: 1040 bytes of flash verified

avrdude_pr1110v1mod2.exe done.  Thank you.
mcuee commented 1 year ago

I wonder what people do for ATxmega devices with flash that exceeds 128k? ... Do bootloaders for these devices expect the ISP command for load extended address?

@stefanrueger It seems to me Arduino and optiboot booloader is not so popular among ATxmega devices. Rather avr109 ( using xboot) is more popular. And you and @MCUdude have helped fixed the issue with ATxmega devices with flash that exceeds 128KB in #1101 recently.

There is an Arduino implementation here. The bootloader is using either CATERINA (USB variant of AVR109) or STK500v2. It seems to support extended address. I do not have the facility to test them as of now. I am not so sure if @MCUdude can test them or not. https://github.com/XMegaForArduino/arduino https://github.com/XMegaForArduino/arduino/tree/master/bootloaders/xmega

mcuee commented 1 year ago

It is a pity that my Arduino Nano Every (official board using ATmega4809)) and Nano 4808 clone (using ATmega4808) do not support bootloader. My ATtiny817 Curiosity Nano is also not a good board to work with bootloaders due to all kinds of limitation.

The only board I have for UPDI AVR is the AVR128DB48 Curiosity Nano board -- it is supposed to work with optiboot_dx but somehow it is also not working very well.

MCUdude commented 1 year ago

@mcuee send me an email, and I'll see if I can get you some more convenient hardware for testing.

hansibull at google's mail service , com
MCUdude commented 1 year ago

There is an Arduino implementation here. The bootloader is using either CATERINA (USB variant of AVR109) or STK500v2. It seems to support extended address. I do not have the facility to test them as of now. I am not so sure if @MCUdude can test them or not. https://github.com/XMegaForArduino/arduino https://github.com/XMegaForArduino/arduino/tree/master/bootloaders/xmega

I currently only have an ATxmega128A3U and an ATmega256A3BU I can test with, but I'll look into it.

It is a pity that my Arduino Nano Every (official board using ATmega4809)) and Nano 4808 clone (using ATmega4808) do not support bootloader. My ATtiny817 Curiosity Nano is also not a good board to work with bootloaders due to all kinds of limitation.

When working with bootloaders, I usually break the Rx/Tx lies from the MCU to the debugger chip, and instead wire up a dedicated USB to serial adapter. It appears to be more reliable for bootloader use at least.

mcuee commented 1 year ago

By the way, terminal mode does not seem to be affected by this issue for optiboot_dx.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_git -c arduino -P COM6 -b 115200 -p avr128db48 -qq -t
avrdude> dump flash 0x1000 0x10
>>> dump flash 0x1000 0x10
1000  ff ff aa 55 ff ff ff ff  ff ff ff ff ff ff ff ff  |...U............|

avrdude> write flash 0x1000 0x55 0xaa 0x55 0xaa
>>> write flash 0x1000 0x55 0xaa 0x55 0xaa
avrdude> flush
>>> flush
avrdude_git.exe: synching cache to device... done
avrdude> dump flash 0x1000 0x10
>>> dump flash 0x1000 0x10
1000  55 aa 55 aa ff ff ff ff  ff ff ff ff ff ff ff ff  |U.U.............|

avrdude> quit
>>> quit
SpenceKonde commented 1 year ago

I can also get you AVR Dx boards with Optiboot-dx and Optiboot-x on them - just email me if you still need (if you're in US, it's easier and faster to get from me, whereas (assuming he has Dx-series boards) MCUdude can get them to you faster if you're in europe.

You can also use the curiosity nano with bootloader on a different set of pins, by selecting NEDBG as programmer, AVR128DA/DB48 with Optiboot as chip (instead of the Microchip board def), and then bootloading, just specify serial pins that you can connect to an external serial adapter, and either manually press reset or wire up an autoreset circuit - I don't think anything keeps it from autoresetting there.

I'd probably send you like... a AVR128DB64, tinyAVR 1624 or 3224 on a rev C (no working LED) PCB, and maybe something with a double D on it to see the differences between large and small memory Dx's - they aren't the same. If I can't get a credible DD available, it'd just be like a AVR64DD48 or something.

stefanrueger commented 1 year ago

Rather than sending h/w, better for me to know what you'd expect from the arduino programmer to send.

@WestfW and @SpenceKonde: are the chip sets that your respective bootloaders deal with mutually exclusive? If so, we can make arduino work with all of your requests: Parts memory size a_div
UPDI-chips (optiboot-dx) flash >64k 2
UPDI-chips (optiboot-dx) flash <=64k 1
UPDI-chips (optiboot-dx) eeprom all 1
PDI-chips (??) flash all 1
PDI-chips (??) eeprom all 1
ISP-chips (optiboot) flash all 2
ISP-chips (optiboot) eeprom all 2

For all devices I would send the load_ext_addr command as SPI extension when needed (ie, when flash has more than 128k memory then it's sent once at the beginning and every time the programmer jumps from one section to the other) irrespective of any ISP commands that are mentioned for that part in avrdude.conf. AVRDUDE has recently introduced a pgm->prog_mode variable that is set to PM_SPM programming (ie, bootloader support) for -c arduino, so the underlying stk500v1 programmer knows the comms is for bootloaders and just needs to consider the expected protocol.

Does that plan work out?

If there are parts that are served by two or more of optiboot, optiboot-dx and optiboot-x and the different bootloaders require a different treatment for the same part then we will need to create another programmer in AVRDUDE as @mcuee has suggested. Not a biggie, but I'd need to know how you want the flash/eeprom addresses served.

If above table is too big a simplification, please feel free to create one that reflects your respective bootloaders.

mcuee commented 1 year ago

DxCore apparently works, but only for the first upload -- the LED blinking works fine as well. The second time it will fail to load.

I am not so sure if this is because of the 8s non-auto-reset problem. I am using Microchip AVR128DB48 Curiosity Nano evaluation board.

@SpenceKonde The 8s delay does work for the optiboot_dx. I need to be fast since Windows will pop up with the mass storage thingy for my AVR128DB48 Curiosity Nano board. I need to close that Windows and enter the bootloader.

There is a strange verification error message for large hex file for avrdude 7.0 release and the 6.3 version bundled with DxCore. I am not so sure about the reason. But verification later using the onboard pkobn_updi shows flash writing is correct.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude7 -C .\avrdude7.conf -c arduino -P COM6 -b 115200 -p avr128db48 
-qq -D -U .\hex2\hexaa64KB_with_blink.hex && echo OK
avrdude7.exe: verification error, first mismatch at byte 0x0200
              0xff != 0x79
avrdude7.exe: verification error; content mismatch

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude7 -C .\avrdude7.conf -c arduino -P COM6 -b 115200 -p avr128db48 
-qq -D -U flash:v:.\hex2\hexaa64KB_with_blink.hex && echo OK
OK

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude7 -C .\avrdude7.conf -c pkobn_updi -p avr128db48 -qq 
-D -U flash:v:.\hex2\hexaa64KB_with_blink.hex && echo OK
              Vtarget                      : 3.31 V
              PDI/UPDI clock Xmega/megaAVR : 100 kHz

OK

Same result for the avrdude 6.3 version bundled with DxCore.

PS C:\work\avr\avrdude_test\avrdude_bin\bin_misc\6.3.0-arduino17or18\bin> .\avrdude -C ..\etc\avrdude.conf 
-c arduino -P COM6 -b 115200 -p avr128db48 -qq -D -U hexaa64KB_with_blink.hex && echo OK
avrdude.exe: verification error, first mismatch at byte 0x0200
             0xff != 0x79
avrdude.exe: verification error; content mismatch

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_git -c pkobn_updi -p avr128db48 -qq -D 
-U flash:v:.\hex2\hexaa64KB_with_blink.hex:i && echo OK
                 Vtarget                      : 3.31 V
                 PDI/UPDI clock Xmega/megaAVR : 100 kHz
OK

There is no such warning message with just the blink hex file.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude7 -C .\avrdude7.conf -c arduino -P COM6 -b 115200 
-p avr128db48 -qq -D -U .\hex2\optiboot_dx_avr128db48_uart3_8s_blink.hex && echo OK
OK

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_git -c pkobn_updi -p avr128db48 -qq 
-U flash:v:.\hex2\optiboot_dx_avr128db48_uart3_8s.hex:i && echo OK
                 Vtarget                      : 3.31 V
                 PDI/UPDI clock Xmega/megaAVR : 100 kHz
OK

Ref:

Test hex file: 64KB hex file with 0xaa, but the first part are replaced with the blink hex file from DxCore (where the first 512B are skipped as 512B is reserved for the bootloader). hexaa64KB_with_blink.zip

mcuee commented 1 year ago

Once I use the following quick mode (to make all a_div =1), git main will also work as avrdude 7.0 release.

PS C:\work\avr\avrdude_test\avrdude_main> git diff
diff --git a/src/stk500.c b/src/stk500.c
index 8966747..bc0d80c 100644
--- a/src/stk500.c
+++ b/src/stk500.c
@@ -784,7 +784,7 @@ static int stk500_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR

   if (strcmp(m->desc, "flash") == 0) {
     memtype = 'F';
-    a_div = 2;
+    a_div = 1;
   } else if (strcmp(m->desc, "eeprom") == 0) {
     memtype = 'E';
     /*
@@ -793,7 +793,7 @@ static int stk500_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR
      * 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;
+    a_div = 1;
   } else {
     return -2;
   }
@@ -879,7 +879,7 @@ static int stk500_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM

   if (strcmp(m->desc, "flash") == 0) {
     memtype = 'F';
-    a_div = 2;
+    a_div = 1;
   } else if (strcmp(m->desc, "eeprom") == 0) {
     memtype = 'E';
     /*
@@ -888,7 +888,7 @@ static int stk500_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM
      * 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;
+    a_div = 1;
   } else {
     return -2;
   }

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_git_mod -c arduino -P COM6 -b 115200 -p avr128db48 
-qq -D -U .\hex2\optiboot_dx_avr128db48_uart3_8s_blink.hex && echo OK
OK

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_git_mod -c pkobn_updi -p avr128db48 -qq -D 
-U flash:v:.\hex2\optiboot_dx_avr128db48_uart3_8s_blink.hex && echo OK
                     Vtarget                      : 3.31 V
                     PDI/UPDI clock Xmega/megaAVR : 100 kHz
OK

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_git_mod -c arduino -P COM6 -b 115200 -p avr128db48 -qq 
-D -U .\hex2\hexaa64KB_with_blink.hex && echo OK
avrdude_git_mod.exe: verification error, first mismatch at byte 0x0200
                     0xff != 0x79
avrdude_git_mod.exe: verification error; content mismatch

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_git_mod -c pkobn_updi -p avr128db48 -qq -D 
-U flash:v:.\hex2\hexaa64KB_with_blink.hex && echo OK
                     Vtarget                      : 3.31 V
                     PDI/UPDI clock Xmega/megaAVR : 100 kHz
OK
mcuee commented 1 year ago

This is my best guess based on the results from @MCUdude and my own test results. And we do not need to worry about ATxmega parts as the popular bootloader there is based on AVR109 (eg: xboot and caterina), flip2 and STK500v2 ( https://github.com/XMegaForArduino/arduino/blob/master/bootloaders/xmega/xmegaBOOT.c). I have not seen any optiboot implementation for ATxmega part.

Note: all the current parts supported by optiboot_x (megaTinyCore and MegaCoreX) have flash size not greater than 64KB.

Parts | memory | size | a_div -- | -- | -- | -- UPDI-chips (optiboot_dx) | flash | >64k | 1 UPDI-chips (optiboot_dx) | flash | <=64k | 1 ? UPDI-chips (optiboot_x megaTinyCore) | flash | <=64k | 1 UPDI-chips (optiboot_x MegaCoreX) | flash | <=64k | 1 UPDI-chips (optiboot_x and optiboot_dx) | eeprom | all | 1 ISP-chips (optiboot) | flash | all | 2 ISP-chips (optiboot) | eeprom | all | 2
mcuee commented 1 year ago

@WestfW, @SpenceKonde and @MCUdude, please review the above. One thing not so clear is for the whether a_div = 1 or a_div =2 for optiboot_dx with AVR Dx parts with 64KB or less Flash. I tend to believe it is a_div =1 as well but I am not sure.

MCUdude commented 1 year ago

@mcuee I don't have any AVR-Dx's with less than 128kiB flash, so I'm not able able to help out figuring out the last unknown a_div. @SpenceKonde probably has though.

mcuee commented 1 year ago

@mcuee I don't have any AVR-Dx's with less than 128kiB flash, so I'm not able able to help out figuring out the last unknown a_div. @SpenceKonde probably has though.

@MCUdude I was trying to order bare AVR DD chips from Taobao but unfortunately they are all out of stock. In the end, I just ordered AVR64DD32 Curiosity Nano board from Mouser Singapore. I should be able to get it within two weeks.

BTW, Mouse Singapore does have DIP version of AVR64DD28-I/SP part at reasonable price (S$4.72/pc or US$3.33/pc), but then the shipping cost is high at S$25 (about US$17.62) so it is not really worth to buy the bare chips. The development tools will usually have free shipment so the board costs S$32.35 (about US$22.80).

stefanrueger commented 1 year ago

the last unknown a_div

I am guessing this must be 1. Please look at PR #1140 that implements what I believe to be a solution to this issue.

mcuee commented 1 year ago

Let's continue the discussion in #1165.