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

The panel's half of the SENSE, SERVO_SENSE and SERVO_WIN link pages. More...

#include "sense_link.h"
#include "sense_link_int.h"
#include <stddef.h>
#include <string.h>

Functions

void sense_link_init (sense_link_t *s)
 Sets up the SENSE link state.
static void forget_reads (sense_link_t *s)
 Everything read under one set-up, forgotten when another is taken or the link goes: what was said about it is news again under the next.
void sense_link_lost (sense_link_t *s)
 The link went: nothing on the page is known, and nothing is read or written until it comes up again.
void sense_link_came_up (sense_link_t *s, uint16_t minor, uint32_t now_ms)
 An IOmcu answered with protocol minor minor.
static bool one_address (uint16_t i228, uint16_t i3221, uint8_t parts)
 Whether the INA228 at i228 shares an address with the INA3221: one of the fitted parts parts, or with none given the one at i3221.
static bool setup_valid (const sense_setup_t *w)
 Whether w is a set-up SETUP can name: every value inside the page's own range.
void sense_link_want (sense_link_t *s, const sense_setup_t *w, uint32_t now_ms)
 The set-up SETUP names now.
static void bus_frame (const sense_link_t *s, uint16_t *out)
 The bus frame as it is to be written: the pins asked and the parts whose own frames the page has not refused.
static bool frame_differs (const sense_link_t *s, uint8_t at)
 Whether the wanted frame differs from the held one.
sense_link_op_kind_t sense_link_write_owed (const sense_link_t *s, uint16_t *regs)
 The write owed now, or NONE, with its registers in regs.
static void read_op (sense_link_op_t *op, sense_link_op_kind_t kind, uint8_t page, uint8_t off, uint8_t n)
 Sets up a read operation.
static bool due (bool asked, uint32_t asked_ms, uint32_t now_ms, uint32_t every)
 Whether a read is due.
bool sense_link_win_on (const sense_link_t *s)
 Whether the INA3221's windows come from SERVO_WIN: the IOmcu has the page and its SENSE page enables the INA3221 with CH1.
unsigned sense_link_status_count (const sense_link_t *s)
 The registers a SENSE status read takes.
bool sense_link_next (sense_link_t *s, uint32_t now_ms, bool idle, sense_link_op_t *op)
 The next exchange owed at now_ms, into op; false for none.
static void new_setup (sense_link_t *s, uint32_t now_ms)
 A set-up was taken, or first read: what was read and said under the old one is gone, and the wait before "not answering" starts again.
static void written (sense_link_t *s, sense_link_op_kind_t w, int result, uint32_t now_ms)
 Handles the result of a write.
static void judge_enc (sense_link_t *s, uint32_t now_ms, bool waited)
 The encoder's part of a SENSE read: not answering, once until it does, and a magnet that is missing, weak or strong, once while its bits stay as they were said – across set-ups, as an edit of another row on SETUP is one.
static void judge_status (sense_link_t *s, uint32_t now_ms)
 What a SENSE read says that the operator is told.
static void judge_servo (sense_link_t *s)
 What a SERVO_SENSE read says: a channel read newly clipped, of the channels the page reads.
static void win_entry (const uint16_t *regs, unsigned k, uint16_t newest, uint32_t now_ms, sense_link_win_t *w)
 Entry k of a SERVO_WIN read, whose newest number is newest.
static void judge_win (sense_link_t *s, const uint16_t *regs, unsigned n, uint32_t now_ms)
 A SERVO_WIN read of n registers from 0: the windows it owes into the queue, oldest first, and the cursor after the last one taken.
void sense_link_done (sense_link_t *s, int result, const uint16_t *regs, uint32_t now_ms)
 How the exchange sense_link_next() gave went: SENSE_LINK_ACK with the registers read (regs, op.n of them; NULL for a write), a NACK reason, or SENSE_LINK_NO_ANSWER.
void sense_link_faults (sense_link_t *s, uint16_t faults)
 STATUS's faults word, as the caller last read it.
uint32_t sense_link_events (sense_link_t *s)
 The events since the last call, SENSE_LINK_EV_*, and cleared.
bool sense_link_event_stands (const sense_link_t *s, uint32_t ev)
 Whether what ev, one SENSE_LINK_EV_* bit, says still holds now.
uint32_t sense_link_event (sense_link_t *s, uint32_t now_ms)
 One event for the alert band, which shows one line and replaces it with the next: the most pressing waiting – no page, a set-up not sent or refused, a stuck bus, a part not answering, another identity, a clipped reading, the store off – cleared, and the rest kept.
void sense_link_event_back (sense_link_t *s, uint32_t ev)
 Put back an event sense_link_event() handed out that never reached the band – another alert replaced it first – with what it was raised with, so it is handed out again after the gap.
bool sense_link_settled (const sense_link_t *s)
 Whether nothing is owed: the page holds the set-up asked, less the frames it refused.

Variables

static const uint16_t k_online [2]
static const uint16_t k_wrong [2]
const uint16_t sense_link_en_bit [2]
static const uint32_t k_silent [2]
static const uint32_t k_wrong_ev [2]

Detailed Description

The panel's half of the SENSE, SERVO_SENSE and SERVO_WIN link pages.

See sense_link.h.

SPDX-License-Identifier: MIT

Function Documentation

◆ bus_frame()

void bus_frame ( const sense_link_t * s,
uint16_t * out )
static

The bus frame as it is to be written: the pins asked and the parts whose own frames the page has not refused.

The encoder's bit goes only to an IOmcu that has it.

Parameters
sThe link state.
outReceives the frame.

◆ due()

bool due ( bool asked,
uint32_t asked_ms,
uint32_t now_ms,
uint32_t every )
static

Whether a read is due.

Parameters
askedtrue when a read was asked.
asked_msThe time the read was asked, in ms.
now_msThe time, in ms.
everyThe period, in ms.
Returns
true when the read is due.

◆ forget_reads()

void forget_reads ( sense_link_t * s)
static

Everything read under one set-up, forgotten when another is taken or the link goes: what was said about it is news again under the next.

Not the magnet: its bits are the part's and the shaft's, not the set-up's, and a weak magnet said once is not said again for an edit of another row (judge_enc()).

Parameters
sThe link state.

◆ frame_differs()

bool frame_differs ( const sense_link_t * s,
uint8_t at )
static

Whether the wanted frame differs from the held one.

Parameters
sThe link state.
atThe first register of the frame.
Returns
true when they differ.

◆ judge_enc()

void judge_enc ( sense_link_t * s,
uint32_t now_ms,
bool waited )
static

The encoder's part of a SENSE read: not answering, once until it does, and a magnet that is missing, weak or strong, once while its bits stay as they were said – across set-ups, as an edit of another row on SETUP is one.

A part said not to answer has its magnet said again when it answers.

Parameters
sThe link state.
now_msThe time, in ms.
waitedtrue when the grace time has passed.

◆ judge_servo()

void judge_servo ( sense_link_t * s)
static

What a SERVO_SENSE read says: a channel read newly clipped, of the channels the page reads.

Parameters
sThe link state.

◆ judge_status()

void judge_status ( sense_link_t * s,
uint32_t now_ms )
static

What a SENSE read says that the operator is told.

Parameters
sThe link state.
now_msThe time, in ms.

◆ judge_win()

void judge_win ( sense_link_t * s,
const uint16_t * regs,
unsigned n,
uint32_t now_ms )
static

A SERVO_WIN read of n registers from 0: the windows it owes into the queue, oldest first, and the cursor after the last one taken.

A read that owes an entry it does not carry takes nothing and asks for the whole page.

Parameters
sThe link state.
regsThe registers read.
nThe number of registers read, from 0.
now_msThe time, in ms.

◆ new_setup()

void new_setup ( sense_link_t * s,
uint32_t now_ms )
static

A set-up was taken, or first read: what was read and said under the old one is gone, and the wait before "not answering" starts again.

Parameters
sThe link state.
now_msThe time, in ms.

◆ one_address()

bool one_address ( uint16_t i228,
uint16_t i3221,
uint8_t parts )
static

Whether the INA228 at i228 shares an address with the INA3221: one of the fitted parts parts, or with none given the one at i3221.

Parameters
i228The INA228 address.
i3221The INA3221 address.
partsThe fitted INA3221 parts, one bit each, or 0.
Returns
true when the addresses are the same.

◆ read_op()

void read_op ( sense_link_op_t * op,
sense_link_op_kind_t kind,
uint8_t page,
uint8_t off,
uint8_t n )
static

Sets up a read operation.

Parameters
opReceives the operation.
kindThe operation kind.
pageThe page number.
offThe first register.
nThe number of registers.

◆ sense_link_came_up()

void sense_link_came_up ( sense_link_t * s,
uint16_t minor,
uint32_t now_ms )

An IOmcu answered with protocol minor minor.

Below SENSE_LINK_MINOR it has neither page and nothing is sent to it, and a part enabled on SETUP raises SENSE_LINK_EV_NO_PAGE.

Parameters
sThe link state.
minorThe IOmcu's protocol minor version.
now_msThe time, in ms.

◆ sense_link_done()

void sense_link_done ( sense_link_t * s,
int result,
const uint16_t * regs,
uint32_t now_ms )

How the exchange sense_link_next() gave went: SENSE_LINK_ACK with the registers read (regs, op.n of them; NULL for a write), a NACK reason, or SENSE_LINK_NO_ANSWER.

Parameters
sThe link state.
resultThe result: an acknowledgement, a NACK's reason or SENSE_LINK_NO_ANSWER.
regsThe registers read, or NULL for a write.
now_msThe time, in ms.

◆ sense_link_event()

uint32_t sense_link_event ( sense_link_t * s,
uint32_t now_ms )

One event for the alert band, which shows one line and replaces it with the next: the most pressing waiting – no page, a set-up not sent or refused, a stuck bus, a part not answering, another identity, a clipped reading, the store off – cleared, and the rest kept.

0 while none waits or while the last one handed out is younger than SENSE_LINK_EVENT_GAP_MS at now_ms.

Parameters
sThe link state.
now_msThe time, in ms.
Returns
The event bit for the alert band, or 0 for none.

◆ sense_link_event_back()

void sense_link_event_back ( sense_link_t * s,
uint32_t ev )

Put back an event sense_link_event() handed out that never reached the band – another alert replaced it first – with what it was raised with, so it is handed out again after the gap.

A clipped event takes its channel back. An event about an IOmcu is not put back once the link has gone.

Parameters
sThe link state.
evThe event to put back.

◆ sense_link_event_stands()

bool sense_link_event_stands ( const sense_link_t * s,
uint32_t ev )

Whether what ev, one SENSE_LINK_EV_* bit, says still holds now.

For the events about the set-up asked: SENSE_LINK_EV_PINS_UNSET and SENSE_LINK_EV_SAME_ADDR while the settings ask it; a refusal – SENSE_LINK_EV_BUS_REFUSED, _I228_REFUSED, _I3221_REFUSED – until the page is known to hold the frame as asked: not refused, and written and taken. A refused value stepped back on SETUP ends it once the IOmcu takes the frame; the rest and the write take SENSE_LINK_SETTLE_MS and a poll. With no IOmcu answering a refusal stands. True for every other event: what a read raised ends with the band's own time.

The caller takes back an alert it showed for such an event once this is false; sense_link_event() drops one waiting that is over.

Parameters
sThe link state.
evOne SENSE_LINK_EV_* bit.
Returns
true while the cause of the event holds.

◆ sense_link_events()

uint32_t sense_link_events ( sense_link_t * s)

The events since the last call, SENSE_LINK_EV_*, and cleared.

Parameters
sThe link state.
Returns
The events as SENSE_LINK_EV_* bits.

◆ sense_link_faults()

void sense_link_faults ( sense_link_t * s,
uint16_t faults )

STATUS's faults word, as the caller last read it.

Parameters
sThe link state.
faultsThe STATUS faults word.

◆ sense_link_init()

void sense_link_init ( sense_link_t * s)

Sets up the SENSE link state.

Parameters
sThe link state to set up.

◆ sense_link_lost()

void sense_link_lost ( sense_link_t * s)

The link went: nothing on the page is known, and nothing is read or written until it comes up again.

Parameters
sThe link state.

◆ sense_link_next()

bool sense_link_next ( sense_link_t * s,
uint32_t now_ms,
bool idle,
sense_link_op_t * op )

The next exchange owed at now_ms, into op; false for none.

Writes only while idle: the bank is disarmed here and at the far end. The caller makes the exchange and reports with sense_link_done().

Parameters
sThe link state.
now_msThe time, in ms.
idletrue while the bank is disarmed here and at the far end.
opReceives the exchange owed.
Returns
true when an exchange is owed.

◆ sense_link_settled()

bool sense_link_settled ( const sense_link_t * s)

Whether nothing is owed: the page holds the set-up asked, less the frames it refused.

Parameters
sThe link state.
Returns
true when nothing is owed.

◆ sense_link_status_count()

unsigned sense_link_status_count ( const sense_link_t * s)

The registers a SENSE status read takes.

Parameters
sThe link state.
Returns
SENSE_LINK_STATUS_COUNT when the AS5600 part is enabled or the INA3221 windows come from SERVO_WIN, else SENSE_LINK_STATUS_COUNT_V48.

◆ sense_link_want()

void sense_link_want ( sense_link_t * s,
const sense_setup_t * w,
uint32_t now_ms )

The set-up SETUP names now.

A part enabled while an IOmcu without the page answers raises SENSE_LINK_EV_NO_PAGE. A set-up with a value outside the page's range – a zeroed snapshot – is ignored: nothing is asked, and nothing is written for it.

Parameters
sThe link state.
wThe set-up SETUP names.
now_msThe time, in ms.

◆ sense_link_win_on()

bool sense_link_win_on ( const sense_link_t * s)

Whether the INA3221's windows come from SERVO_WIN: the IOmcu has the page and its SENSE page enables the INA3221 with CH1.

Parameters
sThe link state.
Returns
true when the INA3221's windows come from SERVO_WIN.

◆ sense_link_write_owed()

sense_link_op_kind_t sense_link_write_owed ( const sense_link_t * s,
uint16_t * regs )

The write owed now, or NONE, with its registers in regs.

Parameters
sThe link state.
regsReceives the registers of the write.
Returns
The write owed, or NONE, as sense_link_op_kind_t.

◆ setup_valid()

bool setup_valid ( const sense_setup_t * w)
static

Whether w is a set-up SETUP can name: every value inside the page's own range.

A zeroed one – a snapshot nobody has published into – is not, and is no reason to write anything.

Parameters
wThe set-up.
Returns
true when every value is inside the page's range.

◆ win_entry()

void win_entry ( const uint16_t * regs,
unsigned k,
uint16_t newest,
uint32_t now_ms,
sense_link_win_t * w )
static

Entry k of a SERVO_WIN read, whose newest number is newest.

Parameters
regsThe registers read.
kThe entry index.
newestThe newest window number.
now_msThe time, in ms.
wReceives the window.

◆ written()

void written ( sense_link_t * s,
sense_link_op_kind_t w,
int result,
uint32_t now_ms )
static

Handles the result of a write.

Parameters
sThe link state.
wThe write.
resultThe result: an acknowledgement, a NACK reason or no answer.
now_msThe time, in ms.

Variable Documentation

◆ k_online

const uint16_t k_online[2]
static
Initial value:
LINK_SN_I3221_ONLINE }

◆ k_silent

const uint32_t k_silent[2]
static
Initial value:
SENSE_LINK_EV_I3221_SILENT }

◆ k_wrong

const uint16_t k_wrong[2]
static
Initial value:
LINK_SN_I3221_ID_WRONG }

◆ k_wrong_ev

const uint32_t k_wrong_ev[2]
static
Initial value:
SENSE_LINK_EV_I3221_WRONG }

◆ sense_link_en_bit

const uint16_t sense_link_en_bit[2]
Initial value:
LINK_SN_EN_I3221 }