|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
The IOmcu's half of the link: answer polls, and fail safe when they stop. More...
#include <stdbool.h>#include <stddef.h>#include <stdint.h>#include "link_msg.h"#include "link_pages.h"Go to the source code of this file.
Data Structures | |
| struct | link_page_t |
| One page, as the IOmcu sees it. More... | |
| struct | link_dev_t |
| The IOmcu's end of the link: pages, the silence watchdog and the arm latch. More... | |
Macros | |
| #define | LINK_DEV_SILENCE_MS 200u |
| Silence after which the IOmcu fills failsafe values on its own authority. | |
Functions | |
| void | link_dev_init (link_dev_t *d, const link_page_t *pages, uint8_t page_count, void *ctx, uint32_t now_ms) |
| Start with no request heard, out of failsafe and with the arm latch set: the first ARM after a start needs a CLEAR ahead of it. | |
| bool | link_dev_dispatch (link_dev_t *d, const link_msg_t *req, link_msg_t *reply, uint32_t now_ms) |
| Decide what to answer, without deciding how to carry it: which page, whether the range fits, whether the write is accepted, and what a NACK (negative acknowledge) says. | |
| bool | link_dev_apply (const link_dev_t *d, const link_msg_t *req, link_msg_t *reply) |
| What link_dev_dispatch() answers, without touching the silence watchdog: the same page lookup, range check, read, write and refusals. | |
| bool | link_dev_tick (link_dev_t *d, uint32_t now_ms) |
| Advance the silence watchdog. | |
| void | link_dev_clear_failsafe (link_dev_t *d, uint32_t now_ms) |
| Leave failsafe and release the arm latch. | |
| void | link_dev_latch_arm (link_dev_t *d) |
| Set the arm latch: a cause other than link silence took the outputs down, and the ARM the host goes on writing does not bring them back. | |
| bool | link_dev_arm_latched (const link_dev_t *d) |
| Whether a write of ARM is refused until the host writes CLEAR. | |
The IOmcu's half of the link: answer polls, and fail safe when they stop.
Pure C with the clock passed in as a millisecond count. No timers, no FreeRTOS, no pico-sdk, so both watchdogs are driven through their transitions on the host, including across the 32-bit wrap at 49.7 days.
SPDX-License-Identifier: MIT
| #define LINK_DEV_SILENCE_MS 200u |
Silence after which the IOmcu fills failsafe values on its own authority.
The ratio follows ArduPilot's IOMCU (I/O microcontroller): the IOmcu gives up after 200ms and the host escalates after 1s, so the processor holding the outputs is the more suspicious of the two.
| bool link_dev_apply | ( | const link_dev_t * | d, |
| const link_msg_t * | req, | ||
| link_msg_t * | reply ) |
What link_dev_dispatch() answers, without touching the silence watchdog: the same page lookup, range check, read, write and refusals.
For a caller on this end that is not the link, such as the bench console (page_console.h): a request from there proves nothing about the panel, so it must not hold the failsafe off.
False only on a null argument.
| d | The link state. |
| req | The request to answer. |
| reply | Receives the answer. |
| bool link_dev_arm_latched | ( | const link_dev_t * | d | ) |
Whether a write of ARM is refused until the host writes CLEAR.
| d | The link state; NULL counts as latched. |
| void link_dev_clear_failsafe | ( | link_dev_t * | d, |
| uint32_t | now_ms ) |
Leave failsafe and release the arm latch.
Not exposed as "the link came back": recovery of the wire is not consent to spin a propeller, so the host asks for this by writing LINK_CLEAR_MAGIC to the control page.
| d | The link state. |
| now_ms | The current time, in ms; restarts the silence watchdog. |
| bool link_dev_dispatch | ( | link_dev_t * | d, |
| const link_msg_t * | req, | ||
| link_msg_t * | reply, | ||
| uint32_t | now_ms ) |
Decide what to answer, without deciding how to carry it: which page, whether the range fits, whether the write is accepted, and what a NACK (negative acknowledge) says.
No transport is visible from here.
False only on a null argument. Every request produces exactly one reply, refusals included: silence means an IOmcu that is not there, and must not also mean a declined request.
| d | The link state. |
| req | The request received. |
| reply | Receives the answer: DATA, ACK or NACK. |
| now_ms | The current time, in ms; restarts the silence watchdog. |
| void link_dev_init | ( | link_dev_t * | d, |
| const link_page_t * | pages, | ||
| uint8_t | page_count, | ||
| void * | ctx, | ||
| uint32_t | now_ms ) |
Start with no request heard, out of failsafe and with the arm latch set: the first ARM after a start needs a CLEAR ahead of it.
| d | The link state to set up. |
| pages | The page table; kept, not copied. |
| page_count | Entries in pages. |
| ctx | Passed to every page callback. |
| now_ms | The current time, in ms. |
| void link_dev_latch_arm | ( | link_dev_t * | d | ) |
Set the arm latch: a cause other than link silence took the outputs down, and the ARM the host goes on writing does not bring them back.
Leaves failsafe as it is.
| d | The link state. |
| bool link_dev_tick | ( | link_dev_t * | d, |
| uint32_t | now_ms ) |
Advance the silence watchdog.
Returns true on the edge where failsafe fires, so the caller can drop the outputs once rather than every tick. The edge sets the arm latch too.
| d | The link state. |
| now_ms | The current time, in ms. |