How to upload arduino bootloader to a custom samd21 usig Jlink mini

Hello I just made a custom samd21 (ATSAMD21E15B) board and would like to place a arduino bootloader so i can easily upload code onto it.

I have already connected the RST, SWDIO, SWCLK, 3v3, and ground to the jlink mini edu.

I do not know what to do now :sweat_smile:

Anyone can guide me thru the steps?

Thanks !

Install Atmel Studio 7 if you want a pretty GUI...

Yes sir, done ! What to do next?

to burn bootloader in Arduino IDE select the board, select the EDBG programmer and use Burn Bootloader

  1. Connect the programmer's SWD connector to your board. Power your board, then the programmer.

  2. In the Atmel Studio 7 menu go to: Tool->Device Programming

  3. Select you programming tool from the drop-down list. Your microcontroller should be detected.

  4. Click on the Apply and Read buttons.

  5. Go to the Fuses section and check that the BOOTPROT fuse is set to 0x7 or 0K. If not change it to 0x7 or 0K. This is to remove the bootloader protection, if any were set previously.

  6. Go to the Memories section and enter the bootloader binary (*.bin) file in the top flash section. Make sure the Erase and Verify check boxes are ticked.

  7. Press the Program button. Your microcontroller's flash memory should be erased, programmed and verified.

The bootloader should be uploaded to you board's microcontroller. Thereafter it should be possible to remove the programmer and upload sketches via the microcontroller's native USB port.

Sorry I took so long to reply,

I could not find BOOTPROT under fuses

Also i do not have the bootloader binary yet, Where can i get those?

Oh the arduino IDE can bun bootloaders, My pc cant detect the board though. im not sure yet if there is some problem on the usb circuit.

Using the JLink mini edu my board is detected so i know the mCU is working properly. Hopefully the pc will detect the board after the placing a bootloader

That's no obstacle to burning the bootloader. It's only required that the PC can communicate with the J-Link. The J-Link handles the communication with the SAMD21 microcontroller to flash the bootloader.

Will using the bootloader of any SAMD21 board work? since im not using the exact same samd21 chip as any arduino board

Hi @John41234

No, it's not possible to use any SAMD21 bootloader. Generally you can get away with using the Arduino Zero bootloader for different SAMD21 E, G & J sized variants, but this only works for those devices with the maximum 256KB flash and 32KB RAM.

Since you mention that you're using the SAMD21E15B with a reduced memory footprint of 32KB flash 4KB RAM, you'll either need to find a precompiled binary for a SAMD21x15A device, or create your own. Creating your own also has the advantage in that it allows you account for status LEDs on your custom board.

The Atmel Studio 7 solution/project files for the SAMD21 are stored in the Arduino Zero's bootloader directory. On my PC it's located here:

C:\Users\Computer\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.8.11\bootloaders\zero

I suggest first copying entire Zero bootloader folder to one with another name and use that, rather than modifying the Arduino Zero's bootloader files directly.

The solution to open in Atmel/Microchip Studio is the Atmel Solution or .atsln file.

The files you need to modify are:

1. board_definitions_arduino_zero.h

You'll need to change the address of the double tap reset "magic number". This is usually stored in the last 4 bytes of RAM, hence if you use the Arduino Zero's bootloader for a device with larger memory you double tap reset won't work. In the code below I've modified tha address to account for the SAMD21E15B's 4K of RAM:

/*
 * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by
 * quickly tapping two times on the reset button.
 * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not
 * be touched from the loaded application.
 */
//#define BOOT_DOUBLE_TAP_ADDRESS           (0x20007FFCul)
#define BOOT_DOUBLE_TAP_ADDRESS           (0x20000FFCul)    // 4K RAM - 4 bytes
#define BOOT_DOUBLE_TAP_DATA              (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS))

In this file you can also configure if you'd also like the option to upload from a serial port as well:

#define BOOT_USART_MODULE                 SERCOM0
#define BOOT_USART_BUS_CLOCK_INDEX        PM_APBCMASK_SERCOM0
#define BOOT_USART_PER_CLOCK_INDEX        GCLK_CLKCTRL_ID_SERCOM0_CORE_Val
#define BOOT_USART_PAD_SETTINGS           UART_RX_PAD3_TX_PAD2
#define BOOT_USART_PAD3                   PINMUX_PA11C_SERCOM0_PAD3
#define BOOT_USART_PAD2                   PINMUX_PA10C_SERCOM0_PAD2
#define BOOT_USART_PAD1                   PINMUX_UNUSED
#define BOOT_USART_PAD0                   PINMUX_UNUSED

If your custom board is CRYSTALLESS, (uses the SAMD21's intenal 32k oscillator instead of an external 32k crystal):

/* Frequency of the board main oscillator */
#define VARIANT_MAINOSC                   (32768ul)
#define CRYSTALLESS                       (1)

If you need to change any of the status/communication LEDs:

/*
 * LEDs definitions
 */
#define BOARD_LED_PORT                    (0)
#define BOARD_LED_PIN                     (17)

#define BOARD_LEDRX_PORT                  (1)
#define BOARD_LEDRX_PIN                   (3)

#define BOARD_LEDTX_PORT                  (0)
#define BOARD_LEDTX_PIN                   (27)

2. bootloader_samd21x18.ld

This is the linker script file that also need changing to account for the microcontroller's memory. Again I've modified the lines for the SAMD21E15B's 4KB RAM:

MEMORY
{
  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x2000 /* First 8KB used by bootloader */
  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00001000-0x0004 /* last 4 bytes used by bootloader to keep data between resets */
}

Once the files have been modified and saved, compile. This should create a binary (*.bin) that you can upload to your microcontroller.

1 Like

The BOOTPROT fuse should be there, I think you just need to scroll up a bit.

I think i have found it, dont know if it is the right one since it wont let me set it to 0x7, here are the images of all the fuse names.


Older versions of Atmel Studio 7 simply give the hexidecmal value of the fuse bitfield, while newer ones attempt to give the user a more human readable output.

The BOOTPROT bifield of 0x7 is the same as 0 Bytes, in other words the bootloader isn't protected.

May i know how the numbering works? i do not have a Rx Tx Leds, but i do have an indicator led on PA15. So PA15 is that port 0, pin 15?

/*
 * LEDs definitions
 */
#define BOARD_LED_PORT                    (0)
#define BOARD_LED_PIN                     (15)

#define BOARD_LEDRX_PORT                  (0)
#define BOARD_LEDRX_PIN                   (0)

#define BOARD_LEDTX_PORT                  (0)
#define BOARD_LEDTX_PIN                   (0)

Is this corect?

Yes, that's correct.

Do i need to change anything here? I do want to upload from usb, im using the native USB of the chip which is PA24 and PA25

Thank you vey much for taking the time in helping me good sir.

With regard to the Rx and Tx LEDs I usually routed them to unused port pins. If that's not possible you could try commenting out these lines, although I haven't looked to see if the bootloader code checks for their existance or not?

As it stands the Arduino Zero's bootloader is able to upload from D0 (PA11) and D1 (PA10), in addition to the native USB port, but only when the native USB is disconnected.

If you've got an external Serial port on your board you could route it to that.

@John41234 I just had a look at the bootloader code and it does check to see if the Tx and Rx LEDs are defined, so it should be OK just to comment out those lines.