avrdudes / avrdude

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

Report: Incorrect SerialUPDI control of AVR64EA32 #1529

Closed askn37 closed 10 months ago

askn37 commented 11 months ago

Report: Incorrect SerialUPDI control of AVR64EA32

This is a known bug as of commit 481a91d.

  1. You are trying to read the "Chip Silicon Revision" register without checking the status of the target device. This will fail if the target device is "resetting" or "sleeping".
  2. The address width used to access the flash area is incorrectly set to 16 bits. Therefore, the IO memory area is accessed instead of the flash area. The correct address width must be 24 bits.(Shouldn't we send 0x55 0x6A 0x00 0x00 0x80 here?)

case.1 Debug log

avrdude: sending 2 bytes [0x55, 0xe6]
avrdude: send: U [55] . [e6] 
avrdude: recv: U [55] . [e6] 
avrdude: recv: A [41] V [56] R [52]   [20]   [20]   [20]   [20]   [20] P [50] : [3a] 3 [33] D [44] : [3a] 1 [31] - [2d] 3 [33] M [4d] 2 [32]   [20] ( [28] B [42] 1 [31] . [2e] 5 [35] 9 [39] F [46] 0 [30] 2 [32] . [2e] 0 [30] ) [29] . [00] 
avrdude: received 32 bytes [0x41, 0x56, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x3a, 0x33, 0x44, 0x3a, 0x31, 0x2d, 0x33, 0x4d, 0x32, 0x20, 0x28, 0x42, 0x31, 0x2e, 0x35, 0x39, 0x46, 0x30, 0x32, 0x2e, 0x30, 0x29, 0x00]
avrdude: received SIB: [AVR     P:3D:1-3M2 (B1.59F02.0)]
avrdude: Device family ID: AVR     
avrdude: NVM interface: P:3
avrdude: Debug interface: D:1
avrdude: PDI oscillator: 3M2 
avrdude: Extra information: (B1.59F02.0)
avrdude: NVM type 3: 16-bit, page oriented
avrdude: reading 1 bytes from 0x000F01
avrdude: ST_PTR to 0x000F01
avrdude: sending 4 bytes [0x55, 0x69, 0x01, 0x0f]
avrdude: send: U [55] i [69] . [01] . [0f] 
avrdude: recv: U [55] i [69] . [01] . [0f] 
avrdude: ser_recv(): programmer is not responding
avrdude: serialupdi_recv(): programmer is not responding
avrdude: UPDI ST_PTR recv failed on ACK
avrdude: ST_PTR operation failed
avrdude serialupdi_initialize() [serialupdi.c:636] error: Reading chip silicon revision failed
avrdude main() [main.c:1404] error: initialization failed, rc=-1
        - double check the connections and try again
        - use -b to set lower baud rate, e.g. -b 57600
        - use -F to override this check

case.2 Debug log

avrdude: processing -U flash:r:avr64ea32/Flash.hex:i
avrdude: reading flash memory ...
avrdude: reading 128 bytes from 0x800000
avrdude: ST_PTR to 0x800000
avrdude: sending 4 bytes [0x55, 0x69, 0x00, 0x00]
avrdude: send: U [55] i [69] . [00] . [00] 
avrdude: recv: U [55] i [69] . [00] . [00] 
avrdude: recv: @ [40] 
avrdude: received 1 bytes [0x40]
avrdude: repeat 128
avrdude: sending 3 bytes [0x55, 0xa0, 0x7f]
avrdude: send: U [55] . [a0] . [7f] 
avrdude: recv: U [55] . [a0] . [7f] 
avrdude: LD8 from ptr++
avrdude: sending 2 bytes [0x55, 0x24]
avrdude: send: U [55] $ [24] 
avrdude: recv: U [55] $ [24] 
avrdude: recv: . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [ff] . [7f] . [02]   [20] . [00] . [07] . [00]   [20] . [00] . [07] . [00]   [20] . [00] . [07] . [00]   [20] . [00] . [07] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [00] . [07] . [00] . [00] . [00] . [00] . [00] . [00] . [05] . [00] . [00] . [00] . [00] * [2a] . [00] . [06] . [00] . [00] . [00] . [00] . [00] . [00] . [10] . [00] . [00] . [00] . [2e] . [00] . [00] . [00] . [00] . [00] . [00] 
avrdude: received 128 bytes [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x02, 0x20, 0x00, 0x07, 0x00, 0x20, 0x00, 0x07, 0x00, 0x20, 0x00, 0x07, 0x00, 0x20, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

Need additional information?

I design my own program writer and create firmware that meets various practical needs. This time, we also acquired control including HV programming using AVR64EA32. I noticed this problem when I was doing comparison testing with other programmers.

Further additional information

There are two execution result logs here. Both are displayed when -vvvvq is specified. One result is the target device is asleep, and the other result is the target device is running.

test_run.log test_sleep.log

mcuee commented 10 months ago

@stefanrueger

Just wondering if this is related to #1249. Thanks.

askn37 commented 10 months ago

IMG_3608

Since I'm an AVR chip collector, I've been experimenting with about 20 models of UPDI AVR bare chips from different family and revisions, along with several different SerialUPDI implementations. Unfortunately, I don't have the recalled chip.

One implementation that showed interesting behavior was using DTR to toggle UART passthrough and a combination of RTS and capacitors to perform a hard reset. This circuit is used in conjunction with the Arduino IDE's serial plotter.

This type cannot use SerialUPDI without the "-xrtsdtr=high" option. Also, the target AVR wakes up more slowly than circuits that don't use it.

When used on the latest main branch (NVMCTRL improved), it stops with "error: Reading chip silicon revision failed". However, disconnecting the RTS reset fixes it without any problems. So it's clear that the capacitor in the reset circuit was interfering. Either the design is wrong or avrdude is impatient.

Therefore, I created a build with "Silicon Check" commented out and experimented with RTS reset, and this time it proceeded normally even though "error: key was not accepted" was displayed. What did you say?

+./avrdude_test/build_darwin/src/avrdude -xrtsdtr=high -p avr64ea32 -c serialupdi -P /dev/cu.usbserial-230 -U userrow:r:avr64ea32/USERROW.hex:i -v

avrdude: Version 7.2-20231024 (d6c61f5f)
         Copyright the AVRDUDE authors;
         see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

         System wide configuration file is /Users/askn/Arduino/UPDI_TEST/avrdude_test/build_darwin/src/avrdude.conf
         User configuration file is /Users/askn/.avrduderc

         Using Port                    : /dev/cu.usbserial-230
         Using Programmer              : serialupdi
         AVR Part                      : AVR64EA32
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         Serial program mode           : yes
         Parallel program mode         : yes
         Memory Detail                 :

                                           Block Poll               Page                       Polled
           Memory Type Alias    Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           fuse0       wdtcfg      0     0     0    0 no          1    1      0     0     0 0x00 0x00
           fuse1       bodcfg      0     0     0    0 no          1    1      0     0     0 0x00 0x00
           fuse2       osccfg      0     0     0    0 no          1    1      0     0     0 0x00 0x00
           fuse5       syscfg0     0     0     0    0 no          1    1      0     0     0 0x00 0x00
           fuse6       syscfg1     0     0     0    0 no          1    1      0     0     0 0x00 0x00
           fuse7       codesize    0     0     0    0 no          1    1      0     0     0 0x00 0x00
           fuse8       bootsize    0     0     0    0 no          1    1      0     0     0 0x00 0x00
           fuses                   0     0     0    0 no         16   16      0     0     0 0x00 0x00
           lock                    0     0     0    0 no          4    1      0     0     0 0x00 0x00
           prodsig     sigrow      0     0     0    0 no        128  128      0     0     0 0x00 0x00
           signature               0     0     0    0 no          3    1      0     0     0 0x00 0x00
           tempsense               0     0     0    0 no          4    1      0     0     0 0x00 0x00
           sernum                  0     0     0    0 no         16    1      0     0     0 0x00 0x00
           userrow     usersig     0     0     0    0 no         64   64      0     0     0 0x00 0x00
           data                    0     0     0    0 no          0    1      0     0     0 0x00 0x00
           io                      0     0     0    0 no       4160    1      0     0     0 0x00 0x00
           sib                     0     0     0    0 no         32    1      0     0     0 0x00 0x00
           eeprom                  0     0     0    0 no        512    8      0     0     0 0x00 0x00
           flash                   0     0     0    0 no      65536  128      0     0     0 0x00 0x00

         Programmer Type : serialupdi
         Description     : SerialUPDI
avrdude: forcing serial DTR/RTS handshake lines HIGH
avrdude: NVM type 3: 24-bit, page oriented
avrdude: entering NVM programming mode
avrdude serialupdi_enter_progmode() error: key was not accepted
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e961f (probably avr64ea32)

avrdude: processing -U userrow:r:avr64ea32/USERROW.hex:i
avrdude: reading userrow/usersig memory ...
Reading | ################################################## | 100% 0.02s
avrdude: writing output file avr64ea32/USERROW.hex
avrdude: leaving NVM programming mode
avrdude: releasing DTR/RTS handshake lines

avrdude done.  Thank you.

This indicates that the UPDI layer has not yet fully woken up when reading "UPDI_CS_ASI_KEY_STATUS" after sending "UPDI_SIB_128", or that key activation took longer than usual. I'm sure avrdude is impatient. There probably aren't any other concerns. thank you.

mcuee commented 10 months ago

@askn37

Thanks a lot for sharing your insight. Nice AVR boards!

Please help to post the full debug log with -vvvv and maybe that can help @dbuchwald and maybe @stefanrueger to debug the issue to make avrdude more robust.

mcuee commented 10 months ago

@askn37

BTW, I see that you have alternative Arduino Core in your repos (in Japanese) https://github.com/askn37 https://github.com/askn37/multix-zinnia-sdk-modernAVR https://github.com/askn37/multix-zinnia-sdk-megaAVR

Just wondering if you compare your Cores with MegaCoreX, megaTinyCore and DxCore. Thanks. https://github.com/MCUdude/MegaCoreX https://github.com/SpenceKonde/megaTinyCore https://github.com/SpenceKonde/DxCore

mcuee commented 10 months ago

@stefanrueger and @dbuchwald

Looks like there is a regression under Windows in git main from avrdude 7.2 release, under Windows.

You can see I have no issues with avrdude 7.2 release. git main has issues.

Edit: looks like a MSVC build vs MinGW build issue. Please refer to later post. Usually I use MinGW build and that is why I see issues.

click for -vvvv debug log of avrdude 7.2 MSVC binary vs avrdude 72 mingw64 binary ``` PS > .\avrdude72 -C .\avrdude72.conf -c serialupdi -P COM16 -p avr64dd32 -vvvv avrdude72: Version 7.2 Copyright the AVRDUDE authors; see https://github.com/avrdudes/avrdude/blob/main/AUTHORS System wide configuration file is C:\work\avr\avrdude_test\avrdude_bin\avrdude72.conf Using Port : COM16 Using Programmer : serialupdi avrdude72: opening serial port ... avrdude72: sending 1 bytes [0x00] avrdude72: send: . [00] avrdude72: recv: . [00] AVR Part : AVR64DD32 RESET disposition : dedicated RETRY pulse : SCK Serial program mode : yes Parallel program mode : yes Memory Detail : Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse0 wdtcfg 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse1 bodcfg 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse2 osccfg 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse5 syscfg0 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse6 syscfg1 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse7 codesize 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse8 bootsize 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuses 0 0 0 0 no 9 16 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- lock 0 0 0 0 no 4 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- tempsense 0 0 0 0 no 2 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- signature 0 0 0 0 no 3 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- prodsig 0 0 0 0 no 125 125 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- sernum 0 0 0 0 no 16 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- userrow usersig 0 0 0 0 no 32 32 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- data 0 0 0 0 no 0 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- eeprom 0 0 0 0 no 256 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- flash 0 0 0 0 no 65536 512 0 0 0 0x00 0x00 Programmer Type : serialupdi Description : SerialUPDI avrdude72: STCS 0x08 to address 0x03 avrdude72: sending 3 bytes [0x55, 0xc3, 0x08] avrdude72: send: U [55] . [c3] . [08] avrdude72: recv: U [55] . [c3] . [08] avrdude72: STCS 0x80 to address 0x02 avrdude72: sending 3 bytes [0x55, 0xc2, 0x80] avrdude72: send: U [55] . [c2] . [80] avrdude72: recv: U [55] . [c2] . [80] avrdude72: LDCS from 0x00 avrdude72: sending 2 bytes [0x55, 0x80] avrdude72: send: U [55] . [80] avrdude72: recv: U [55] . [80] avrdude72: recv: 0 [30] avrdude72: received 1 bytes [0x30] avrdude72: UDPI init OK avrdude72: UPDI link initialization OK avrdude72: LDCS from 0x0B avrdude72: sending 2 bytes [0x55, 0x8b] avrdude72: send: U [55] . [8b] avrdude72: recv: U [55] . [8b] avrdude72: recv: . [92] avrdude72: received 1 bytes [0x92] avrdude72: device is in SLEEP mode avrdude72: sending 2 bytes [0x55, 0xe6] avrdude72: send: U [55] . [e6] avrdude72: recv: U [55] . [e6] avrdude72: recv: A [41] V [56] R [52] [20] [20] [20] [20] [20] P [50] : [3a] 2 [32] D [44] : [3a] 1 [31] - [2d] 3 [33] M [4d] 2 [32] [20] ( [28] A [41] 3 [33] . [2e] K [4b] V [56] 0 [30] 0 [30] K [4b] . [2e] 0 [30] ) [29] . [00] avrdude72: received 32 bytes [0x41, 0x56, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x3a, 0x32, 0x44, 0x3a, 0x31, 0x2d, 0x33, 0x4d, 0x32, 0x20, 0x28, 0x41, 0x33, 0x2e, 0x4b, 0x56, 0x30, 0x30, 0x4b, 0x2e, 0x30, 0x29, 0x00] avrdude72: received SIB: [AVR P:2D:1-3M2 (A3.KV00K.0)] avrdude72: Device family ID: AVR avrdude72: NVM interface: P:2 avrdude72: Debug interface: D:1 avrdude72: PDI oscillator: 3M2 avrdude72: Extra information: (A3.KV00K.0) avrdude72: NVM type 2: 24-bit, word oriented write avrdude72: STCS 0x08 to address 0x03 avrdude72: sending 3 bytes [0x55, 0xc3, 0x08] avrdude72: send: U [55] . [c3] . [08] avrdude72: recv: U [55] . [c3] . [08] avrdude72: STCS 0x80 to address 0x02 avrdude72: sending 3 bytes [0x55, 0xc2, 0x80] avrdude72: send: U [55] . [c2] . [80] avrdude72: recv: U [55] . [c2] . [80] avrdude72: LDCS from 0x00 avrdude72: sending 2 bytes [0x55, 0x80] avrdude72: send: U [55] . [80] avrdude72: recv: U [55] . [80] avrdude72: recv: 0 [30] avrdude72: received 1 bytes [0x30] avrdude72: UDPI init OK avrdude72: entering NVM programming mode avrdude72: LDCS from 0x0B avrdude72: sending 2 bytes [0x55, 0x8b] avrdude72: send: U [55] . [8b] avrdude72: recv: U [55] . [8b] avrdude72: recv: . [92] avrdude72: received 1 bytes [0x92] avrdude72: UPDI writing key avrdude72: sending 2 bytes [0x55, 0xe0] avrdude72: send: U [55] . [e0] avrdude72: recv: U [55] . [e0] avrdude72: sending 8 bytes [0x20, 0x67, 0x6f, 0x72, 0x50, 0x4d, 0x56, 0x4e] avrdude72: send: [20] g [67] o [6f] r [72] P [50] M [4d] V [56] N [4e] avrdude72: recv: [20] g [67] o [6f] r [72] P [50] M [4d] V [56] N [4e] avrdude72: LDCS from 0x07 avrdude72: sending 2 bytes [0x55, 0x87] avrdude72: send: U [55] . [87] avrdude72: recv: U [55] . [87] avrdude72: recv: . [10] avrdude72: received 1 bytes [0x10] avrdude72: key status: 0x10 avrdude72: sending reset request avrdude72: STCS 0x59 to address 0x08 avrdude72: sending 3 bytes [0x55, 0xc8, 0x59] avrdude72: send: U [55] . [c8] Y [59] avrdude72: recv: U [55] . [c8] Y [59] avrdude72: sending release reset request avrdude72: STCS 0x00 to address 0x08 avrdude72: sending 3 bytes [0x55, 0xc8, 0x00] avrdude72: send: U [55] . [c8] . [00] avrdude72: recv: U [55] . [c8] . [00] avrdude72: LDCS from 0x0B avrdude72: sending 2 bytes [0x55, 0x8b] avrdude72: send: U [55] . [8b] avrdude72: recv: U [55] . [8b] avrdude72: recv: 8 [38] avrdude72: received 1 bytes [0x38] avrdude72: LDCS from 0x0B avrdude72: sending 2 bytes [0x55, 0x8b] avrdude72: send: U [55] . [8b] avrdude72: recv: U [55] . [8b] avrdude72: recv: . [08] avrdude72: received 1 bytes [0x08] avrdude72: entered NVM programming mode avrdude72: AVR device initialized and ready to accept instructions Reading | | 0% 0.00 s avrdude72: LDCS from 0x0B avrdude72: sending 2 bytes [0x55, 0x8b] avrdude72: send: U [55] . [8b] avrdude72: recv: U [55] . [8b] avrdude72: recv: . [08] avrdude72: received 1 bytes [0x08] avrdude72: LD from 0x001100 avrdude72: sending 5 bytes [0x55, 0x08, 0x00, 0x11, 0x00] avrdude72: send: U [55] . [08] . [00] . [11] . [00] avrdude72: recv: U [55] . [08] . [00] . [11] . [00] avrdude72: recv: . [1e] avrdude72: received 1 bytes [0x1e] avrdude72: LD from 0x001101 avrdude72: sending 5 bytes [0x55, 0x08, 0x01, 0x11, 0x00] avrdude72: send: U [55] . [08] . [01] . [11] . [00] avrdude72: recv: U [55] . [08] . [01] . [11] . [00] avrdude72: recv: . [96] avrdude72: received 1 bytes [0x96] avrdude72: LD from 0x001102 avrdude72: sending 5 bytes [0x55, 0x08, 0x02, 0x11, 0x00] avrdude72: send: U [55] . [08] . [02] . [11] . [00] avrdude72: recv: U [55] . [08] . [02] . [11] . [00] avrdude72: recv: . [1a] avrdude72: received 1 bytes [0x1a] Reading | ################################################## | 100% 0.03 s avrdude72: device signature = 0x1e961a (probably avr64dd32) avrdude72: leaving NVM programming mode avrdude72: sending reset request avrdude72: STCS 0x59 to address 0x08 avrdude72: sending 3 bytes [0x55, 0xc8, 0x59] avrdude72: send: U [55] . [c8] Y [59] avrdude72: recv: U [55] . [c8] Y [59] avrdude72: sending release reset request avrdude72: STCS 0x00 to address 0x08 avrdude72: sending 3 bytes [0x55, 0xc8, 0x00] avrdude72: send: U [55] . [c8] . [00] avrdude72: recv: U [55] . [c8] . [00] avrdude72: STCS 0x0C to address 0x03 avrdude72: sending 3 bytes [0x55, 0xc3, 0x0c] avrdude72: send: U [55] . [c3] . [0c] avrdude72: recv: U [55] . [c3] . [0c] avrdude72 done. Thank you. PS>.\avrdude_git -c serialupdi -P ch340 -p avr64dd32 -vvvv avrdude_git: Version 7.2-20231024 (d6c61f5f) Copyright the AVRDUDE authors; see https://github.com/avrdudes/avrdude/blob/main/AUTHORS System wide configuration file is C:\work\avr\avrdude_test\avrdude_bin\avrdude.conf Using Port : COM16 Using Programmer : serialupdi avrdude_git: opening serial port ... avrdude_git: sending 1 bytes [0x00] avrdude_git: send: . [00] avrdude_git: recv: . [00] AVR Part : AVR64DD32 RESET disposition : dedicated RETRY pulse : SCK Serial program mode : yes Parallel program mode : yes Memory Detail : Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse0 wdtcfg 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse1 bodcfg 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse2 osccfg 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse5 syscfg0 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse6 syscfg1 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse7 codesize 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse8 bootsize 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuses 0 0 0 0 no 16 16 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- lock 0 0 0 0 no 4 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- prodsig sigrow 0 0 0 0 no 128 128 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- signature 0 0 0 0 no 3 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- tempsense 0 0 0 0 no 4 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- sernum 0 0 0 0 no 16 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- userrow usersig 0 0 0 0 no 32 32 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- data 0 0 0 0 no 0 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- io 0 0 0 0 no 4160 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- sib 0 0 0 0 no 32 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- eeprom 0 0 0 0 no 256 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- flash 0 0 0 0 no 65536 512 0 0 0 0x00 0x00 Programmer Type : serialupdi Description : SerialUPDI avrdude_git: STCS 0x08 to address 0x03 avrdude_git: sending 3 bytes [0x55, 0xc3, 0x08] avrdude_git: send: U [55] . [c3] . [08] avrdude_git: ser_recv(): programmer is not responding avrdude_git: STCS 0x80 to address 0x02 avrdude_git: sending 3 bytes [0x55, 0xc2, 0x80] avrdude_git: send: U [55] . [c2] . [80] avrdude_git: ser_recv(): programmer is not responding avrdude_git: LDCS from 0x00 avrdude_git: sending 2 bytes [0x55, 0x80] avrdude_git: send: U [55] . [80] avrdude_git: ser_recv(): programmer is not responding avrdude_git: ser_recv(): programmer is not responding avrdude_git: serialupdi_recv(): programmer is not responding avrdude_git: check failed avrdude_git: datalink not active, resetting ... avrdude_git: sending double break avrdude_git: send: . [00] avrdude_git: recv: . [00] avrdude_git: send: . [00] avrdude_git: recv: . [00] avrdude_git: STCS 0x08 to address 0x03 avrdude_git: sending 3 bytes [0x55, 0xc3, 0x08] avrdude_git: send: U [55] . [c3] . [08] avrdude_git: ser_recv(): programmer is not responding avrdude_git: STCS 0x80 to address 0x02 avrdude_git: sending 3 bytes [0x55, 0xc2, 0x80] avrdude_git: send: U [55] . [c2] . [80] avrdude_git: ser_recv(): programmer is not responding avrdude_git: LDCS from 0x00 avrdude_git: sending 2 bytes [0x55, 0x80] avrdude_git: send: U [55] . [80] avrdude_git: ser_recv(): programmer is not responding avrdude_git: ser_recv(): programmer is not responding avrdude_git: serialupdi_recv(): programmer is not responding avrdude_git: check failed avrdude_git: restoring datalink failed avrdude_git serialupdi_initialize() [serialupdi.c:569] error: UPDI link initialization failed avrdude_git main() [main.c:1399] error: initialization failed, rc=-1 - double check the connections and try again - use -b to set lower baud rate, e.g. -b 57600 - use -F to override this check avrdude_git: leaving NVM programming mode avrdude_git: sending reset request avrdude_git: STCS 0x59 to address 0x08 avrdude_git: sending 3 bytes [0x55, 0xc8, 0x59] avrdude_git: send: U [55] . [c8] Y [59] avrdude_git: ser_recv(): programmer is not responding avrdude_git: sending release reset request avrdude_git: STCS 0x00 to address 0x08 avrdude_git: sending 3 bytes [0x55, 0xc8, 0x00] avrdude_git: send: U [55] . [c8] . [00] avrdude_git: ser_recv(): programmer is not responding avrdude_git: STCS 0x0C to address 0x03 avrdude_git: sending 3 bytes [0x55, 0xc3, 0x0c] avrdude_git: send: U [55] . [c3] . [0c] avrdude_git: ser_recv(): programmer is not responding avrdude_git done. Thank you. ```
mcuee commented 10 months ago

Looking at the histories, there are not many changes. I will try to find the commit which causes the regression. https://github.com/avrdudes/avrdude/commits/main/src/serialupdi.c

The following commit is already causing problems: Added support for chip silicon revision number https://github.com/avrdudes/avrdude/commit/ac760ff49064c5de53abed709057341ec4a78b64

PS>.\avrdude_ac760ff -C .\avrdude_ac760ff.conf -c serialupdi -P COM16 -p avr64dd32 -v

avrdude_ac760ff: Version 7.2-20230725 (ac760ff4)
...
avrdude_ac760ff serialupdi_initialize() error: UPDI link initialization failed
avrdude_ac760ff main() error: initialization failed, rc=-1
                - double check the connections and try again
                - use -b to set lower baud rate, e.g. -b 57600
                - use -F to override this check
avrdude_ac760ff: leaving NVM programming mode

avrdude_ac760ff done.  Thank you.
mcuee commented 10 months ago

Hmm, no, it seems to be a MinGW vs MSVC issue.

Official MSVC build is okay but not my MinGW build, even for avrdude 7.2 release version. I will check out git main later.

PS>.\avrdude72_mingw64 -C .\avrdude72.conf -c serialupdi -P COM16 -p avr64dd32 -v

avrdude72_mingw64: Version 7.2
...
avrdude72_mingw64 serialupdi_initialize() error: UPDI link initialization failed
avrdude72_mingw64 main() error: initialization failed, rc=-1
                  - double check the connections and try again
                  - use -b to set lower baud rate, e.g. -b 57600
                  - use -F to override this check
avrdude72_mingw64: leaving NVM programming mode

avrdude72_mingw64 done.  Thank you.

PS>.\avrdude72_msvc -C .\avrdude72.conf -c serialupdi -P COM16 -p avr64dd32 -v

avrdude72_msvc: Version 7.2
 ...
avrdude72_msvc: device is in SLEEP mode
avrdude72_msvc: NVM type 2: 24-bit, word oriented write
avrdude72_msvc: entering NVM programming mode
avrdude72_msvc: AVR device initialized and ready to accept instructions
avrdude72_msvc: device signature = 0x1e961a (probably avr64dd32)
avrdude72_msvc: leaving NVM programming mode

avrdude72_msvc done.  Thank you.
mcuee commented 10 months ago

Same for git main, using the github action binary of git main (not my build).

MSVC build is okay, but not MinGW build.

PS>pwd

Path
----
C:\work\avr\avrdude_test\avrdude_bin\github\avrdude-mingw-x86_64

PS>.\avrdude -c serialupdi -P COM16 -p avr64dd32 -v

avrdude: Version 7.2-20231024 (d6c61f5)
...
avrdude serialupdi_initialize() error: UPDI link initialization failed
avrdude main() error: initialization failed, rc=-1
        - double check the connections and try again
        - use -b to set lower baud rate, e.g. -b 57600
        - use -F to override this check
avrdude: leaving NVM programming mode

avrdude done.  Thank you.

PS>cd .\avrdude-msvc-x64\
PS>pwd

Path
----
C:\work\avr\avrdude_test\avrdude_bin\github\avrdude-msvc-x64

PS>.\avrdude -c serialupdi -P COM16 -p avr64dd32 -v

avrdude: Version 7.2-20231024 (d6c61f5)
...
avrdude: device is in SLEEP mode
avrdude: NVM type 2: 24-bit, word oriented write
avrdude: Chip silicon revision: 1.3
avrdude: entering NVM programming mode
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e961a (probably avr64dd32)
avrdude: leaving NVM programming mode

avrdude done.  Thank you.
mcuee commented 10 months ago

Then I checked MSVC build: 1) avrdude 7.1 and avrdude 7.2 official MSVC binary work with both -v and -vvvv. 2) avrdude git main MSVC github action binary works with with both -v and -vvvv. 3) avrdude 7.0 official MSVC binary works with -v, -vv and -vvv but not -vvvv.

MinGW build.

1) avrdude 7.1 and avrdude 7.2 mingw64 binary does not work with either -v or -vvvv. Without -v it works. 2) avrdude git main mingw64 github action binary does not work with either -v or -vvvv. Without -v it works. 3) avrdude 7.0 mingw64 binary does not work with either -v or -vvvv. Without -v it works.

So this is not a regression, The issue has been there since avrdude 7.0 release (first official release to support serialupdi).

askn37 commented 10 months ago

@mcuee

BTW, I see that you have alternative Arduino Core in your repos (in Japanese) https://github.com/askn37 https://github.com/askn37/multix-zinnia-sdk-modernAVR https://github.com/askn37/multix-zinnia-sdk-megaAVR

Just wondering if you compare your Cores with MegaCoreX, megaTinyCore and DxCore. Thanks. https://github.com/MCUdude/MegaCoreX https://github.com/SpenceKonde/megaTinyCore https://github.com/SpenceKonde/DxCore

Of course, the cross-check has been completed. The avrdude used when each project is set up with Arduino IDE can be obtained from the link below.

My project (multix-zinnia-sdk) is the only one that has 7.2 deployed as of today. This is because we are dealing with AVR_EA (NVMCTRLv3 chip). MCUdude supports all NVMCTRLv0 chips, so there is nothing to worry about. SpenceKonde (Dr.Azzy) uses "prog.py" and does not use avrdude's built-in SerialUPDI, so it is avrdude 6.3.

That's why it was my duty to launch this issue.

https://github.com/askn37/

http://downloads.arduino.cc/tools/avrdude_7.2-arduino.1_Linux_ARMv6.tar.gz http://downloads.arduino.cc/tools/avrdude_7.2-arduino.1_Linux_ARM64.tar.gz http://downloads.arduino.cc/tools/avrdude_7.2-arduino.1_macOS_64bit.tar.gz http://downloads.arduino.cc/tools/avrdude_7.2-arduino.1_Linux_64bit.tar.gz http://downloads.arduino.cc/tools/avrdude_7.2-arduino.1_Linux_32bit.tar.gz http://downloads.arduino.cc/tools/avrdude_7.2-arduino.1_Windows_32bit.tar.gz

https://github.com/MCUdude/

http://downloads.arduino.cc/tools/avrdude_7.1-arduino.1_Linux_ARMv6.tar.gz http://downloads.arduino.cc/tools/avrdude_7.1-arduino.1_Linux_ARM64.tar.gz http://downloads.arduino.cc/tools/avrdude_7.1-arduino.1_macOS_64bit.tar.gz http://downloads.arduino.cc/tools/avrdude_7.1-arduino.1_Linux_64bit.tar.gz http://downloads.arduino.cc/tools/avrdude_7.1-arduino.1_Linux_32bit.tar.gz http://downloads.arduino.cc/tools/avrdude_7.1-arduino.1_Windows_32bit.tar.gz

https://github.com/SpenceKonde/

http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino18-armhf-pc-linux-gnu.tar.bz2 http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino18-aarch64-pc-linux-gnu.tar.bz2 http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino18-x86_64-apple-darwin12.tar.bz2 http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino18-x86_64-pc-linux-gnu.tar.bz2 http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino18-i686-w64-mingw32.zip

mcuee commented 10 months ago

@askn37

Thanks for adopting avrdude 7.2 release!

@MCUdude will for sure adopt avrdude 7.2 for his MegaCoreX for the next release (or maybe 7.3 release depends on the timing). The current 1.1.2 release was on 2023-05-01 so it was before avrdude 7.2 release.

As for DxCore and megaTinyCore, there are issues created to adopt avrdude 7.2. I think @SpenceKonde will adopt avrdude 7.2 release in the near future. He actually wanted to adopt earlier but there were no suitable binaries at that time.

askn37 commented 10 months ago

@mcuee

The following commit is already causing problems: Added support for chip silicon revision number https://github.com/avrdudes/avrdude/commit/ac760ff49064c5de53abed709057341ec4a78b64

I believe the code in question is placed in "static int serialupdi_initialize" because it requires "const AVRPART p". But in reality, if you could just "enter NVM programming mode" and run it, you would have been fine. However, the "static int serialupdi_enter_progmode" that does this does not take "const AVRPART p" as an argument. Therefore, this change still requires consideration.

The current AVR64EA32-I/PT (TQFP Revision B1) may have unknown errata. After writing the ERASE/NVMPROG/USERROW key, the UPDI_CS_ASI_KEY_STATUS register may be unreadable or unchanged. This is especially true in high voltage mode. Is there a problem with UPDI clock synchronization? But I don't have an oscilloscope that can decode his UPDI communications, so I can't find any evidence yet. There has been no response from Microchip either.

mcuee commented 10 months ago

Errata for AVR EA family Rev B1. Indeed there are issues related to UPDI and NVM programming. https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ProductDocuments/Errata/AVR64EA-28-32-48-SilConErrataClarif-DS80001048.pdf

Device 2.2.1. NVM Programming Does Not Work Below 2.7V 2.2.2. Reduced Flash Endurance for VDD Below BODLEVEL3 2.2.3. Write Operation Lost if Consecutive Writes to Specific Address Spaces

CRCSCAN 2.3.1. Running CRC Scan on Part of The Flash is Non-Functional

NVMCTRL 2.4.1. Flash Multi Page Erase Non-Functional from UPDI 2.4.2. Flash-Self Programming Failing When Flash Read During Programming

USART 2.5.1. Receiver Non-Functional after Detection of Inconsistent Synchronization Field

mcuee commented 10 months ago

Further debug under Windows: -b 57600 works with MinGW build.

-b 57600 works for MinGW build with -v or -vvvv ``` PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_git -c serialupdi -P COM11 -p avr64dd32 -v -b 57600 avrdude_git: Version 7.2-20231018 (481a91dd) Copyright the AVRDUDE authors; see https://github.com/avrdudes/avrdude/blob/main/AUTHORS System wide configuration file is C:\work\avr\avrdude_test\avrdude_bin\avrdude.conf Using Port : COM11 Using Programmer : serialupdi Overriding Baud Rate : 57600 AVR Part : AVR64DD32 RESET disposition : dedicated RETRY pulse : SCK Serial program mode : yes Parallel program mode : yes Memory Detail : Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse0 wdtcfg 0 0 0 0 no 1 1 0 0 0 0x00 0x00 fuse1 bodcfg 0 0 0 0 no 1 1 0 0 0 0x00 0x00 fuse2 osccfg 0 0 0 0 no 1 1 0 0 0 0x00 0x00 fuse5 syscfg0 0 0 0 0 no 1 1 0 0 0 0x00 0x00 fuse6 syscfg1 0 0 0 0 no 1 1 0 0 0 0x00 0x00 fuse7 codesize 0 0 0 0 no 1 1 0 0 0 0x00 0x00 fuse8 bootsize 0 0 0 0 no 1 1 0 0 0 0x00 0x00 fuses 0 0 0 0 no 16 16 0 0 0 0x00 0x00 lock 0 0 0 0 no 4 1 0 0 0 0x00 0x00 prodsig sigrow 0 0 0 0 no 128 128 0 0 0 0x00 0x00 signature 0 0 0 0 no 3 1 0 0 0 0x00 0x00 tempsense 0 0 0 0 no 4 1 0 0 0 0x00 0x00 sernum 0 0 0 0 no 16 1 0 0 0 0x00 0x00 userrow usersig 0 0 0 0 no 32 32 0 0 0 0x00 0x00 data 0 0 0 0 no 0 1 0 0 0 0x00 0x00 io 0 0 0 0 no 4160 1 0 0 0 0x00 0x00 sib 0 0 0 0 no 32 1 0 0 0 0x00 0x00 eeprom 0 0 0 0 no 256 1 0 0 0 0x00 0x00 flash 0 0 0 0 no 65536 512 0 0 0 0x00 0x00 Programmer Type : serialupdi Description : SerialUPDI avrdude_git: device is in SLEEP mode avrdude_git: NVM type 2: 24-bit, word oriented write avrdude_git: Chip silicon revision: 1.3 avrdude_git: entering NVM programming mode avrdude_git: AVR device initialized and ready to accept instructions avrdude_git: device signature = 0x1e961a (probably avr64dd32) avrdude_git: leaving NVM programming mode avrdude_git done. Thank you. PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_git -c serialupdi -P COM11 -p avr64dd32 -vvvv -b 57600 avrdude_git: Version 7.2-20231018 (481a91dd) Copyright the AVRDUDE authors; see https://github.com/avrdudes/avrdude/blob/main/AUTHORS System wide configuration file is C:\work\avr\avrdude_test\avrdude_bin\avrdude.conf Using Port : COM11 Using Programmer : serialupdi Overriding Baud Rate : 57600 avrdude_git: opening serial port ... avrdude_git: sending 1 bytes [0x00] avrdude_git: send: . [00] avrdude_git: recv: . [00] AVR Part : AVR64DD32 RESET disposition : dedicated RETRY pulse : SCK Serial program mode : yes Parallel program mode : yes Memory Detail : Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse0 wdtcfg 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse1 bodcfg 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse2 osccfg 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse5 syscfg0 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse6 syscfg1 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse7 codesize 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuse8 bootsize 0 0 0 0 no 1 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- fuses 0 0 0 0 no 16 16 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- lock 0 0 0 0 no 4 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- prodsig sigrow 0 0 0 0 no 128 128 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- signature 0 0 0 0 no 3 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- tempsense 0 0 0 0 no 4 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- sernum 0 0 0 0 no 16 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- userrow usersig 0 0 0 0 no 32 32 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- data 0 0 0 0 no 0 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- io 0 0 0 0 no 4160 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- sib 0 0 0 0 no 32 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- eeprom 0 0 0 0 no 256 1 0 0 0 0x00 0x00 Block Poll Page Polled Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- flash 0 0 0 0 no 65536 512 0 0 0 0x00 0x00 Programmer Type : serialupdi Description : SerialUPDI avrdude_git: STCS 0x08 to address 0x03 avrdude_git: sending 3 bytes [0x55, 0xc3, 0x08] avrdude_git: send: U [55] . [c3] . [08] avrdude_git: recv: . [00] . [d8] . [f8] avrdude_git: STCS 0x80 to address 0x02 avrdude_git: sending 3 bytes [0x55, 0xc2, 0x80] avrdude_git: send: U [55] . [c2] . [80] avrdude_git: recv: U [55] . [c2] . [80] avrdude_git: LDCS from 0x00 avrdude_git: sending 2 bytes [0x55, 0x80] avrdude_git: send: U [55] . [80] avrdude_git: recv: U [55] . [80] avrdude_git: ser_recv(): programmer is not responding avrdude_git: serialupdi_recv(): programmer is not responding avrdude_git: check failed avrdude_git: datalink not active, resetting ... avrdude_git: sending double break avrdude_git: send: . [00] avrdude_git: recv: . [00] avrdude_git: send: . [00] avrdude_git: recv: . [00] avrdude_git: STCS 0x08 to address 0x03 avrdude_git: sending 3 bytes [0x55, 0xc3, 0x08] avrdude_git: send: U [55] . [c3] . [08] avrdude_git: recv: U [55] . [c3] . [08] avrdude_git: STCS 0x80 to address 0x02 avrdude_git: sending 3 bytes [0x55, 0xc2, 0x80] avrdude_git: send: U [55] . [c2] . [80] avrdude_git: recv: U [55] . [c2] . [80] avrdude_git: LDCS from 0x00 avrdude_git: sending 2 bytes [0x55, 0x80] avrdude_git: send: U [55] . [80] avrdude_git: recv: U [55] . [80] avrdude_git: recv: 0 [30] avrdude_git: received 1 bytes [0x30] avrdude_git: UDPI init OK avrdude_git: UPDI link initialization OK avrdude_git: LDCS from 0x0B avrdude_git: sending 2 bytes [0x55, 0x8b] avrdude_git: send: U [55] . [8b] avrdude_git: recv: U [55] . [8b] avrdude_git: recv: . [92] avrdude_git: received 1 bytes [0x92] avrdude_git: device is in SLEEP mode avrdude_git: sending 2 bytes [0x55, 0xe6] avrdude_git: send: U [55] . [e6] avrdude_git: recv: U [55] . [e6] avrdude_git: recv: A [41] V [56] R [52] [20] [20] [20] [20] [20] P [50] : [3a] 2 [32] D [44] : [3a] 1 [31] - [2d] 3 [33] M [4d] 2 [32] [20] ( [28] A [41] 3 [33] . [2e] K [4b] V [56] 0 [30] 0 [30] K [4b] . [2e] 0 [30] ) [29] . [00] avrdude_git: received 32 bytes [0x41, 0x56, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x3a, 0x32, 0x44, 0x3a, 0x31, 0x2d, 0x33, 0x4d, 0x32, 0x20, 0x28, 0x41, 0x33, 0x2e, 0x4b, 0x56, 0x30, 0x30, 0x4b, 0x2e, 0x30, 0x29, 0x00] avrdude_git: received SIB: [AVR P:2D:1-3M2 (A3.KV00K.0)] avrdude_git: Device family ID: AVR avrdude_git: NVM interface: P:2 avrdude_git: Debug interface: D:1 avrdude_git: PDI oscillator: 3M2 avrdude_git: Extra information: (A3.KV00K.0) avrdude_git: NVM type 2: 24-bit, word oriented write avrdude_git: reading 1 bytes from 0x000F01 avrdude_git: ST_PTR to 0x000F01 avrdude_git: sending 5 bytes [0x55, 0x6a, 0x01, 0x0f, 0x00] avrdude_git: send: U [55] j [6a] . [01] . [0f] . [00] avrdude_git: recv: U [55] j [6a] . [01] . [0f] . [00] avrdude_git: recv: @ [40] avrdude_git: received 1 bytes [0x40] avrdude_git: LD8 from ptr++ avrdude_git: sending 2 bytes [0x55, 0x24] avrdude_git: send: U [55] $ [24] avrdude_git: recv: U [55] $ [24] avrdude_git: recv: . [13] avrdude_git: received 1 bytes [0x13] avrdude_git: Received chip silicon revision 0x13 avrdude_git: Chip silicon revision: 1.3 avrdude_git: STCS 0x08 to address 0x03 avrdude_git: sending 3 bytes [0x55, 0xc3, 0x08] avrdude_git: send: U [55] . [c3] . [08] avrdude_git: recv: U [55] . [c3] . [08] avrdude_git: STCS 0x80 to address 0x02 avrdude_git: sending 3 bytes [0x55, 0xc2, 0x80] avrdude_git: send: U [55] . [c2] . [80] avrdude_git: recv: U [55] . [c2] . [80] avrdude_git: LDCS from 0x00 avrdude_git: sending 2 bytes [0x55, 0x80] avrdude_git: send: U [55] . [80] avrdude_git: recv: U [55] . [80] avrdude_git: recv: 0 [30] avrdude_git: received 1 bytes [0x30] avrdude_git: UDPI init OK avrdude_git: entering NVM programming mode avrdude_git: LDCS from 0x0B avrdude_git: sending 2 bytes [0x55, 0x8b] avrdude_git: send: U [55] . [8b] avrdude_git: recv: U [55] . [8b] avrdude_git: recv: . [92] avrdude_git: received 1 bytes [0x92] avrdude_git: UPDI writing key avrdude_git: sending 2 bytes [0x55, 0xe0] avrdude_git: send: U [55] . [e0] avrdude_git: recv: U [55] . [e0] avrdude_git: sending 8 bytes [0x20, 0x67, 0x6f, 0x72, 0x50, 0x4d, 0x56, 0x4e] avrdude_git: send: [20] g [67] o [6f] r [72] P [50] M [4d] V [56] N [4e] avrdude_git: recv: [20] g [67] o [6f] r [72] P [50] M [4d] V [56] N [4e] avrdude_git: LDCS from 0x07 avrdude_git: sending 2 bytes [0x55, 0x87] avrdude_git: send: U [55] . [87] avrdude_git: recv: U [55] . [87] avrdude_git: recv: . [10] avrdude_git: received 1 bytes [0x10] avrdude_git: key status: 0x10 avrdude_git: sending reset request avrdude_git: STCS 0x59 to address 0x08 avrdude_git: sending 3 bytes [0x55, 0xc8, 0x59] avrdude_git: send: U [55] . [c8] Y [59] avrdude_git: recv: U [55] . [c8] Y [59] avrdude_git: sending release reset request avrdude_git: STCS 0x00 to address 0x08 avrdude_git: sending 3 bytes [0x55, 0xc8, 0x00] avrdude_git: send: U [55] . [c8] . [00] avrdude_git: recv: U [55] . [c8] . [00] avrdude_git: LDCS from 0x0B avrdude_git: sending 2 bytes [0x55, 0x8b] avrdude_git: send: U [55] . [8b] avrdude_git: recv: U [55] . [8b] avrdude_git: recv: 8 [38] avrdude_git: received 1 bytes [0x38] avrdude_git: LDCS from 0x0B avrdude_git: sending 2 bytes [0x55, 0x8b] avrdude_git: send: U [55] . [8b] avrdude_git: recv: U [55] . [8b] avrdude_git: recv: . [08] avrdude_git: received 1 bytes [0x08] avrdude_git: entered NVM programming mode avrdude_git: AVR device initialized and ready to accept instructions Reading | | 0% 0.00 s avrdude_git: LDCS from 0x0B avrdude_git: sending 2 bytes [0x55, 0x8b] avrdude_git: send: U [55] . [8b] avrdude_git: recv: U [55] . [8b] avrdude_git: recv: . [08] avrdude_git: received 1 bytes [0x08] avrdude_git: LD from 0x001100 avrdude_git: sending 5 bytes [0x55, 0x08, 0x00, 0x11, 0x00] avrdude_git: send: U [55] . [08] . [00] . [11] . [00] avrdude_git: recv: U [55] . [08] . [00] . [11] . [00] avrdude_git: recv: . [1e] avrdude_git: received 1 bytes [0x1e] avrdude_git: LD from 0x001101 avrdude_git: sending 5 bytes [0x55, 0x08, 0x01, 0x11, 0x00] avrdude_git: send: U [55] . [08] . [01] . [11] . [00] avrdude_git: recv: U [55] . [08] . [01] . [11] . [00] avrdude_git: recv: . [96] avrdude_git: received 1 bytes [0x96] avrdude_git: LD from 0x001102 avrdude_git: sending 5 bytes [0x55, 0x08, 0x02, 0x11, 0x00] avrdude_git: send: U [55] . [08] . [02] . [11] . [00] avrdude_git: recv: U [55] . [08] . [02] . [11] . [00] avrdude_git: recv: . [1a] avrdude_git: received 1 bytes [0x1a] Reading | ################################################## | 100% 0.05 s avrdude_git: device signature = 0x1e961a (probably avr64dd32) avrdude_git: leaving NVM programming mode avrdude_git: sending reset request avrdude_git: STCS 0x59 to address 0x08 avrdude_git: sending 3 bytes [0x55, 0xc8, 0x59] avrdude_git: send: U [55] . [c8] Y [59] avrdude_git: recv: U [55] . [c8] Y [59] avrdude_git: sending release reset request avrdude_git: STCS 0x00 to address 0x08 avrdude_git: sending 3 bytes [0x55, 0xc8, 0x00] avrdude_git: send: U [55] . [c8] . [00] avrdude_git: recv: U [55] . [c8] . [00] avrdude_git: STCS 0x0C to address 0x03 avrdude_git: sending 3 bytes [0x55, 0xc3, 0x0c] avrdude_git: send: U [55] . [c3] . [0c] avrdude_git: recv: U [55] . [c3] . [0c] avrdude_git done. Thank you. ```
stefanrueger commented 10 months ago

or avrdude is impatient

@askn37 Is there a good place in serialupdi_initialize() to put an usleep() to solve this problem and how long for?

Also, I wonder whether some OS open() calls twiddle RTS while other OS don't touch RTS when opening a serial connection.

dbuchwald commented 10 months ago

@stefanrueger I would be very careful with changes like this. I remember that one of the main challenges in SerialUPDI implementation was making sure it "sort-of-works" for all the platforms, because, as you noticed, actual support for "standard" "POSIX" operations on serial ports varies wildly between seemingly similar systems, depending on drivers, hardware and such. As far as I recall, the original pymcuprog implementation for the "break" signal was to change baud rate to 300 and transmit then:

https://github.com/microchip-pic-avr-tools/pymcuprog/blob/main/pymcuprog/serialupdi/physical.py#L89

If you are interested, I have some notes on why it was not possible to use "standard" "POSIX" feature of tcsendbreak() which would make much more sense. Yeah, tread carefully, this stuff is slippery slope.

And if you decide to add this usleep thing in serialupdi_initialize, then please, make sure to gate it with build-specific #ifdef so it doesn't pollute and break other implementations.

mcuee commented 10 months ago

@dbuchwald and @stefanrueger

I can actually live with the current git as it suggests to use -b 57600 which does sort out the issue, if the fix is not simple.

PS>.\avrdude_git -c serialupdi -P COM11 -p avr64dd32 -v

avrdude_git: Version 7.2-20231024 (d6c61f5f)
...
avrdude_git serialupdi_initialize() error: UPDI link initialization failed
avrdude_git main() error: initialization failed, rc=-1
            - double check the connections and try again
            - use -b to set lower baud rate, e.g. -b 57600
            - use -F to override this check
avrdude_git: leaving NVM programming mode

avrdude_git done.  Thank you.

PS>.\avrdude_git -c serialupdi -P COM11 -p avr64dd32 -v -b 57600

avrdude_git: Version 7.2-20231024 (d6c61f5f)
...
avrdude_git: device is in SLEEP mode
avrdude_git: NVM type 2: 24-bit, word oriented write
avrdude_git: Chip silicon revision: 1.3
avrdude_git: entering NVM programming mode
avrdude_git: AVR device initialized and ready to accept instructions
avrdude_git: device signature = 0x1e961a (probably avr64dd32)
avrdude_git: leaving NVM programming mode

avrdude_git done.  Thank you.

BTW, pymcuprog does work.

(py310x64venv) PS>pymcuprog ping -d avr64dd32 -t uart -u com11
Connecting to SerialUPDI
Pinging device...
Ping response: 1E961A
Done.

(py310x64venv) PS>pymcuprog ping -d avr64dd32 -t uart -u com11 -v debug
Connecting to SerialUPDI
pymcuprog.programmer - INFO - Setting up programming session for 'avr64dd32'
pymcuprog.deviceinfo.deviceinfo - INFO - Looking for device avr64dd32
pymcuprog.serialupdi.physical - INFO - Opening port 'com11' at 115200 baud (timeout 1.0s)
pymcuprog.serialupdi.physical - DEBUG - send : [0x00]
pymcuprog.serialupdi.link - DEBUG - STCS to 0x03
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC3, 0x08]
pymcuprog.serialupdi.link - DEBUG - STCS to 0x02
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC2, 0x80]
pymcuprog.serialupdi.link - DEBUG - LDCS from 0x00
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x80]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x30]
pymcuprog.serialupdi.link - INFO - UPDI init OK
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xE6]
pymcuprog.serialupdi.application - INFO - SIB: 'AVR     P:2D:1-3M2 (A3.KV00K.0)'
pymcuprog.serialupdi.application - INFO - Device family ID: 'AVR'
pymcuprog.serialupdi.application - INFO - NVM interface: 'P:2'
pymcuprog.serialupdi.application - INFO - Debug interface: 'D:1'
pymcuprog.serialupdi.application - INFO - PDI oscillator: '3M2'
pymcuprog.serialupdi.application - INFO - Extra info: '(A3.KV00K.0)'
pymcuprog.serialupdi.application - INFO - NVM type 2: 24-bit, word oriented write
pymcuprog.serialupdi.link - DEBUG - STCS to 0x03
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC3, 0x08]
pymcuprog.serialupdi.link - DEBUG - STCS to 0x02
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC2, 0x80]
pymcuprog.serialupdi.link - DEBUG - LDCS from 0x00
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x80]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x30]
pymcuprog.serialupdi.link - INFO - UPDI init OK
pymcuprog.serialupdi.link - DEBUG - LDCS from 0x00
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x80]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x30]
pymcuprog.serialupdi.application - INFO - PDI revision = 0x03
pymcuprog.serialupdi.link - DEBUG - LDCS from 0x0B
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x8B]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x92]
pymcuprog.serialupdi.link - DEBUG - LDCS from 0x0B
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x8B]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x92]
pymcuprog.serialupdi.application - INFO - Entering NVM programming mode
pymcuprog.serialupdi.link - DEBUG - Writing key
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xE0]
pymcuprog.serialupdi.physical - DEBUG - send : [0x20, 0x67, 0x6F, 0x72, 0x50, 0x4D, 0x56, 0x4E]
pymcuprog.serialupdi.link - DEBUG - LDCS from 0x07
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x87]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x10]
pymcuprog.serialupdi.application - DEBUG - Key status = 0x10
pymcuprog.serialupdi.application - INFO - Apply reset
pymcuprog.serialupdi.link - DEBUG - STCS to 0x08
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC8, 0x59]
pymcuprog.serialupdi.application - INFO - Release reset
pymcuprog.serialupdi.link - DEBUG - STCS to 0x08
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC8, 0x00]
pymcuprog.serialupdi.link - DEBUG - LDCS from 0x0B
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x8B]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x38]
pymcuprog.serialupdi.link - DEBUG - LDCS from 0x0B
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x8B]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x08]
pymcuprog.serialupdi.application - DEBUG - Now in NVM programming mode
Pinging device...
pymcuprog.programmer - INFO - Reading device ID...
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xE6]
pymcuprog.serialupdi.application - INFO - SIB: 'AVR     P:2D:1-3M2 (A3.KV00K.0)'
pymcuprog.serialupdi.application - INFO - Device family ID: 'AVR'
pymcuprog.serialupdi.application - INFO - NVM interface: 'P:2'
pymcuprog.serialupdi.application - INFO - Debug interface: 'D:1'
pymcuprog.serialupdi.application - INFO - PDI oscillator: '3M2'
pymcuprog.serialupdi.application - INFO - Extra info: '(A3.KV00K.0)'
pymcuprog.serialupdi.application - INFO - NVM type 2: 24-bit, word oriented write
pymcuprog.serialupdi.link - DEBUG - STCS to 0x03
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC3, 0x08]
pymcuprog.serialupdi.link - DEBUG - STCS to 0x02
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC2, 0x80]
pymcuprog.serialupdi.link - DEBUG - LDCS from 0x00
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x80]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x30]
pymcuprog.serialupdi.link - INFO - UPDI init OK
pymcuprog.serialupdi.link - DEBUG - LDCS from 0x00
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x80]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x30]
pymcuprog.serialupdi.application - INFO - PDI revision = 0x03
pymcuprog.serialupdi.link - DEBUG - LDCS from 0x0B
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x8B]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x08]
pymcuprog.serialupdi.readwrite - DEBUG - Reading 3 bytes from 0x1100
pymcuprog.serialupdi.link - INFO - ST to ptr
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x6A, 0x00, 0x11, 0x00]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x40]
pymcuprog.serialupdi.link - DEBUG - Repeat 3
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xA0, 0x02]
pymcuprog.serialupdi.link - DEBUG - LD8 from ptr++
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x24]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x1E, 0x96, 0x1A]
pymcuprog.serialupdi.readwrite - DEBUG - Reading 1 bytes from 0x0F01
pymcuprog.serialupdi.link - INFO - ST to ptr
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x6A, 0x01, 0x0F, 0x00]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x40]
pymcuprog.serialupdi.link - DEBUG - LD8 from ptr++
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x24]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x13]
pymcuprog.serialupdi.application - INFO - Device ID from serialupdi = '1E961A' rev 'T'
pymcuprog.nvm - INFO - Device family: 'AVR'
pymcuprog.serialupdi.readwrite - DEBUG - Reading 3 bytes from 0x1100
pymcuprog.serialupdi.link - INFO - ST to ptr
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x6A, 0x00, 0x11, 0x00]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x40]
pymcuprog.serialupdi.link - DEBUG - Repeat 3
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xA0, 0x02]
pymcuprog.serialupdi.link - DEBUG - LD8 from ptr++
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x24]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x1E, 0x96, 0x1A]
pymcuprog.nvm - INFO - Device ID: '1E961A'
pymcuprog.serialupdi.readwrite - DEBUG - Reading 1 bytes from 0x0F01
pymcuprog.serialupdi.link - INFO - ST to ptr
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x6A, 0x01, 0x0F, 0x00]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x40]
pymcuprog.serialupdi.link - DEBUG - LD8 from ptr++
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x24]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x13]
pymcuprog.nvm - DEBUG - Device revision: 0x13
pymcuprog.nvm - INFO - Device revision: '1.3'
pymcuprog.serialupdi.readwrite - DEBUG - Reading 10 bytes from 0x1103
pymcuprog.serialupdi.link - INFO - ST to ptr
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x6A, 0x03, 0x11, 0x00]
pymcuprog.serialupdi.physical - DEBUG - receive : [0x40]
pymcuprog.serialupdi.link - DEBUG - Repeat 10
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xA0, 0x09]
pymcuprog.serialupdi.link - DEBUG - LD8 from ptr++
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x24]
pymcuprog.serialupdi.physical - DEBUG - receive : [0xFF, 0x7E, 0x03, 0xA4, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
pymcuprog.nvm - INFO - Device serial number: 'b'ff7e03a40dffffffffff''
Ping response: 1E961A
pymcuprog.serialupdi.application - INFO - Leaving NVM programming mode
pymcuprog.serialupdi.application - INFO - Apply reset
pymcuprog.serialupdi.link - DEBUG - STCS to 0x08
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC8, 0x59]
pymcuprog.serialupdi.application - INFO - Release reset
pymcuprog.serialupdi.link - DEBUG - STCS to 0x08
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC8, 0x00]
pymcuprog.serialupdi.link - DEBUG - STCS to 0x03
pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC3, 0x0C]
Done.
pymcuprog.serialupdi.physical - INFO - Closing port 'com11'
xedbg commented 10 months ago

As far as I recall, the original pymcuprog implementation for the "break" signal was to change baud rate to 300 and transmit

This is correct. serialupdi in pymcuprog is tested using the nano's cdc, and BREAK support in the nano's cdc was only implemented quite recently, to the 300baud workaround was used. Edit: and I think the lower-bound for the nano's cdc was reduced to support this...

dbuchwald commented 10 months ago

BTW, pymcuprog does work.

I'm not entirely sure what libraries for serial communication are used by MinGW build of AVRDUDE, but it's actually possible that there is some difference compared to Python interpreter build, and this might explain why it behaves differently (as in: works with higher baud rate, because this is the discrepancy we are looking at, right?).

askn37 commented 10 months ago

@stefanrueger

@askn37 Is there a good place in serialupdi_initialize() to put an usleep() to solve this problem and how long for? Also, I wonder whether some OS open() calls twiddle RTS while other OS don't touch RTS when opening a serial connection.

I discovered this problem in a prototype circuit using a CH340X (board on the right in the photo above). This is very special and can be targeted to UPDI_AVR, ATSAM, ESP32, or STM32 by toggling a jumper. Except for AVR, DTR and RTS are independent and independently control his BOOT and RESET pins on ARM chips etc.

However, AVR (using the "-xrtsdtr" option) does not differentiate between DTR and RTS. Both can be HIGH or LOW at the same time. Therefore, use a capacitor to control the AVR's RESET LOW for a few milliseconds to tens of seconds after DTR/RTS goes HIGH. If "-c arduino" knows that on startup he will generate a 100ms HIGH pulse to DTR/RTS, otherwise he will generate a LOW level, this is usually , I understand that it is a ritual to start the bootloader. ('-c arduino' starts after another 100ms)

In this interesting circuit, the problem was that the reset pulse was not completed when SerialUPDI started. So I tried adding a delay at the end of "updi_set_rtsdtr_mode" and it started working correctly. I needed at least 95ms, so depending on individual differences you may want 150ms. However, this is limited to this circuit.

static void updi_set_rtsdtr_mode(const PROGRAMMER *pgm) {
  updi_rts_mode rts_mode = updi_get_rts_mode(pgm);

  if (rts_mode == RTS_MODE_DEFAULT) {
    return;
  }

  serial_set_dtr_rts(&pgm->fd, 0);
  serial_set_dtr_rts(&pgm->fd, rts_mode == RTS_MODE_LOW ? 1 : 0);

  /* TEST : startup UART circuit delay */
  usleep(150 * 1000);
}

FTDI typically has both DTR and RTS. However, CH340N and CH340E are RTS only. These allow you to reset the AVR or use only RTS if you want to switch to UART passthrough. On the other hand, ESP32 and STM32 circuits have a habit of using DTR for boot control and RTS for reset. This circuit is made accordingly.

mcuee commented 10 months ago

BTW, pymcuprog does work.

I'm not entirely sure what libraries for serial communication are used by MinGW build of AVRDUDE, but it's actually possible that there is some difference compared to Python interpreter build, and this might explain why it behaves differently (as in: works with higher baud rate, because this is the discrepancy we are looking at, right?).

MinGW build of avrdude should use the same native Windows serial API as MSVC build. Here we should ignore the libserialport stuff in git main which is only available in MinGW build since avrdude 7.2 release does not have libserialport). However, I think there are some code path differences (ifdefs) between MinGW build and MSVC build. Just an example of different code paths -- I am not saying the following causing this issue though.

BTW, I just checked pymcuprog under MSYS2 mingw64 Python and it works fine there. Previous Python environment is MSVC build of Python. But I am not so sure if this findings help at all or not. And pymcuprog uses pyserial, which may behave a bit different from the native Windows serial API used by avrdude, even though pyserial is based on native Windows API. https://github.com/microchip-pic-avr-tools/pymcuprog/blob/main/requirements.txt https://github.com/pyserial/pyserial/blob/master/serial/win32.py

All in all, I think we have a timing issue somewhere due to platform specifc codes for MinGW.

pymcuprog under MSYS2 mingw6 Python ``` MINGW64 /c/work/avr/avrdude_test/avrdude_main $ pip install pymcuprog Collecting pymcuprog Using cached pymcuprog-3.14.2.9-py3-none-any.whl (241 kB) Requirement already satisfied: pyserial in c:/msys64/mingw64/lib/python3.10/site-packages (from pymcuprog) (3.5) Collecting intelhex (from pymcuprog) Using cached intelhex-2.3.0-py2.py3-none-any.whl (50 kB) Collecting appdirs (from pymcuprog) Using cached appdirs-1.4.4-py2.py3-none-any.whl (9.6 kB) Collecting pyyaml (from pymcuprog) Downloading PyYAML-6.0.1.tar.gz (125 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 125.2/125.2 kB 1.9 MB/s eta 0:00:00 Installing build dependencies ... done Getting requirements to build wheel ... done Preparing metadata (pyproject.toml) ... done Collecting pyedbglib>=2.20 (from pymcuprog) Downloading pyedbglib-2.23.0.14-py3-none-any.whl (76 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 76.4/76.4 kB 4.4 MB/s eta 0:00:00 Requirement already satisfied: cython in c:/msys64/mingw64/lib/python3.10/site-packages (from pyedbglib>=2.20->pymcuprog) (0.29.33) Requirement already satisfied: hidapi in c:/msys64/mingw64/lib/python3.10/site-packages (from pyedbglib>=2.20->pymcuprog) (0.13.1) Requirement already satisfied: setuptools>=19.0 in c:/msys64/mingw64/lib/python3.10/site-packages (from hidapi->pyedbglib>=2.20->pymcuprog) (67.8.0) Building wheels for collected packages: pyyaml Building wheel for pyyaml (pyproject.toml) ... done Created wheel for pyyaml: filename=PyYAML-6.0.1-cp310-cp310-mingw_x86_64.whl size=45380 sha256=40dd8382e15ba9daf513fa718c50689d871ccac86186f5ba83dc2055f287e0e9 Stored in directory: c:/users/xiaof/appdata/local/pip/cache/wheels/31/d1/78/088142cfc0422adcca7bb0af40ef696b55b777a44f2e10739c Successfully built pyyaml Installing collected packages: intelhex, appdirs, pyyaml, pyedbglib, pymcuprog Successfully installed appdirs-1.4.4 intelhex-2.3.0 pyedbglib-2.23.0.14 pymcuprog-3.14.2.9 pyyaml-6.0.1 $ pymcuprog ping -d avr64dd32 -t uart -u com11 -v debug Connecting to SerialUPDI pymcuprog.programmer - INFO - Setting up programming session for 'avr64dd32' pymcuprog.deviceinfo.deviceinfo - INFO - Looking for device avr64dd32 pymcuprog.serialupdi.physical - INFO - Opening port 'com11' at 115200 baud (timeout 1.0s) pymcuprog.serialupdi.physical - DEBUG - send : [0x00] pymcuprog.serialupdi.link - DEBUG - STCS to 0x03 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC3, 0x08] pymcuprog.serialupdi.link - DEBUG - STCS to 0x02 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC2, 0x80] pymcuprog.serialupdi.link - DEBUG - LDCS from 0x00 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x80] pymcuprog.serialupdi.physical - DEBUG - receive : [0x30] pymcuprog.serialupdi.link - INFO - UPDI init OK pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xE6] pymcuprog.serialupdi.application - INFO - SIB: 'AVR P:2D:1-3M2 (A3.KV00K.0)' pymcuprog.serialupdi.application - INFO - Device family ID: 'AVR' pymcuprog.serialupdi.application - INFO - NVM interface: 'P:2' pymcuprog.serialupdi.application - INFO - Debug interface: 'D:1' pymcuprog.serialupdi.application - INFO - PDI oscillator: '3M2' pymcuprog.serialupdi.application - INFO - Extra info: '(A3.KV00K.0)' pymcuprog.serialupdi.application - INFO - NVM type 2: 24-bit, word oriented write pymcuprog.serialupdi.link - DEBUG - STCS to 0x03 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC3, 0x08] pymcuprog.serialupdi.link - DEBUG - STCS to 0x02 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC2, 0x80] pymcuprog.serialupdi.link - DEBUG - LDCS from 0x00 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x80] pymcuprog.serialupdi.physical - DEBUG - receive : [0x30] pymcuprog.serialupdi.link - INFO - UPDI init OK pymcuprog.serialupdi.link - DEBUG - LDCS from 0x00 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x80] pymcuprog.serialupdi.physical - DEBUG - receive : [0x30] pymcuprog.serialupdi.application - INFO - PDI revision = 0x03 pymcuprog.serialupdi.link - DEBUG - LDCS from 0x0B pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x8B] pymcuprog.serialupdi.physical - DEBUG - receive : [0x92] pymcuprog.serialupdi.link - DEBUG - LDCS from 0x0B pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x8B] pymcuprog.serialupdi.physical - DEBUG - receive : [0x92] pymcuprog.serialupdi.application - INFO - Entering NVM programming mode pymcuprog.serialupdi.link - DEBUG - Writing key pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xE0] pymcuprog.serialupdi.physical - DEBUG - send : [0x20, 0x67, 0x6F, 0x72, 0x50, 0x4D, 0x56, 0x4E] pymcuprog.serialupdi.link - DEBUG - LDCS from 0x07 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x87] pymcuprog.serialupdi.physical - DEBUG - receive : [0x10] pymcuprog.serialupdi.application - DEBUG - Key status = 0x10 pymcuprog.serialupdi.application - INFO - Apply reset pymcuprog.serialupdi.link - DEBUG - STCS to 0x08 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC8, 0x59] pymcuprog.serialupdi.application - INFO - Release reset pymcuprog.serialupdi.link - DEBUG - STCS to 0x08 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC8, 0x00] pymcuprog.serialupdi.link - DEBUG - LDCS from 0x0B pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x8B] pymcuprog.serialupdi.physical - DEBUG - receive : [0x38] pymcuprog.serialupdi.link - DEBUG - LDCS from 0x0B pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x8B] pymcuprog.serialupdi.physical - DEBUG - receive : [0x08] pymcuprog.serialupdi.application - DEBUG - Now in NVM programming mode Pinging device... pymcuprog.programmer - INFO - Reading device ID... pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xE6] pymcuprog.serialupdi.application - INFO - SIB: 'AVR P:2D:1-3M2 (A3.KV00K.0)' pymcuprog.serialupdi.application - INFO - Device family ID: 'AVR' pymcuprog.serialupdi.application - INFO - NVM interface: 'P:2' pymcuprog.serialupdi.application - INFO - Debug interface: 'D:1' pymcuprog.serialupdi.application - INFO - PDI oscillator: '3M2' pymcuprog.serialupdi.application - INFO - Extra info: '(A3.KV00K.0)' pymcuprog.serialupdi.application - INFO - NVM type 2: 24-bit, word oriented write pymcuprog.serialupdi.link - DEBUG - STCS to 0x03 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC3, 0x08] pymcuprog.serialupdi.link - DEBUG - STCS to 0x02 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC2, 0x80] pymcuprog.serialupdi.link - DEBUG - LDCS from 0x00 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x80] pymcuprog.serialupdi.physical - DEBUG - receive : [0x30] pymcuprog.serialupdi.link - INFO - UPDI init OK pymcuprog.serialupdi.link - DEBUG - LDCS from 0x00 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x80] pymcuprog.serialupdi.physical - DEBUG - receive : [0x30] pymcuprog.serialupdi.application - INFO - PDI revision = 0x03 pymcuprog.serialupdi.link - DEBUG - LDCS from 0x0B pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x8B] pymcuprog.serialupdi.physical - DEBUG - receive : [0x08] pymcuprog.serialupdi.readwrite - DEBUG - Reading 3 bytes from 0x1100 pymcuprog.serialupdi.link - INFO - ST to ptr pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x6A, 0x00, 0x11, 0x00] pymcuprog.serialupdi.physical - DEBUG - receive : [0x40] pymcuprog.serialupdi.link - DEBUG - Repeat 3 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xA0, 0x02] pymcuprog.serialupdi.link - DEBUG - LD8 from ptr++ pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x24] pymcuprog.serialupdi.physical - DEBUG - receive : [0x1E, 0x96, 0x1A] pymcuprog.serialupdi.readwrite - DEBUG - Reading 1 bytes from 0x0F01 pymcuprog.serialupdi.link - INFO - ST to ptr pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x6A, 0x01, 0x0F, 0x00] pymcuprog.serialupdi.physical - DEBUG - receive : [0x40] pymcuprog.serialupdi.link - DEBUG - LD8 from ptr++ pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x24] pymcuprog.serialupdi.physical - DEBUG - receive : [0x13] pymcuprog.serialupdi.application - INFO - Device ID from serialupdi = '1E961A' rev 'T' pymcuprog.nvm - INFO - Device family: 'AVR' pymcuprog.serialupdi.readwrite - DEBUG - Reading 3 bytes from 0x1100 pymcuprog.serialupdi.link - INFO - ST to ptr pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x6A, 0x00, 0x11, 0x00] pymcuprog.serialupdi.physical - DEBUG - receive : [0x40] pymcuprog.serialupdi.link - DEBUG - Repeat 3 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xA0, 0x02] pymcuprog.serialupdi.link - DEBUG - LD8 from ptr++ pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x24] pymcuprog.serialupdi.physical - DEBUG - receive : [0x1E, 0x96, 0x1A] pymcuprog.nvm - INFO - Device ID: '1E961A' pymcuprog.serialupdi.readwrite - DEBUG - Reading 1 bytes from 0x0F01 pymcuprog.serialupdi.link - INFO - ST to ptr pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x6A, 0x01, 0x0F, 0x00] pymcuprog.serialupdi.physical - DEBUG - receive : [0x40] pymcuprog.serialupdi.link - DEBUG - LD8 from ptr++ pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x24] pymcuprog.serialupdi.physical - DEBUG - receive : [0x13] pymcuprog.nvm - DEBUG - Device revision: 0x13 pymcuprog.nvm - INFO - Device revision: '1.3' pymcuprog.serialupdi.readwrite - DEBUG - Reading 10 bytes from 0x1103 pymcuprog.serialupdi.link - INFO - ST to ptr pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x6A, 0x03, 0x11, 0x00] pymcuprog.serialupdi.physical - DEBUG - receive : [0x40] pymcuprog.serialupdi.link - DEBUG - Repeat 10 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xA0, 0x09] pymcuprog.serialupdi.link - DEBUG - LD8 from ptr++ pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0x24] pymcuprog.serialupdi.physical - DEBUG - receive : [0xFF, 0x7E, 0x03, 0xA4, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] pymcuprog.nvm - INFO - Device serial number: 'b'ff7e03a40dffffffffff'' Ping response: 1E961A pymcuprog.serialupdi.application - INFO - Leaving NVM programming mode pymcuprog.serialupdi.application - INFO - Apply reset pymcuprog.serialupdi.link - DEBUG - STCS to 0x08 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC8, 0x59] pymcuprog.serialupdi.application - INFO - Release reset pymcuprog.serialupdi.link - DEBUG - STCS to 0x08 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC8, 0x00] pymcuprog.serialupdi.link - DEBUG - STCS to 0x03 pymcuprog.serialupdi.physical - DEBUG - send : [0x55, 0xC3, 0x0C] Done. pymcuprog.serialupdi.physical - INFO - Closing port 'com11' ```
mcuee commented 10 months ago

FTDI typically has both DTR and RTS. However, CH340N and CH340E are RTS only. These allow you to reset the AVR or use only RTS if you want to switch to UART passthrough.

This is a bit tricky to deal with as different design may use different lines. I did some research earlier this year as well.

BTW, I have looked into the cheap USB-TTL converters sold in Taobao/AliExpress, using CH340x series, FT232BL/RL series, CP2102 and PL2303 series. There are others like CH341x, CP2104, FT232H/FT2232H/FT4232H, etc.

1) Quite some of them do not have any other signal pins other than TXD/RXD. Then they may have 5V or 3V3 or both, then GND.

2) Some of them have DTR pin

3) Some of them have RTS/CTS pins, usually come in a pair

4) Some FT232 based adapter may have more pins available, including one with the 6-pin AVRISP connectors and DTR/CTS.

stefanrueger commented 10 months ago

@askn37 Impressive hardware

combination of RTS and capacitors to perform a hard reset

Is this a standard reset circuit similar to the recommended AVR reset circuit?

If so then I recommend the following lines to carry out a reset:

  // This code assumes a negative-logic USB to TTL serial adapter
  // Set RTS/DTR high to discharge the series-capacitor, if present
  serial_set_dtr_rts(&pgm->fd, 0);
  usleep(20*1000);
  // Pull the RTS/DTR line low to reset AVR
  serial_set_dtr_rts(&pgm->fd, 1);
  // Max 100 us: charging a cap longer creates a high reset spike above Vcc
  usleep(100);
  // Set the RTS/DTR line back to high, so direct connection to reset works
  serial_set_dtr_rts(&pgm->fd, 0);

  if((120+xdelay) > 0)
    usleep((120+xdelay)*1000); // Wait until board comes out of reset

Here xdelay is a parameter for additional sleep [ms] after reset that can be set by the user with -xdelay=...; it can be negative. This code works when RTS is directly connected to RESET or when RTS is decoupled via an in-line capacitor from RESET.

Above approach is different to the current lines https://github.com/avrdudes/avrdude/blob/d6c61f5fab4d0d061fb85233acee6ecaa85dd9c0/src/updi_link.c#L49-L50

I get the impression that updi_set_rtsdtr_mode() is meant for communication via DTR and for reset via RTS. If this is the case, I think we should separate rts and dtr handling into two functions serial_set_rts() and serial_set_dtr() to manage the signals independently. We should have some code similar to above for explicitly resetting the board and deploy a typical wait of 120 ms (user changable) after reset. Even we do not give explicit reset to the board, we should be aware that the OS open() statement can twiddle RTS and thus create a reset if we want this or not. So there should always be a sleep after open()/explicit reset.

And yes, @dbuchwald, you are absolutely right about being careful about changes we do...

mcuee commented 10 months ago

Haha, looks like we are talking multiple issues here with serialupdi. 1) NVM v3 for AVR EA and EB bug-- fixed by PR #1531 2) General sleep issue with moder UPDI parts (at least AVR DA/DB/DD and EA/EB) -- seems to be fixed as well, even though there is a warning as per @askn37 under his macOS testing 3) Sleep issue specific to MinGW build under Windows with AVR DD (and maybe others) -- this shows some sort of timing issues at higher baud rate like 115200 and (57600 is okay). 4) DTR/RTS reset handling

mcuee commented 10 months ago

@stefanrueger

Just want to mention that I tried your reset patch and it does not help. I tried different xdelay value of -50, 0, 100 and 1000 and they do not help.

I believe for my testing the reset code does not matter since I only use three pins (Vcc, GND and UPDI) pins to connect a CH340 based serialupdi programmer to the target.

PS>git diff
diff --git a/src/updi_link.c b/src/updi_link.c
index dba4a67e..80054e61 100644
--- a/src/updi_link.c
+++ b/src/updi_link.c
@@ -42,12 +42,25 @@
 static void updi_set_rtsdtr_mode(const PROGRAMMER *pgm) {
   updi_rts_mode rts_mode = updi_get_rts_mode(pgm);

+  int xdelay=100;
+
   if (rts_mode == RTS_MODE_DEFAULT) {
     return;
   }

+  // This code assumes a negative-logic USB to TTL serial adapter
+  // Set RTS/DTR high to discharge the series-capacitor, if present
+  serial_set_dtr_rts(&pgm->fd, 0);
+  usleep(20*1000);
+  // Pull the RTS/DTR line low to reset AVR
+  serial_set_dtr_rts(&pgm->fd, 1);
+  // Max 100 us: charging a cap longer creates a high reset spike above Vcc
+  usleep(100);
+  // Set the RTS/DTR line back to high, so direct connection to reset works
   serial_set_dtr_rts(&pgm->fd, 0);
-  serial_set_dtr_rts(&pgm->fd, rts_mode == RTS_MODE_LOW ? 1 : 0);
+
+  if((120+xdelay) > 0)
+    usleep((120+xdelay)*1000); // Wait until board comes out of reset
 }

 static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflags)
mcuee commented 10 months ago

One of the better designed serialupdi programmer comes from @MCUdude, which has dual functionality -- UPDI or Serial UART mode (and can be used in Auto mode which automatically switch between the two modes). https://www.tindie.com/products/mcudude/serialupdi-programmer/

Schemaics: https://d3s5r33r268y59.cloudfront.net/datasheets/27214/2022-06-28-07-47-24/SerialUPDI_R1_Schematic.pdf

You can see that it has only RTS pin and no DTR pin. And if the RTS pin is not connected, UPDI programming will still work.

Simple UPDI programmers will only have three pins -- VCC, GND and UPDI pin. https://github.com/SpenceKonde/AVR-Guidance/blob/master/UPDI/jtag2updi.md

askn37 commented 10 months ago

@mcuee At first, I didn't expect it to become such a wide-ranging discussion! It might be better to close this and separate it into another topic.

@stefanrueger

This is the schematic for the CH340X prototype board. The CH340X is an improved version of the CH340E and also includes the features of the CH340K. CH340K had problems in the past due to VID differences, but CH340X has high compatibility. By adding additional resistors to TNOW, DTR can be extended in two ways during POR.

2318_UARTLGC.pdf

The latest hardware design guide for modernAVR can be found in their respective datasheets. UPDI and RESET have built-in 30kΩ pull-ups that activate on POR, unlike older AVRs. Therefore, only a stabilizing capacitor is required externally. If you add a reset switch, also add a filter resistor.

SS 2023-10-28 8 42 37

His RESET prototype board for AVR follows the latest design guidelines. The difference is that instead of being connected to GND, it is connected to his RTS, which is Low by default. Therefore, the stabilization capacitor is charged by the internal pull-up. When the RTS changes, it discharges with opposite polarity and the potential drops for a short time. It will stay below 0.2VDD until RESET is charged again.

Old AVR design guides recommended a 10kΩ RESET pullup. The reason this is no longer mentioned is probably because the internal high frequency RC oscillator is slow and you want to have enough time for POR. Additionally, the UPDI circuit (sub-CPU) operates using a dedicated internal RC oscillator that is separate from the main clock. In the worst case, it may boot slower than the main CPU. To avoid this (preventing abnormalities due to inrush current), FUSE has a startup timer setting. The adjustment range is up to 64ms, so it is best to keep this delay phenomenon in mind.

mcuee commented 10 months ago

@mcuee At first, I didn't expect it to become such a wide-ranging discussion! It might be better to close this and separate it into another topic.

No issues, It is probably my fault. :-)

I think we can continue here as the topics are all related to serialupdi.

mcuee commented 10 months ago

I tried to debug the MinGW 115200bps issue and adding usleep here and there does not help.

I think the issue is that ir can not communicate at 115200 bps at all, at least initially with the MinGW build. Adding usleep will not help.

PS>git diff
diff --git a/src/serialupdi.c b/src/serialupdi.c
index f93eb5de..7e34709d 100644
--- a/src/serialupdi.c
+++ b/src/serialupdi.c
@@ -566,7 +566,7 @@ static int serialupdi_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
   uint8_t reset_link_required=0;

   if (updi_link_init(pgm) < 0) {
-    pmsg_error("UPDI link initialization failed\n");
+    pmsg_error("UPDI link initialization failed main\n");
     return -1;
   }
   pmsg_notice2("UPDI link initialization OK\n");
diff --git a/src/updi_link.c b/src/updi_link.c
index dba4a67e..18a92108 100644
--- a/src/updi_link.c
+++ b/src/updi_link.c
@@ -42,12 +42,25 @@
 static void updi_set_rtsdtr_mode(const PROGRAMMER *pgm) {
   updi_rts_mode rts_mode = updi_get_rts_mode(pgm);

+  int xdelay=-50;
+
   if (rts_mode == RTS_MODE_DEFAULT) {
     return;
   }

+  // This code assumes a negative-logic USB to TTL serial adapter
+  // Set RTS/DTR high to discharge the series-capacitor, if present
+  serial_set_dtr_rts(&pgm->fd, 0);
+  usleep(20*1000);
+  // Pull the RTS/DTR line low to reset AVR
+  serial_set_dtr_rts(&pgm->fd, 1);
+  // Max 100 us: charging a cap longer creates a high reset spike above Vcc
+  usleep(100);
+  // Set the RTS/DTR line back to high, so direct connection to reset works
   serial_set_dtr_rts(&pgm->fd, 0);
-  serial_set_dtr_rts(&pgm->fd, rts_mode == RTS_MODE_LOW ? 1 : 0);
+
+  if((120+xdelay) > 0)
+    usleep((120+xdelay)*1000); // Wait until board comes out of reset
 }

 static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflags)
@@ -213,12 +226,16 @@ static int updi_link_init_session_parameters(const PROGRAMMER *pgm)  {
         self.stcs(constants.UPDI_CS_CTRLB, 1 << constants.UPDI_CTRLB_CCDETDIS_BIT)
         self.stcs(constants.UPDI_CS_CTRLA, 1 << constants.UPDI_CTRLA_IBDLY_BIT)
 */
+  usleep(100);
   if (updi_link_stcs(pgm, UPDI_CS_CTRLB, 1 << UPDI_CTRLB_CCDETDIS_BIT) < 0) {
-    return -1;
+    pmsg_debug("session orameters initialisation failed B\n");
+       return -1;
   }
-
+
+  usleep(100);
   if (updi_link_stcs(pgm, UPDI_CS_CTRLA, 1 << UPDI_CTRLA_IBDLY_BIT) < 0) {
-    return -1;
+    pmsg_debug("session orameters initialisation failed A\n");
+       return -1;
   }

   return 0;
@@ -274,25 +291,30 @@ int updi_link_init(const PROGRAMMER *pgm) {
                 raise PymcuprogError("UPDI initialisation failed")
 */
   if (updi_link_init_session_parameters(pgm) < 0) {
-    pmsg_debug("session initialisation failed\n");
+    pmsg_debug("session initialisation failed 1\n");
     return -1;
   }
+
+  usleep(100);

   if (updi_link_check(pgm) < 0) {
     pmsg_debug("datalink not active, resetting ...\n");
     if (updi_physical_send_double_break(pgm) < 0) {
-      pmsg_debug("datalink initialisation failed\n");
+      pmsg_debug("datalink initialisation failed 2\n");
       return -1;
     }
+       usleep(100);
     if (updi_link_init_session_parameters(pgm) < 0) {
-      pmsg_debug("session initialisation failed\n");
+      pmsg_debug("session initialisation failed 3\n");
       return -1;
     }
+       usleep(100);
     if (updi_link_check(pgm) < 0) {
-      pmsg_debug("restoring datalink failed\n");
+      pmsg_debug("restoring datalink failed 4\n");
       return -1;
     }
   }
+
   return 0;
 }

PS>cd ..\avrdude_bin
PS>.\avrdude_mod -C .\avrdude_pr1538.conf -c serialupdi -P COM11 -p avr64dd32 -vvvv

avrdude_mod: Version 7.2-20231024 (d6c61f5f)
             Copyright the AVRDUDE authors;
             see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

             System wide configuration file is C:\work\avr\avrdude_test\avrdude_bin\avrdude_pr1538.conf

             Using Port                    : COM11
             Using Programmer              : serialupdi
avrdude_mod: opening serial port ...
avrdude_mod: sending 1 bytes [0x00]
avrdude_mod: send: . [00]
avrdude_mod: recv: . [00]
             AVR Part                      : AVR64DD32
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             Serial program mode           : yes
             Parallel program mode         : yes
 ...
avrdude_mod: STCS 0x08 to address 0x03
avrdude_mod: sending 3 bytes [0x55, 0xc3, 0x08]
avrdude_mod: send: U [55] . [c3] . [08]
avrdude_mod: ser_recv(): programmer is not responding
avrdude_mod: STCS 0x80 to address 0x02
avrdude_mod: sending 3 bytes [0x55, 0xc2, 0x80]
avrdude_mod: send: U [55] . [c2] . [80]
avrdude_mod: ser_recv(): programmer is not responding
avrdude_mod: LDCS from 0x00
avrdude_mod: sending 2 bytes [0x55, 0x80]
avrdude_mod: send: U [55] . [80]
avrdude_mod: ser_recv(): programmer is not responding
avrdude_mod: ser_recv(): programmer is not responding
avrdude_mod: serialupdi_recv(): programmer is not responding
avrdude_mod: check failed
avrdude_mod: datalink not active, resetting ...
avrdude_mod: sending double break
avrdude_mod: send: . [00]
avrdude_mod: recv: . [00]
avrdude_mod: send: . [00]
avrdude_mod: recv: . [00]
avrdude_mod: STCS 0x08 to address 0x03
avrdude_mod: sending 3 bytes [0x55, 0xc3, 0x08]
avrdude_mod: send: U [55] . [c3] . [08]
avrdude_mod: ser_recv(): programmer is not responding
avrdude_mod: STCS 0x80 to address 0x02
avrdude_mod: sending 3 bytes [0x55, 0xc2, 0x80]
avrdude_mod: send: U [55] . [c2] . [80]
avrdude_mod: ser_recv(): programmer is not responding
avrdude_mod: LDCS from 0x00
avrdude_mod: sending 2 bytes [0x55, 0x80]
avrdude_mod: send: U [55] . [80]
avrdude_mod: ser_recv(): programmer is not responding
avrdude_mod: ser_recv(): programmer is not responding
avrdude_mod: serialupdi_recv(): programmer is not responding
avrdude_mod: check failed
avrdude_mod: restoring datalink failed 4
avrdude_mod serialupdi_initialize() [serialupdi.c:569] error: UPDI link initialization failed main
avrdude_mod main() [main.c:1399] error: initialization failed, rc=-1
            - double check the connections and try again
            - use -b to set lower baud rate, e.g. -b 57600
            - use -F to override this check
avrdude_mod: leaving NVM programming mode
avrdude_mod: sending reset request
avrdude_mod: STCS 0x59 to address 0x08
avrdude_mod: sending 3 bytes [0x55, 0xc8, 0x59]
avrdude_mod: send: U [55] . [c8] Y [59]
avrdude_mod: ser_recv(): programmer is not responding
avrdude_mod: sending release reset request
avrdude_mod: STCS 0x00 to address 0x08
avrdude_mod: sending 3 bytes [0x55, 0xc8, 0x00]
avrdude_mod: send: U [55] . [c8] . [00]
avrdude_mod: ser_recv(): programmer is not responding
avrdude_mod: STCS 0x0C to address 0x03
avrdude_mod: sending 3 bytes [0x55, 0xc3, 0x0c]
avrdude_mod: send: U [55] . [c3] . [0c]
avrdude_mod: ser_recv(): programmer is not responding

avrdude_mod done.  Thank you.
mcuee commented 10 months ago

Even at baud rate of 57600 it failed initially but luckily it can recover.

...
...
avrdude_mod: STCS 0x08 to address 0x03
avrdude_mod: sending 3 bytes [0x55, 0xc3, 0x08]
avrdude_mod: send: U [55] . [c3] . [08]
avrdude_mod: recv: . [00] . [d8] . [f8]
avrdude_mod: STCS 0x80 to address 0x02
avrdude_mod: sending 3 bytes [0x55, 0xc2, 0x80]
avrdude_mod: send: U [55] . [c2] . [80]
avrdude_mod: recv: U [55] . [c2] . [80]
avrdude_mod: LDCS from 0x00
avrdude_mod: sending 2 bytes [0x55, 0x80]
avrdude_mod: send: U [55] . [80]
avrdude_mod: recv: U [55] . [80]
avrdude_mod: ser_recv(): programmer is not responding
avrdude_mod: serialupdi_recv(): programmer is not responding
avrdude_mod: check failed
avrdude_mod: datalink not active, resetting ...
avrdude_mod: sending double break
avrdude_mod: send: . [00]
avrdude_mod: recv: . [00]
avrdude_mod: send: . [00]
avrdude_mod: recv: . [00]
avrdude_mod: STCS 0x08 to address 0x03
avrdude_mod: sending 3 bytes [0x55, 0xc3, 0x08]
avrdude_mod: send: U [55] . [c3] . [08]
avrdude_mod: recv: U [55] . [c3] . [08]
avrdude_mod: STCS 0x80 to address 0x02
avrdude_mod: sending 3 bytes [0x55, 0xc2, 0x80]
avrdude_mod: send: U [55] . [c2] . [80]
avrdude_mod: recv: U [55] . [c2] . [80]
avrdude_mod: LDCS from 0x00
avrdude_mod: sending 2 bytes [0x55, 0x80]
avrdude_mod: send: U [55] . [80]
avrdude_mod: recv: U [55] . [80]
avrdude_mod: recv: 0 [30]
avrdude_mod: received 1 bytes [0x30]
avrdude_mod: UDPI init OK
avrdude_mod: UPDI link initialization OK
avrdude_mod: LDCS from 0x0B
avrdude_mod: sending 2 bytes [0x55, 0x8b]
avrdude_mod: send: U [55] . [8b]
avrdude_mod: recv: U [55] . [8b]
avrdude_mod: recv: . [92]
avrdude_mod: received 1 bytes [0x92]
avrdude_mod: device is in SLEEP mode
avrdude_mod: sending 2 bytes [0x55, 0xe6]
avrdude_mod: send: U [55] . [e6]
avrdude_mod: recv: U [55] . [e6]
avrdude_mod: recv: A [41] V [56] R [52]   [20]   [20]   [20]   [20]   [20] P [50] : [3a] 2 [32] D [44] : [3a] 1 [31] - [2d] 3 [33] M [4d] 2 [32]   [20] ( [28] A [41] 3 [33] . [2e] K [4b] V [56] 0 [30] 0 [30] K [4b] . [2e] 0 [30] ) [29] . [00]
avrdude_mod: received 32 bytes [0x41, 0x56, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x3a, 0x32, 0x44, 0x3a, 0x31, 0x2d, 0x33, 0x4d, 0x32, 0x20, 0x28, 0x41, 0x33, 0x2e, 0x4b, 0x56, 0x30, 0x30, 0x4b, 0x2e, 0x30, 0x29, 0x00]
avrdude_mod: received SIB: [AVR     P:2D:1-3M2 (A3.KV00K.0)]
avrdude_mod: Device family ID: AVR
avrdude_mod: NVM interface: P:2
avrdude_mod: Debug interface: D:1
avrdude_mod: PDI oscillator: 3M2
avrdude_mod: Extra information: (A3.KV00K.0)
avrdude_mod: NVM type 2: 24-bit, word oriented write
avrdude_mod: reading 1 bytes from 0x000F01
avrdude_mod: ST_PTR to 0x000F01
avrdude_mod: sending 5 bytes [0x55, 0x6a, 0x01, 0x0f, 0x00]
avrdude_mod: send: U [55] j [6a] . [01] . [0f] . [00]
avrdude_mod: recv: U [55] j [6a] . [01] . [0f] . [00]
avrdude_mod: recv: @ [40]
avrdude_mod: received 1 bytes [0x40]
avrdude_mod: LD8 from ptr++
avrdude_mod: sending 2 bytes [0x55, 0x24]
avrdude_mod: send: U [55] $ [24]
avrdude_mod: recv: U [55] $ [24]
avrdude_mod: recv: . [13]
avrdude_mod: received 1 bytes [0x13]
avrdude_mod: Received chip silicon revision 0x13
avrdude_mod: Chip silicon revision: 1.3
avrdude_mod: STCS 0x08 to address 0x03
avrdude_mod: sending 3 bytes [0x55, 0xc3, 0x08]
avrdude_mod: send: U [55] . [c3] . [08]
avrdude_mod: recv: U [55] . [c3] . [08]
avrdude_mod: STCS 0x80 to address 0x02
avrdude_mod: sending 3 bytes [0x55, 0xc2, 0x80]
avrdude_mod: send: U [55] . [c2] . [80]
avrdude_mod: recv: U [55] . [c2] . [80]
avrdude_mod: LDCS from 0x00
avrdude_mod: sending 2 bytes [0x55, 0x80]
avrdude_mod: send: U [55] . [80]
avrdude_mod: recv: U [55] . [80]
avrdude_mod: recv: 0 [30]
avrdude_mod: received 1 bytes [0x30]
avrdude_mod: UDPI init OK
avrdude_mod: entering NVM programming mode
avrdude_mod: LDCS from 0x0B
avrdude_mod: sending 2 bytes [0x55, 0x8b]
avrdude_mod: send: U [55] . [8b]
avrdude_mod: recv: U [55] . [8b]
avrdude_mod: recv: . [92]
avrdude_mod: received 1 bytes [0x92]
avrdude_mod: UPDI writing key
avrdude_mod: sending 2 bytes [0x55, 0xe0]
avrdude_mod: send: U [55] . [e0]
avrdude_mod: recv: U [55] . [e0]
avrdude_mod: sending 8 bytes [0x20, 0x67, 0x6f, 0x72, 0x50, 0x4d, 0x56, 0x4e]
avrdude_mod: send:   [20] g [67] o [6f] r [72] P [50] M [4d] V [56] N [4e]
avrdude_mod: recv:   [20] g [67] o [6f] r [72] P [50] M [4d] V [56] N [4e]
avrdude_mod: LDCS from 0x07
avrdude_mod: sending 2 bytes [0x55, 0x87]
avrdude_mod: send: U [55] . [87]
avrdude_mod: recv: U [55] . [87]
avrdude_mod: recv: . [10]
avrdude_mod: received 1 bytes [0x10]
avrdude_mod: key status: 0x10
avrdude_mod: sending reset request
avrdude_mod: STCS 0x59 to address 0x08
avrdude_mod: sending 3 bytes [0x55, 0xc8, 0x59]
avrdude_mod: send: U [55] . [c8] Y [59]
avrdude_mod: recv: U [55] . [c8] Y [59]
avrdude_mod: sending release reset request
avrdude_mod: STCS 0x00 to address 0x08
avrdude_mod: sending 3 bytes [0x55, 0xc8, 0x00]
avrdude_mod: send: U [55] . [c8] . [00]
avrdude_mod: recv: U [55] . [c8] . [00]
avrdude_mod: LDCS from 0x0B
avrdude_mod: sending 2 bytes [0x55, 0x8b]
avrdude_mod: send: U [55] . [8b]
avrdude_mod: recv: U [55] . [8b]
avrdude_mod: recv: 8 [38]
avrdude_mod: received 1 bytes [0x38]
avrdude_mod: LDCS from 0x0B
avrdude_mod: sending 2 bytes [0x55, 0x8b]
avrdude_mod: send: U [55] . [8b]
avrdude_mod: recv: U [55] . [8b]
avrdude_mod: recv: . [08]
avrdude_mod: received 1 bytes [0x08]
avrdude_mod: entered NVM programming mode
avrdude_mod: AVR device initialized and ready to accept instructions
Reading |                                                    | 0% 0.00 s
avrdude_mod: LDCS from 0x0B
avrdude_mod: sending 2 bytes [0x55, 0x8b]
avrdude_mod: send: U [55] . [8b]
avrdude_mod: recv: U [55] . [8b]
avrdude_mod: recv: . [08]
avrdude_mod: received 1 bytes [0x08]
avrdude_mod: LD from 0x001100
avrdude_mod: sending 5 bytes [0x55, 0x08, 0x00, 0x11, 0x00]
avrdude_mod: send: U [55] . [08] . [00] . [11] . [00]
avrdude_mod: recv: U [55] . [08] . [00] . [11] . [00]
avrdude_mod: recv: . [1e]
avrdude_mod: received 1 bytes [0x1e]
avrdude_mod: LD from 0x001101
avrdude_mod: sending 5 bytes [0x55, 0x08, 0x01, 0x11, 0x00]
avrdude_mod: send: U [55] . [08] . [01] . [11] . [00]
avrdude_mod: recv: U [55] . [08] . [01] . [11] . [00]
avrdude_mod: recv: . [96]
avrdude_mod: received 1 bytes [0x96]
avrdude_mod: LD from 0x001102
avrdude_mod: sending 5 bytes [0x55, 0x08, 0x02, 0x11, 0x00]
avrdude_mod: send: U [55] . [08] . [02] . [11] . [00]
avrdude_mod: recv: U [55] . [08] . [02] . [11] . [00]
avrdude_mod: recv: . [1a]
avrdude_mod: received 1 bytes [0x1a]
Reading | ################################################## | 100% 0.05 s
avrdude_mod: device signature = 0x1e961a (probably avr64dd32)
avrdude_mod: leaving NVM programming mode
avrdude_mod: sending reset request
avrdude_mod: STCS 0x59 to address 0x08
avrdude_mod: sending 3 bytes [0x55, 0xc8, 0x59]
avrdude_mod: send: U [55] . [c8] Y [59]
avrdude_mod: recv: U [55] . [c8] Y [59]
avrdude_mod: sending release reset request
avrdude_mod: STCS 0x00 to address 0x08
avrdude_mod: sending 3 bytes [0x55, 0xc8, 0x00]
avrdude_mod: send: U [55] . [c8] . [00]
avrdude_mod: recv: U [55] . [c8] . [00]
avrdude_mod: STCS 0x0C to address 0x03
avrdude_mod: sending 3 bytes [0x55, 0xc3, 0x0c]
avrdude_mod: send: U [55] . [c3] . [0c]
avrdude_mod: recv: U [55] . [c3] . [0c]

avrdude_mod done.  Thank you.
mcuee commented 10 months ago

As there is no issue with -c, I think I will just leave this paticular MinGW build issue for now.

WIthout -c, both the mingw64 binary and VS2022 x64 (MSVC64) binary of git main works until 230400 baud. I can check the LED blinking to see if the erase (LED OFF) or programming (LED blinking) is really working or not. And it is working.

PS>.\avrdude_git -c serialupdi -P COM41 -p avr64dd32 -b 230400 -e
avrdude_git: AVR device initialized and ready to accept instructions
avrdude_git: device signature = 0x1e961a (probably avr64dd32)
avrdude_git: erasing chip

avrdude_git done.  Thank you.

PS>.\avrdude_git -c serialupdi -P COM41 -p avr64dd32 -b 230400 -U .\sleep.hex
avrdude_git: AVR device initialized and ready to accept instructions
avrdude_git: device signature = 0x1e961a (probably avr64dd32)
avrdude_git: Note: flash memory has been specified, an erase cycle will be performed.
             To disable this feature, specify the -D option.
avrdude_git: erasing chip

avrdude_git: processing -U flash:w:.\sleep.hex:i
avrdude_git: reading input file .\sleep.hex for flash
             with 276 bytes in 1 section within [0, 0x113]
             using 1 page and 236 pad bytes
avrdude_git: writing 276 bytes flash ...
Writing | ################################################## | 100% 0.09 s
avrdude_git: 276 bytes of flash written
avrdude_git: verifying flash memory against .\sleep.hex
Reading | ################################################## | 100% 0.04 s
avrdude_git: 276 bytes of flash verified

avrdude_git done.  Thank you.

PS>.\avrdude_git -c serialupdi -P COM41 -p avr64dd32 -b 230400
avrdude_git: AVR device initialized and ready to accept instructions
avrdude_git: device signature = 0x1e961a (probably avr64dd32)

avrdude_git done.  Thank you.

As per the following documentation from @SpenceKonde, for DxCore, 57600bps works across different adapters. https://github.com/SpenceKonde/AVR-Guidance/blob/master/UPDI/jtag2updi.md

57600 baud maximizes compatibility with suboptimal adapters and/or wiring.

230400 baud is the "standard" speed for uploading, and is supported by all serial adapters I am aware of.

345600 baud (1.5x 230400) works out to be about the maximum baud rate for continuous writing, but not all serial adapters support it.

460800 baud for HT42B435 - this is a special workaround for the HT42B435

mcuee commented 10 months ago

As there is no issue with -c, I think I will just leave this paticular MinGW build issue for now.

Looks like this is very specific to MSYS2 mingw compiler. I just tested Arduino-packing build of avrdude 7.2 mingw32 release and my own git main build using cross-compiling, there are no issues with -v or -vvvv. So I think I will not debug further.

Arduino-packing official build of avrdude 7.2 release https://github.com/arduino/avrdude-packing/releases/tag/7.2-arduino.1

My own git main build https://github.com/mcuee/avrdude-packing/releases/tag/snapshot_2023-10-24

PS>.\avrdude_git_arduino -c serialupdi -P COM41 -p avr64dd32 -b 230400 -vvvv

avrdude_git_arduino: Version 7.2-20231024 (d6c61f5)
                     Copyright the AVRDUDE authors;
                     see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

                     System wide configuration file is C:\work\avr\avrdude_test\avrdude_bin\avrdude.conf

                     Using Port                    : COM41
                     Using Programmer              : serialupdi
                     Overriding Baud Rate          : 230400
avrdude_git_arduino: opening serial port ...
avrdude_git_arduino: serial_baud_lookup(): using non-standard baud rate: 230400
avrdude_git_arduino: sending 1 bytes [0x00]
avrdude_git_arduino: send: . [00]
avrdude_git_arduino: recv: . [00]
                     AVR Part                      : AVR64DD32
                     RESET disposition             : dedicated
                     RETRY pulse                   : SCK
                     Serial program mode           : yes
                     Parallel program mode         : yes
                     Memory Detail                 :
...
                     Programmer Type : serialupdi
                     Description     : SerialUPDI
avrdude_git_arduino: STCS 0x08 to address 0x03
avrdude_git_arduino: sending 3 bytes [0x55, 0xc3, 0x08]
avrdude_git_arduino: send: U [55] . [c3] . [08]
avrdude_git_arduino: recv: U [55] . [c3] . [08]
avrdude_git_arduino: STCS 0x80 to address 0x02
avrdude_git_arduino: sending 3 bytes [0x55, 0xc2, 0x80]
avrdude_git_arduino: send: U [55] . [c2] . [80]
avrdude_git_arduino: recv: U [55] . [c2] . [80]
avrdude_git_arduino: LDCS from 0x00
avrdude_git_arduino: sending 2 bytes [0x55, 0x80]
avrdude_git_arduino: send: U [55] . [80]
avrdude_git_arduino: recv: U [55] . [80]
avrdude_git_arduino: recv: 0 [30]
avrdude_git_arduino: received 1 bytes [0x30]
avrdude_git_arduino: UDPI init OK
avrdude_git_arduino: UPDI link initialization OK
avrdude_git_arduino: LDCS from 0x0B
avrdude_git_arduino: sending 2 bytes [0x55, 0x8b]
avrdude_git_arduino: send: U [55] . [8b]
avrdude_git_arduino: recv: U [55] . [8b]
avrdude_git_arduino: recv: . [92]
avrdude_git_arduino: received 1 bytes [0x92]
avrdude_git_arduino: device is in SLEEP mode
avrdude_git_arduino: sending 2 bytes [0x55, 0xe6]
avrdude_git_arduino: send: U [55] . [e6]
avrdude_git_arduino: recv: U [55] . [e6]
avrdude_git_arduino: recv: A [41] V [56] R [52]   [20]   [20]   [20]   [20]   [20] P [50] : [3a] 2 [32] D [44] : [3a] 1 [31] - [2d] 3 [33] M [4d] 2 [32]   [20] ( [28] A [41] 3 [33] . [2e] K [4b] V [56] 0 [30] 0 [30] K [4b] . [2e] 0 [30] ) [29] . [00]
avrdude_git_arduino: received 32 bytes [0x41, 0x56, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x3a, 0x32, 0x44, 0x3a, 0x31, 0x2d, 0x33, 0x4d, 0x32, 0x20, 0x28, 0x41, 0x33, 0x2e, 0x4b, 0x56, 0x30, 0x30, 0x4b, 0x2e, 0x30, 0x29, 0x00]
avrdude_git_arduino: received SIB: [AVR     P:2D:1-3M2 (A3.KV00K.0)]
avrdude_git_arduino: Device family ID: AVR
avrdude_git_arduino: NVM interface: P:2
avrdude_git_arduino: Debug interface: D:1
avrdude_git_arduino: PDI oscillator: 3M2
avrdude_git_arduino: Extra information: (A3.KV00K.0)
avrdude_git_arduino: NVM type 2: 24-bit, word oriented write
avrdude_git_arduino: reading 1 bytes from 0x000F01
avrdude_git_arduino: ST_PTR to 0x000F01
avrdude_git_arduino: sending 5 bytes [0x55, 0x6a, 0x01, 0x0f, 0x00]
avrdude_git_arduino: send: U [55] j [6a] . [01] . [0f] . [00]
avrdude_git_arduino: recv: U [55] j [6a] . [01] . [0f] . [00]
avrdude_git_arduino: recv: @ [40]
avrdude_git_arduino: received 1 bytes [0x40]
avrdude_git_arduino: LD8 from ptr++
avrdude_git_arduino: sending 2 bytes [0x55, 0x24]
avrdude_git_arduino: send: U [55] $ [24]
avrdude_git_arduino: recv: U [55] $ [24]
avrdude_git_arduino: recv: . [13]
avrdude_git_arduino: received 1 bytes [0x13]
avrdude_git_arduino: Received chip silicon revision 0x13
avrdude_git_arduino: Chip silicon revision: 1.3
avrdude_git_arduino: STCS 0x08 to address 0x03
avrdude_git_arduino: sending 3 bytes [0x55, 0xc3, 0x08]
avrdude_git_arduino: send: U [55] . [c3] . [08]
avrdude_git_arduino: recv: U [55] . [c3] . [08]
avrdude_git_arduino: STCS 0x80 to address 0x02
avrdude_git_arduino: sending 3 bytes [0x55, 0xc2, 0x80]
avrdude_git_arduino: send: U [55] . [c2] . [80]
avrdude_git_arduino: recv: U [55] . [c2] . [80]
avrdude_git_arduino: LDCS from 0x00
avrdude_git_arduino: sending 2 bytes [0x55, 0x80]
avrdude_git_arduino: send: U [55] . [80]
avrdude_git_arduino: recv: U [55] . [80]
avrdude_git_arduino: recv: 0 [30]
avrdude_git_arduino: received 1 bytes [0x30]
avrdude_git_arduino: UDPI init OK
avrdude_git_arduino: entering NVM programming mode
avrdude_git_arduino: LDCS from 0x0B
avrdude_git_arduino: sending 2 bytes [0x55, 0x8b]
avrdude_git_arduino: send: U [55] . [8b]
avrdude_git_arduino: recv: U [55] . [8b]
avrdude_git_arduino: recv: . [92]
avrdude_git_arduino: received 1 bytes [0x92]
avrdude_git_arduino: UPDI writing key
avrdude_git_arduino: sending 2 bytes [0x55, 0xe0]
avrdude_git_arduino: send: U [55] . [e0]
avrdude_git_arduino: recv: U [55] . [e0]
avrdude_git_arduino: sending 8 bytes [0x20, 0x67, 0x6f, 0x72, 0x50, 0x4d, 0x56, 0x4e]
avrdude_git_arduino: send:   [20] g [67] o [6f] r [72] P [50] M [4d] V [56] N [4e]
avrdude_git_arduino: recv:   [20] g [67] o [6f] r [72] P [50] M [4d] V [56] N [4e]
avrdude_git_arduino: LDCS from 0x07
avrdude_git_arduino: sending 2 bytes [0x55, 0x87]
avrdude_git_arduino: send: U [55] . [87]
avrdude_git_arduino: recv: U [55] . [87]
avrdude_git_arduino: recv: . [10]
avrdude_git_arduino: received 1 bytes [0x10]
avrdude_git_arduino: key status: 0x10
avrdude_git_arduino: sending reset request
avrdude_git_arduino: STCS 0x59 to address 0x08
avrdude_git_arduino: sending 3 bytes [0x55, 0xc8, 0x59]
avrdude_git_arduino: send: U [55] . [c8] Y [59]
avrdude_git_arduino: recv: U [55] . [c8] Y [59]
avrdude_git_arduino: sending release reset request
avrdude_git_arduino: STCS 0x00 to address 0x08
avrdude_git_arduino: sending 3 bytes [0x55, 0xc8, 0x00]
avrdude_git_arduino: send: U [55] . [c8] . [00]
avrdude_git_arduino: recv: U [55] . [c8] . [00]
avrdude_git_arduino: LDCS from 0x0B
avrdude_git_arduino: sending 2 bytes [0x55, 0x8b]
avrdude_git_arduino: send: U [55] . [8b]
avrdude_git_arduino: recv: U [55] . [8b]
avrdude_git_arduino: recv: 8 [38]
avrdude_git_arduino: received 1 bytes [0x38]
avrdude_git_arduino: LDCS from 0x0B
avrdude_git_arduino: sending 2 bytes [0x55, 0x8b]
avrdude_git_arduino: send: U [55] . [8b]
avrdude_git_arduino: recv: U [55] . [8b]
avrdude_git_arduino: recv: . [08]
avrdude_git_arduino: received 1 bytes [0x08]
avrdude_git_arduino: entered NVM programming mode
avrdude_git_arduino: AVR device initialized and ready to accept instructions
Reading |                                                    | 0% 0.00 s
avrdude_git_arduino: LDCS from 0x0B
avrdude_git_arduino: sending 2 bytes [0x55, 0x8b]
avrdude_git_arduino: send: U [55] . [8b]
avrdude_git_arduino: recv: U [55] . [8b]
avrdude_git_arduino: recv: . [08]
avrdude_git_arduino: received 1 bytes [0x08]
avrdude_git_arduino: LD from 0x001100
avrdude_git_arduino: sending 5 bytes [0x55, 0x08, 0x00, 0x11, 0x00]
avrdude_git_arduino: send: U [55] . [08] . [00] . [11] . [00]
avrdude_git_arduino: recv: U [55] . [08] . [00] . [11] . [00]
avrdude_git_arduino: recv: . [1e]
avrdude_git_arduino: received 1 bytes [0x1e]
avrdude_git_arduino: LD from 0x001101
avrdude_git_arduino: sending 5 bytes [0x55, 0x08, 0x01, 0x11, 0x00]
avrdude_git_arduino: send: U [55] . [08] . [01] . [11] . [00]
avrdude_git_arduino: recv: U [55] . [08] . [01] . [11] . [00]
avrdude_git_arduino: recv: . [96]
avrdude_git_arduino: received 1 bytes [0x96]
avrdude_git_arduino: LD from 0x001102
avrdude_git_arduino: sending 5 bytes [0x55, 0x08, 0x02, 0x11, 0x00]
avrdude_git_arduino: send: U [55] . [08] . [02] . [11] . [00]
avrdude_git_arduino: recv: U [55] . [08] . [02] . [11] . [00]
avrdude_git_arduino: recv: . [1a]
avrdude_git_arduino: received 1 bytes [0x1a]
Reading | ################################################## | 100% 0.01 s
avrdude_git_arduino: device signature = 0x1e961a (probably avr64dd32)
avrdude_git_arduino: leaving NVM programming mode
avrdude_git_arduino: sending reset request
avrdude_git_arduino: STCS 0x59 to address 0x08
avrdude_git_arduino: sending 3 bytes [0x55, 0xc8, 0x59]
avrdude_git_arduino: send: U [55] . [c8] Y [59]
avrdude_git_arduino: recv: U [55] . [c8] Y [59]
avrdude_git_arduino: sending release reset request
avrdude_git_arduino: STCS 0x00 to address 0x08
avrdude_git_arduino: sending 3 bytes [0x55, 0xc8, 0x00]
avrdude_git_arduino: send: U [55] . [c8] . [00]
avrdude_git_arduino: recv: U [55] . [c8] . [00]
avrdude_git_arduino: STCS 0x0C to address 0x03
avrdude_git_arduino: sending 3 bytes [0x55, 0xc3, 0x0c]
avrdude_git_arduino: send: U [55] . [c3] . [0c]
avrdude_git_arduino: recv: U [55] . [c3] . [0c]

avrdude_git_arduino done.  Thank you.
askn37 commented 10 months ago

Thoughts on silicon revision checking

Revision checking is currently implemented in four types: jtag3.c, jtagmkII.c, serialupdi.c, and stk500v2.c. Among these, jtag is called with optional functions such as "pgm->read_chip_rev". STK500/600 is also referenced after "program_enable". Before that, only serialupdi.c is referenced.

If you think about it, the revision information should be a clue to identifying the errata, which is her 4th byte in the 3-byte signature extension. Therefore, it stands to reason that there is a close relationship between signatures and amendments. It would be even more useful if they were displayed side by side in the console log.

I think it would be better and more consistent to implement serialupdi.c, similar to jtag*.c. I think that's the case based on main.c, what do you think?

mcuee commented 10 months ago

@askn37

Reading chip revision is already done in PR #1474 by @MCUdude, for jtag3.c, jtagmkII.c, serialupdi.c, and stk500v2.c. So you are saying the implementation for serialupdi.c is different from the other three and you want to make it consistent, right?

askn37 commented 10 months ago

@mcuee

Yes, that's right.

By the way, I have often read REVID by writing it as below.

     memory "revid"
         size = 1;
         offset = 0x0f01;
         readsize = 1;
     ;

echo dump revid | avrdude -qt ...

There is a reason why I got into the habit of checking REVID. The SIB of AVR32DA32 rev.A3 that I obtained in the past is

AVR_____P:2D:1-3

This is the same as AVR_DB and later, "AVR" + 5 spaces.

However, the SIB of AVR128DA28 rev.A7 that I ordered after that was

____AVR_P:2D:1-3

Same style as tinyAVR/megaAVR, 4 blank spaces + "AVR"? ? ? (In addition, it was an error product that was not normally shipped because it had a large scratch caused by a failure to cut it with a diamond saw)

Apparently AVR128DA28/32/48/64 (DS40002183C) is this old style. AVR64DA28/32/48/64 (DS40002233B) and AVR32DA28/32/48 (DS40002228B) are different in some strange ways.

dbuchwald commented 10 months ago

Guys, I'm sorry, but I feel a bit lost in these discussions, and I find them harder and harder to follow. Apologies if you expect my input on some of the topics brought up here, but at this point I can only react on certain trigger words :)

I noticed discussion about RTS/DTR and using it for resetting AVR - sounds like a good idea, but before you make changes to the code that handles it in SerialUPDI, please note that this additional setting (-x rtsdtr=[low|high]) was implemented specifically to enable aforementioned SerialUPDI programmer by MCUDude to toggle between UPDI and Serial mode. I'm talking about this device (which I'm also using, but only in SerialUPDI mode):

IMG_6434 IMG_6435

So, my point is that whatever you decide about using RTS/DTR lines, please keep in mind that there is at least one device in the wild that makes strong assumption as to what these signals are for, and compatibility, if possible, should be maintained.

Otherwise, if you need me to look at some code or test something - please tag me in the post, otherwise I might miss it.

mcuee commented 10 months ago

@dbuchwald

I think the only thing for you now is to take a look at the log from @askn37 here to see if you have any concerns or not.

There is a warning in his log.

avrdude: forcing serial DTR/RTS handshake lines HIGH
avrdude: NVM type 3: 24-bit, page oriented
avrdude: entering NVM programming mode
avrdude serialupdi_enter_progmode() error: key was not accepted
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e961f (probably avr64ea32)

@askn37 mentions the following which may or may not be an issue.

This indicates that the UPDI layer has not yet fully woken up when reading "UPDI_CS_ASI_KEY_STATUS" after sending "UPDI_SIB_128", or that key activation took longer than usual. I'm sure avrdude is impatient. There probably aren't any other concerns. thank you.

mcuee commented 10 months ago

Thoughts on silicon revision checking

Revision checking is currently implemented in four types: jtag3.c, jtagmkII.c, serialupdi.c, and stk500v2.c. Among these, jtag is called with optional functions such as "pgm->read_chip_rev". STK500/600 is also referenced after "program_enable". Before that, only serialupdi.c is referenced.

If you think about it, the revision information should be a clue to identifying the errata, which is her 4th byte in the 3-byte signature extension. Therefore, it stands to reason that there is a close relationship between signatures and amendments. It would be even more useful if they were displayed side by side in the console log.

I think it would be better and more consistent to implement serialupdi.c, similar to jtag*.c. I think that's the case based on main.c, what do you think?

@askn37

You are welcome to come out with a PR to make serialupdi.c handling of chip revision ID to be more consistent with the others. Thanks.

mcuee commented 10 months ago

So, my point is that whatever you decide about using RTS/DTR lines, please keep in mind that there is at least one device in the wild that makes strong assumption as to what these signals are for, and compatibility, if possible, should be maintained.

So there will be three cases. 1) typical serialupdi programmer which has only three lines --> VCC, GND and UPDI. 2) @MCUdude's specific SerialUPDI programmer which has dual mode (UPDI and UART mode). The code currently supports this with -x rtsdtr=[low|high. 3) Other UPDI programmers which may provide DTR/RTS pins to reset the MCU.

@dbuchwald and @stefanrueger One possibilty is to use a different -x generic_rts and -x generic_dtr for the 3rd type, if we want to support the 3rd type.

dbuchwald commented 10 months ago

@stefanrueger

I get the impression that updi_set_rtsdtr_mode() is meant for communication via DTR and for reset via RTS. If this is the case, I think we should separate rts and dtr handling into two functions serial_set_rts() and serial_set_dtr() to manage the signals independently.

The only reason this was implemented was to support the dual-mode operation of MCUdude's programmer. I don't remember why it was both RTS and DTR at the same time, but maybe it could be separated.

I'm currently going over the very long e-mail discussion between myself and MCUdude about the quirks of serial interfaces, and I found some small things that might help you anticipate potential issues:

The reason why I asked you to implement "pull DTR/RTS low" during the Avrdude session was that I could use this signal on the programmer to automatically switch between UPDI and serial mode. I think we both agree that this is a nice feature. This would work because DTR/RTS signal is high when a serial monitor is open. Now we have a signal that switches between high and low, indicating what "mode" we are in.

Or so I thought...

It turns out that the statement above is correct if you're using a Mac as I do. On Windows and Linux (I've tested with Ubuntu), the DTR/RTS signal is actually pulled low when a serial connection is open. This is the opposite of what's happening on my mac! There are even people asking about this on Stack Overflow: https://stackoverflow.com/questions/17601142/os-x-serial-port-open-with-dtr-low

After more research, I discovered that this is probably a bug in the Apple CH340 driver that ships with MacOS. After upgrading the driver to the one from WCH (the manufacturer of CH340 chips), this problem is solved, and DTR/RTS stays low when a serial session is active.

Also another thing is that the 300-baud workaround I borrowed from pymcuprog (and the reason for it was that tcsendbreak not being portable) can cause pulses on these DTR/RTS lines in some cases:

The reason you were seeing these pulses during AVRDUDE session (usually only at the beginning), is that there is somewhat weird code in the serialupdi driver. I took it directly from pymcuprog, and I must say I didn’t like it a lot, but assumed it necessary. See, NVM programming interface works as very simple and limited state machine. Should something go wrong it simply clams up and stops responding to any requests at all. The only way to get it to work again is to force NVM controller reset by sending two consecutive serial break messages around 24ms each. The way it is implemented in pymcuprog (and this is the part I didn’t like) is that connection mode is changed to 300 baud 8E1 and 0x00 value is sent out. 0x00 encoded in 8E1 at 300 baud translates to approx. 24ms low signal and does the job. I copied this functionality hoping to look into it some day and possibly fix it in my implementation. Now, what happens is in AVRDUDE is that the code responsible for changing connection speed actually disconnects serial and connects it again, changing some internal OS driver structures. These disconnect/connect events were causing strange pulses you saw.

Again, I'm not trying to say that my implementation is perfect and should not be changed. Feel free to change it any way you want, and if you need my help, I will provide it.

What I am saying is that when I worked on it almost two years ago I went through a lot of testing in different environments, and some discrepancies between them were deal-breakers for some pretty good ideas. That being said, context might have changed during these two years, some of these issues might have been fixed. Maybe the MacOS bug has been fixed in the meantime.

askn37 commented 10 months ago

HEADS UP

Using DTR/RTS instead of GPIO will definitely have side effects as it is not compliant with regulations such as RS232C. Don't expect 100% compatibility. . . . But it's convenient, isn't it?

Arduino IDE Serial Monitor (Windows/macos/Linux)

This would be a good standard to use. DTR/RTS is not asserted. The behavior when opened varies depending on the OS and driver. In most cases, RTS=LOW and DTR=LOW when open and RTS=HIGH and DTR=HIGH when closed. So if your target has an auto-reset circuit (series capacitor), it will reset every time you open it again.

The CH330/CH340 series was well received, so the manufacturer improved the driver so that RTS=LOW when opened.

Screen and MINICOM (*UNIX)

When opened, asserts DTR/RTS. The UART switching implementation for "microUPDI adapter" will not work properly because DTR = HIGH and RTS = HIGH. Workarounds include turning off "hardware flow", temporarily setting it to 0bps, and running stty. (I'm not good at it so I don't know the details)

TeraTerm (Windows)

DTR/RTS is normally not asserted. You can turn DTR/RTS on and off individually as needed using the "hardware flow" or using a macro file.

mcuee commented 10 months ago

HEADS UP

Using DTR/RTS instead of GPIO will definitely have side effects as it is not compliant with regulations such as RS232C. Don't expect 100% compatibility. . . . But it's convenient, isn't it?

To be honest, I think we (avrdude project) do not really need to take care of the serial monitor function. Rather we need to take care of the programming function which may invovle chip reset.

There are special cases for serialupdi which takes care of @MCUdude's paticular design.

For jtag2updi, it is the same siutation, only certain type of cictuits will work with -xrtsdtr. My Uno clones do not work.

If we really want to be more generic, I think we need generic dtr, rts and at least cts handling to give the user more freedoms. But then we can only cater for typical circuits and probably not for all cases.

So far the following PR seems to work fine for different platforms. The focus is the bootloaders (urclock, optiboot and wiring) programming where proper chip reset is important. The focus is not the UART monitor.

stefanrueger commented 10 months ago

OK, I learned a few things about the way different OS assert DTR/RTS during the low-level open() call of the serial port; I also learned about the behaviour of several terminal programs and how it affects some auto-reset circuits. My take-away is that we should improve the documentation of this aspect in doc/avrdude.texi, for example by providing a section 5.5 Auto-reset boards with information from https://github.com/avrdudes/avrdude/issues/1529#issuecomment-1783764457. I'd like to invite @askn37 to start a PR on this. I would be happy to contribute to it. And don't worry about language @askn37: your English is crisp and clear.

By the way, I have often read REVID by writing it as below.

     memory "revid"
         size = 1;
         offset = 0x0f01;
         readsize = 1;
     ;

echo dump revid | avrdude -qt ...

@askn37 Pro Tip: try using avrdude -qT "read io 0xf01 1" instead. See this discussion why we implemented the general io memory rather than (many) memories like revid. I plan a future PR that adds a new terminal command register and the symbolic layout of the register file for each part, so you can query register syscfg.revid instead of read io 0xf01.

Other than this, we probably might want to close the issue as the main problem that NVMCTRL v3 should use 24 bit is solved.

stefanrueger commented 10 months ago

@dbuchwald Thanks for explaining the motivation and history of the rtsdts handling. That is really helpful!

askn37 commented 10 months ago

@mcuee

To be honest, I think we (avrdude project) do not really need to take care of the serial monitor function. Rather we need to take care of the programming function which may invovle chip reset.

Ok, I agree with that policy. (However, since the main purpose of UART passthrough is to allow "programming writer" and "serial monitor" to coexist, you should keep in mind that there are some combinations that will not work as expected. In that case, "programming writer" must be given priority.)

mcuee commented 10 months ago

Other than this, we probably might want to close the issue as the main problem that NVMCTRL v3 should use 24 bit is solved.

I agree.

mcuee commented 10 months ago

@mcuee

To be honest, I think we (avrdude project) do not really need to take care of the serial monitor function. Rather we need to take care of the programming function which may invovle chip reset.

Ok, I agree with that policy. (However, since the main purpose of UART passthrough is to allow "programming writer" and "serial monitor" to coexist, you should keep in mind that there are some combinations that will not work as expected. In that case, "programming writer" must be given priority.)

Yes, I agree with you here.

mcuee commented 10 months ago

Just want to mention the sleep MinGW issue is indeed specific to MSYS2 mingw compiler. I just built avrdude using MSYS2 clang64 and it works fine.

PS> .\avrdude_git_clang64.exe -c serialupdi -P COM41 -p avr64dd32 -vvvv

avrdude_git_clang64: Version 7.2-20231024 (d6c61f5f)
                     Copyright the AVRDUDE authors;
                     see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

                     System wide configuration file is C:\work\avr\avrdude_test\avrdude_bin\avrdude.conf

                     Using Port                    : COM41
                     Using Programmer              : serialupdi
avrdude_git_clang64: opening serial port ...
avrdude_git_clang64: sending 1 bytes [0x00]
avrdude_git_clang64: send: . [00]
avrdude_git_clang64: recv: . [00]
                     AVR Part                      : AVR64DD32
                     RESET disposition             : dedicated
                     RETRY pulse                   : SCK
                     Serial program mode           : yes
                     Parallel program mode         : yes
                     Memory Detail                 :
...
avrdude_git_clang64: STCS 0x08 to address 0x03
avrdude_git_clang64: sending 3 bytes [0x55, 0xc3, 0x08]
avrdude_git_clang64: send: U [55] . [c3] . [08]
avrdude_git_clang64: recv: U [55] . [c3] . [08]
avrdude_git_clang64: STCS 0x80 to address 0x02
avrdude_git_clang64: sending 3 bytes [0x55, 0xc2, 0x80]
avrdude_git_clang64: send: U [55] . [c2] . [80]
avrdude_git_clang64: recv: U [55] . [c2] . [80]
avrdude_git_clang64: LDCS from 0x00
avrdude_git_clang64: sending 2 bytes [0x55, 0x80]
avrdude_git_clang64: send: U [55] . [80]
avrdude_git_clang64: recv: U [55] . [80]
avrdude_git_clang64: recv: 0 [30]
avrdude_git_clang64: received 1 bytes [0x30]
avrdude_git_clang64: UDPI init OK
avrdude_git_clang64: UPDI link initialization OK
avrdude_git_clang64: LDCS from 0x0B
avrdude_git_clang64: sending 2 bytes [0x55, 0x8b]
avrdude_git_clang64: send: U [55] . [8b]
avrdude_git_clang64: recv: U [55] . [8b]
avrdude_git_clang64: recv: . [92]
avrdude_git_clang64: received 1 bytes [0x92]
avrdude_git_clang64: device is in SLEEP mode
avrdude_git_clang64: sending 2 bytes [0x55, 0xe6]
avrdude_git_clang64: send: U [55] . [e6]
avrdude_git_clang64: recv: U [55] . [e6]
avrdude_git_clang64: recv: A [41] V [56] R [52]   [20]   [20]   [20]   [20]   [20] P [50] : [3a] 2 [32] D [44] : [3a] 1 [31] - [2d] 3 [33] M [4d] 2 [32]   [20] ( [28] A [41] 3 [33] . [2e] K [4b] V [56] 0 [30] 0 [30] K [4b] . [2e] 0 [30] ) [29] . [00]
avrdude_git_clang64: received 32 bytes [0x41, 0x56, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x3a, 0x32, 0x44, 0x3a, 0x31, 0x2d, 0x33, 0x4d, 0x32, 0x20, 0x28, 0x41, 0x33, 0x2e, 0x4b, 0x56, 0x30, 0x30, 0x4b, 0x2e, 0x30, 0x29, 0x00]
avrdude_git_clang64: received SIB: [AVR     P:2D:1-3M2 (A3.KV00K.0)]
avrdude_git_clang64: Device family ID: AVR
avrdude_git_clang64: NVM interface: P:2
avrdude_git_clang64: Debug interface: D:1
avrdude_git_clang64: PDI oscillator: 3M2
avrdude_git_clang64: Extra information: (A3.KV00K.0)
avrdude_git_clang64: NVM type 2: 24-bit, word oriented write
avrdude_git_clang64: reading 1 bytes from 0x000F01
avrdude_git_clang64: ST_PTR to 0x000F01
avrdude_git_clang64: sending 5 bytes [0x55, 0x6a, 0x01, 0x0f, 0x00]
avrdude_git_clang64: send: U [55] j [6a] . [01] . [0f] . [00]
avrdude_git_clang64: recv: U [55] j [6a] . [01] . [0f] . [00]
avrdude_git_clang64: recv: @ [40]
avrdude_git_clang64: received 1 bytes [0x40]
avrdude_git_clang64: LD8 from ptr++
avrdude_git_clang64: sending 2 bytes [0x55, 0x24]
avrdude_git_clang64: send: U [55] $ [24]
avrdude_git_clang64: recv: U [55] $ [24]
avrdude_git_clang64: recv: . [13]
avrdude_git_clang64: received 1 bytes [0x13]
avrdude_git_clang64: Received chip silicon revision 0x13
avrdude_git_clang64: Chip silicon revision: 1.3
avrdude_git_clang64: STCS 0x08 to address 0x03
avrdude_git_clang64: sending 3 bytes [0x55, 0xc3, 0x08]
avrdude_git_clang64: send: U [55] . [c3] . [08]
avrdude_git_clang64: recv: U [55] . [c3] . [08]
avrdude_git_clang64: STCS 0x80 to address 0x02
avrdude_git_clang64: sending 3 bytes [0x55, 0xc2, 0x80]
avrdude_git_clang64: send: U [55] . [c2] . [80]
avrdude_git_clang64: recv: U [55] . [c2] . [80]
avrdude_git_clang64: LDCS from 0x00
avrdude_git_clang64: sending 2 bytes [0x55, 0x80]
avrdude_git_clang64: send: U [55] . [80]
avrdude_git_clang64: recv: U [55] . [80]
avrdude_git_clang64: recv: 0 [30]
avrdude_git_clang64: received 1 bytes [0x30]
avrdude_git_clang64: UDPI init OK
avrdude_git_clang64: entering NVM programming mode
avrdude_git_clang64: LDCS from 0x0B
avrdude_git_clang64: sending 2 bytes [0x55, 0x8b]
avrdude_git_clang64: send: U [55] . [8b]
avrdude_git_clang64: recv: U [55] . [8b]
avrdude_git_clang64: recv: . [92]
avrdude_git_clang64: received 1 bytes [0x92]
avrdude_git_clang64: UPDI writing key
avrdude_git_clang64: sending 2 bytes [0x55, 0xe0]
avrdude_git_clang64: send: U [55] . [e0]
avrdude_git_clang64: recv: U [55] . [e0]
avrdude_git_clang64: sending 8 bytes [0x20, 0x67, 0x6f, 0x72, 0x50, 0x4d, 0x56, 0x4e]
avrdude_git_clang64: send:   [20] g [67] o [6f] r [72] P [50] M [4d] V [56] N [4e]
avrdude_git_clang64: recv:   [20] g [67] o [6f] r [72] P [50] M [4d] V [56] N [4e]
avrdude_git_clang64: LDCS from 0x07
avrdude_git_clang64: sending 2 bytes [0x55, 0x87]
avrdude_git_clang64: send: U [55] . [87]
avrdude_git_clang64: recv: U [55] . [87]
avrdude_git_clang64: recv: . [10]
avrdude_git_clang64: received 1 bytes [0x10]
avrdude_git_clang64: key status: 0x10
avrdude_git_clang64: sending reset request
avrdude_git_clang64: STCS 0x59 to address 0x08
avrdude_git_clang64: sending 3 bytes [0x55, 0xc8, 0x59]
avrdude_git_clang64: send: U [55] . [c8] Y [59]
avrdude_git_clang64: recv: U [55] . [c8] Y [59]
avrdude_git_clang64: sending release reset request
avrdude_git_clang64: STCS 0x00 to address 0x08
avrdude_git_clang64: sending 3 bytes [0x55, 0xc8, 0x00]
avrdude_git_clang64: send: U [55] . [c8] . [00]
avrdude_git_clang64: recv: U [55] . [c8] . [00]
avrdude_git_clang64: LDCS from 0x0B
avrdude_git_clang64: sending 2 bytes [0x55, 0x8b]
avrdude_git_clang64: send: U [55] . [8b]
avrdude_git_clang64: recv: U [55] . [8b]
avrdude_git_clang64: recv: 8 [38]
avrdude_git_clang64: received 1 bytes [0x38]
avrdude_git_clang64: LDCS from 0x0B
avrdude_git_clang64: sending 2 bytes [0x55, 0x8b]
avrdude_git_clang64: send: U [55] . [8b]
avrdude_git_clang64: recv: U [55] . [8b]
avrdude_git_clang64: recv: . [08]
avrdude_git_clang64: received 1 bytes [0x08]
avrdude_git_clang64: entered NVM programming mode
avrdude_git_clang64: AVR device initialized and ready to accept instructions
Reading |                                                    | 0% 0.00 s
avrdude_git_clang64: LDCS from 0x0B
avrdude_git_clang64: sending 2 bytes [0x55, 0x8b]
avrdude_git_clang64: send: U [55] . [8b]
avrdude_git_clang64: recv: U [55] . [8b]
avrdude_git_clang64: recv: . [08]
avrdude_git_clang64: received 1 bytes [0x08]
avrdude_git_clang64: LD from 0x001100
avrdude_git_clang64: sending 5 bytes [0x55, 0x08, 0x00, 0x11, 0x00]
avrdude_git_clang64: send: U [55] . [08] . [00] . [11] . [00]
avrdude_git_clang64: recv: U [55] . [08] . [00] . [11] . [00]
avrdude_git_clang64: recv: . [1e]
avrdude_git_clang64: received 1 bytes [0x1e]
avrdude_git_clang64: LD from 0x001101
avrdude_git_clang64: sending 5 bytes [0x55, 0x08, 0x01, 0x11, 0x00]
avrdude_git_clang64: send: U [55] . [08] . [01] . [11] . [00]
avrdude_git_clang64: recv: U [55] . [08] . [01] . [11] . [00]
avrdude_git_clang64: recv: . [96]
avrdude_git_clang64: received 1 bytes [0x96]
avrdude_git_clang64: LD from 0x001102
avrdude_git_clang64: sending 5 bytes [0x55, 0x08, 0x02, 0x11, 0x00]
avrdude_git_clang64: send: U [55] . [08] . [02] . [11] . [00]
avrdude_git_clang64: recv: U [55] . [08] . [02] . [11] . [00]
avrdude_git_clang64: recv: . [1a]
avrdude_git_clang64: received 1 bytes [0x1a]
Reading | ################################################## | 100% 0.02 s
avrdude_git_clang64: device signature = 0x1e961a (probably avr64dd32)
avrdude_git_clang64: leaving NVM programming mode
avrdude_git_clang64: sending reset request
avrdude_git_clang64: STCS 0x59 to address 0x08
avrdude_git_clang64: sending 3 bytes [0x55, 0xc8, 0x59]
avrdude_git_clang64: send: U [55] . [c8] Y [59]
avrdude_git_clang64: recv: U [55] . [c8] Y [59]
avrdude_git_clang64: sending release reset request
avrdude_git_clang64: STCS 0x00 to address 0x08
avrdude_git_clang64: sending 3 bytes [0x55, 0xc8, 0x00]
avrdude_git_clang64: send: U [55] . [c8] . [00]
avrdude_git_clang64: recv: U [55] . [c8] . [00]
avrdude_git_clang64: STCS 0x0C to address 0x03
avrdude_git_clang64: sending 3 bytes [0x55, 0xc3, 0x0c]
avrdude_git_clang64: send: U [55] . [c3] . [0c]
avrdude_git_clang64: recv: U [55] . [c3] . [0c]

avrdude_git_clang64 done.  Thank you.
askn37 commented 10 months ago

I'm looking into "serialupdi_initialize".

Things I can do right away:

The "read chip silicon revision" process that inspired this investigation can be improved by simply moving it to the end of the function. Since "serialupdi_enter_progmode" is called before that, "UPDI_ASI_SYS_STATUS_NVMPROG" will be true and will not be affected. (However, if "LOCKSTATUS=1", NVMPROG will fail, so you should not investigate)

Strange part:

"updi_read_sib" is called after checking "UPDI_ASI_SYS_STATUS". This is strange. This is because "UPDI_ASI_SYS_STATUS" expands with each version of his NVMCTRL. v0 has meaning on 5 bits, v2 has meaning on 6 bits, and v3 has meaning on all 8 bits. Therefore, you need to check the version of NVMCTRL by calling 'updi_read_sib' and reading 'UPDI_ASI_SYS_STATUS'. There are no particular problems with v2. However, v3 added an important "BOOTDONE" bit. Set to 1 when the CPU completes the "power-on reset" boot process. Otherwise, you are not ready to run "serialupdi_enter_progmode". So you have to read "UPDI_ASI_SYS_STATUS" again and wait until it becomes 1, or try a few times and abort on timeout. And that should be done before any other investigation.

What I know:

For NVMCTRLv0/2, it is safe to run "serialupdi_enter_progmode" when "RSTSYS=0", "INSLEEP=any", "NVMPROG=any", "UROWPROG=0", "LOCKSTATUS=0". v3 also requires "BOOTDONE=1". (At the same time, for v3, this may make it less susceptible to the negative effects of DTR/RTS control.) ('INSLEEP=1' can be ignored as 'ASI_RESET' is used to enable 'NVMPROG_KEY'. However, at this stage if 'NVMPROG=1' use 'RSTSYS =0') is needed.)

mcuee commented 10 months ago

Things I can do right away:

The "read chip silicon revision" process that inspired this investigation can be improved by simply moving it to the end of the function. Since "serialupdi_enter_progmode" is called before that, "UPDI_ASI_SYS_STATUS_NVMPROG" will be true and will not be affected. (However, if "LOCKSTATUS=1", NVMPROG will fail, so you should not investigate)

@askn37

I think this is safe to do. PR is welcome.