Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative fix proposal for #1832 #1835

Merged
merged 3 commits into from
Jul 15, 2024
Merged

Conversation

dbuchwald
Copy link
Contributor

This is alternative fix for issue #1832, but this one works with multiple bootrow write operations. When possible (v0/v3/v5), it uses NVMCTRL CTRLA page erase/page write operation, and when not available (v2/v4) it performs explicit page erase operation before page write.

@mcuee mcuee added the bug Something isn't working label Jul 6, 2024
@stefanrueger
Copy link
Collaborator

Works like a charm! I wondered about the byte write, though (see below)

Here my tests:

Creating a test file for AVR64DU28

$ avrdude -c dryrun -p 64du28 -xrandom -xseed=7 -U all:r:64du28-dry-backup.hex

avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9622 (probably 64du28)
         reading multiple memories ...
         eeprom          | ################################################## | 100% 0.00 s 
         flash           | ################################################## | 100% 0.00 s 
         fuses           | ################################################## | 100% 0.00 s 
         lock            | ################################################## | 100% 0.00 s 
         prodsig/sigrow  | ################################################## | 100% 0.00 s 
         bootrow         | ################################################## | 100% 0.00 s 
         userrow/usersig | ################################################## | 100% 0.00 s 
         sib             | ################################################## | 100% 0.00 s 
         writing 66740 bytes to output file 64du28-dry-backup.hex

avrdude done.  Thank you.

Writing test file to AVR64DU28 (incl bootrow)

$ avrdude -c serialupdi -p 64du28 -U all:w:64du28-dry-backup.hex

avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9622 (probably 64du28)
avrdude: NOT erasing chip as page erase will be used for new flash/bootrow contents
avrdude: reading 66740 bytes for multiple memories from input file 64du28-dry-backup.hex
avrdude: 256 bytes eeprom in 1 section [0, 0xff]
         writing 256 bytes to eeprom ...
         writing | ################################################## | 100% 10.24 s 
         reading | ################################################## | 100% 1.06 s 
         256 bytes of eeprom verified
avrdude: 65536 bytes flash in 1 section [0, 0xffff]: 128 pages and 0 pad bytes
         writing 65536 bytes to flash ...
         writing | ################################################## | 100% 14.04 s 
         reading | ################################################## | 100% 8.97 s 
         65536 bytes of flash verified
avrdude: 16 bytes fuses in 1 section [0, 15]
         writing 16 bytes to fuses ..., 16 bytes written, 16 verified
avrdude: 4 bytes lock in 1 section [0, 3]
         writing 4 bytes to lock ..., 4 bytes written, 4 verified
avrdude: 256 bytes bootrow in 1 section [0, 0xff]: 1 page and 0 pad bytes
         writing 256 bytes to bootrow ...
         writing | ################################################## | 100% 0.08 s 
         reading | ################################################## | 100% 0.04 s 
         256 bytes of bootrow verified
avrdude: 512 bytes userrow/usersig in 1 section [0, 0x1ff]: 1 page and 0 pad bytes
         writing 512 bytes to userrow/usersig ...
         writing | ################################################## | 100% 0.20 s 
         reading | ################################################## | 100% 0.23 s 
         512 bytes of userrow/usersig verified

avrdude done.  Thank you.

Writing bootrow a second time

$ avrdude -c serialupdi -p 64du28 -U bootrow:w:'"This is a test"':m

avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9622 (probably 64du28)
avrdude: reading 15 bytes for bootrow from input file "This is a test"
         in 1 section [0, 14]: 1 page and 241 pad bytes
         writing 15 bytes to bootrow ...
         writing | ################################################## | 100% 0.14 s 
         reading | ################################################## | 100% 0.04 s 
         15 bytes of bootrow verified

avrdude done.  Thank you.

Reading bootrow

$ avrdude -c serialupdi -p 64du28 -U bootrow:r:-:I

avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9622 (probably 64du28)
         reading bootrow memory ...
         reading | ################################################## | 100% 0.04 s 
         writing 256 bytes to output file <stdout>
:200000005468697320697320612074657374002020204040402040204040404020402020AB // 00000> This is a test.   @@@ @ @@@@ @   bootrow
:200020002020402040202040204040404040402040404020404020204040202020202020C0 // 00020>   @ @  @ @@@@@@ @@@ @@  @@      
:200040002020402040402020402020404040402020202020402040402020404020402020E0 // 00040>   @ @@  @  @@@@     @ @@  @@ @  
:20006000404020404040402040404020404020402040402020404020402040402020402000 // 00060> @@ @@@@ @@@ @@ @ @@  @@ @ @@  @ 
:20008000202020204040204020204020204040204020204040404020402020404020402080 // 00080>     @@ @  @  @@ @  @@@@ @  @@ @ 
:2000A000402040202040402040202040404020404040402040202040202020202020202080 // 000a0> @ @  @@ @  @@@ @@@@ @  @        
:2000C0004040202020402040204040404040204040204020404020402040402040404020A0 // 000c0> @@   @ @ @@@@@ @@ @ @@ @ @@ @@@ 
:2000E00040202020404020404040202020204020204040202040204020626F6F74726F7774 // 000e0> @   @@ @@@    @  @@  @ @ bootrow
:00000001FF

avrdude done.  Thank you.

This has tested the paged r/w functions. Bytewise is not needed as AVRDUDE treats bootrow as paged memory.

I don't know much about UPDI, and wondered how it implements bytewise write to flash-like memories. Seeing that this PR implements bytewise access, I temporarily forced AVRDUDE to use bytewise access by setting page_size to 1:

Change to force bytewise access

diff --git a/src/avrdude.conf.in b/src/avrdude.conf.in
index 035dd141..aa186aaf 100644
--- a/src/avrdude.conf.in
+++ b/src/avrdude.conf.in
@@ -24398,9 +24398,9 @@ part parent "64dd28" # 64du28
 
     memory "bootrow"
         size               = 256;
-        page_size          = 256;
+        page_size          = 1;
         offset             = 0x1100;
-        readsize           = 256;
+        readsize           = 1;
     ;
 
     memory "userrow"

Reading bootrow still works (but slower)

$ avrdude -c serialupdi -p 64du28 -U bootrow:r:-:I

avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9622 (probably 64du28)
         reading bootrow memory ...
         reading | ################################################## | 100% 0.04 s 
         writing 256 bytes to output file <stdout>
:200000005468697320697320612074657374002020204040402040204040404020402020AB // 00000> This is a test.   @@@ @ @@@@ @   bootrow
:200020002020402040202040204040404040402040404020404020204040202020202020C0 // 00020>   @ @  @ @@@@@@ @@@ @@  @@      
:200040002020402040402020402020404040402020202020402040402020404020402020E0 // 00040>   @ @@  @  @@@@     @ @@  @@ @  
:20006000404020404040402040404020404020402040402020404020402040402020402000 // 00060> @@ @@@@ @@@ @@ @ @@  @@ @ @@  @ 
:20008000202020204040204020204020204040204020204040404020402020404020402080 // 00080>     @@ @  @  @@ @  @@@@ @  @@ @ 
:2000A000402040202040402040202040404020404040402040202040202020202020202080 // 000a0> @ @  @@ @  @@@ @@@@ @  @        
:2000C0004040202020402040204040404040204040204020404020402040402040404020A0 // 000c0> @@   @ @ @@@@@ @@ @ @@ @ @@ @@@ 
:2000E00040202020404020404040202020204020204040202040204020626F6F74726F7774 // 000e0> @   @@ @@@    @  @@  @ @ bootrow
:00000001FF

avrdude done.  Thank you.

... but writing fails

$ avrdude -c serialupdi -p 64du28 -U bootrow:w:'"This is a test"':m

avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9622 (probably 64du28)
avrdude: reading 15 bytes for bootrow from input file "This is a test"
         in 1 section [0, 14]
         writing 15 bytes to bootrow ...
         writing | -------------------------------------------------- | 0% 10.06 s 
avrdude error: wait NVM ready timed out
avrdude error: command buffer erase failed
 *** failed
avrdude error: unable to write bootrow (rc = -1)

avrdude done.  Thank you.

Here trace.txt from

$ avrdude -c serialupdi -p 64du28 -U bootrow:w:'"This is a test"':m -vvvl trace.txt

I am 100% OK with this PR because only paged access is needed for bootrow, but just (out of curiosity) wonder how bytewise write to flash works in UPDI.

@stefanrueger stefanrueger linked an issue Jul 7, 2024 that may be closed by this pull request
@stefanrueger stefanrueger merged commit 6039247 into avrdudes:main Jul 15, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bootrow r/w does not work for -c serialupdi
3 participants