avrdudes / avrdude

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

SerialUPDI - unable to write USERROW memory on AVR64DU32 #1655

Closed dbuchwald closed 6 months ago

dbuchwald commented 6 months ago

First reported by @MCUdude in discussion #1473.

This issue is related to SerialUPDI programmer and first ever tested DU chip, and it's pretty easy to replicate:

avrdude log ``` $ avrdude -cserialupdi -pavr64du32 -P ch340 -T 'write userrow 0 "The quick brown fox jumpes over the lazy dog"' -vvvv avrdude: Version 7.2-20230720 Copyright the AVRDUDE authors; see https://github.com/avrdudes/avrdude/blob/main/AUTHORS System wide configuration file is /usr/local/etc/avrdude.conf User configuration file is /Users/hans/.avrduderc Using port : /dev/cu.usbserial-1420 Using programmer : serialupdi avrdude: opening serial port ... avrdude: sending 1 bytes [0x00] avrdude: ser_send: . [00] avrdude: ser_recv: . [00] AVR Part : AVR64DU32 Programming modes : UPDI, SPM Memory Size Pg size Offset ----------------------------------------- eeprom 256 1 0x1400 flash 65536 512 0x800000 fuses 16 1 0x1050 fuse0/wdtcfg 1 1 0x1050 fuse1/bodcfg 1 1 0x1051 fuse2/osccfg 1 1 0x1052 fuse5/syscfg0 1 1 0x1055 fuse6/syscfg1 1 1 0x1056 fuse7/codesize 1 1 0x1057 fuse8/bootsize 1 1 0x1058 fusea/pdicfg 2 1 0x105a lock 4 1 0x1040 prodsig/sigrow 128 128 0x1080 signature 3 1 0x1080 tempsense 4 1 0x1084 sernum 16 1 0x1090 bootrow 256 256 0x1100 userrow/usersig 512 512 0x1200 io 4160 1 0 sram 8192 1 0x6000 sib 32 1 0 Variants Package F max T range V range ------------------------------------------------------------------- AVR64DU32-VQFN/TQFP QFP32 32 MHz [-40 C, 85 C] [1.8 V, 5.5 V] Programmer Type : serialupdi Description : SerialUPDI avrdude: STCS 0x08 to address 0x03 avrdude: sending 3 bytes [0x55, 0xc3, 0x08] avrdude: ser_send: U [55] . [c3] . [08] avrdude: ser_recv: U [55] . [c3] . [08] avrdude: STCS 0x80 to address 0x02 avrdude: sending 3 bytes [0x55, 0xc2, 0x80] avrdude: ser_send: U [55] . [c2] . [80] avrdude: ser_recv: U [55] . [c2] . [80] avrdude: LDCS from 0x00 avrdude: sending 2 bytes [0x55, 0x80] avrdude: ser_send: U [55] . [80] avrdude: ser_recv: U [55] . [80] avrdude: ser_recv: 0 [30] avrdude: received 1 bytes [0x30] avrdude: UDPI init OK avrdude: UPDI link initialization OK avrdude: LDCS from 0x0B avrdude: sending 2 bytes [0x55, 0x8b] avrdude: ser_send: U [55] . [8b] avrdude: ser_recv: U [55] . [8b] avrdude: ser_recv: . [82] avrdude: received 1 bytes [0x82] avrdude: sending 2 bytes [0x55, 0xe6] avrdude: ser_send: U [55] . [e6] avrdude: ser_recv: U [55] . [e6] avrdude: ser_recv: A [41] V [56] R [52] [20] [20] [20] [20] [20] P [50] : [3a] 4 [34] D [44] : [3a] 1 [31] - [2d] 3 [33] M [4d] 2 [32] [20] ( [28] A [41] 2 [32] . [2e] K [4b] V [56] 0 [30] 0 [30] S [53] . [2e] 0 [30] ) [29] . [00] avrdude: received 32 bytes [0x41, 0x56, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x3a, 0x34, 0x44, 0x3a, 0x31, 0x2d, 0x33, 0x4d, 0x32, 0x20, 0x28, 0x41, 0x32, 0x2e, 0x4b, 0x56, 0x30, 0x30, 0x53, 0x2e, 0x30, 0x29, 0x00] avrdude: received SIB: [AVR P:4D:1-3M2 (A2.KV00S.0)] avrdude: Device family ID: AVR avrdude: NVM interface: P:4 avrdude: Debug interface: D:1 avrdude: PDI oscillator: 3M2 avrdude: Extra information: (A2.KV00S.0) avrdude: NVM type 4: 24-bit, word oriented avrdude: STCS 0x08 to address 0x03 avrdude: sending 3 bytes [0x55, 0xc3, 0x08] avrdude: ser_send: U [55] . [c3] . [08] avrdude: ser_recv: U [55] . [c3] . [08] avrdude: STCS 0x80 to address 0x02 avrdude: sending 3 bytes [0x55, 0xc2, 0x80] avrdude: ser_send: U [55] . [c2] . [80] avrdude: ser_recv: U [55] . [c2] . [80] avrdude: LDCS from 0x00 avrdude: sending 2 bytes [0x55, 0x80] avrdude: ser_send: U [55] . [80] avrdude: ser_recv: U [55] . [80] avrdude: ser_recv: 0 [30] avrdude: received 1 bytes [0x30] avrdude: UDPI init OK avrdude: entering NVM programming mode avrdude: LDCS from 0x0B avrdude: sending 2 bytes [0x55, 0x8b] avrdude: ser_send: U [55] . [8b] avrdude: ser_recv: U [55] . [8b] avrdude: ser_recv: . [82] avrdude: received 1 bytes [0x82] avrdude: sending reset request avrdude: STCS 0x59 to address 0x08 avrdude: sending 3 bytes [0x55, 0xc8, 0x59] avrdude: ser_send: U [55] . [c8] Y [59] avrdude: ser_recv: U [55] . [c8] Y [59] avrdude: UPDI writing key avrdude: sending 2 bytes [0x55, 0xe0] avrdude: ser_send: U [55] . [e0] avrdude: ser_recv: U [55] . [e0] avrdude: sending 8 bytes [0x20, 0x67, 0x6f, 0x72, 0x50, 0x4d, 0x56, 0x4e] avrdude: ser_send: [20] g [67] o [6f] r [72] P [50] M [4d] V [56] N [4e] avrdude: ser_recv: [20] g [67] o [6f] r [72] P [50] M [4d] V [56] N [4e] avrdude: LDCS from 0x07 avrdude: sending 2 bytes [0x55, 0x87] avrdude: ser_send: U [55] . [87] avrdude: ser_recv: U [55] . [87] avrdude: ser_recv: . [10] avrdude: received 1 bytes [0x10] avrdude: key status: 0x10 avrdude: sending reset request avrdude: STCS 0x59 to address 0x08 avrdude: sending 3 bytes [0x55, 0xc8, 0x59] avrdude: ser_send: U [55] . [c8] Y [59] avrdude: ser_recv: U [55] . [c8] Y [59] avrdude: sending release reset request avrdude: STCS 0x00 to address 0x08 avrdude: sending 3 bytes [0x55, 0xc8, 0x00] avrdude: ser_send: U [55] . [c8] . [00] avrdude: ser_recv: U [55] . [c8] . [00] avrdude: LDCS from 0x0B avrdude: sending 2 bytes [0x55, 0x8b] avrdude: ser_send: U [55] . [8b] avrdude: ser_recv: U [55] . [8b] avrdude: ser_recv: ( [28] avrdude: received 1 bytes [0x28] avrdude: LDCS from 0x0B avrdude: sending 2 bytes [0x55, 0x8b] avrdude: ser_send: U [55] . [8b] avrdude: ser_recv: U [55] . [8b] avrdude: ser_recv: . [08] avrdude: received 1 bytes [0x08] avrdude: entered NVM programming mode avrdude: reading 1 bytes from 0x000F01 avrdude: ST_PTR to 0x000F01 avrdude: sending 5 bytes [0x55, 0x6a, 0x01, 0x0f, 0x00] avrdude: ser_send: U [55] j [6a] . [01] . [0f] . [00] avrdude: ser_recv: U [55] j [6a] . [01] . [0f] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [12] avrdude: received 1 bytes [0x12] avrdude: Received chip silicon revision 0x12 avrdude: Chip silicon revision: 1.2 avrdude: AVR device initialized and ready to accept instructions Reading | | 0% 0.00 s avrdude: LDCS from 0x0B avrdude: sending 2 bytes [0x55, 0x8b] avrdude: ser_send: U [55] . [8b] avrdude: ser_recv: U [55] . [8b] avrdude: ser_recv: . [08] avrdude: received 1 bytes [0x08] avrdude: LD from 0x001080 avrdude: sending 5 bytes [0x55, 0x08, 0x80, 0x10, 0x00] avrdude: ser_send: U [55] . [08] . [80] . [10] . [00] avrdude: ser_recv: U [55] . [08] . [80] . [10] . [00] avrdude: ser_recv: . [1e] avrdude: received 1 bytes [0x1e] avrdude: LD from 0x001081 avrdude: sending 5 bytes [0x55, 0x08, 0x81, 0x10, 0x00] avrdude: ser_send: U [55] . [08] . [81] . [10] . [00] avrdude: ser_recv: U [55] . [08] . [81] . [10] . [00] avrdude: ser_recv: . [96] avrdude: received 1 bytes [0x96] avrdude: LD from 0x001082 avrdude: sending 5 bytes [0x55, 0x08, 0x82, 0x10, 0x00] avrdude: ser_send: U [55] . [08] . [82] . [10] . [00] avrdude: ser_recv: U [55] . [08] . [82] . [10] . [00] avrdude: ser_recv: ! [21] avrdude: received 1 bytes [0x21] Reading | ################################################## | 100% 0.02 s avrdude: device signature = 0x1e9621 (probably avr64du32) avrdude: processing -T write userrow 0 "The quick brown fox jumpes over the lazy dog" avrdude: (write) writing 45 bytes starting from address 0x00 Caching | | 0% 0.00 s avrdude: reading 32 bytes from 0x001200 avrdude: ST_PTR to 0x001200 avrdude: sending 5 bytes [0x55, 0x6a, 0x00, 0x12, 0x00] avrdude: ser_send: U [55] j [6a] . [00] . [12] . [00] avrdude: ser_recv: U [55] j [6a] . [00] . [12] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x001220 avrdude: ST_PTR to 0x001220 avrdude: sending 5 bytes [0x55, 0x6a, 0x20, 0x12, 0x00] avrdude: ser_send: U [55] j [6a] [20] . [12] . [00] avrdude: ser_recv: U [55] j [6a] [20] . [12] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x001240 avrdude: ST_PTR to 0x001240 avrdude: sending 5 bytes [0x55, 0x6a, 0x40, 0x12, 0x00] avrdude: ser_send: U [55] j [6a] @ [40] . [12] . [00] avrdude: ser_recv: U [55] j [6a] @ [40] . [12] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x001260 avrdude: ST_PTR to 0x001260 avrdude: sending 5 bytes [0x55, 0x6a, 0x60, 0x12, 0x00] avrdude: ser_send: U [55] j [6a] ` [60] . [12] . [00] avrdude: ser_recv: U [55] j [6a] ` [60] . [12] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x001280 avrdude: ST_PTR to 0x001280 avrdude: sending 5 bytes [0x55, 0x6a, 0x80, 0x12, 0x00] avrdude: ser_send: U [55] j [6a] . [80] . [12] . [00] avrdude: ser_recv: U [55] j [6a] . [80] . [12] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x0012A0 avrdude: ST_PTR to 0x0012A0 avrdude: sending 5 bytes [0x55, 0x6a, 0xa0, 0x12, 0x00] avrdude: ser_send: U [55] j [6a] . [a0] . [12] . [00] avrdude: ser_recv: U [55] j [6a] . [a0] . [12] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x0012C0 avrdude: ST_PTR to 0x0012C0 avrdude: sending 5 bytes [0x55, 0x6a, 0xc0, 0x12, 0x00] avrdude: ser_send: U [55] j [6a] . [c0] . [12] . [00] avrdude: ser_recv: U [55] j [6a] . [c0] . [12] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x0012E0 avrdude: ST_PTR to 0x0012E0 avrdude: sending 5 bytes [0x55, 0x6a, 0xe0, 0x12, 0x00] avrdude: ser_send: U [55] j [6a] . [e0] . [12] . [00] avrdude: ser_recv: U [55] j [6a] . [e0] . [12] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x001300 avrdude: ST_PTR to 0x001300 avrdude: sending 5 bytes [0x55, 0x6a, 0x00, 0x13, 0x00] avrdude: ser_send: U [55] j [6a] . [00] . [13] . [00] avrdude: ser_recv: U [55] j [6a] . [00] . [13] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x001320 avrdude: ST_PTR to 0x001320 avrdude: sending 5 bytes [0x55, 0x6a, 0x20, 0x13, 0x00] avrdude: ser_send: U [55] j [6a] [20] . [13] . [00] avrdude: ser_recv: U [55] j [6a] [20] . [13] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x001340 avrdude: ST_PTR to 0x001340 avrdude: sending 5 bytes [0x55, 0x6a, 0x40, 0x13, 0x00] avrdude: ser_send: U [55] j [6a] @ [40] . [13] . [00] avrdude: ser_recv: U [55] j [6a] @ [40] . [13] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x001360 avrdude: ST_PTR to 0x001360 avrdude: sending 5 bytes [0x55, 0x6a, 0x60, 0x13, 0x00] avrdude: ser_send: U [55] j [6a] ` [60] . [13] . [00] avrdude: ser_recv: U [55] j [6a] ` [60] . [13] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x001380 avrdude: ST_PTR to 0x001380 avrdude: sending 5 bytes [0x55, 0x6a, 0x80, 0x13, 0x00] avrdude: ser_send: U [55] j [6a] . [80] . [13] . [00] avrdude: ser_recv: U [55] j [6a] . [80] . [13] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x0013A0 avrdude: ST_PTR to 0x0013A0 avrdude: sending 5 bytes [0x55, 0x6a, 0xa0, 0x13, 0x00] avrdude: ser_send: U [55] j [6a] . [a0] . [13] . [00] avrdude: ser_recv: U [55] j [6a] . [a0] . [13] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x0013C0 avrdude: ST_PTR to 0x0013C0 avrdude: sending 5 bytes [0x55, 0x6a, 0xc0, 0x13, 0x00] avrdude: ser_send: U [55] j [6a] . [c0] . [13] . [00] avrdude: ser_recv: U [55] j [6a] . [c0] . [13] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] avrdude: reading 32 bytes from 0x0013E0 avrdude: ST_PTR to 0x0013E0 avrdude: sending 5 bytes [0x55, 0x6a, 0xe0, 0x13, 0x00] avrdude: ser_send: U [55] j [6a] . [e0] . [13] . [00] avrdude: ser_recv: U [55] j [6a] . [e0] . [13] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: repeat 32 avrdude: sending 3 bytes [0x55, 0xa0, 0x1f] avrdude: ser_send: U [55] . [a0] . [1f] avrdude: ser_recv: U [55] . [a0] . [1f] avrdude: LD8 from ptr++ avrdude: sending 2 bytes [0x55, 0x24] avrdude: ser_send: U [55] $ [24] avrdude: ser_recv: U [55] $ [24] avrdude: ser_recv: . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] . [ff] avrdude: received 32 bytes [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] Caching | ################################################## | 100% 0.25 s avrdude: synching cache to device ... Writing | | 0% 0.00 s avrdude: UPDI writing key avrdude: sending 2 bytes [0x55, 0xe0] avrdude: ser_send: U [55] . [e0] avrdude: ser_recv: U [55] . [e0] avrdude: sending 8 bytes [0x65, 0x74, 0x26, 0x73, 0x55, 0x4d, 0x56, 0x4e] avrdude: ser_send: e [65] t [74] & [26] s [73] U [55] M [4d] V [56] N [4e] avrdude: ser_recv: e [65] t [74] & [26] s [73] U [55] M [4d] V [56] N [4e] avrdude: LDCS from 0x07 avrdude: sending 2 bytes [0x55, 0x87] avrdude: ser_send: U [55] . [87] avrdude: ser_recv: U [55] . [87] avrdude: ser_recv: [20] avrdude: received 1 bytes [0x20] avrdude: key status: 0x20 avrdude: sending reset request avrdude: STCS 0x59 to address 0x08 avrdude: sending 3 bytes [0x55, 0xc8, 0x59] avrdude: ser_send: U [55] . [c8] Y [59] avrdude: ser_recv: U [55] . [c8] Y [59] avrdude: sending release reset request avrdude: STCS 0x00 to address 0x08 avrdude: sending 3 bytes [0x55, 0xc8, 0x00] avrdude: ser_send: U [55] . [c8] . [00] avrdude: ser_recv: U [55] . [c8] . [00] avrdude: LDCS from 0x0B avrdude: sending 2 bytes [0x55, 0x8b] avrdude: ser_send: U [55] . [8b] avrdude: ser_recv: U [55] . [8b] avrdude: ser_recv: $ [24] avrdude: received 1 bytes [0x24] avrdude: invalid length Writing | -------------------------------------------------- | 0% 0.02 s avrdude serialupdi_write_userrow() [serialupdi.c:546] error: writing USER ROW failed avrdude: serialupdi_write_byte(userrow, 0x0000, 0x54) avrdude: ST to 0x001200 avrdude: sending 5 bytes [0x55, 0x48, 0x00, 0x12, 0x00] avrdude: ser_send: U [55] H [48] . [00] . [12] . [00] avrdude: ser_recv: U [55] H [48] . [00] . [12] . [00] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: sending 1 bytes [0x54] avrdude: ser_send: T [54] avrdude: ser_recv: T [54] avrdude: ser_recv: @ [40] avrdude: received 1 bytes [0x40] avrdude: serialupdi_read_byte(userrow, 0x0000) avrdude: LD from 0x001200 avrdude: sending 5 bytes [0x55, 0x08, 0x00, 0x12, 0x00] avrdude: ser_send: U [55] . [08] . [00] . [12] . [00] avrdude: ser_recv: U [55] . [08] . [00] . [12] . [00] avrdude: ser_recv(): programmer is not responding avrdude: serialupdi_recv(): programmer is not responding avrdude: LD operation recv failed avrdude writeCachePage() [avrcache.c:301] error: userrow access error at addr 0x0000 avrdude: leaving NVM programming mode avrdude: sending reset request avrdude: STCS 0x59 to address 0x08 avrdude: sending 3 bytes [0x55, 0xc8, 0x59] avrdude: ser_send: U [55] . [c8] Y [59] avrdude: ser_recv: U [55] . [c8] Y [59] avrdude: sending release reset request avrdude: STCS 0x00 to address 0x08 avrdude: sending 3 bytes [0x55, 0xc8, 0x00] avrdude: ser_send: U [55] . [c8] . [00] avrdude: ser_recv: U [55] . [c8] . [00] avrdude: STCS 0x0C to address 0x03 avrdude: sending 3 bytes [0x55, 0xc3, 0x0c] avrdude: ser_send: U [55] . [c3] . [0c] avrdude: ser_recv: U [55] . [c3] . [0c] avrdude done. Thank you. ```

Root cause of the issue is the fact that so far all the USERROW memories were 64 bytes or smaller, and the implementations so far were based on the sequence of "set pointer; repeat ; write byte and increase pointer", which was fine as long as these memories were 256 bytes or less (this is limitation of the repeat command which takes single byte as a parameter.

Most probably the fix would be to change the USERROW write operation to "set pointer; repeat <number_of_bytes/2>; write 2-byte word and increase pointer", but this could introduce regression to all the old parts, so this needs to be tested carefully.

It would also be very helpful to have access to the datasheet of the chip in question, it might actually contain some guidelines for handling such a large memory.

@stefanrueger, @mcuee, @askn37 - do you think I should add any additional information here?

dbuchwald commented 6 months ago

@MCUdude I have prepared preliminary fix, which should not introduce any regression for previously tested chips:

https://github.com/dbuchwald/avrdude/tree/issue_1655

Can you check if it fixes issue on AVR64DU28?

Basically the change is that if the USERROW memory is larger than 256 bytes then word-based write operation is performed instead of the previously used byte-based write.

I have also tested word-based write of USERROW against AVR16EA28 and it seems to have worked just fine, so maybe some day we could simplify code by changing to word-based write for all the UPDI AVRs, but I wouldn't introduce this so late into release cycle.

askn37 commented 6 months ago

do you think I should add any additional information here?

I agree that you are absolutely right.

The maximum amount of memory that can be written with one set of repeated commands is 256 words, which is consistent with all known datasheet descriptions. At least I haven't read anything else written. And this is probably the upper limit that can be achieved with his current UPDI system. If a page size of 1024 bytes appears in the future, I think the specifications will probably be expanded or some kind of improvement will be proposed at that time.

MCUdude commented 6 months ago

I'm away for the weekend, but will be back and can continue testing on Sunday evening.

But is the userrow size 64 or 512 bytes?

dbuchwald commented 6 months ago

I'm away for the weekend, but will be back and can continue testing on Sunday evening.

Sure, sorry, didn't mean to rush you.

But is the userrow size 64 or 512 bytes?

For a minute I was hoping it was 64 bytes but no, after inspecting atpack and pymcuprog source I came to the conclusion that the size of USERROW memory for AVR64DU32 and AVR64DU28 is, indeed, 512 bytes.

askn37 commented 6 months ago

It is stated on page 3 to 4 of the brief note.

https://askn37.github.io/documents/AVR-DU-Product-Brief-DS40002328.pdf

screanshot

Even in this document, it is unlikely that you are confusing it with bit amount.

askn37 commented 6 months ago

The following products have been registered on Mouser and DigiKey.

FBP-AVR-DU-ISO26262 Development Software ISO 26262 Functional Safety Basic Package for the AVR DU MCU Family Factory Special Order: Obtain a quote to verify the current price, lead-time and ordering requirements of the manufacturer. https://www.mouser.fi/ProductDetail/Microchip-Technology/FBP-AVR-DU-ISO26262?qs=mELouGlnn3ezslVP1LToMA%3D%3D

It appears to be a development kit to obtain ISO 26262 approval. I had no idea it would be possible to pre-order items like this before the individual chips went on sale.

From this, we can infer that an automotive-grade derivative of AVR-DU also exists. This suggests that there may be signatures that differ from the usual products, such as the ATtiny416auto example.

MCUdude commented 6 months ago

@dbuchwald your suggested fix did the trick! 🚀

$ ./test-avrdude -p "-c serialupdi -pavr64du32 -P ch340" -e /Users/hans/Downloads/avrdude-terminal/src/avrdude
Testing /Users/hans/Downloads/avrdude-terminal/src/avrdude version 7.2-20230720
Prepare "-c serialupdi -pavr64du32 -P ch340" and press 'enter' or 'space' to continue. Press any other key to skip
✅   0.533 s: fuse access: clear, set and read eesave fuse bit
✅   0.504 s: fuse access: set eesave fusebit to delete EEPROM on chip erase
✅   0.504 s: chip erase
✅   3.934 s: flash -U write/verify holes_rjmp_loops_65536B.hex
✅   2.277 s: flash -T write/verify holes_rjmp_loops_65536B.hex
✅   0.576 s: eeprom check whether programmer can flip 0s to 1s
✅   2.986 s: eeprom -U write/verify holes_pack_my_box_256B.hex
✅   5.504 s: eeprom -T write/verify holes_{the_five_boxing_wizards,pack_my_box}_256B.hex
✅   2.379 s: chip erase and spot check flash is actually erased
✅   0.783 s: spot check eeprom is erased, too
✅   2.239 s: usersig -T/-U write/read random_data_512B.bin
stefanrueger commented 6 months ago

Brilliant! Thanks all round for ironing out this problem and confirming it has done so!

stefanrueger commented 6 months ago

@dbuchwald Could you do the honours and submit a PR, please?

dbuchwald commented 6 months ago

@MCUdude thanks for testing it. I'm really glad it worked!

@stefanrueger PR is ready here: https://github.com/avrdudes/avrdude/pull/1659