|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
The IOmcu's sensor service: what core 1 does each 1ms tick with the orders core 0 gives it, and the snapshot of what it read that core 0 publishes on the link. More...
Go to the source code of this file.
Data Structures | |
| struct | sense_cmd_t |
| What core 0 asks for. More... | |
| struct | sense_snap_t |
| What core 1 hands back after each step. More... | |
| struct | sense_svc_io_t |
| The wire, the clock, the recovery and the pins. More... | |
| struct | sense_svc_t |
| The sensor service: its schedule and the command state it acts on. More... | |
Macros | |
| #define | SENSE_SCAN_FIRST 0x40u |
| The first address a scan asks, and how many. | |
| #define | SENSE_SCAN_COUNT 16u |
Functions | |
| void | sense_svc_init (sense_svc_t *v, const sense_svc_io_t *io) |
| A service with the bus closed; the first step takes its command whole. | |
| void | sense_svc_step (sense_svc_t *v, const sense_cmd_t *cmd, sense_snap_t *out) |
One tick, every 1ms: cmd acted on, the schedule ticked while the bus is open, and out filled. | |
| bool | sense_window_over (const sense_window_t *w, int32_t clip_ua, uint16_t limit_ma) |
Whether window w of a channel passed limit_ma: its highest current rounded to mA (as SENSE_WIN shows it) above the limit, or a sample clipped at the top of the range when that top, clip_ua (the top code's current, 163.8mV across the shunt), is above the limit. | |
The IOmcu's sensor service: what core 1 does each 1ms tick with the orders core 0 gives it, and the snapshot of what it read that core 0 publishes on the link.
Core 0 owns the link pages and the outputs; core 1 owns the I2C (Inter-Integrated Circuit) bus. Two plain structs pass between them, each copied whole under a lock by the firmware: sense_cmd_t from core 0 to core 1, sense_snap_t back. This module is core 1's side in pure C, so the host suite runs it against fake_ina.h; the lock, the timer and the I2C block are the firmware's (firmware/iomcu/src/sense_core1.c, sense_i2c.c).
Each step, in this order:
Set-up cfg_gen moved: the bus is closed, then opened on the command's pins when a part is enabled, and the schedule started afresh – every part probed again, the windows, the run and the capture empty. A bus that does not open reads closed and nothing is ticked. Run run_gen moved: sense_sched_arm(), the run's peaks and totals start again. Capture cap_gen moved: armed with the command's levels, or disarmed. An arm the schedule refuses – no FAST channel, its INA3221 not online, or no bus open – ends at once as lost and counts as a capture ended. The count runs on across set-ups. Edge edge_set for this cap_gen, once: sense_sched_cap_edge(). Tick sense_sched_tick(). Scan at the first tick of an open bus, then every SENSE_RETRY_MS while an enabled part is not online: every address from 0x40 to 0x4F that no online part holds is asked for one byte. Not on a stuck bus and not while a capture is under way. Each answer goes to sense_bus (sense_bus_note()): a held line, or SENSE_STUCK_TIMEOUTS timeouts in a row, mark the bus stuck and end the scan, and the recovery is due at the next tick, parts online or not; a NACK is an empty address and no error. An address that gave no answer keeps its last one. An online part's address counts as answering without being asked: a read at it would clear the flags its last register pointer holds. 16 addresses at 400kHz are about 0.8ms of bus time, in the tick they run in. Encoder with the AS5600 enabled, the bus is opened and the schedule reads the part at 0x36 on the ticks that read no rotation item (sense_sched.h). The scan does not look for it: its address is fixed and outside 0x40 to 0x4F, and it counts for nothing in "a part is missing". Snapshot every field from the schedule, with the generations the step has taken, so core 0 can tell a reading of the set-up, run and capture in force from one that came before them. FAST's window ring and the reset counts are the schedule's, and start again with a set-up.
Pure C, no SDK (software development kit). Host-tested in test_sense_svc.
SPDX-License-Identifier: MIT
| void sense_svc_init | ( | sense_svc_t * | v, |
| const sense_svc_io_t * | io ) |
A service with the bus closed; the first step takes its command whole.
| v | The service to set up. |
| io | The callbacks the service calls. |
| void sense_svc_step | ( | sense_svc_t * | v, |
| const sense_cmd_t * | cmd, | ||
| sense_snap_t * | out ) |
One tick, every 1ms: cmd acted on, the schedule ticked while the bus is open, and out filled.
| v | The service. |
| cmd | The command to act on. |
| out | Receives the snapshot. |
| bool sense_window_over | ( | const sense_window_t * | w, |
| int32_t | clip_ua, | ||
| uint16_t | limit_ma ) |
Whether window w of a channel passed limit_ma: its highest current rounded to mA (as SENSE_WIN shows it) above the limit, or a sample clipped at the top of the range when that top, clip_ua (the top code's current, 163.8mV across the shunt), is above the limit.
Never with a limit of 0, and never for a negative current. The service judges each channel's window once, as it closes, on core 1, so no window is missed however late core 0 takes the snapshot.
| w | The window to judge. |
| clip_ua | The current at the top code, in µA. |
| limit_ma | The limit, in mA. |