Atmel SAMD support


I would like to add the following Arduino Core to Platformio: GitHub - qbolsee/ArduinoCore-fab-sam: This is a fork from arduino/ArduinoCore-samd on GitHub. This will be used to maintain Arduino support for SAM D|L|C (M0+ and M4F) boards including the MattairTech Xeno Mini and the MT-D21E (see It adds support for new devices like the D51, L21, C21, and D11. It also adds new clock sources, like a high speed crystal or internal oscillator.

How would I go about doing this? What’s the process? Has it been documented somewhere? It’s a little confusing between boards, platforms, libraries and frameworks…

Many thanks for your help!

The clostest thing to developer documentation you’ll see is probably my post. The PlatformIO-side documentation on self-developing integrations for new platforms / frameworks is lacking in my eyes, not covering it from start-to-finish in enough detail. Things like modifying existing platforms or logic is also not covered.

You may also look at similiar work as e.g. done in

1 Like

Oh wow, great documentation! Thanks a lot! It might be a little over my head, but I’ll give it a shot.

@maxgerhardt after reading your documentation I tried tinkering with the atmelsam package to get the new framework to work (locally), but I’m getting a bunch of errors:

KeyError: "Invalid board option 'build.core'":
  File "/Users/stephanemuller/.platformio/penv/lib/python3.8/site-packages/platformio/builder/", line 181:
  File "/Users/stephanemuller/.platformio/packages/tool-scons/scons-local-4.3.0/SCons/Script/", line 597:
    return _SConscript(self.fs, *files, **subst_kw)
  File "/Users/stephanemuller/.platformio/packages/tool-scons/scons-local-4.3.0/SCons/Script/", line 285:
    exec(compile(scriptdata, scriptname, 'exec'), call_stack[-1].globals)
  File "/Users/stephanemuller/.platformio/platforms/atmelsam/builder/", line 220:
    if board.get("build.core") in ("adafruit", "seeed", "sparkfun") and board.get(
  File "/Users/stephanemuller/.platformio/penv/lib/python3.8/site-packages/platformio/platform/", line 46:
    raise KeyError("Invalid board option '%s'" % path)

I’m guessing everything stems from the first one env.SConscript("$BUILD_SCRIPT") and more specifically from the builder process I’ve tried to tweak, but I don’t know where to look. Do you have a suggestion or an idea?

You’re using a custom board JSON file with the core property inside the build object not set? It’s crashing at

Oh, yes indeed! Ok, fixed that.
Now it’s telling me it can’t find Arduino.h… That’s weird… It’s seeing the fabsam framework alright, even the variant shows up. And in VS the include is not even underlined.

Processing samd11c14a (platform: atmelsam; board: samd11c14a)
Verbose mode can be enabled via `-v, --verbose` option
PLATFORM: Atmel SAM (7.1.0) > Generic Atmel SAMD11C14A
DEBUG: Current (cmsis-dap) On-board (cmsis-dap) External (atmel-ice)
 - framework-arduino-fabsam 1.8.3 
 - tool-bossac 1.10700.190624 (1.7.0) 
 - toolchain-gccarmnoneeabi 1.70201.0 (7.2.1)
LDF: Library Dependency Finder ->
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 0 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio/build/samd11c14a/src/main.o
src/main.cpp:1:10: fatal error: Arduino.h: No such file or directory

The next problem you’ll have is, now that you’ve created framework-arduino-fabsam, is the builder script for it. That is, the piece of Python code that tells PlatformIO (aka SCons) where do find all needed header and source files and how to build them, like the original Arduino core would through the settings declared in its platform.txt and boards.txt.

Since you’ve selected framework = arduino, PlatofrmIO will invoke the builder script at platform-atmelsam/ at develop · platformio/platform-atmelsam · GitHub. This however just selects one of the underlying builder scripts in platform-atmelsam/builder/frameworks/arduino at develop · platformio/platform-atmelsam · GitHub, whicih will be the script due to the logic previously linked.

Not finding Arduino.h has to do with the fact that the include path

is added.

For your core Arduino.h is in cores/arduino/Arduino.h. The logic above would add cores/BUILD_CORE with BUILD_CORE having the value arduino, so that is correct, but the problem is that FRAMEWORK_DIR wold be wrongly computed since it’s looking for framework-arduino-samd-<build.core value from JSON file>, but you named it framework-arduino-fabsam.

Eitehr fork the platform-atmelsam repository and correct this logic (because possibly more adapations are needed?) and refer to its Git link with platform = <git link here> in the platformio.ini or rename your framework package.

Hm on second thought, it’s checking that all directories exist

so the fault might be somewhere else. You can insert print statements into the builder scripts (if using the default, C:\Users\<user>\.platformio\platforms\atmelsam\builder\frameworks\arduino\ and see what paths it is appending.

I think I’m starting to get it. Here is what I did exactly:

My ini file looks like this:

platform_packages = framework-arduino-fabsam
platform = atmelsam
board = samd11c14a
upload_protocol = sam-ba

I created a board in the atmelsam directory:

  "build": {
    "cpu": "cortex-m0plus",
    "f_cpu": "20000000L",
    "mcu": "samd11c14a",
    "core": "fabsam",
    "variant": "Generic_D11C14A"

Created the framework-arduino-fabsam folder in the .platformio/packages/ with a package.json file.

Modified this line in the .plarformio/platforms/atmelsam/builder/frameworks/

MCU_FAMILY = board.get(
    "build.system", "sam" if build_mcu.startswith("at91") else ("fabsam" if build_mcu.startswith("samd11c") else "samd"))

Created a in the arduino folder:

env = DefaultEnvironment()
platform = env.PioPlatform()
board = env.BoardConfig()

framework_package = "framework-arduino"
if board.get("build.core", "").lower() != "arduino":
    framework_package += "-%s" % board.get("build.core").lower()
FRAMEWORK_DIR = platform.get_package_dir(framework_package)

SYSTEM_DIR = os.path.join(FRAMEWORK_DIR, "system")

assert os.path.isdir(SYSTEM_DIR)
assert os.path.isdir(FRAMEWORK_DIR)



        os.path.join(FRAMEWORK_DIR, "cores", "arduino")

Will do it more cleanly once it works, but it still won’t… I think this should work but for some reason I have the feeling it’s not getting all the way where I want it.

And many thanks for taking this time to help :slight_smile:

That’s missing a LIBPATH (folder(s) where .a static libraries can be found that are referred to in LIBS) and LINKFLAGS (linker invocation flags) closing ) at least.

Also you can copy-paste the code platform-atmelsam/ at develop · platformio/platform-atmelsam · GitHub into your builder script.

This part is basically SCons environment configuration, most of which can be copy-pasted from the original script or looked up in other builder scripts, e.g., Arduino-AVR (platform-atmelavr/ at develop · platformio/platform-atmelavr · GitHub) or STM32 (Arduino_Core_STM32/ at main · stm32duino/Arduino_Core_STM32 · GitHub).

A general explanation of the SCons environment variable can be found in SCons 4.4.0.

What’s weird here is that you don’t specificy a source for it with @ <source> at the end? Like @ file://<some path> or @ <git repo link>. Or does it then really source it from the existing C:\Users\<user>\.platformio\packages\framework-arduino-fabsam folder?

Yes, I copied the framework in the .platformio directory.

I don’t get it. I have changed my ini file to this:

platform = atmelsam
board = samd11c14a
framework = arduino
upload_protocol = sam-ba

Because, as I understand it, it will check the atmelsam package and since I’ve chosen the arduino framework, it should launch and in turn

However, now I’m getting this error:

KeyError: 'framework-arduino-samd-fabsam'

When I have explicitly written in the

MCU_FAMILY = "fabsam"

if env.BoardConfig().get("build.core", "").lower() == "mbcwb":
            "framework-arduino-mbcwb"), "tools", ""))
    env.SConscript(os.path.join("arduino", "" % MCU_FAMILY))

How is this error even possible then??

I have also copied the, renamed it and basically just changed the framework_package. There might be other things to change, but one thing at a time…

comes from this logic if you still have it in your new builder script

Just replace

framework_package = "framework-arduino-samd"
if VENDOR_CORE != "arduino":
    framework_package += "-%s" % VENDOR_CORE


framework_package = "framework-arduino-fabsam"

or rename your package to the expected framework-arduino-samd-fabsam.

That’s what I did…

Ok, so I renamed the directory framework-arduino-samd-fabsam and all references to it. Turns out I had forgotten to add the framework to the platform.json as well.

But now I have this error:

Tool Manager: Installing platformio/framework-arduino-samd-fabsam @ ~1.8.3
Error: Could not find the package with 'platformio/framework-arduino-samd-fabsam @ ~1.8.3' requirements for your system 'darwin_x86_64

It never ends… :frowning: How come it doesn’t find the directory when it’s in the .platformio/packages directory already?

You should upload the framework-arduino-samd-fabsam to a Git(hub) repo and put that in as the version for the package inside the platform.json, then it should have no problems installing it.

I pushed the package.json the the git repo of the framework so we should be good now. And yet… the error message stays the same. It can’t find the reference to the framework. It’s not getting past the platform.json I think.

It looks like it’s looking at the root of the platformio directory, is that normal?

My platform.json addition:

    "framework-arduino-samd-fabsam": {
      "type": "framework",
      "optional": true,
      "owner": "platformio",
      "version": "~1.16.18"

The package.json of the framework:

  "name": "framework-arduino-samd-fabsam",
  "version": "1.16.18",
  "description": "Arduino Wiring-based Framework for Microchip SAM D microcontrollers",
  "keywords": [
  "repository": {
    "type": "git",
    "url": ""

Is that part the actual problem?

The version there must be, also remove owner.

My God this has no end… Platformio can now find the repo and the framework directory, but it’s generating hundreds of erros.

It’s weird because when I try to open each files it’s saying it can’t find them (although they exist)… From the kind of errors my guess would be that it can’t find the CMSIS framework with all the register definitions, but in the build/arduino/ the framework is still defined:

import os

from SCons.Script import DefaultEnvironment

env = DefaultEnvironment()
platform = env.PioPlatform()
board = env.BoardConfig()

VENDOR_CORE = board.get("build.core", "").lower()

framework_package = "framework-arduino-samd-fabsam"
FRAMEWORK_DIR = platform.get_package_dir(framework_package)
CMSIS_DIR = platform.get_package_dir("framework-cmsis")
CMSIS_ATMEL_DIR = platform.get_package_dir("framework-cmsis-atmel")

assert all(os.path.isdir(d) for d in (FRAMEWORK_DIR, CMSIS_DIR, CMSIS_ATMEL_DIR))

I’m sorry for all this back and forth…