|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
SPDX-License-Identifier: MIT. More...
Functions | |
| static bool | elapsed_at_least (uint32_t now, uint32_t then, uint32_t ms) |
| Every comparison is an unsigned difference against a timeout, never a comparison of two timestamps. | |
| void | heartbeat_gen_init (heartbeat_gen_t *g) |
| Start held low: nothing downstream may run until this loop asks for it. | |
| bool | heartbeat_gen_step (heartbeat_gen_t *g, uint32_t now_ms, bool alive) |
| Advance the generator; returns the level the pin should be driven to. | |
| void | heartbeat_mon_init (heartbeat_mon_t *m) |
| Start not alive, with no edge seen. | |
| void | heartbeat_mon_edge (heartbeat_mon_t *m, uint32_t now_ms) |
| Record an edge on the safety line. | |
| bool | heartbeat_mon_alive (heartbeat_mon_t *m, uint32_t now_ms) |
| Whether the line may be believed now. | |
SPDX-License-Identifier: MIT.
|
inlinestatic |
Every comparison is an unsigned difference against a timeout, never a comparison of two timestamps.
A 32-bit millisecond counter wraps after 49.7 days, and now < then is wrong for about 1ms either side of the wrap; the subtraction wraps with the counter and stays correct.
| void heartbeat_gen_init | ( | heartbeat_gen_t * | g | ) |
Start held low: nothing downstream may run until this loop asks for it.
| g | Generator state to initialise. |
| bool heartbeat_gen_step | ( | heartbeat_gen_t * | g, |
| uint32_t | now_ms, | ||
| bool | alive ) |
Advance the generator; returns the level the pin should be driven to.
alive is the caller's own judgement of whether it is fit to keep the bench running – touch answering, link up, no latched stop. When it is false the line goes low immediately rather than merely stopping: waiting for the monostable to time out would spend its whole period still enabled, and the fastest correct thing to do with a stop is all of it at once.
Call it as often as you like; it edges no faster than HEARTBEAT_PERIOD_MS.
| g | Generator state. |
| now_ms | Current time, in milliseconds. |
| alive | true when the caller judges the bench fit to run. |
| bool heartbeat_mon_alive | ( | heartbeat_mon_t * | m, |
| uint32_t | now_ms ) |
Whether the line may be believed now.
Must be called even when no edges are arriving: silence is the failure this exists to catch, and silence generates no events. Calling it is what notices that nothing has happened.
| m | Monitor state. |
| now_ms | Current time, in milliseconds. |
| void heartbeat_mon_edge | ( | heartbeat_mon_t * | m, |
| uint32_t | now_ms ) |
Record an edge on the safety line.
Called from wherever edges are noticed – an interrupt, or a poll that samples faster than HEARTBEAT_MIN_GAP_MS. It only ever costs a subtraction and a compare, so an ISR is a fine place for it.
| m | Monitor state. |
| now_ms | Time of the edge, in milliseconds. |
| void heartbeat_mon_init | ( | heartbeat_mon_t * | m | ) |
Start not alive, with no edge seen.
| m | Monitor state to initialise. |