firmware_quickstart/firmware_quickstart.rs
1//! Minimal Binary/Binary static correction surface for firmware.
2//!
3//! Binary is the safe default: general irregular or unknown spacing, no extra
4//! index bytes, exact `ceil(log2(N))` probes per axis. This table is tiny, so
5//! Linear would store the same knots; choosing between them is a target-code
6//! question, not a payload one. See the strategy guide (not packaged):
7//! <https://github.com/photon-circus/ph-surfaces/blob/v0.1.0/docs/choosing-a-strategy.md>.
8//!
9//! Host `main` is an assertion harness. The declarations are `static` and
10//! `core`-compatible: no heap, no I/O, no cache, no runtime table construction.
11//! Payload and comparison counts are not flash, cycles, or WCET; measure those
12//! on a named target.
13
14use ph_surfaces::{AxisLookup, BilinearSurface, BinaryAxis, SurfaceError};
15
16static X: [u16; 2] = [100, 200];
17static Y: [u16; 2] = [10, 30];
18static VALUES: [[i32; 2]; 2] = [
19 [0, 100], // Y = 10
20 [40, 180], // Y = 30
21];
22
23static SURFACE: BilinearSurface<2, 2> = BilinearSurface::new(&X, &Y, &VALUES);
24
25fn main() {
26 // Declared knot: the three interpolation steps land exactly on the stored
27 // value, so it is recovered without numerical drift.
28 assert_eq!(SURFACE.evaluate(100, 10), Ok(0));
29 // Interior operating point from docs/interpolation-walkthrough.md:
30 // lower-X 25, upper-X 75, Y 50.
31 assert_eq!(SURFACE.evaluate(125, 20), Ok(50));
32 assert_eq!(
33 SURFACE.evaluate(0, 20),
34 Err(SurfaceError::XBelow {
35 coordinate: 0,
36 bound: 100
37 })
38 );
39
40 assert_eq!(BilinearSurface::<2, 2>::VALUE_BYTES, 16);
41 assert_eq!(BilinearSurface::<2, 2>::PAYLOAD_BYTES, 24);
42 assert_eq!(BilinearSurface::<2, 2>::SUCCESS_INTERPOLATIONS, 3);
43 assert_eq!(BilinearSurface::<2, 2>::SUCCESS_GRID_READS, 4);
44 assert_eq!(<BinaryAxis<2>>::MAX_SEARCH_COMPARISONS, 1);
45 assert_eq!(
46 BilinearSurface::<2, 2>::HANDLE_BYTES,
47 core::mem::size_of::<BilinearSurface<2, 2>>()
48 );
49}