I'm trying to program the ATSAMD21G18 on Adafruit Feather M0 and over SWD Using a Segger J-Link EDU Nano.

When I try to download the program to the chip through Atmel Studio it fails verification at address 0x000000. This result is explained by the NVM Fuse field USER_WORD_0.NVMCRL_BOOTPROT, which is set to 2 protecting the first 8192 bytes in the flash. (I can verify this is actually the case by writing to individual bytes in flash, writing has no effect for addresses below 0x2000).

However, everything I have tried to change this memory has failed. Atmel studio reports a verification fail at the address of the Fuse (0x0804000). J-Link Commander doesn't report any error writing, but when I read back the value of the fuse has not changed.

  • 1
    \$\begingroup\$ you read the atmel documentation and followed what it said to unlock those registers? please post your code. \$\endgroup\$ – old_timer May 14 '19 at 12:20
  • \$\begingroup\$ Right now there's no code in memory as I erased the entire flash with the chip erase command. I'm trying to access that memory from the programming interface, not the application code. I haven't noticed any procedure to unlock the fuses. The lock bits are in NVM User row which is mapped to 0x0804000 address. \$\endgroup\$ – chamod May 14 '19 at 22:29
  • \$\begingroup\$ @old_timer I misinterpreted datasheet thinking just because the area was mapped to memory addresses I could write to it. Only after I took a look at this code I realized the write access method is different (Section 22.6.4 on datasheet). I managed to follow the steps manually through j-Link commander and got it working. \$\endgroup\$ – chamod May 15 '19 at 0:07
  • 1
    \$\begingroup\$ I'm trying to disable BOOTPROT on a SAMD21 using a Stlink V2 - could you please post your solution as an answer in more detail? It would be helpful in getting it to work on the STlink \$\endgroup\$ – Peter Gibson Aug 15 '19 at 4:11
  • \$\begingroup\$ @PeterGibson I don't have a feather M0 at hand to verify, but I tried on a custom board using the same MCU and it worked as expected. \$\endgroup\$ – chamod Aug 15 '19 at 5:44

I found out that in order to write to the NVM, you have to talk to it though the NVMC. (NVM controller). The steps to changing the BOOTPROT fuses are as follows. (I extracted these steps from the source code of Black Magic Probe

  1. Read NVM User Row HIGH and LOW words and record them somewhere.
  2. Load the address of NVM User Row LOW word into the NVMC address register. (Right shifted by one)
  3. Issue the NVRAM Erase AUX Row command by writing 0xa505 to NVMC Control A register
  4. Modify the User Row Low as per requirements. (In order to unlock the whole bootloader region you have to set the 3 least significant bits to high)
  5. Write the modified User row LOW and HIGH back to the original addresses.
  6. Issue the NVRAM Write Aux Page command by writing 0xa506 to NVMC Control A register.

I did this on J-Link commander console, so the commands I issued were as follows.

mem32 0x0x00804000, 1 #Note this, this is the low word of NVM User Row 
mem32 0x0x00804004, 1 #High word of NVM User row

w4 0x4100401c, 0x0x00402000 #Load the address of User row LOW to address register
#Datasheet says this address has to be right shifted by 1 for some reason

w4 0x41004000, 0xa505 #Issue the erase aux command

#write modified to low and high
w4 0x0x00804000, modified_low_word
w4 0x0x00804004, high_word

w4  0x41004000, 0xa506 #issue write command

Note that I did this by hand, so there was quite a bit of delay between the commands. If you're going to script this somehow, it's important to poll the NVMC Ready flag in between commands. (Bit 0 of NVMC INFLAG register)

  • \$\begingroup\$ Thanks so much for this. I'm not even sure this is possible with the Stlink V2, but this is a great help \$\endgroup\$ – Peter Gibson Aug 15 '19 at 6:05
  • \$\begingroup\$ Now the real question is how the chip ended up like that in the first place. \$\endgroup\$ – Lundin Aug 15 '19 at 6:23
  • \$\begingroup\$ I think in my case, I ran into a bug with OpenOCD while trying to flash it with the STLink. Thanks for the link to the Black Magic Probe - I ended up flashing the BMP firmware on a spare Blue Pill board and using the monitor unlock_bootprot command directly to unlock the SAMD. Posted details below. \$\endgroup\$ – Peter Gibson Aug 16 '19 at 3:07

Not an answer to the above, but perhaps relevant to others who end up here. I was trying to flash a SAMD21 using the STLink V2, but ran into issues with the boot protection (possibly due to a bug in OpenOCD)

According to this answer this is not a recommended configuration https://electronics.stackexchange.com/a/371297/554

I ended up using the STLink-v2 to flash a spare STM32 Blue Pill with the Black Magic Probe firmware by following these instructions https://buger.dread.cz/category/stm32.html

Then used the Black Magic Probe (through GDB) to unlock the boot protection and flash the SAMD21

$ /home/peter/snap/arduino-mhall119/5/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-gdb

(gdb) target extended-remote /dev/ttyACM0
Remote debugging using /dev/ttyACM0
(gdb) monitor swdp_scan
Available Targets:
No. Att Driver
 1      Atmel SAMD21G18A (rev D) M0+
(gdb) attach 1
Attaching to Remote target
warning: No executable has been specified and target does not support
determining executable automatically.  Try using the "file" command.
0x00001314 in ?? ()
(gdb) file samd21_sam_ba.hex 
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from samd21_sam_ba.hex...(no debugging symbols found)...done.
(gdb) monitor unlock_flash
(gdb) monitor unlock_bootprot
(gdb) monitor erase_mass     
Erase successful!
(gdb) load
Loading section .sec1, size 0x1968 lma 0x0
Start address 0x60c, load size 6504
Transfer rate: 37 KB/sec, 929 bytes/write.

The monitor command in GDB has MCU specific extensions that only appear once attached to the target.

  • \$\begingroup\$ thank you so much! Worked perfectly to unlock the bootloader of an adafruit trinket m0. \$\endgroup\$ – sarfata Oct 30 '19 at 5:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.