ATSAMD51G18A compatibility with Adafruit Metro M4

Hi all,

I've been trying to get a board working with Arduino that uses an ATSAMD51G18A chip. I thought the Adafruit Metro M4 was basically equivalent, so I started working with that. However, once I upload a sketch, it appears that the microcontroller locks up or is otherwise not working. Once I double tap the reset button, I'm back in bootloader mode and I can try again.

The bootloader is the standard bootloader that I compiled with the ATSAMD51G18A chip rather than the ATSAMD51J19A chip like on the Metro M4 board. I was really hoping it was just a bootloader issue, but using mine or the stock Metro M4 bootloader seems to produce the same results.

My (limited) understanding was that these ARM chips were basically pin compatible, so besides missing some pins and some flash, everything should work. Does anybody have a deeper understanding than me that can help point me in the right direction? Would deleting all the extra pins help at all?

I appreciate any light you can shed.


Hi rondrop,

The issue could be that the bootloader is configured for SAMD51J19A/SAMD51G19A with 512kB flash and 192kB RAM, while the SAMD51G18A uses 256kB flash and 128kB flash.

The following example are the changes I needed to make for my custom SAMD51J20A board with 1MB flash and 256kB RAM.

To account for this it's necessary to firstly change the location of the double tap (reset) address, that's stored in the the last RAM location. This is in the bootloader definition file (board_definitions_metro_m4.h) in the "bootloader" directory, you'll need to recompile the bootloader:

#define BOOT_DOUBLE_TAP_ADDRESS           (0x2003FFFCul)

The address is 4 bytes back from the last location in RAM.

This file also contains the definitions for the bootloader's LEDs and serial port pins.

Secondly, you'll also need to change the flash and RAM memory configuration in the flash with and without bootloader linker scripts, (flash_with_bootloader.ld and flash_without_bootloader.ld files) in the "variant" directory:

  FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00100000-0x4000 /* First 16KB used by bootloader */
  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000
  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000
  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000

Thirdly the memory configuration should also be specified in the "boards.txt" file:


... the "boards.txt" file should also specify the microcontroller itself: -D__SAMD51__ {build.usb_flags} -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16

The bootloader starting up, but the sketch stalling can also occur if there's a problem with the board's external 32.768kHz crystal. The bootloader runs crystalless so is unaffected and runs as normal, but stalls when switching over to the external oscillator.

Hi MartinL!

Thanks for you very detailed reply! Unfortunately, I’ve never been particularly good with setting up compilers, and when I try to open the project file for the bootloader in Atmel Studio, it doesn’t compile. Looks like it can’t find files. Running ‘make’ says the same things. Maybe if I move the bootloader file to my Atmel Studio directory it would work?

Anyway, I tried using the UF2 bootloader code from Github (GitHub - microsoft/uf2-samdx1: USB Mass Storage bootloader (based on UF2) for SAMD21 and SAMD51), which has a chip definition for the ATSAMD51G18A. I was able to successfully compile that, and I’m hoping that is equivalent to the Adafruit version. All I did was change the chip, so I’m also hoping that all the required changes were made!

I did change the board definition file to reflect the smaller flash size. There was a sketch offset parameter, but I tried changing that from 0x4000 to 0x2000 with no change.

I did not realize that the bootloader was crystalless. I will try to verify that my crystal is working. Is there an easy way to make the bootloader use the crystal, so then I will know it’s not working if the board is completely dead?

Hi rondrop,

You could try configuring the board (an thereby sketches) to run crystalless (like the Adafruit Itsy Bitsy M4) by setting the -DCRYSTALLESS flag in the "boards.txt" file: -DADAFRUIT_ITSYBITSY_M4_EXPRESS -D__SAMD51__ {build.usb_flags} -D__FPU_PRESENT -DARM_MATH_CM4 -DCRYSTALLESS -mfloat-abi=hard -mfpu=fpv4-sp-d16

This might be the easiest way to check if the external crystal is an issue.

No luck running it crystalless. I’ll spend some time trying to compile the adafruit bootloader rather than the basic UF2 bootloader and see if that works.

As a side note, if anyone has experience building the Adafruit Metro M4 bootloader code, I'm having a ton of trouble. The readme says "type make" and it'll compile for the Metro M4. Nothing but problems. Says board ID not defined, uint8_t not defined, PORTx not defined, etc. Running make at the command line and opening the files in Atmel Studio both produce errors. Is there something I'm missing?

Hi rondrop,

To compile the UF2 bootloader with a Makefile, it's necessary to download and install the "Create Project from Makefile" extension for Atmel Studio 7:

After installation this appears as on option in Atmel Studio 7's "Tools" menu.

I tried the “Make from Makefile” and just opened the Studio 7 solution file that already existed in the bootloader folder. Still nothing. Seems like required includes aren’t making it in for some reason. Even the script for building all the bootloaders doesn’t work for me.

The Adafruit Itsy-Bitsy M4 uses a SAMD51G (48pin) part - can you just use the itsybitsy Core from adafruit?

I tried the "Make from Makefile" and just opened the Studio 7 solution file that already existed in the bootloader folder. Still nothing. Seems like required includes aren't making it in for some reason. Even the script for building all the bootloaders doesn't work for me.

Have you tried downloading and installing the Atmel Studio 7 extension "Create Project from Makefile" I provided in the link?

Atmel Studio 7 requires this extension, to build the project from the Makefile supplied with the UF2 bootloader code.

Hi westfw,

Thanks for that tip. I didn’t realize it was the 48 pin part for that, and it runs without a crystal (if for some reason my crystal isn’t working). Unfortunately, it still doesn’t work for me. And interestingly, after about 10 seconds or so, it’ll reset with this bootloader, and pop up the bootloader drive. RAM size and flash size problem?


I did install the “Create project from Makefile” extension, and created a project with the Makefile in the bootloader folder. Still no dice. All the standard definitions are missing somehow. See the picture I uploaded. Stuff like this I just can’t understand, especially considering Adafruit says it’s readily compile-able.

I’m ordering some of the G19A parts to replace the G18A on the board I have and hope for the best.



Hi Ron,

Using the G19A will make things easier, as you’ll be able to simply upload the standard Metro M4’s UF2 bootloader.

I’ve just noticed that Adafruit include the Atmel Studio 7 solution (.atsln) and project (.cproj) files with their Metro M4 bootloader in the directory “…\bootloader\MetroM4…”. This should allow you to successfully build the UF2 bootloader without resorting to the Makefile.

The other thing is that Adafruit forked the Microsoft “uf2-samdx1” project and now maintain their own copy on Github: GitHub - adafruit/uf2-samdx1: MSC bootloader (based on UF2) for SAMD21. The bootloader binaries can be found here:

Thanks for your help Martin.

When I try to open the studio files, it fails to compile. I don't know whats wrong. I don't know why those basic definitions are failing, but maybe I don't have something configured right?

I ordered the G19A, so I'll see if I can get the stock bootloader to work tomorrow. Otherwise I'm stumped why the bootloader modified for the G18A won't work at all.

Ok, the ATSAMD51G19A chips came in today, and after swapping it in, the default Adafruit bootloader works, or rather, with the "correct" bootloader, the sketch will run after uploading. Interesting note, I selected the Feather M4 instead of the Metro M4, because I had butchered the boards.txt definitions.

I'm going to go back and reload the stock Adafruit board defs, as well as try out my "custom" bootloaders specified for this particular chip and see what I see. I'm still not satisfied with these results, because I don't see why the other variant can't work based on all of these changes. I'll post what I find.

Ok, so uploading my "modified" bootloader for the G19A chip works. There must be more chip definitions hidden that aren't in the general makefile for the board. I would think that changing the chip family would change whatever is necessary, but apparently not.

Anyway, thanks for all your help. It'd still be nice to know what was wrong...