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

The SENSE, SERVO_SENSE and SERVO_WIN link pages. More...

#include "sense_page.h"
#include "sense_page_int.h"
#include <stddef.h>
#include <string.h>
#include "as5600.h"
#include "ina228.h"
#include "ina3221.h"
#include "link_msg.h"
#include "link_pages.h"

Macros

#define I3221_FULL_SCALE_UV   163800uL
#define MA_MAX   32767u

Functions

void sense_page_defaults (uint16_t *cfg)
 The set-up as a page starts, into cfg (LINK_SN_CONFIG_COUNT registers): what a store record from before protocol 4.7 restores.
void sense_page_init (sense_page_t *p)
 Set a SENSE page to its start-up state.
static bool i228_calibrates (uint16_t shunt_uohm, uint16_t max_da)
 Whether the driver can calibrate the INA228 for this shunt and maximum: one rule, the driver's, so the page takes no set-up the part refuses.
uint32_t sense_i3221_full_scale_ma (uint16_t shunt_dmohm)
 The INA3221's full scale in mA for a shunt of shunt_dmohm tenths of a milliohm: 163.8mV across it. 1638 at 0.1Ohm. 0 for no shunt.
bool sense_page_enabled (const sense_page_t *p)
 Whether either part is enabled, and so the bus runs.
uint8_t sense_page_sda (const sense_page_t *p)
 The bus's pins and clock.
uint8_t sense_page_scl (const sense_page_t *p)
 The SCL pin of the bus.
uint32_t sense_page_hz (const sense_page_t *p)
 The bus clock in Hz.
uint64_t sense_page_pins (const sense_page_t *p)
 The pins the set-up holds, as a reservation mask; 0 while neither part is enabled.
uint64_t sense_page_held (const sense_page_t *p)
 Those and the pins core 1 has not let go of yet (sense_page_t.held): a bus moved or closed keeps its old pins for about 1ms.
static bool pin_free (const sense_page_t *p, const outputs_t *o, uint16_t pin, uint64_t taken)
 Whether pin may carry the bus: in the bank, not another page's, not reserved unless it is one this page already holds, and no output's.
static bool pins_ok (const uint16_t *c)
 Whether the set-up's pins are ones the bus can ever open: one I2C block's pair, link_sn_pins_pair().
static bool values_ok (const uint16_t *c)
 The values themselves, whatever is enabled: a set-up kept in flash is one a later enable can take without another write.
void sense_page_forget (sense_page_t *p)
 Every register core 1 fills, on both pages and the map's, cleared.
uint8_t sense_cfg_check (const sense_page_t *p, const uint16_t *next, const outputs_t *o, uint64_t taken)
 A SENSE set-up next (LINK_SN_CONFIG_COUNT registers) judged as a write is: values, pins, addresses and channels; 0 or the refusal.
void sense_cfg_take (sense_page_t *p, const uint16_t *next)
 next in force: the generation moves, and every reading of the set-up before it goes (sense_page_forget()).
uint8_t sense_page_write (sense_page_t *p, uint8_t off, uint8_t n, const uint16_t *in, const outputs_t *o, uint64_t taken)
 A SENSE write, validated whole before any of it is stored.
void sense_page_read (const sense_page_t *p, uint8_t off, uint8_t n, uint16_t *out)
 Read SENSE registers into out.
static bool pwm_surface (const sense_page_t *p, const outputs_t *o, uint8_t ch)
 Whether output channel ch is a surface a PWM slot renders: the one kind of output whose pulse edge a capture can be timed from.
void sense_page_bound (sense_page_t *p, uint8_t slots)
 Which output slots the silicon bound (bit n slot n): a capture arms only on a PWM slot that renders frames.
void sense_page_ports (sense_page_t *p, uint8_t ports)
 Which programming ports render a pulse while the bank drives (bit n port n): bound to the PWM generator, switched on in LINK_PG_PWM and not held by the KST port.
bool sense_page_port_gone (const sense_page_t *p)
 Whether the capture in CAP_ARM names a programming port that renders no pulse now: its PWM switched off, its pin gone, or the KST port on the pin.
static bool arm_output (const sense_page_t *p, const outputs_t *o, uint16_t arm)
 Whether the output a capture names renders a frame to time from.
static uint8_t arm_check (const sense_page_t *p, const uint16_t *f, const outputs_t *o)
 A capture's frame, CAP_ARM to CAP_BAND_MA, judged as an arm.
uint8_t sense_servo_write (sense_page_t *p, uint8_t off, uint8_t n, const uint16_t *in, const outputs_t *o)
 A SERVO_SENSE write.
void sense_servo_read (const sense_page_t *p, uint8_t off, uint8_t n, uint16_t *out)
 Read SERVO_SENSE registers into out.
void sense_win_read (const sense_page_t *p, uint8_t off, uint8_t n, uint16_t *out)
 A SERVO_WIN read: CH1's ring as last published, and the capture's state, count and clipped bit as SERVO_SENSE reads them at this moment. The page takes no write.
bool sense_page_step (sense_page_t *p, bool driving)
 One pass: a bank that is not driving ends a capture that has not finished – CAP_ARM 0, CAP_STATE idle – and returns true.
uint8_t sense_page_slots_check (const sense_page_t *p, const uint16_t *slots)
 LINK_NACK_BAD_VALUE for an OUTPUTS page (slots, LINK_OS_COUNT registers) that binds a slot to a pin sense_page_held() names, the refusal the SUPPLY page gives for its own; 0 otherwise.
void sense_page_cmd (const sense_page_t *p, sense_cmd_t *cmd)
 The order for core 1 from the page: the set-up and its generation, and the capture's.
static void reg_32 (uint16_t *r, uint32_t v)
 A 32-bit value into two registers, low half first.
static unsigned mirror_part (const sense_page_t *p)
 The INA3221 SENSE names, 0 to 3: the part whose channels, identity and resets the SENSE and SERVO_SENSE registers show.
static bool clipped (const sense_window_t *w)
 Whether a window clipped at either limit.
static uint16_t part_flags (sense_state_t st, bool id_ok, uint16_t online, uint16_t good, uint16_t wrong)
 The flags of one part: online, a good identity, a wrong identity.
static uint16_t sense_flags (const sense_snap_t *s, unsigned a)
 The FLAGS register of a snapshot: the bus, both parts and the INA228 clipped flag.
static bool totals_ok (const sense_snap_t *s, uint16_t run_gen)
 Whether the snapshot's charge and energy are run run_gen's.
static void publish_sense (uint16_t *r, const sense_snap_t *s, uint16_t run_gen, unsigned a)
 Publish the SENSE registers of a snapshot.
static void publish_channels (uint16_t *r, const sense_snap_t *s, unsigned a)
 Publish each channel's last window into the SERVO_SENSE registers.
static void publish_ring (uint16_t *r, const sense_snap_t *s, unsigned a)
 FAST's ring into SERVO_WIN: the newest window's number, then each entry. The capture's registers are filled at the read (sense_win_read()).
static void publish_capture (uint16_t *r, const sense_snap_t *s)
 Publish the snapshot's capture into the SERVO_SENSE registers.
static void publish_enc (uint16_t *r, const sense_snap_t *s)
 The output encoder's registers 26 to 30.
void sense_page_publish (sense_page_t *p, const sense_snap_t *s, uint16_t run_gen)
 What core 1 read into the read-only registers of both pages, when s was taken under the set-up in force.
static uint16_t hundredths (float x)
 Volts or amps in hundredths, rounded and held to a register.
void sense_page_esc (sense_page_t *p, bool v_ok, float volts, bool i_ok, float amps)
 The ESC's own telemetry voltage and current, each with its valid bit, into SENSE registers 23 to 25.
void sense_page_bench (sense_page_t *p, const sense_snap_t *s, uint16_t run_gen, bool driving, bench_state_t *b)
 The BENCH page's numbers from the INA228, over what the ESC's telemetry put in b, once the peaks of b are tracked.
uint16_t sense_page_caps (const sense_page_t *p)
 The capability bits the set-up makes true: LINK_CAP_PACK_SENSE while the INA228 is enabled, LINK_CAP_SERVO_SENSE while the INA3221 is – fitted as configured, not online now – or, with SENSE_MAP in force, while a channel it reads watches an output channel or a programming port (sense_map.h).

Detailed Description

The SENSE, SERVO_SENSE and SERVO_WIN link pages.

See sense_page.h.

SPDX-License-Identifier: MIT

Function Documentation

◆ arm_check()

uint8_t arm_check ( const sense_page_t * p,
const uint16_t * f,
const outputs_t * o )
static

A capture's frame, CAP_ARM to CAP_BAND_MA, judged as an arm.

Parameters
pThe page.
fThe capture frame, LINK_SS_CAP_FRAME registers.
oThe outputs model.
Returns
0 when the arm is taken; otherwise a LINK_NACK_* refusal.

◆ arm_output()

bool arm_output ( const sense_page_t * p,
const outputs_t * o,
uint16_t arm )
static

Whether the output a capture names renders a frame to time from.

Parameters
pThe page.
oThe outputs model.
armThe CAP_ARM register.
Returns
true when the output the capture names renders a frame to time from.

◆ clipped()

bool clipped ( const sense_window_t * w)
static

Whether a window clipped at either limit.

Parameters
wThe window.
Returns
true when either clip flag is set.

◆ hundredths()

uint16_t hundredths ( float x)
static

Volts or amps in hundredths, rounded and held to a register.

Parameters
xThe value in volts or amps.
Returns
The value in hundredths, rounded and held to 0 to 65535; 0 for a negative value or NaN.

◆ i228_calibrates()

bool i228_calibrates ( uint16_t shunt_uohm,
uint16_t max_da )
static

Whether the driver can calibrate the INA228 for this shunt and maximum: one rule, the driver's, so the page takes no set-up the part refuses.

Parameters
shunt_uohmThe shunt in micro-ohms.
max_daThe maximum current in units of 10mA.
Returns
true when ina228_calibrate() accepts the set-up.

◆ mirror_part()

unsigned mirror_part ( const sense_page_t * p)
static

The INA3221 SENSE names, 0 to 3: the part whose channels, identity and resets the SENSE and SERVO_SENSE registers show.

Parameters
pThe page.
Returns
The INA3221 part index, 0 to 3; 0 for an address out of range.

◆ part_flags()

uint16_t part_flags ( sense_state_t st,
bool id_ok,
uint16_t online,
uint16_t good,
uint16_t wrong )
static

The flags of one part: online, a good identity, a wrong identity.

Parameters
stThe part's state.
id_oktrue when the identity passes.
onlineThe flag for an online part.
goodThe flag for a good identity.
wrongThe flag for a wrong identity.
Returns
The flags the part sets.

◆ pin_free()

bool pin_free ( const sense_page_t * p,
const outputs_t * o,
uint16_t pin,
uint64_t taken )
static

Whether pin may carry the bus: in the bank, not another page's, not reserved unless it is one this page already holds, and no output's.

Parameters
pThe page.
oThe outputs model.
pinThe pin to test.
takenBit n: pin n is held by another page.
Returns
true when the pin may carry the bus.

◆ pins_ok()

bool pins_ok ( const uint16_t * c)
static

Whether the set-up's pins are ones the bus can ever open: one I2C block's pair, link_sn_pins_pair().

Judged whatever is enabled, so the page holds no pair a later enable is refused for. One set-up that is not a pair passes: nothing enabled and SDA or SCL 0, which is what a panel writes for pins that are not set (sense_link.c writes 0 for a pin at -1).

Parameters
cThe set-up's registers.
Returns
true when SDA and SCL are one I2C pair, or nothing is enabled and one of them is 0.

◆ publish_capture()

void publish_capture ( uint16_t * r,
const sense_snap_t * s )
static

Publish the snapshot's capture into the SERVO_SENSE registers.

Parameters
rThe SERVO_SENSE registers, filled in place.
sThe snapshot.

◆ publish_channels()

void publish_channels ( uint16_t * r,
const sense_snap_t * s,
unsigned a )
static

Publish each channel's last window into the SERVO_SENSE registers.

Parameters
rThe SERVO_SENSE registers, filled in place.
sThe snapshot.
aThe INA3221 part index, 0 to 3.

◆ publish_enc()

void publish_enc ( uint16_t * r,
const sense_snap_t * s )
static

The output encoder's registers 26 to 30.

The angle and its figures are the snapshot's only for a part that is online or was: a part gone offline keeps its last reading and loses ONLINE, and the still time goes on counting from it.

Parameters
rThe SENSE registers, filled in place.
sThe snapshot.

◆ publish_ring()

void publish_ring ( uint16_t * r,
const sense_snap_t * s,
unsigned a )
static

FAST's ring into SERVO_WIN: the newest window's number, then each entry. The capture's registers are filled at the read (sense_win_read()).

Parameters
rThe SERVO_WIN registers, filled in place.
sThe snapshot.
aThe INA3221 part index, 0 to 3.

◆ publish_sense()

void publish_sense ( uint16_t * r,
const sense_snap_t * s,
uint16_t run_gen,
unsigned a )
static

Publish the SENSE registers of a snapshot.

Parameters
rThe SENSE registers, LINK_SN_COUNT entries, filled in place.
sThe snapshot.
run_genThe generation of the current run.
aThe INA3221 part index, 0 to 3.

◆ pwm_surface()

bool pwm_surface ( const sense_page_t * p,
const outputs_t * o,
uint8_t ch )
static

Whether output channel ch is a surface a PWM slot renders: the one kind of output whose pulse edge a capture can be timed from.

Parameters
pThe page.
oThe outputs model.
chOutput channel.
Returns
true when the channel is a surface that a bound PWM slot renders.

◆ reg_32()

void reg_32 ( uint16_t * r,
uint32_t v )
static

A 32-bit value into two registers, low half first.

Parameters
rTwo registers, written in place, low half first.
vThe 32-bit value.

◆ sense_cfg_check()

uint8_t sense_cfg_check ( const sense_page_t * p,
const uint16_t * next,
const outputs_t * o,
uint64_t taken )

A SENSE set-up next (LINK_SN_CONFIG_COUNT registers) judged as a write is: values, pins, addresses and channels; 0 or the refusal.

Not the bank's state: the caller asks that.

Parameters
pThe page.
nextThe set-up to judge, LINK_SN_CONFIG_COUNT registers.
oThe outputs model.
takenBit n: pin n is held by another page.
Returns
0, or LINK_NACK_BAD_VALUE for a refused set-up.

◆ sense_cfg_take()

void sense_cfg_take ( sense_page_t * p,
const uint16_t * next )

next in force: the generation moves, and every reading of the set-up before it goes (sense_page_forget()).

Parameters
pThe page.
nextThe set-up, LINK_SN_CONFIG_COUNT registers.

◆ sense_flags()

uint16_t sense_flags ( const sense_snap_t * s,
unsigned a )
static

The FLAGS register of a snapshot: the bus, both parts and the INA228 clipped flag.

Parameters
sThe snapshot.
aThe INA3221 part index, 0 to 3.
Returns
The FLAGS register value.

◆ sense_i3221_full_scale_ma()

uint32_t sense_i3221_full_scale_ma ( uint16_t shunt_dmohm)

The INA3221's full scale in mA for a shunt of shunt_dmohm tenths of a milliohm: 163.8mV across it. 1638 at 0.1Ohm. 0 for no shunt.

Parameters
shunt_dmohmThe shunt in tenths of a milliohm.
Returns
The full scale in mA; 0 for a shunt of 0.

◆ sense_page_bench()

void sense_page_bench ( sense_page_t * p,
const sense_snap_t * s,
uint16_t run_gen,
bool driving,
bench_state_t * b )

The BENCH page's numbers from the INA228, over what the ESC's telemetry put in b, once the peaks of b are tracked.

The INA228 is BENCH's source (LINK_BN_SENSED) while it is enabled and online, and stays it to the end of a run it was online in: a part that drops out while driving leaves voltage, current and power empty, not the ESC's. Voltage and current are the last 50ms window's means, each valid with a sample in it; power is their product, valid with both. The peaks are run run_gen's, from the 500Hz samples, and until core 1 has started that run, the live readings. Charge and energy are the part's ENERGY and CHARGE, with LINK_BN_TOTALS_OK, while they are the run's totals; otherwise 0 and the bit clear. Nothing changes while the INA228 is not BENCH's source.

Parameters
pThe page.
sThe snapshot core 1 took.
run_genThe generation of the current run.
drivingtrue while the bank drives.
bThe BENCH state, updated in place.

◆ sense_page_bound()

void sense_page_bound ( sense_page_t * p,
uint8_t slots )

Which output slots the silicon bound (bit n slot n): a capture arms only on a PWM slot that renders frames.

The IOmcu says so after every change of the bindings; until it does, no slot counts as bound.

Parameters
pThe page.
slotsBit n: output slot n is bound to silicon.

◆ sense_page_caps()

uint16_t sense_page_caps ( const sense_page_t * p)

The capability bits the set-up makes true: LINK_CAP_PACK_SENSE while the INA228 is enabled, LINK_CAP_SERVO_SENSE while the INA3221 is – fitted as configured, not online now – or, with SENSE_MAP in force, while a channel it reads watches an output channel or a programming port (sense_map.h).

They change only with a SENSE or SENSE_MAP write taken, because a panel reads the identity page at link-up and again after such a write, not on every poll; whether a part answers is FLAGS' and BENCH bit 5's, which it polls.

Parameters
pThe page, or NULL.
Returns
The capability bits; 0 for a NULL p.

◆ sense_page_cmd()

void sense_page_cmd ( const sense_page_t * p,
sense_cmd_t * cmd )

The order for core 1 from the page: the set-up and its generation, and the capture's.

The INA228's maximum in mA, the INA3221's shunt in µΩ; a capture's level before the command left to CH1 (SENSE_CAP_RISE_AUTO). run_gen, edge_set and edge_us are the caller's, and left as they are.

Parameters
pThe page.
cmdReceives the order for core 1.

◆ sense_page_defaults()

void sense_page_defaults ( uint16_t * cfg)

The set-up as a page starts, into cfg (LINK_SN_CONFIG_COUNT registers): what a store record from before protocol 4.7 restores.

Parameters
cfgReceives LINK_SN_CONFIG_COUNT registers, zeroed first; NULL is ignored.

◆ sense_page_enabled()

bool sense_page_enabled ( const sense_page_t * p)

Whether either part is enabled, and so the bus runs.

Parameters
pThe page, or NULL.
Returns
true when either part is enabled; false for a NULL p.

◆ sense_page_esc()

void sense_page_esc ( sense_page_t * p,
bool v_ok,
float volts,
bool i_ok,
float amps )

The ESC's own telemetry voltage and current, each with its valid bit, into SENSE registers 23 to 25.

Parameters
pThe page, updated in place.
v_oktrue when volts is valid.
voltsThe ESC voltage in V.
i_oktrue when amps is valid.
ampsThe ESC current in A.

◆ sense_page_forget()

void sense_page_forget ( sense_page_t * p)

Every register core 1 fills, on both pages and the map's, cleared.

Parameters
pThe page.

◆ sense_page_held()

uint64_t sense_page_held ( const sense_page_t * p)

Those and the pins core 1 has not let go of yet (sense_page_t.held): a bus moved or closed keeps its old pins for about 1ms.

What no output may have.

Parameters
pThe page, or NULL.
Returns
The pins of sense_page_pins() and those core 1 has not let go of; 0 for a NULL p.

◆ sense_page_hz()

uint32_t sense_page_hz ( const sense_page_t * p)

The bus clock in Hz.

Parameters
pThe page, or NULL.
Returns
The clock in Hz (the set-up's kHz times 1000); 0 for a NULL p.

◆ sense_page_init()

void sense_page_init ( sense_page_t * p)

Set a SENSE page to its start-up state.

Parameters
pThe page; zeroed, then set to the defaults.

◆ sense_page_pins()

uint64_t sense_page_pins ( const sense_page_t * p)

The pins the set-up holds, as a reservation mask; 0 while neither part is enabled.

Parameters
pThe page, or NULL.
Returns
Bit n set for pin n of SDA and SCL; 0 while neither part is enabled or for a NULL p.

◆ sense_page_port_gone()

bool sense_page_port_gone ( const sense_page_t * p)

Whether the capture in CAP_ARM names a programming port that renders no pulse now: its PWM switched off, its pin gone, or the KST port on the pin.

The caller ends such a capture as it ends one whose bank stopped driving, with sense_page_step(p, false).

Parameters
pThe page, or NULL.
Returns
true when the capture names a programming port that renders no pulse; false for NULL p.

◆ sense_page_ports()

void sense_page_ports ( sense_page_t * p,
uint8_t ports )

Which programming ports render a pulse while the bank drives (bit n port n): bound to the PWM generator, switched on in LINK_PG_PWM and not held by the KST port.

A capture with LINK_SS_ARM_PORT arms only on one of them. Until told, none.

Parameters
pThe page.
portsBit n: programming port n renders a pulse.

◆ sense_page_publish()

void sense_page_publish ( sense_page_t * p,
const sense_snap_t * s,
uint16_t run_gen )

What core 1 read into the read-only registers of both pages, when s was taken under the set-up in force.

SENSE: FLAGS, PRESENT, the IDs, ERRORS, the die temperature, DIAG_ALRT, the charge and energy while they are the totals of run run_gen (sense_run_t.totals_ok), 0 otherwise, and RESETS. SERVO_SENSE: each channel's last window and its flags, the window number, and the capture when s was taken under the capture order in force. SERVO_WIN: CH1's ring, a clipped sample counted at the end of the range it read. Values are rounded to their register's step and held to its range.

FLAGS bit 3 (LINK_SN_I228_CLIPPED) is set when the INA228's last window held a clipped current, or the run's peaks lack one.

Parameters
pThe page, updated in place.
sThe snapshot core 1 took.
run_genThe generation of the current run.

◆ sense_page_read()

void sense_page_read ( const sense_page_t * p,
uint8_t off,
uint8_t n,
uint16_t * out )

Read SENSE registers into out.

Parameters
pThe page.
offFirst register of the window.
nNumber of registers to read.
outReceives n register values; left unchanged for a NULL p or out, or a window past LINK_SN_COUNT.

◆ sense_page_scl()

uint8_t sense_page_scl ( const sense_page_t * p)

The SCL pin of the bus.

Parameters
pThe page, or NULL.
Returns
The SCL pin number; 0 for a NULL p.

◆ sense_page_sda()

uint8_t sense_page_sda ( const sense_page_t * p)

The bus's pins and clock.

The SDA pin of the bus.

Parameters
pThe page, or NULL.
Returns
The SDA pin number; 0 for a NULL p.

◆ sense_page_slots_check()

uint8_t sense_page_slots_check ( const sense_page_t * p,
const uint16_t * slots )

LINK_NACK_BAD_VALUE for an OUTPUTS page (slots, LINK_OS_COUNT registers) that binds a slot to a pin sense_page_held() names, the refusal the SUPPLY page gives for its own; 0 otherwise.

Taken instead, such a slot would be left unbound with nothing on the wire to say so.

Parameters
pThe page, or NULL.
slotsThe OUTPUTS slot registers, LINK_OUT_SLOTS slots of LINK_OS_STRIDE registers each.
Returns
0, or LINK_NACK_BAD_VALUE for a NULL slots or a slot bound to a held pin.

◆ sense_page_step()

bool sense_page_step ( sense_page_t * p,
bool driving )

One pass: a bank that is not driving ends a capture that has not finished – CAP_ARM 0, CAP_STATE idle – and returns true.

A finished capture keeps its result until the next arm.

Parameters
pThe page.
drivingtrue while the bank drives.
Returns
true when an unfinished capture was ended; false otherwise or for NULL p.

◆ sense_page_write()

uint8_t sense_page_write ( sense_page_t * p,
uint8_t off,
uint8_t n,
const uint16_t * in,
const outputs_t * o,
uint64_t taken )

A SENSE write, validated whole before any of it is stored.

Refused: off the page (BAD_RANGE); a read-only register (READ_ONLY); a value out of its range, a reserved register written other than 0, SDA and SCL not one I2C block's pair (link_sn_pins_pair()) whatever is enabled – but for nothing enabled with SDA or SCL 0, a panel's pins that are not set – and while a part is enabled a pin past the bank, reserved, bound to an output or in taken, the two parts on one address while both are enabled, the INA3221 enabled with no channel, an INA228 shunt and maximum ina228_calibrate() refuses (past 163.84mV across the shunt, or a full scale past INA228_FS_MA_LIMIT at the range it chooses), and any change while o is driving (BAD_VALUE). A write of the set-up in force is taken armed or not.

The INA228's calibration is the driver's, ina228_calibrate(), so the page refuses exactly the set-ups the driver could not run.

taken is the pins another page holds: the SUPPLY page's, supply_page_pins(). The bank's reservation covers them on the IOmcu as well; they are named here so the page refuses them by itself.

A set-up taken clears every register core 1 fills – FLAGS, PRESENT, the IDs, ERRORS, the readings, the SERVO_SENSE windows and a finished capture's result, CAP_ARM with it, RESETS and the SERVO_WIN ring – so nothing read under the old set-up shows until core 1 has read under the new one. The ESC's telemetry and CAP_SEQ stay.

Parameters
pThe page; updated when the write is taken.
offFirst register of the window.
nNumber of registers in the window; 0 applies nothing.
inThe n register values to write.
oThe outputs model; a change while it drives is refused.
takenBit n: pin n is held by another page (supply_page_pins()).
Returns
0 when the write is taken or changes nothing; otherwise LINK_NACK_BAD_RANGE, LINK_NACK_READ_ONLY or LINK_NACK_BAD_VALUE.

◆ sense_servo_read()

void sense_servo_read ( const sense_page_t * p,
uint8_t off,
uint8_t n,
uint16_t * out )

Read SERVO_SENSE registers into out.

Parameters
pThe page.
offFirst register of the window.
nNumber of registers to read.
outReceives n register values; left unchanged for a NULL p or out, or a window past LINK_SS_COUNT.

◆ sense_servo_write()

uint8_t sense_servo_write ( sense_page_t * p,
uint8_t off,
uint8_t n,
const uint16_t * in,
const outputs_t * o )

A SERVO_SENSE write.

CAP_ARM written 0 at the head of the write disarms, is never refused, and stores nothing else of the write. Any other write is an arm, LINK_SS_CAP_FRAME registers from CAP_ARM. Refused: off the page (BAD_RANGE); a read-only register (READ_ONLY); not the whole frame, CAP_ARM with bits it does not have, an INA3221 channel that is not 1 (LINK_SS_CAP_CH) or not read, an output channel that is not a surface on a PWM slot bound to silicon (sense_page_bound()), with LINK_SS_ARM_PORT a programming port that renders no pulse (sense_page_ports()), a movement or band of 0 or past 32767mA (BAD_VALUE); an arm while o is not armed for the surfaces (NOT_ARMED). The holding level is signed mA and every value of it is taken, -32768 to

  1. An arm restarts the capture: CAP_STATE armed, the results 0.
Parameters
pThe page; updated when the write is taken.
offFirst register of the window.
nNumber of registers in the window.
inThe n register values to write.
oThe outputs model; an arm needs its surfaces armed.
Returns
0 when the write is taken; otherwise LINK_NACK_BAD_RANGE, LINK_NACK_READ_ONLY, LINK_NACK_BAD_VALUE or LINK_NACK_NOT_ARMED.

◆ sense_win_read()

void sense_win_read ( const sense_page_t * p,
uint8_t off,
uint8_t n,
uint16_t * out )

A SERVO_WIN read: CH1's ring as last published, and the capture's state, count and clipped bit as SERVO_SENSE reads them at this moment. The page takes no write.

Parameters
pThe page.
offFirst register of the window.
nNumber of registers to read.
outReceives n register values.

◆ totals_ok()

bool totals_ok ( const sense_snap_t * s,
uint16_t run_gen )
static

Whether the snapshot's charge and energy are run run_gen's.

Parameters
sThe snapshot.
run_genThe generation of the run the totals must belong to.
Returns
true when the charge and energy are the totals of run_gen and the INA228 is online.

◆ values_ok()

bool values_ok ( const uint16_t * c)
static

The values themselves, whatever is enabled: a set-up kept in flash is one a later enable can take without another write.

Parameters
cThe set-up's registers.
Returns
true when every value is in its range and the INA228 calibration passes.