A small, complete, buildable F Prime flight-software deployment for the Microchip SAMD21 Curiosity Nano (ATSAMD21G17D, ARM Cortex-M0+, 128 KiB flash, 16 KiB RAM), running baremetal.
This repository builds off of other repositories:
- SAMD21 Drivers fprime-samd
- fprime-baremetal OSAL
One submodule pin is temporary: lib/fprime points at lestarch-autobot/fprime branch
samd-reference-kronos3-upstream-devel — the previous Kronos3/fprime upstream pin merged with
nasa/fprime devel (which carries nasa/fprime#6237:
Drv.AsyncSpi / Drv.AsyncGuardedSpi, AsyncSpiCfg). Move the pin back to Kronos3/fprime once its
upstream branch picks up that devel. config-samd-reference/AsyncSpiCfg.fpp sizes the async SPI
driver at four slots for this deployment.
The SAMD21 Curiosity Nano (Microchip part number DM320119) and nothing else. Optional:
an I2C device for I2cTester to talk to, and a jumper between the two GPIO pins so
GpioIn can see what GpioOut drives.
| Function | Pin(s) | Peripheral |
|---|---|---|
| Uplink / downlink UART | PA22 (TX), PB22 (RX) | SERCOM5, 115200 8N1, LSB first |
| I2C | PA12 (SDA), PA13 (SCL) | SERCOM4, 400 kHz fast mode |
| GPIO input | PA23 | pull-up, EIC interrupt on both edges |
| GPIO output | PA25 | push-pull |
| Rate-group tick | — | RTC, ultra-low-power 32 kHz oscillator, 8 Hz |
PA22 / PB22 are the pins the Curiosity Nano routes to its on-board nEDBG debugger's USB
CDC virtual COM port (CDC RX / CDC TX in the kit user guide), so the single USB cable that
powers and programs the board also carries uplink / downlink — no external USB-serial
adapter is needed. To use a different UART instead, re-pin comDriver in
CuriosityReference/Top/instances.fpp.
git clone --recursive https://github.com/fprime-community/fprime-samd-reference.git
cd fprime-samd-reference
python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
fprime-util generate samd21g17
fprime-util build -j"$(nproc)" -p CuriosityReference samd21g17The build prints an arm-none-eabi-size -A table and leaves artifacts in
build-artifacts/samd21g17/CuriosityReference/:
bin/CuriosityReference.elf linked image
bin/CuriosityReference.elf.bin raw binary, loads at 0x0000
bin/CuriosityReference.elf.hex Intel HEX
bin/CuriosityReference.map linker map
bin/CuriosityReference.nm symbol sizes
bin/CuriosityReference.objdump disassembly
dict/TopTopologyDictionary.json the dictionary the ground system reads
Always generate with fprime-util — it's what passes settings.ini's
library_locations and default_cmake_options to CMake; a bare cmake --preset ...
never reads settings.ini. Once the cache exists, the presets in CMakePresets.json
share fprime-util's binaryDir, so you can also drive the build directly:
cmake --build --preset samd21g17--recursive pulls the complete F Prime history, which is large. Neither the build nor
the tools need it:
git clone --recursive --shallow-submodules \
https://github.com/fprime-community/fprime-samd-reference.gitor, to keep full history but skip file contents you never check out:
git clone --recursive --filter=blob:none \
https://github.com/fprime-community/fprime-samd-reference.gitlib/fprime-samd/cmake/toolchain/samd21-bare-toolchain.cmake finds arm-none-eabi-gcc,
CMSIS and CMSIS-Atmel by absolute path under
~/.arduino15/packages/adafruit/tools, at pinned versions, with no /usr/bin fallback
and no non-Arduino branch for CMSIS. An apt-installed gcc-arm-none-eabi won't be found,
and wouldn't supply the SAMD21 device headers (sam.h) anyway. Install the toolchain the
way the toolchain file expects:
arduino-cli core update-index \
--additional-urls https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
arduino-cli core install adafruit:samd@1.7.17 \
--additional-urls https://adafruit.github.io/arduino-board-index/package_adafruit_index.jsonDon't float that version: 9-2019q4, 5.4.0 and 1.2.2 are literal path components in
the toolchain file, and a core bump that moves any tool version breaks path resolution
with a FATAL_ERROR at configure time.
Or use the devcontainer, which does all of this for you.
With a J-Link probe on the SWD pads:
python3 scripts/jlink_flash.py CuriosityReferenceThe script discovers deployments from the root CMakeLists.txt, reads
default_toolchain from settings.ini, selects ATSAMD21G17A (JLinkExe has no D
variant; the geometry is identical), and loads the .bin at 0x0000 — there's no
bootloader on this board. scripts/flash.jlink is the command template it renders.
The on-board nEDBG debugger speaks CMSIS-DAP rather than J-Link's protocol. To flash
through it instead, point pymcuprog or OpenOCD at the same .bin:
openocd -f interface/cmsis-dap.cfg -c "transport select swd" -f target/at91samdXX.cfg \
-c "program build-artifacts/samd21g17/CuriosityReference/bin/CuriosityReference.elf.bin 0x00000000 verify reset exit"fprime-gds -n \
--dictionary build-artifacts/samd21g17/CuriosityReference/dict/TopTopologyDictionary.json \
--packet-set-name Main \
--communication-selection uart \
--uart-device /dev/ttyACM0 \
--uart-baud 115200 \
--framing-selection fprime-n because the binary runs on the board, not the host. --packet-set-name Main
selects the packet set the topology declares (telemetry packets Main); telemetry here
is packetized, not per-channel, so without it the GDS can't decode the stream.
/dev/ttyACM0 is the nEDBG virtual COM port (the same USB cable used for flashing).
--framing-selection fprime because the deployment frames with the F Prime protocol and
newer fprime-gds releases default to CCSDS space packets.
See CONTRIBUTING.md. Briefly: build before you push, run
fprime-util format over your changes, and watch the flash/RAM delta CI posts on your
pull request — this repository's whole claim is that F Prime fits in 128 KiB.
Apache-2.0. See LICENSE and NOTICE. The submodules under lib/ keep
their own licenses and are not redistributed here.