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

The panel's half of the TONE (0x2D) link page, protocol 4.8: what is written to it, in what order, what is read from it and how often, and what a read means for the operator. More...

#include <stdbool.h>
#include <stdint.h>
#include "link_pages.h"

Go to the source code of this file.

Data Structures

struct  tone_setup_t
 The set-up as SETUP INTERFACES has it. More...
 One exchange the TONE link asks the caller to make. More...
struct  tone_beep_t
 One beep as the page reported it. More...
struct  tone_readout_t
 The screen's copy: a plain value the control task fills and the renderer reads. More...
 The panel's state of the TONE link page. More...

Macros

#define TONE_LINK_MINOR   8u
 The protocol minor that has the TONE page.
#define TONE_LINK_SETTLE_MS   500u
 A set-up rests this long after its last edit before it is written: a held + or - on SETUP steps a value about 30 times a second, and each write is a flash save at the IOmcu.
#define TONE_LINK_READ_MS   40u
 Registers 8 to 23 are due this long after the last read while the tap is enabled: under the 50ms poll, so every BENCH poll reads them.
#define TONE_LINK_RETRY_MS   5000u
 A first frame refused on a busy pin is offered again this often: freeing the pin on OUTPUTS, SENSE, SUPPLY or PROG lets it through.
#define TONE_LINK_STALE_MS   500u
 A read older than this no longer says the tap runs.
#define TONE_LINK_WINDOW_STALE_MS   1500u
 A WINDOW that has not moved for this long, while FLAGS says the tap runs, no longer says it runs: the detector closes a window every 8ms, edges or none, so a count that stands is a capture that stopped while the page still answers.
#define TONE_LINK_EVENT_GAP_MS   5000u
 How long an event handed out by tone_link_event() has the alert band before the next one is handed out.
#define TONE_LINK_HISTORY   8u
 The beeps the panel keeps for the screen.
#define TONE_LINK_SHOWN   4u
 The beeps the readout carries, newest first.
#define TONE_LINK_STATUS_COUNT   ((unsigned)LINK_TN_COUNT - (unsigned)LINK_TN_FLAGS)
 Registers 8 to 23, as read.
#define TONE_LINK_BEEP_COUNT   ((unsigned)LINK_TN_EVT_FLAGS - (unsigned)LINK_TN_EVT_SEQ + 1u)
 EVT_SEQ to EVT_FLAGS, as read.
#define TONE_LINK_NO_ANSWER   (-1)
 What came of an exchange: ACK or DATA, a NACK's reason, or none.
#define TONE_LINK_ACK   0
#define TONE_LINK_EV_SETUP
 The events about the set-up asked, which tone_link_event_stands() judges.

Enumerations

enum  {
  TONE_LINK_EV_NO_PAGE = 0x01 , TONE_LINK_EV_PIN_REFUSED = 0x02 , TONE_LINK_EV_SETUP_REFUSED = 0x04 , TONE_LINK_EV_PIN_BUSY = 0x08 ,
  TONE_LINK_EV_OVERRUN = 0x10
}
 Things the caller tells the operator about, each once. More...
enum  tone_link_op_kind_t {
  TONE_LINK_OP_NONE = 0 , TONE_LINK_OP_READ_SETUP , TONE_LINK_OP_FRAME0 , TONE_LINK_OP_FRAME1 ,
  TONE_LINK_OP_STATUS , TONE_LINK_OP_SELECT , TONE_LINK_OP_BEEP
}
 The exchange tone_link_next() asks for. More...
enum  tone_state_t {
  TONE_STATE_OFF = 0 , TONE_STATE_NO_PAGE , TONE_STATE_WAITING , TONE_STATE_RUNNING ,
  TONE_STATE_REFUSED , TONE_STATE_STOPPED
}
 What the tap is doing, for the screen. More...
enum  { TONE_LINK_ROWS_TAP = 0x01 , TONE_LINK_ROWS_BEEP = 0x02 }
 The rows of SETUP INTERFACES, for tone_link_unheld(): the first frame's – Phase tap, Tap pin and the two tones – and the second's – pitch split, gap and periods.

Functions

void tone_link_init (tone_link_t *t)
 Sets up the tone link state.
void tone_link_lost (tone_link_t *t)
 The link went: nothing on the page is known, and nothing is read or written until it comes up again.
void tone_link_came_up (tone_link_t *t, uint16_t minor, uint32_t now_ms)
 An IOmcu answered with protocol minor minor.
void tone_link_want (tone_link_t *t, const tone_setup_t *w, uint32_t now_ms)
 The set-up SETUP names now.
bool tone_link_next (tone_link_t *t, uint32_t now_ms, tone_link_op_t *op)
 The next exchange owed at now_ms, into op; false for none.
void tone_link_done (tone_link_t *t, int result, const uint16_t *regs, uint32_t now_ms)
 How the exchange tone_link_next() gave went: TONE_LINK_ACK with the registers read (regs, op.n of them; NULL for a write), a NACK reason, or TONE_LINK_NO_ANSWER.
uint16_t tone_link_event (tone_link_t *t, uint32_t now_ms)
 One event for the alert band, which shows one line and replaces it with the next: the most pressing waiting, cleared, and the rest kept.
bool tone_link_event_stands (const tone_link_t *t, uint16_t ev)
 Whether what ev, one TONE_LINK_EV_* bit, says still holds now.
void tone_link_event_back (tone_link_t *t, uint16_t ev)
 Put back an event tone_link_event() handed out that never reached the band, so it is handed out again after the gap.
bool tone_link_settled (const tone_link_t *t)
 Whether nothing is owed: the page holds the set-up asked, less the frames it refused.
uint8_t tone_link_unheld (const tone_link_t *t)
 The frames whose values as asked are not the ones the page holds, TONE_LINK_ROWS_*: not written yet, or refused.
unsigned tone_link_beeps (const tone_link_t *t, tone_beep_t *out, unsigned max)
 The beeps the panel has read, newest first, at most max; how many.
uint32_t tone_link_read_count (const tone_link_t *t)
 Beeps read since init, and beeps the panel did not read: the ring moved past them, or the page no longer held them.
uint32_t tone_link_missed (const tone_link_t *t)
 Counts the beeps the panel did not read.
uint16_t tone_link_flags (const tone_link_t *t)
 FLAGS as last read, 0 before any read.
void tone_link_readout (const tone_link_t *t, uint32_t now_ms, tone_readout_t *r)
 The screen's copy of everything above, at now_ms.
unsigned tone_link_pin (const tone_link_t *t)
 The pin and the tone range asked, for the alerts' text.
unsigned tone_link_f_min (const tone_link_t *t)
 The lower end of the tone range asked, for the alerts' text.
unsigned tone_link_f_max (const tone_link_t *t)
 The upper end of the tone range asked, for the alerts' text.
bool tone_link_held_pin (const tone_link_t *t, int *pin)
 The tap's pin the page holds by its last read or write, as the IOmcu reserves it (tone_page_pins()): the pin while ENABLE has the tap on and the last status read does not say the pin refused, -1 otherwise and while the IOmcu has no TONE page.

Detailed Description

The panel's half of the TONE (0x2D) link page, protocol 4.8: what is written to it, in what order, what is read from it and how often, and what a read means for the operator.

The IOmcu reads one motor phase on a GPIO (the phase tap) and turns its edges into beeps and their pitch; the panel sets the tap up from SETUP INTERFACES and reads the beeps. An IOmcu whose protocol minor is below TONE_LINK_MINOR has no such page and nothing is sent to it: not a write and not a read. With the tap enabled on SETUP, the operator is told so.

The set-up is two frames of four registers: ENABLE to F_MAX_HZ (0 to 3) and SPLIT_PCT to register 7 (4 to 7). Each is written whole. The page judges every frame against the whole set-up it would leave, and a low F_MIN_HZ needs a long GAP_MS, so when both frames change the one whose intermediate set-up is valid goes first:

  1. what the page holds is read first, TONE 0 to 6, once per link-up, and nothing is written that it already holds;
  2. the frames that differ, in the order above;
  3. a frame the page refuses is not written again until the set-up changes or the link comes up again – except the first, refused for a pin something else holds, which is offered again every TONE_LINK_RETRY_MS and said once. A page from 4.17 (LINK_MINOR_TONE_BUSY) says that refusal with LINK_NACK_BUSY, and only that one is offered again. An older page says BAD_VALUE for a busy pin and for bad values alike: its refusal is offered again unless the frame's tones fail on their face – the high tone not above the low one, or the gap held too short for the low tone.

Switching the tap off writes the first frame with the values the page holds and ENABLE clear, whatever range is asked; the range follows in a frame of its own. The readout is not OFF while the page holds ENABLE. A saved tap the page refused for a busy pin at boot is offered again every TONE_LINK_RETRY_MS while FLAGS says so, and not said again.

A write that enables the tap, or moves it to another pin, starts the capture again with the ring empty and the numbering going on: the panel takes its place at BEEP_HEAD at the next status. A change of the range or of the other values leaves the ring, the numbering and the panel's place.

The tap is an input and drives nothing, so a write does not wait for an idle bank. It waits TONE_LINK_SETTLE_MS since the set-up's last edit, because the IOmcu keeps each change in flash.

While the page holds ENABLE set, registers 8 to 23 are read every TONE_LINK_READ_MS. The IOmcu keeps the last LINK_TN_RING beeps, numbered 1 to 65535 and then 1 again. The panel asks for each number in turn: it writes EVT_SEL, then reads EVT_SEQ to EVT_FLAGS. A read does not consume a beep, so a reply that does not come loses nothing: the same beep is asked for again. A beep that has left the ring when the panel asks, or that the panel is more than LINK_TN_RING behind BEEP_HEAD, is counted in tone_link_missed().

Pure C, no link of its own: the caller makes each exchange and reports how it went. Control task only.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ TONE_LINK_EV_SETUP

#define TONE_LINK_EV_SETUP
Value:

The events about the set-up asked, which tone_link_event_stands() judges.

◆ TONE_LINK_WINDOW_STALE_MS

#define TONE_LINK_WINDOW_STALE_MS   1500u

A WINDOW that has not moved for this long, while FLAGS says the tap runs, no longer says it runs: the detector closes a window every 8ms, edges or none, so a count that stands is a capture that stopped while the page still answers.

SUPPLY's and SENSE's counts are judged the same way, at 1500ms for SUPPLY.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Things the caller tells the operator about, each once.

Enumerator
TONE_LINK_EV_NO_PAGE 

The tap is enabled and the IOmcu has no TONE page.

TONE_LINK_EV_PIN_REFUSED 

The page refused the first frame: the pin, or the tone range.

TONE_LINK_EV_SETUP_REFUSED 

The page refused the second frame: split, gap or periods.

TONE_LINK_EV_PIN_BUSY 

FLAGS says the pin is not free: a set-up kept in the IOmcu's flash met a binding at boot.

TONE_LINK_EV_OVERRUN 

FLAGS says the capture overran: a beep was cut.

◆ tone_link_op_kind_t

The exchange tone_link_next() asks for.

Enumerator
TONE_LINK_OP_READ_SETUP 

TONE 0 to 6: what the page holds

TONE_LINK_OP_FRAME0 

TONE 0 to 3

TONE_LINK_OP_FRAME1 

TONE 4 to 7

TONE_LINK_OP_STATUS 

TONE 8 to 23

TONE_LINK_OP_SELECT 

TONE 13, the beep wanted

TONE_LINK_OP_BEEP 

TONE 14 to 21, the beep selected

◆ tone_state_t

What the tap is doing, for the screen.

Enumerator
TONE_STATE_OFF 

not enabled on SETUP

TONE_STATE_NO_PAGE 

enabled; the IOmcu has no page

TONE_STATE_WAITING 

enabled; no link, or nothing read yet

TONE_STATE_RUNNING 

the capture runs

TONE_STATE_REFUSED 

the pin is not free

TONE_STATE_STOPPED 

enabled and not running

Function Documentation

◆ tone_link_beeps()

unsigned tone_link_beeps ( const tone_link_t * t,
tone_beep_t * out,
unsigned max )

The beeps the panel has read, newest first, at most max; how many.

Parameters
tThe link state.
outReceives the beeps, newest first.
maxThe number of entries out holds.
Returns
The number of beeps written to out.

◆ tone_link_came_up()

void tone_link_came_up ( tone_link_t * t,
uint16_t minor,
uint32_t now_ms )

An IOmcu answered with protocol minor minor.

Below TONE_LINK_MINOR it has no page and nothing is sent to it, and the tap enabled on SETUP raises TONE_LINK_EV_NO_PAGE.

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

◆ tone_link_done()

void tone_link_done ( tone_link_t * t,
int result,
const uint16_t * regs,
uint32_t now_ms )

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

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

◆ tone_link_event()

uint16_t tone_link_event ( tone_link_t * t,
uint32_t now_ms )

One event for the alert band, which shows one line and replaces it with the next: the most pressing waiting, cleared, and the rest kept.

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

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

◆ tone_link_event_back()

void tone_link_event_back ( tone_link_t * t,
uint16_t ev )

Put back an event tone_link_event() handed out that never reached the band, so it is handed out again after the gap.

An event about an IOmcu is not put back once the link has gone.

Parameters
tThe link state.
evThe event to put back.

◆ tone_link_event_stands()

bool tone_link_event_stands ( const tone_link_t * t,
uint16_t ev )

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

A refused frame – TONE_LINK_EV_PIN_REFUSED for the first, TONE_LINK_EV_SETUP_REFUSED for the second – until the page is known to hold that frame as asked: not refused, and written and taken. A value stepped back on SETUP ends it once the IOmcu takes the frame, after TONE_LINK_SETTLE_MS and a poll. TONE_LINK_EV_PIN_BUSY until the tap is off as asked and held, or a status read under the first frame as asked shows its pin taken (FLAGS bit 1 clear). With no IOmcu answering they stand. True for every other event.

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

Parameters
tThe link state.
evOne TONE_LINK_EV_* bit.
Returns
true while the cause of the event holds.

◆ tone_link_f_max()

unsigned tone_link_f_max ( const tone_link_t * t)

The upper end of the tone range asked, for the alerts' text.

Parameters
tThe link state.
Returns
The upper end of the tone range asked.

◆ tone_link_f_min()

unsigned tone_link_f_min ( const tone_link_t * t)

The lower end of the tone range asked, for the alerts' text.

Parameters
tThe link state.
Returns
The lower end of the tone range asked.

◆ tone_link_flags()

uint16_t tone_link_flags ( const tone_link_t * t)

FLAGS as last read, 0 before any read.

Parameters
tThe link state.
Returns
FLAGS as last read.

◆ tone_link_held_pin()

bool tone_link_held_pin ( const tone_link_t * t,
int * pin )

The tap's pin the page holds by its last read or write, as the IOmcu reserves it (tone_page_pins()): the pin while ENABLE has the tap on and the last status read does not say the pin refused, -1 otherwise and while the IOmcu has no TONE page.

False, -1, while that is not known: no link, or no read yet. pin may be NULL.

Parameters
tThe link state.
pinReceives the pin, or -1 while not known; may be NULL.
Returns
true when the pin is known.

◆ tone_link_init()

void tone_link_init ( tone_link_t * t)

Sets up the tone link state.

Parameters
tThe link state to set up.

◆ tone_link_lost()

void tone_link_lost ( tone_link_t * t)

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

The beep history stays on screen.

Parameters
tThe link state.

◆ tone_link_missed()

uint32_t tone_link_missed ( const tone_link_t * t)

Counts the beeps the panel did not read.

Parameters
tThe link state.
Returns
The beeps missed since init.

◆ tone_link_next()

bool tone_link_next ( tone_link_t * t,
uint32_t now_ms,
tone_link_op_t * op )

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

The caller makes the exchange and reports with tone_link_done().

Parameters
tThe link state.
now_msThe time, in ms.
opReceives the exchange owed.
Returns
true when an exchange is owed.

◆ tone_link_pin()

unsigned tone_link_pin ( const tone_link_t * t)

The pin and the tone range asked, for the alerts' text.

Parameters
tThe link state.
Returns
The tap's pin asked.

◆ tone_link_read_count()

uint32_t tone_link_read_count ( const tone_link_t * t)

Beeps read since init, and beeps the panel did not read: the ring moved past them, or the page no longer held them.

Parameters
tThe link state.
Returns
The beeps read since init.

◆ tone_link_readout()

void tone_link_readout ( const tone_link_t * t,
uint32_t now_ms,
tone_readout_t * r )

The screen's copy of everything above, at now_ms.

The status's values are filled only while tone_readout_t.read holds; the beeps and the missed count are the panel's own and stay.

Parameters
tThe link state.
now_msThe time, in ms.
rReceives the copy.

◆ tone_link_settled()

bool tone_link_settled ( const tone_link_t * t)

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

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

◆ tone_link_unheld()

uint8_t tone_link_unheld ( const tone_link_t * t)

The frames whose values as asked are not the ones the page holds, TONE_LINK_ROWS_*: not written yet, or refused.

The comparison is want against held, the two this module writes from. 0 while no IOmcu answers and before the page has been read. An IOmcu without the page holds no tap, and a tap that is on is named.

Parameters
tThe link state.
Returns
The frames not held as asked, as a TONE_LINK_ROWS_* value.

◆ tone_link_want()

void tone_link_want ( tone_link_t * t,
const tone_setup_t * w,
uint32_t now_ms )

The set-up SETUP names now.

The tap enabled while an IOmcu without the page answers raises TONE_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
tThe link state.
wThe set-up SETUP names.
now_msThe time, in ms.