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, 2019 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, 2019 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, 2019 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\$ Aug 15, 2019 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, 2019 at 5:44

3 Answers 3


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 0x00804000, 1 #Note this, this is the low word of NVM User Row 
mem32 0x00804004, 1 #High word of NVM User row

w4 0x4100401c, 0x00402000 #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 0x00804000, modified_low_word
w4 0x00804004, 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\$ Aug 15, 2019 at 6:05
  • \$\begingroup\$ Now the real question is how the chip ended up like that in the first place. \$\endgroup\$
    – Lundin
    Aug 15, 2019 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\$ Aug 16, 2019 at 3:07
  • \$\begingroup\$ I was able to do this using an st link and openocd using the mww and mdw commands. \$\endgroup\$
    – munchausen
    Jul 16, 2021 at 16:11

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, 2019 at 5:03

This procedure also works for ATSAMD21E17 and probably others. You can create a script for jlink.exe to execute all the steps:


device ATSAMD21E17D  ;connect
si swd               ;select swd programming interface
speed 4000           ;set speed 4khz
r                    ;reset
sleep 250            ;sleep  msec
w4 00804000, D8E0C7FF;user area low word
sleep 250            ;sleep  msec
w4 00804004, FFFFFC5D;user area high word
sleep 250            ;sleep  msec
w4  41004000, a506   ;issue write command
sleep 250            ;sleep  msec
                     ;check if written
mem32 0x00804000, 1  ;check if erased
mem32 0x00804004, 1  ; check if erase


run with

jlink.exe -device ATSAMD21E17D -autoconnect 1 -commanderscript jlink_script

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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