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

The panel's half of the KST link page. More...

#include "kst_link.h"
#include <stddef.h>
#include <string.h>

Macros

#define STAGE_WINDOWS   6u
#define RESULTS_N   ((unsigned)LINK_KS_IMAGE - (unsigned)LINK_KS_FAIL)
#define RES(reg)

Enumerations

enum  {
  X_NONE = 0 , X_STATUS , X_STAGE , X_SUPPLY ,
  X_LEAVE_MS , X_CMD , X_RESULTS , X_VIEW_BACKUP ,
  X_BACKUP , X_VIEW_IMAGE , X_IMAGE
}

Functions

static void image_to_regs (const kst_image_t *img, uint16_t *regs)
 Packs an image into registers, two bytes each, low byte first.
static void image_from_regs (const uint16_t *regs, kst_image_t *img)
 Unpacks registers into an image, low byte first.
static bool op_writes (link_kst_op_t op)
 Whether an operation writes the servo.
static bool op_staged (link_kst_op_t op)
 Whether an operation writes or verifies the servo.
static void finish (kst_link_t *k, kst_link_outcome_kind_t kind, uint8_t nack)
 The operation on its way ends here, as kind.
void kst_link_init (kst_link_t *k)
 Sets up the link state for the KST link page.
void kst_link_lost (kst_link_t *k)
 The link went: an operation on its way ends as KST_LINK_OUT_NO_ANSWER and nothing is read or written until it comes up again.
void kst_link_came_up (kst_link_t *k, uint16_t minor)
 An IOmcu answered with protocol minor minor.
bool kst_link_has_page (const kst_link_t *k)
 Whether the IOmcu has the page: false while none answers.
static kst_link_start_t ready (const kst_link_t *k)
 Whether a start is allowed now.
kst_link_start_t kst_link_start (kst_link_t *k, const kst_link_request_t *r)
 Start an operation.
kst_link_start_t kst_link_fetch (kst_link_t *k)
 Read the results and the images again without an operation: for a panel that started while the port is out of PWM.
static void cmd_in_doubt (kst_link_t *k)
 The request's command went and no answer came: it is not sent again.
void kst_link_abort (kst_link_t *k)
 STOP, or the operator's cancel.
static bool ask (kst_link_t *k, kst_link_xfer_t *x, uint8_t kind, bool write, uint8_t off, uint8_t n, const uint16_t *regs)
 Sets up one exchange with the KST page.
static bool ask_status (kst_link_t *k, uint32_t now_ms, kst_link_xfer_t *x)
 Sets up a status read of the KST page.
static bool due (const kst_link_t *k, uint32_t now_ms, uint32_t period)
 Whether a periodic read is due.
static bool ask_cmd (kst_link_t *k, kst_link_xfer_t *x)
 Sets up the write of the command to the KST page.
static bool ask_fetch (kst_link_t *k, kst_link_xfer_t *x)
 Sets up the next fetch of the results or an image.
bool kst_link_next (kst_link_t *k, uint32_t now_ms, kst_link_xfer_t *x)
 The next exchange owed at now_ms, into x; false for none.
static bool page_took_cmd (const kst_link_t *k, const uint16_t *regs)
 Whether the page regs took the command that was not sent again.
static bool op_went_back (const kst_link_t *k, const uint16_t *regs)
 Whether the page regs is one that started again since the status last read, whatever its SEQ.
static void on_status (kst_link_t *k, const uint16_t *regs)
 Takes a status read into the state.
static void fetch_done (kst_link_t *k)
 Ends a fetch and makes the module ready.
static void on_refused (kst_link_t *k, uint8_t kind, uint8_t nack)
 Handles an exchange the page refused.
void kst_link_done (kst_link_t *k, int result, const uint16_t *regs)
 How the exchange kst_link_next() gave went: KST_LINK_ACK with the registers read (regs, x.n of them; NULL for a write), a NACK reason, or KST_LINK_NO_ANSWER.
static kst_link_phase_t phase_shown (const kst_link_t *k)
 The phase as the screen sees it: an operation that runs and has sent no frame yet plans.
kst_link_phase_t kst_link_phase (const kst_link_t *k)
 Where the module is.
bool kst_link_outcome (kst_link_t *k, kst_link_outcome_t *out)
 How the last operation went, once: false while there is nothing new.
void kst_link_readout (const kst_link_t *k, kst_link_readout_t *r)
 The screen's copy of the page.
bool kst_link_image (const kst_link_t *k, kst_image_t *out)
 The servo's registers as last fetched; false while there are none.
bool kst_link_backup (const kst_link_t *k, kst_image_t *out)
 The backup the IOmcu's session holds, as last fetched.

Detailed Description

The panel's half of the KST link page.

See kst_link.h.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ RES

#define RES ( reg)
Value:
((unsigned)(reg) - (unsigned)LINK_KS_FAIL)

Function Documentation

◆ ask()

bool ask ( kst_link_t * k,
kst_link_xfer_t * x,
uint8_t kind,
bool write,
uint8_t off,
uint8_t n,
const uint16_t * regs )
static

Sets up one exchange with the KST page.

Parameters
kThe link state.
xReceives the exchange.
kindThe exchange kind.
writetrue for a write.
offThe first register on the page.
nThe number of registers.
regsThe registers to write, or NULL for a read.
Returns
Always true.

◆ ask_cmd()

bool ask_cmd ( kst_link_t * k,
kst_link_xfer_t * x )
static

Sets up the write of the command to the KST page.

Parameters
kThe link state.
xReceives the exchange.
Returns
Always true.

◆ ask_fetch()

bool ask_fetch ( kst_link_t * k,
kst_link_xfer_t * x )
static

Sets up the next fetch of the results or an image.

Parameters
kThe link state.
xReceives the exchange.
Returns
The result of ask() for the fetch kind.

◆ ask_status()

bool ask_status ( kst_link_t * k,
uint32_t now_ms,
kst_link_xfer_t * x )
static

Sets up a status read of the KST page.

Parameters
kThe link state.
now_msThe time, in ms.
xReceives the exchange.
Returns
true when the read is set up.

◆ cmd_in_doubt()

void cmd_in_doubt ( kst_link_t * k)
static

The request's command went and no answer came: it is not sent again.

Whether the page took it, the next status read says (on_status()). That read has KST_LINK_RETRIES tries of its own.

Parameters
kThe link state.

◆ due()

bool due ( const kst_link_t * k,
uint32_t now_ms,
uint32_t period )
static

Whether a periodic read is due.

Parameters
kThe link state.
now_msThe time, in ms.
periodThe period, in ms.
Returns
true when the read was never made or period has passed since the last one.

◆ fetch_done()

void fetch_done ( kst_link_t * k)
static

Ends a fetch and makes the module ready.

Parameters
kThe link state.

◆ finish()

void finish ( kst_link_t * k,
kst_link_outcome_kind_t kind,
uint8_t nack )
static

The operation on its way ends here, as kind.

Parameters
kThe link state.
kindThe outcome kind.
nackThe NACK reason of the last answer, or 0.

◆ image_from_regs()

void image_from_regs ( const uint16_t * regs,
kst_image_t * img )
static

Unpacks registers into an image, low byte first.

Parameters
regsThe registers.
imgReceives the image.

◆ image_to_regs()

void image_to_regs ( const kst_image_t * img,
uint16_t * regs )
static

Packs an image into registers, two bytes each, low byte first.

Parameters
imgThe image.
regsReceives the registers.

◆ kst_link_abort()

void kst_link_abort ( kst_link_t * k)

STOP, or the operator's cancel.

A request whose command has not gone is dropped (KST_LINK_OUT_DROPPED). A command that went without an answer is not sent again: a read of registers 0 to 3 follows. A page at the SEQ before the command did not take it, which drops the request too; any other SEQ is an IOmcu that started again (KST_LINK_OUT_RESTARTED). A page took it when it shows the command's SEQ and either the command's operation in LINK_KS_OP or a refusal. The command's SEQ with operation NONE and no refusal is an IOmcu that started again, at SEQ 0 after 0xFFFF: KST_LINK_OUT_RESTARTED, never KST_LINK_OUT_DONE. So is operation NONE at any SEQ after a status read that named an operation: the page keeps the last operation started until the IOmcu starts again. A page that has taken no command reads SEQ 0 and NONE before and after a start, and its first command counts as dropped. A page that took it runs the operation, and the ABORT ends it with KST_SES_ERR_ABORTED. The read unanswered KST_LINK_RETRIES times ends the request with KST_LINK_OUT_NO_ANSWER. The command ABORT is sent as soon as the page is known; an operation that runs ends with KST_SES_ERR_ABORTED. An ABORT the page refuses is followed by a read of registers 0 to 3 with the same checks: a page off the panel's SEQ, or with its operation back at NONE, ends the operation as KST_LINK_OUT_RESTARTED, never KST_LINK_OUT_DONE. An ABORT refused with LINK_NACK_BAD_VALUE goes again after that read, with the page's SEQ.

Parameters
kThe link state.

◆ kst_link_backup()

bool kst_link_backup ( const kst_link_t * k,
kst_image_t * out )

The backup the IOmcu's session holds, as last fetched.

Parameters
kThe link state.
outReceives the backup image.
Returns
true when out holds the backup.

◆ kst_link_came_up()

void kst_link_came_up ( kst_link_t * k,
uint16_t minor )

An IOmcu answered with protocol minor minor.

Below KST_LINK_MINOR it has no page and nothing is sent to it.

Parameters
kThe link state.
minorThe IOmcu's protocol minor version.

◆ kst_link_done()

void kst_link_done ( kst_link_t * k,
int result,
const uint16_t * regs )

How the exchange kst_link_next() gave went: KST_LINK_ACK with the registers read (regs, x.n of them; NULL for a write), a NACK reason, or KST_LINK_NO_ANSWER.

Parameters
kThe link state.
resultThe result: an acknowledgement, a NACK's reason or KST_LINK_NO_ANSWER.
regsThe registers read, or NULL for a write.

◆ kst_link_fetch()

kst_link_start_t kst_link_fetch ( kst_link_t * k)

Read the results and the images again without an operation: for a panel that started while the port is out of PWM.

No outcome.

Parameters
kThe link state.
Returns
The start result, as kst_link_start() gives it.

◆ kst_link_has_page()

bool kst_link_has_page ( const kst_link_t * k)

Whether the IOmcu has the page: false while none answers.

Parameters
kThe link state.
Returns
true while the IOmcu answers and has the page.

◆ kst_link_image()

bool kst_link_image ( const kst_link_t * k,
kst_image_t * out )

The servo's registers as last fetched; false while there are none.

Parameters
kThe link state.
outReceives the servo's image.
Returns
true when out holds the image.

◆ kst_link_init()

void kst_link_init ( kst_link_t * k)

Sets up the link state for the KST link page.

Parameters
kThe link state to set up.

◆ kst_link_lost()

void kst_link_lost ( kst_link_t * k)

The link went: an operation on its way ends as KST_LINK_OUT_NO_ANSWER and nothing is read or written until it comes up again.

The images stay.

Parameters
kThe link state.

◆ kst_link_next()

bool kst_link_next ( kst_link_t * k,
uint32_t now_ms,
kst_link_xfer_t * x )

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

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

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

◆ kst_link_outcome()

bool kst_link_outcome ( kst_link_t * k,
kst_link_outcome_t * out )

How the last operation went, once: false while there is nothing new.

Parameters
kThe link state.
outReceives the outcome.
Returns
true when a new outcome was written to out.

◆ kst_link_phase()

kst_link_phase_t kst_link_phase ( const kst_link_t * k)

Where the module is.

KST_LINK_PLANNING while the operation runs and the page last read says it plans.

Parameters
kThe link state.
Returns
The phase of the module.

◆ kst_link_readout()

void kst_link_readout ( const kst_link_t * k,
kst_link_readout_t * r )

The screen's copy of the page.

Parameters
kThe link state.
rReceives the copy of the page.

◆ kst_link_start()

kst_link_start_t kst_link_start ( kst_link_t * k,
const kst_link_request_t * r )

Start an operation.

Taken in KST_LINK_READY only; any other answer than KST_LINK_START_OK means nothing is sent.

A LEAVE with leave_ms above LINK_KST_LEAVE_MS_MAX is KST_LINK_START_ARG: the value is refused, not clamped.

A WRITE and a RELEASE are planned at the IOmcu from the image it read. The request names the image the panel last fetched by its CRC (cyclic redundancy check), and the IOmcu refuses with LINK_KST_REF_START when it holds another.

Parameters
kThe link state.
rThe request to start.
Returns
KST_LINK_START_OK when the operation is started, else the reason it is not.

◆ on_refused()

void on_refused ( kst_link_t * k,
uint8_t kind,
uint8_t nack )
static

Handles an exchange the page refused.

Parameters
kThe link state.
kindThe exchange kind.
nackThe NACK reason.

◆ on_status()

void on_status ( kst_link_t * k,
const uint16_t * regs )
static

Takes a status read into the state.

Parameters
kThe link state.
regsThe registers of the page as read.

◆ op_staged()

bool op_staged ( link_kst_op_t op)
static

Whether an operation writes or verifies the servo.

Parameters
opThe operation.
Returns
true for a write-type operation or VERIFY.

◆ op_went_back()

bool op_went_back ( const kst_link_t * k,
const uint16_t * regs )
static

Whether the page regs is one that started again since the status last read, whatever its SEQ.

The IOmcu names the operation it last started in LINK_KS_OP and keeps it until the next one; a refused command leaves it. Only a start of the IOmcu sets it back to NONE. A page that has started no operation yet reads NONE before and after a start, and only its SEQ tells.

Parameters
kThe link state.
regsThe registers of the page as read.
Returns
true when the page names no operation after a status read named one.

◆ op_writes()

bool op_writes ( link_kst_op_t op)
static

Whether an operation writes the servo.

Parameters
opThe operation.
Returns
true for WRITE, RESTORE or RELEASE.

◆ page_took_cmd()

bool page_took_cmd ( const kst_link_t * k,
const uint16_t * regs )
static

Whether the page regs took the command that was not sent again.

A command taken leaves its SEQ, and either its operation in LINK_KS_OP or a refusal in LINK_KS_RESULT's high byte. A page that started again has SEQ 0, operation NONE and no refusal: at SEQ 0, the command after 0xFFFF, the SEQ alone does not tell the two apart. The command's operation is never NONE.

Parameters
kThe link state.
regsThe registers of the page as read.
Returns
true when the page's SEQ is the command's SEQ and the page shows the command's operation or a refusal.

◆ phase_shown()

kst_link_phase_t phase_shown ( const kst_link_t * k)
static

The phase as the screen sees it: an operation that runs and has sent no frame yet plans.

Parameters
kThe link state.
Returns
The phase the screen shows.

◆ ready()

kst_link_start_t ready ( const kst_link_t * k)
static

Whether a start is allowed now.

Parameters
kThe link state.
Returns
KST_LINK_START_OK when a start is allowed, else the reason it is refused.