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
lib/fprime tracks nasa/fprime devel (at or past
nasa/fprime#6326, whose assert-hook names
lib/fprime-samd implements). config-samd-reference/AsyncSpiCfg.fpp sizes the async SPI
driver (Drv.AsyncSpi / Drv.AsyncGuardedSpi) 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.
nasa/fprime builds this deployment and runs CuriosityReference/test/int on a Curiosity Nano
through fprime-ci with the samd-ci plugin from
lib/fprime-samd/ci. The configuration is
lib/fprime-samd/ci/sample-configs/samd21g17.yml; .github/actions/setup installs the plugin and
the cross toolchain for it. The same two commands reproduce the flow locally:
pip install ./lib/fprime-samd/ci
fprime-ci -c ./lib/fprime-samd/ci/sample-configs/samd21g17.yml --add-stage build # build, archive.tar.gz
fprime-ci -c ./lib/fprime-samd/ci/sample-configs/samd21g17.yml --skip-stage build # flash, GDS, pytestThe second command needs openocd, the board on /dev/samd21-curiosity
(lib/fprime-samd/ci/udev/91-samd21-curiosity.rules), and nothing else holding that port.
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.