avrdudes / avrdude

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

Writing BOOTROW for Curiosity Nano #1868

Closed askn37 closed 2 months ago

askn37 commented 2 months ago

This is a valid suggestion for the following products. It may also be valid for the AVR-DU/EB series and PICKit4.

diff --git a/src/jtag3.c b/src/jtag3.c
index e164a157..51223fb4 100644
--- a/src/jtag3.c
+++ b/src/jtag3.c
@@ -1883,6 +1883,12 @@ static int jtag3_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRME
     cmd[3] = XMEGA_ERASE_EEPROM_PAGE;
   } else if (mem_is_userrow(m)) {
     cmd[3] = XMEGA_ERASE_USERSIG;
+  } else if (mem_is_bootrow(m)) {
+    cmd[3] = XMEGA_ERASE_USERSIG;
+    // TENTATIVE: This is inaccurate, but preferable to XMEGA_ERASE_APP_PAGE.
+    // Quote ATDF: <memory-segment name="BOOTROW", ... type="user_signatures"/>
+    // But you can't actually erase it.
+    // nEDBG, ICE-FW <= 1.31 (rel 39), BOOTROW can only be cleared by a chip erase.
   } else {
     cmd[3] = XMEGA_ERASE_APP_PAGE;
   }
@@ -1952,7 +1958,8 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM
     }
     cmd[3] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM_PAGE;
     PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
-  } else if (mem_is_userrow(m)) {
+  } else if (mem_is_userrow(m) || mem_is_bootrow(m)) {
+    // BOOTROW can be written to like USERSIG, but it cannot be erased.
     cmd[3] = MTYPE_USERSIG;
   } else if (mem_is_boot(m)) {
     cmd[3] = MTYPE_BOOT_FLASH;
@@ -2040,7 +2047,7 @@ static int jtag3_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRME
       return -1;
   } else if (mem_is_sigrow(m)) {
     cmd[3] = MTYPE_PRODSIG;
-  } else if (mem_is_userrow(m)) {
+  } else if (mem_is_userrow(m) || mem_is_bootrow(m)) {
     cmd[3] = MTYPE_USERSIG;
   } else if (mem_is_boot(m)) {
     cmd[3] = MTYPE_BOOT_FLASH;
@@ -2149,7 +2156,8 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
     cmd[3] = MTYPE_LOCK_BITS;
     if (pgm->flag & PGM_FL_IS_DW)
       unsupp = 1;
-  } else if (mem_is_userrow(mem)) {
+  } else if (mem_is_userrow(mem) || mem_is_bootrow(mem)) {
+    // BOOTROW can be written to like USERSIG, but it cannot be erased.
     cmd[3] = MTYPE_USERSIG;
   } else if (mem_is_sigrow(mem)) {
     if (p->prog_modes & (PM_PDI | PM_UPDI)) {
@@ -2322,7 +2330,8 @@ static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRME
     cmd[3] = MTYPE_LOCK_BITS;
     if (pgm->flag & PGM_FL_IS_DW)
       unsupp = 1;
-  } else if (mem_is_userrow(mem)) {
+  } else if (mem_is_userrow(mem) || mem_is_bootrow(mem)) {
+    // BOOTROW can be written to like USERSIG, but it cannot be erased.
     cmd[3] = MTYPE_USERSIG;
   } else if (mem_is_io(mem) || mem_is_sram(mem))
     cmd[3] = MTYPE_SRAM;

Before the patch, BOOTROW can only be read, rewriting fails, and pages cannot be erased.

After the patch, BOOTROW can be rewritten with the following exceptions:

The basis for the fix is ​​the following statement in the ATDF file:

               <memory-segment exec="0"
                               name="BOOTROW"
                               pagesize="0x40"
                               rw="RW"
                               size="0x40"
                               start="0x1100"
                               type="user_signatures"/>

Based on this explanation, we will provisionally treat BOOTROW as a "user_signatures" type.

stefanrueger commented 2 months ago

@askn37 Great contribution! Thanks. We have a preference for PRs as opposed to patches. That reduces maintainer workload and gives credit to the person who came up with the code. Would you be so kind to submit a PR? Thanks!

Small tip: perhaps clarify in all related comments that it is nEDBG (FW <= ... ) cannot erase BOOTROW as bootrow can be erased by other drivers, eg, serialudpi.

MCUdude commented 2 months ago

Confirmed: "Curiosity Nano AVR32DU32" ICE-FW(nEDBG) <= 1.31 (rel 39) - Page-Erase fail "Curiosity Nano AVR16EB32" and PICKit4 have not been tested yet. https://github.com/avrdudes/avrdude/issues/1868

I can test the AVR-EB using a Curiosity Nano and a PICkit4

askn37 commented 2 months ago

@MCUdude

I can test the AVR-EB using a Curiosity Nano and a PICkit4

Can you help me? Unfortunately, I only realized yesterday that "Curiosity Nano AVR16EB32" is not on my shopping list. It's a shame that I can't buy PICKit4 again.