A bare-metal C firmware for the SAMD51J20A microcontroller that blinks an LED at PA22 every second. This project serves as the foundation for the BlackWing CubeSat mission.
- Microcontroller: ATSAMD51J20A (Cortex-M4)
- LED Pin: PA22
- Blink Rate: 1 second ON / 1 second OFF
- Development Environment: VS Code + WSL + ARM toolchain
- Programmer: Microchip PICkit5
- PA22 → LED (with current-limiting resistor)
- GND → Ground
- 3.3V → Power supply
- J2 Program PICKit5
- Pin 1: 3.3V Target ------- Pin 2: VDD (Sense)
- Pin 2: SWDIO ------------- Pin 8: SWDIO (TDO)
- Pin 3: SWCLK ------------- Pin 5: SWCLK (TCK)
- Pin 4: NRST -------------- Pin 1: NRST (Reset)
- Pin 5: GND --------------- Pin 3: GND
-
Pin 4: SWO (TRACE) NC -
Pin 6: NC -
Pin 7: NC
Important: Pull-up resistors (10kΩ) on SWDIO and SWCLK to VDD are recommended but not required.
- WSL (Windows Subsystem for Linux)
- ARM GNU Toolchain:
arm-none-eabi-gcc - Microchip Studio (for programming via PICkit5)
- make (installed in WSL)
wsl make clean && wsl make allOutput files:
blink.elf- ELF executableblink.hex- Intel HEX formatblink.bin- Binary format
These settings are essential for SAMD51 programming to work:
- Open MPLAB IPE v6.25
- Operate → Device Programming
- Tool: Select "PICkit 5"
- Device: ATSAMD51J20A
- Advanced Settings
- Comms SWD Speed: Change from 2.00 MHz to 0.100 MHz
⚠️ - Program Speed: Change from NORMAL to LOW
⚠️
- Build firmware:
wsl make all - Open
blink.hexin Microchip Studio - Tools → Device Programming
- Apply the settings above
- Click Program
- Wait for "Programming complete"
- Look for blue horizontal bar moving back and forth
- If not moving, PICKit5 programmer and/or is stuck
Issue: "Error: open failed" or connection timeout
- Solution: Reduce SWD speed to 0.100 MHz and set Program Speed to LOW
Issue: PICkit5 hangs or device not detected
- Solution: Unplug the PICkit5 USB cable, wait 5 seconds, replug
Issue: LED doesn't blink after programming
- Verify:
- Board is powered (check 3.3V)
- PA22 pin is connected to LED
- LED has current-limiting resistor (~330Ω recommended)
- LED polarity is correct (anode to PA22, cathode to GND)
main.c- Main application (LED toggle logic)startup_samd51.c- Cortex-M4 vector table and reset handlerlinker.ld- Linker script (memory layout)include/samd51.h- Register definitions and memory-mapped addressesMakefile- Build configuration
- Power On/Reset → CPU loads SP and PC from vector table (0x00000000)
- Vector Table → Points to
Reset_Handler - Reset Handler → Calls
main() - main() → Configures PA22 as output, enters infinite toggle loop
The current implementation uses direct memory-mapped register access:
/* Set PA22 as output */
*(volatile uint32_t *)(0x41008000 + 0) = (1 << LED_PIN);
/* Toggle PA22 */
*(volatile uint32_t *)(0x41008000 + 0x1C) = (1 << LED_PIN);PORT Base Address: 0x41008000
- DIRSET (offset 0x00) - Set pin as output
- OUTTGL (offset 0x1C) - Toggle output pin
- Flash MicroPython firmware to SAMD51
- Use same PICkit5 settings (0.100 MHz SWD speed)
- Develop CubeSat mission logic in Python
- ✅ Downloaded CircuitPython firmware for SAMD51
- ✅ Converted firmware.uf2 to firmware.hex
- ✅ Programmed via PICkit5 with 0.100 MHz SWD speed
- Have issues with USB enumeration as comm port for ciruitPython
- Verified REPL access via USB
- Created custom board definitions
- See CircuitPythonOnSAMD.md for detailed setup
- Add sensor interfaces (I2C, SPI)
- Implement communications protocols
- Integrate with PyCubed framework
| Issue | Cause | Workaround |
|---|---|---|
| SWD connection fails | Default 2.00 MHz too fast for SAMD51 | Set to 0.100 MHz in Microchip Studio |
| PICkit5 hangs during programming | USB power issue | Unplug/replug USB cable |
| LED doesn't toggle | Clock not enabled or PORT not configured | Verify 3.3V supply and PA22 connections |
- Compiler: arm-none-eabi-gcc
- CPU: Cortex-M4 (default 1 MHz internal oscillator)
- Optimization: -O0 (no optimization, for debugging)
- Flash Memory: 1 MB (only ~240 bytes used)
- RAM: 256 KB (currently unused)
Terry Carpenter 12/19/2025 PyCubed V5 Bring Up
BlackWing CubeSat Project - SAMD51-based satellite control system