128k vs 256k ATSAMD21

Hi all - I have a project I'm developing that uses an ATSAMD21G18A, same as the Arduino Zero. I'm not using all of the 256k flash space nor the full RAM, but I do need the extra pins to allow me more access to the SERCOMs. I have been experimenting with the ATSAMD21G17A, which is the 128k flash variant and so far everything is working. I added a new board to the IDE and my code compiles and runs fine.

Will I run into any issues by using the 128k version of the part? The cost savings from the 'G17 is significant over the life of the product, and if I have no issues then I have another couple of designs I could migrate to the 128k version to reduce my costs.

I think that if I use less than the 128k plus bootloader size of flash, and don't need more memory than the 128k part has I should be okay. The code I compile for the G17 runs fine on the G18.

If anyone has experience with the smaller flash unit's I'd be very happy to know. I'm currently using the ATSAMD21E17 on several other designs with a different core, and have had no issues with them.

Hi pharaohamps,

It's been a while since I set up a custom board for another SAMD21 variant. As far as I can remember it requires the following changes:

1. Boards.txt File

In the "boards.txt" the memory size and the variant compiler flags:

arduino_zero_native.upload.maximum_size=262144
arduino_zero_native.build.extra_flags=-D__SAMD21G18A__ {build.usb_flags}

2. Linker Scripts

The linker scripts can be found in the .../variants/... folder in the Arduino core files.

The linker script files "flash_with_bootloader.ld" and/or "flash_without_bootloader" memory map (at the head of each file):

/* Linker script to configure memory regions.
 * Need modifying for a specific board.
 *   FLASH.ORIGIN: starting address of flash
 *   FLASH.LENGTH: length of flash
 *   RAM.ORIGIN: starting address of RAM bank 0
 *   RAM.LENGTH: length of RAM bank 0
 */
MEMORY
{
  FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */
  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}

3. Bootloader Double Tap Reset

In the bootloader "boards_definitions.h" file, the double tap address needs to be placed 4 bytes from the end of the 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_DATA              (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS))

MartinL, thanks so much for your advice.

I'd already made the changes to the boards.txt file as you indicated as well as creating a new linker script with the smaller memory sizes.

Regarding the linker scripts, this is what I have in my 128k variant:

MEMORY
{
  FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00020000-0x4000 /* First 16KB used by bootloader */
  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00004000
}

I'm using a 16kbyte bootloader rather than the stock SAM-BA at 8kbyte.

The RAM should be half the size, but does it start at the same address?

I'm not using the double-tap to start the bootloader so that should not matter, it's a USB mass storage uploader that relies on a pin being held low at boot when USB is connected.

The RAM should be half the size, but does it start at the same address?

Yes, the RAM starts at the same address (0x20000000) regardless of which variant is used.

Can you post your custom board files?

I posted working definitions for the samd21e15 here.

Pretty much all here already - you need a new linker script to tell the compiler where to start your code if you're using a different bootloader size, some tweaks to your boards.txt.

If you have the E15 working you can add in support for E16, E17, E18 easily just by changing the RAM and FLASH sizes in your linker script and boards.txt.

I know this is an old post, but i just want to know if the bootloader you used for the ATSAMD21G17A is the same Arduino Zero bootloader for the ATSAMD21G18?

Hi 2n3904,

The bootloaders for the SAMD21G17A and SAMD21G18A would be identical, but unfortunately the memory location (address) of the double tap reset status is different. Other than that they're the same.

The double tap reset status is mapped to the last 4 bytes (32-bit word) of the microcontroller's internal static RAM address space, to prevent it being inadvertently overwritten.

On the SAMD21G18A with 32KB SRAM:

SRAM Start Address: 0x20000000 (hexidecimal)
SRAM Size: 0x8000 (32KB)

Double Tap Status Address: 0x20000000 + 0x8000 - 4 = 0x20007FFC

On the SAMD21G17A with 16KB SRAM:

SRAM Start Address: 0x20000000 (hexidecimal)
SRAM Size: 0x4000 (16KB)

Double Tap Status Address: 0x20000000 + 0x4000 - 4 = 0x20003FFC

Therefore it's necessary to modify the BOOT_DOUBLE_TAP_ADDRESS definition in bootloader's "board_definitions.h" file then recompile it:

#define BOOT_DOUBLE_TAP_ADDRESS           (0x20003FFCul)

It's also an opportunity to change the value of the bootloader status LEDs further down in the file, if your custom board differs from the Arduino Zero, (or whatever flavour of SAMD21 development board you're using).

MartinL, thank you very much!

I’m actually gonna be using the samd21e15 version with 32pins. At first i thought that the Arduino Zero bootloader will just work with any samd21 chips. Will your instructions for the 48pin version also work with the 32 pin version?

I'm actually gonna be using the samd21e15 version with 32pins. At first i thought that the Arduino Zero bootloader will just work with any samd21 chips. Will your instructions for the 48pin version also work with the 32 pin version?

If you're using the smaller "E" variant together with less memory then it's necessary to first change the double tap address to 0x20000FFC, to account for the 4K of SRAM, then check that the LED's port pins are configured in the "boards_definitions.h" file.

I also forgot to mention in the last post that you'll also need to change the bootloader's linker scipt file "bootloader_samd21x18a.ld" file to account for the smaller RAM size:

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

The bootloader itself doesn't depend on the variant or size of the SAMD21, however the Arduino Core code used to create sketches does and requires the "boards.txt", "variant.h", "variant.cpp" and "flash_with_bootloader.ld" to be changed accordingly. In this case it may be worth looking at Adafruit's Trinket M0 (SAMD21E18A) or Rabid Prototypes Tau board (SAMD21E17A) core code as examples.

Adafruit Trinket M0: Adafruit Trinket M0 - for use with CircuitPython & Arduino IDE : ID 3500 : $8.95 : Adafruit Industries, Unique & fun DIY electronics and kits

Rabid Prototypes Tau: Tau | Rabid Prototypes

Just got the ATSAMD21E17D chips yesterday and started soldering with a custom board i made. On the bootloader side i edited some files as mentioned by MartinL on the Arduino Zero package and compiled it. Uploaded the compiled bootloader using a J-Link via Atmel Studio 7. I think the bootloader works as the board seems to be detected in my Windows 10 PC as "Arduino Zero bootloader(COM27)".

Edited the boards.txt and added these lines:

arduino_zero_ATSAMD21E17D.name=Arduino Zero (ATSAMD21E17D) -DCRYSTALLESS
arduino_zero_ATSAMD21E17D.vid.0=0x2341
arduino_zero_ATSAMD21E17D.pid.0=0x804d
arduino_zero_ATSAMD21E17D.vid.1=0x2341
arduino_zero_ATSAMD21E17D.pid.1=0x004d
arduino_zero_ATSAMD21E17D.vid.2=0x2341
arduino_zero_ATSAMD21E17D.pid.2=0x824d
arduino_zero_ATSAMD21E17D.vid.3=0x2341
arduino_zero_ATSAMD21E17D.pid.3=0x024d

arduino_zero_ATSAMD21E17D.upload.tool=bossac
arduino_zero_ATSAMD21E17D.upload.protocol=sam-ba
arduino_zero_ATSAMD21E17D.upload.maximum_size=131072
arduino_zero_ATSAMD21E17D.upload.use_1200bps_touch=true
arduino_zero_ATSAMD21E17D.upload.wait_for_upload_port=true
arduino_zero_ATSAMD21E17D.upload.native_usb=true
#arduino_zero_ATSAMD21E17D.upload.speed=57600
arduino_zero_ATSAMD21E17D.build.mcu=cortex-m0plus
arduino_zero_ATSAMD21E17D.build.f_cpu=48000000L
arduino_zero_ATSAMD21E17D.build.usb_product="Arduino Zero"
arduino_zero_ATSAMD21E17D.build.usb_manufacturer="Arduino LLC"
arduino_zero_ATSAMD21E17D.build.board=SAMD_ZERO
arduino_zero_ATSAMD21E17D.build.core=arduino
arduino_zero_ATSAMD21E17D.build.extra_flags=-D__SAMD21G18A__ {build.usb_flags} -DCRYSTALLESS
arduino_zero_ATSAMD21E17D.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld
arduino_zero_ATSAMD21E17D.build.openocdscript=openocd_scripts/arduino_zero.cfg
arduino_zero_ATSAMD21E17D.build.variant=ATSAMD21E17D
arduino_zero_ATSAMD21E17D.build.variant_system_lib=
arduino_zero_ATSAMD21E17D.build.vid=0x2341
arduino_zero_ATSAMD21E17D.build.pid=0x804d
arduino_zero_ATSAMD21E17D.bootloader.tool=openocd
arduino_zero_ATSAMD21E17D.bootloader.file=zero/samd21_sam_ba.bin

I copied the original arduino_zero variant folder and renamed it as ATSAMD21E17D and edited the linker_scripts to account for the smaller sizes in FLASH and RAM. For the other files like pins_arduino.h, variant.cpp, and variant.h, I just copied them from hydronics2/samd21_QFP_reference_PCB since it's also using the same 32pin E version of the samd21 chip.

Now on to uploading a sample sketch on Arduino 1.8.10. Problem is i keep getting error:

No device found on COM27
Set binary mode
readWord(addr=0)=0x20003ffc
readWord(addr=0xe000ed00)=0x410cc601
readWord(addr=0x41002018)=0x10012694
version()=v2.0 [Arduino:XYZ] Dec 11 2019 22:16:43
chipId=0x10010094
Unsupported ARM920T architecture
Send auto-baud
Set binary mode
readWord(addr=0)=0x20003ffc
readWord(addr=0xe000ed00)=0x410cc601
readWord(addr=0x41002018)=0x10012694
version()=v2.0 [Arduino:XYZ] Dec 11 2019 22:16:43
chipId=0x10010094
Unsupported ARM920T architecture
An error occurred while uploading the sketch

Im not sure what to do next so im hoping you can help.

The samd bootloader has weird timing wrt reset.
Have you tried the double-tap reset sequence to get into the bootloader?
(I think the arduino bootloader has that. It might be just a sparkfun/adafruit thing.)

Also, did you change the openocd script at all?

westfw:
The samd bootloader has weird timing wrt reset.
Have you tried the double-tap reset sequence to get into the bootloader?
(I think the arduino bootloader has that. It might be just a sparkfun/adafruit thing.)

Also, did you change the openocd script at all?

Yes and yes.

I think it has something to do with the BOSSA program not supporting the ATSAMD21E17D chip. Anyone with a compiled bossa with support of this chip?

Should be there:

Not the Id that you’re seeing, though