rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
sense_svc.h File Reference

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...

#include <stdbool.h>
#include <stdint.h>
#include "sense_bus.h"
#include "sense_sched.h"

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.

Detailed Description

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

Function Documentation

◆ sense_svc_init()

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.

Parameters
vThe service to set up.
ioThe callbacks the service calls.

◆ sense_svc_step()

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.

Parameters
vThe service.
cmdThe command to act on.
outReceives the snapshot.

◆ sense_window_over()

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.

Parameters
wThe window to judge.
clip_uaThe current at the top code, in µA.
limit_maThe limit, in mA.
Returns
true when the window passed the limit.