Two cores, one hard deadline
One of these jobs has a deadline and the others do not. That single asymmetry is what decides the whole firmware architecture — the split is not for throughput, it is so the thing that must not be late cannot be made late by anything else.
The split
- Sensor samplingMeasured
Temperature, salinity, turbidity and depth into the rolling average.
- SolverMeasured
Scores the candidate set each tick and publishes the winner.
- TelemetryImplemented
State out to the deck console. Droppable by design.
- DDS synthesisMeasured
Phase accumulator steps a Q15 sine table into the transmit buffer.
- DMA serviceMeasured
Refills the buffer before it drains. This is the deadline.
- Echo captureImplemented
ADC into the receive buffer, gated after the blanking interval.
Why a lookup table
A phase accumulator into a Q15 lookup costs a handful of cycles per sample. Calling sinf() per sample does not fit inside the sample period at these rates, which is why the table is a design constraint rather than a micro-optimisation.
It is worth being precise about this, because "we used a lookup table" sounds like a shortcut and is the opposite. The synthesis rate is what makes the bandwidth available, the bandwidth is what sets range resolution, and range resolution is the number the whole instrument is measured on.
Telemetry to the deck console is droppable by design — if the link is congested, the console goes stale and the payload carries on surveying. Nothing on core 1 has that property, which is why nothing else is allowed to run there.