|
STAR
Cal STAR — firmware, DAQ server, and engine design
|
Read this before you build, flash or regenerate anything for the flight computer. This applies to people and to coding agents (Claude, Codex, ...). It lists what has to be installed, how the board is wired for programming, and the rules that keep the build matched to the chip that is actually on the board.
Status as of 2026-11-04: tools installed and checked on Inez's Mac (Apple Silicon). The firmware builds with PlatformIO ([env:flight], see How the build works). Rev 1 board arriving ~2026-11-05. No firmware has been flashed to real hardware yet.
| MCU | STM32H723VET6: LQFP100 package, 512 KB flash, 564 KB RAM, Cortex-M7 up to 550 MHz |
| Datasheet | ST DS13313 covers VE/VG/ZE/ZG in one document (on Inez's Mac: ~/Downloads/Berkeley/datasheets/DS_stm32h723ve.pdf) |
| CubeMX project | firmware.ioc, target STM32H723VETx |
| Debug port | SWD on header P1 (PA13 SWDIO, PA14 SWCLK) |
| Board facts | pins, power tree, every chip: GitHub issue #137, Inez's comment of 2026-10-29 |
Verified 2026-11-04 against the rev 1 schematic (Flight_Computer_Schematic.PDF, MCU sheet 2/12): U1 is the STM32H723VET6, its pin numbers fit LQFP100, and every routed pin's net matches the pin's assignment in firmware.ioc (GPS UART checked end to end: GPS TXD → PD14 UART9_RX, GPS RXD ← PD15 UART9_TX). The only .ioc differences are the open TODOs: HSE off on PH0/PH1, PA10 set as USB ID but not connected, PA15 set as JTDI (unused, SWD only).
Where the assembled board differs from the schematic:
| Ref | Schematic / BOM says | Board actually has | Consequence |
|---|---|---|---|
| U3 | H3LIS331DLTR | H3LIS100DLTR (Inez, 2026-11-04) | Use the H3LIS100DL datasheet (ST DocID027504 Rev 2, flight_computer_documents/en.DM00162193.pdf), not DS9012 (the H3LIS331DL's). See the facts below. |
H3LIS100DL facts the driver depends on (DocID027504 Rev 2, checked 2026-11-04):
| Value | Page | |
|---|---|---|
| Range | ±100 g, fixed (no full-scale bits; CTRL_REG4 0x23 holds only SIM) | 9, 28 |
| Output | 8-bit, two's complement, one register per axis: OUT_X 0x29, OUT_Y 0x2B, OUT_Z 0x2D | 30 |
| Sensitivity | 780 mg/digit typ. (so g = raw × 0.78) | 9 |
| Zero-g offset | ±1.5 g typ. | 9 |
| WHO_AM_I (0x0F) | 0x32 (same as the H3LIS331DL, so the ID check can't tell them apart) | 25 |
| Power-on state | CTRL_REG1 (0x20) = 0x07: power-down. Write PM = 001 (normal) to measure. | 24, 25 |
| Normal-mode ODR | DR1:DR0 = 00/01/10 → 50/100/400 Hz (11 not allowed) | 26 |
| SPI | mode 3 (clock idles high, sample on rising edge), ≤ 10 MHz, first byte = RW(bit 7) MS(bit 6, auto-increment) + 6-bit address | 11, 20 |
| Supply | 2.16–3.6 V; turn-on 1/ODR + 1 ms | 1, 10 |
At 0.78 g per count, this part reads impacts and boost, not small accelerations; low-g motion belongs to the ISM330DHCX.
Why it matters: PlatformIO has no board definition for the VET6. The closest one, nucleo_h723zg, is a ZG part with 1 MB of flash and 144 pins. If you borrow it without overriding the flash size, a build can pass the size check and then fail to flash, or flash into memory that isn't there. Always state 512 KB (board_upload.maximum_size = 524288) and use the linker script CubeMX generates for the VET6.
| ST-Link | Board (P1) | Why |
|---|---|---|
| SWDIO | PA13 | data line of the debug port |
| SWCLK | PA14 | clock of the debug port |
| GND | GND | common reference, always required |
| NRST | NRST | lets the tool reset the chip; needed to "connect under reset" |
| VTref (T_VCC) | 3V3 | the ST-Link reads the board voltage from this; it does not power the board |
| Tool | Version checked | What it's for | Install | Check |
|---|---|---|---|---|
| STM32CubeMX | 6.18 | edits firmware.ioc and generates the startup, HAL and FreeRTOS code | already in /Applications/STMicroelectronics/ | open the app |
| STM32Cube FW_H7 package | V1.13.0 (what the .ioc records) | ST's HAL drivers for the H7 | CubeMX downloads it on first Generate Code | ~/STM32Cube/Repository/STM32Cube_FW_H7_V1.13.0 exists |
| Arm GNU toolchain (arm-none-eabi-gcc) | 15.3.rel2 | optional: only for the plain CMake build. The PlatformIO build downloads its own GCC 14.2. | brew install --cask gcc-arm-embedded (asks for your password) | arm-none-eabi-gcc --version |
| CMake + Ninja | 4.4.3 / 1.13.2 | build system CubeMX's CMake output uses | brew install cmake ninja | cmake --version, ninja --version |
| PlatformIO Core (pio) | 6.2.0 | team's build/upload tool on the other boards; runs the radio host tests | installed under ~/.platformio; put ~/.platformio/penv/bin on PATH (below) | pio --version |
| PlatformIO ststm32 platform + tools | ststm32 20.0.0, openocd 3.1200.7, gcc 7.2.1 | STM32 builds and uploads through pio | pio pkg install -g -p platformio/ststm32 | pio pkg list -g |
| OpenOCD | 0.12.0 | flashes and debugs over the ST-Link (target/stm32h7x.cfg) | brew install open-ocd | openocd --version |
| stlink tools (st-flash, st-info) | 1.9.0 | quick probe and flash; supports H72x/H73x | brew install stlink | st-info --probe with the ST-Link plugged in |
| STM32CubeProgrammer | latest | ST's official flasher; also updates the ST-Link's own firmware | manual download from st.com (needs a free myST login) | open the app |
| clang-format | 23.1.4 | C/C++ formatting (./format.sh) | brew install clang-format | ./format.sh --check |
| black | 26.10.1 | Python formatting (./format.sh) | brew install pipx && pipx install black | black --version |
macOS needs no USB driver for the ST-Link.
PATH lines (add to ~/.zshrc, then open a new terminal):
The compiler must be GCC 11 or newer. [env:flight] pins GCC 14.2 (platform_packages), and the plain CMake build uses Arm GNU 15.3 from PATH. PlatformIO's ststm32 ships its own GCC 7.2 (2017), and it cannot link this project: CubeMX's STM32H723xx_FLASH.ld uses the READONLY keyword (GCC 11+), and the old linker stops with non constant or forward reference address expression for section .ARM.extab. Checked 2026-11-04: with GCC 7.2 all 54 sources compiled and only the link failed. CubeMX's CMake files call whatever arm-none-eabi-gcc is on PATH, so the CMake build needs 15.3 installed. Don't mix compilers in one build, and never remove the platform_packages pin from [env:flight]. Do not "fix" a link error by deleting READONLY from the linker script. CubeMX rewrites that file on every generate.
With the board powered and the ST-Link wired:
If the flash size says 1048576 you are talking to a different chip (a Nucleo board?), not the flight computer.
Then a read-only OpenOCD connect:
If it fails with unable to connect to the target, check in this order: power, GND, the SWDIO/SWCLK pair (swapped is common), then try connecting under reset:
The one command (from the repo root; -d names the project folder):
It builds the firmware, then flashes it over the ST-Link with OpenOCD. Drop -t upload to only build. The first build downloads GCC 14.2 into ~/.platformio (no password needed). The image is firmware/Flight_Computer/.pio/build/flight/firmware.elf (and .bin).
From VS Code (PlatformIO IDE extension):
VS Code's generated .vscode/ folder is gitignored; don't commit it.
Without PlatformIO, the same image can be flashed directly:
Run it before every commit. It lists every check with ✅/❌ and exits non-zero on any failure; CI runs it too.
--board needs the board powered and the ST-Link on P1; it uses PlatformIO's own OpenOCD and arm-none-eabi-gdb, so nothing extra to install.
On boot, bringup_task (src/board/bringup_task.c) releases each chip's reset in order, then runs the self-test over every chip (see src/app/DEVICE_CHECKS.md and the commit history of board_bringup.c, one commit per chip). It never enables a pyro output and never transmits on the radio.
| You see | Meaning |
|---|---|
| LED1 blinking fast | checks running (up to ~30 s if many fail) |
| LED1 1 Hz, LED2 off | READY: every chip passed and the battery is OK (or the board is on USB) |
| LED1 1 Hz, LED2 blinking with it | WARN: an optional chip (GPS, Ethernet, SD NAND) failed, or the battery is below 7.0 V |
| LED1 1 Hz, LED2 solid | FAIL: a required chip (IMU, high-g, baro, radio, eMMC) failed, or the battery is below 6.6 V, above 8.8 V or unreadable |
| LED2 on, LED1 stopped | Error_Handler() halted the chip (an on-chip init failed) |
| no LED at all | not running: power, flash or clock problem |
The battery is judged only when the TPS2121 runs the board from it (SW_ST, PE10, high). On USB the ADC reads USB's 5 V, so the report says "on USB" and does not judge the pack. The 7.0 V / 6.6 V levels are proposals (#137), the same as Aaron's idle module (PR #162). Conversion and sources: src/app/battery.h (schematic p.2 and p.12).
Reading the report: the board writes the whole self-test as text, one line per chip plus the battery voltage and the verdict. In a PlatformIO debug session (bug icon in VS Code; it uses the ST-Link), type in the debug console:
g_bringup_report.report also holds the verdict, battery.mv and result_bits (bit = device id, set when it passed; the radio SelfTest frame's field). For the raw fields, add g_bringup_report to Watch. self_test.devices[i] holds each chip's result (1 = PASS, 2 = FAIL, 3 = TIMEOUT, 4 = NOT_CONFIGURED, 5 = NOT_IMPLEMENTED), diagnostic and attempts; analog.counts[] holds the raw ADC counts in board_adc.h order. Diagnostic codes are documented in board_bringup.h (GNSS: baud that worked; SD NAND: stage << 8 | R1; eMMC: manufacturer ID).
[env:flight] in platformio.ini (checked 2026-11-04: builds, 40 KB of 512 KB flash, hard-float ABI, vector table at 0x08000000):
CubeMX also wrote CMakeLists.txt/CMakePresets.json, so a plain CMake build works too, with Arm GNU on PATH: cmake --preset Debug && cmake --build --preset Debug.
After every CubeMX Generate Code: run pio run -d firmware/Flight_Computer -e flight before committing. A newly enabled peripheral's HAL file lands in Drivers/.../Src and is picked up automatically. A new middleware folder needs a build_src_filter line. Still open in the .ioc: HSE (25 MHz Y1) + PLL (SYSCLK is 64 MHz from HSI), USB device-only.