code wiki / (root) / nx_robot_hal.nx

nx_robot_hal.nx

buildroot/runtime/nx_robot_hal.nx

3747 B78 linesdepth 2pulls 2 transitivereach 1 importersview sourcekind librarytopic robot
docsdependenciesstructsconstsfunctions

about

nx_robot_hal.nx -- SOVEREIGN fail-safe hardware-write DRIVER (the HAL the generated firmware binds to). This is the never-brick-critical rung (#26): the layer that actually writes actuator outputs and reads sensors. NEVER-BRICK BY CONSTRUCTION + proven MECHANICALLY by the gate (not promised): * every actuator write is CLAMPED to a safe envelope [HW_SAFE_MIN, HW_SAFE_MAX] before it lands -- no command, however large/negative/malicious, can escape it (defense-in-depth even if the firmware's own clamp were wrong); * pins default to SAFE (0 / disabled) on init; * a WATCHDOG forces an e-stop (all outputs safe) if not kicked; * E-STOP is latched and zeroes every output; * sensor readings are range-checked (out-of-range => invalid => firmware goes safe). Backend here is a MOCK device (an i64 register array) so the whole chain is gate-provable WITHOUT real hardware. HONEST: binding these to a real board's MMIO addresses (the actual GPIO/PWM/step registers) is the final step and needs the bench -- but the fail-safe LOGIC is real + proven now. State layout (i64 array hw): hw[0..HW_NP) = actual pin outputs; hw[HW_NP+p] = sensor[p]; hw[2*HW_NP] = watchdog counter; hw[2*HW_NP+1] = estop latch. license_tier: ORIGINAL expect_exit: 0

dependencies 1 imports · 1 importers

nx_syscalls.nx nx_robot_hal.nx nx_robot_hal_gate.nx

imports: nx_syscalls.nx

imported by: nx_robot_hal_gate.nx

structs

none

consts

19const HW_NP: i64 = 32
20const HW_SAFE_MAX: i64 = 400 // actuator output ceiling (e.g. step-rate / current cap)
21const HW_SAFE_MIN: i64 = 0 - 400
22const HW_SENSOR_MIN: i64 = 0
23const HW_SENSOR_MAX: i64 = 4095 // 12-bit ADC
24const HW_WD_LIMIT: i64 = 100 // watchdog ticks before auto e-stop

functions

27func hwd_new() -> *i64
called by 1: main calls 1: sys_mmap
34func hwd_init_pin(hw: *i64, pin: i64) -> i64 { hw[pin] = 0; return 0 } // safe default
37func hwd_estop(hw: *i64) -> i64
called by 2: hwd_wd_tickmain
46func hwd_drive(hw: *i64, pin: i64, u: i64) -> i64
called by 1: main
56func hwd_drive_raw(hw: *i64, pin: i64, u: i64) -> i64 { hw[pin] = u; return u }
called by 1: main
59func hwd_out(hw: *i64, pin: i64) -> i64 { return hw[pin] }
called by 1: main
61func hwd_set_sensor(hw: *i64, pin: i64, val: i64) -> i64 { hw[HW_NP + pin] = val; return 0 }
62func hwd_read_sensor(hw: *i64, pin: i64) -> i64 { return hw[HW_NP + pin] }
65func hwd_sensor_invalid(s: i64) -> i64
called by 1: main
72func hwd_wd_kick(hw: *i64) -> i64 { hw[2 * HW_NP] = 0; return 0 }
73func hwd_wd_tick(hw: *i64) -> i64
called by 1: main calls 1: hwd_estop
78func hwd_estopped(hw: *i64) -> i64 { return hw[2 * HW_NP + 1] }
called by 1: main