# SAMD21 - How do I write to NVM fuses?

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.

• you read the atmel documentation and followed what it said to unlock those registers? please post your code. – old_timer May 14 at 12:20
• 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. – chamod May 14 at 22:29
• @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. – chamod May 15 at 0:07
• 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 – Peter Gibson Aug 15 at 4:11
• @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. – chamod Aug 15 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

#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)

• Thanks so much for this. I'm not even sure this is possible with the Stlink V2, but this is a great help – Peter Gibson Aug 15 at 6:05
• Now the real question is how the chip ended up like that in the first place. – Lundin Aug 15 at 6:23
• 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. – Peter Gibson Aug 16 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!

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