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

The panel's half of the KST (0x32) link page, protocol 4.13 to 4.15: the programming ports for KST and Chaservo servos. More...

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

Go to the source code of this file.

Data Structures

 An operation as the screen asks for it. More...
 The outcome of an operation that ended, as the link module reports it. More...
 The screen's copy: a plain value the control task fills and the renderer reads. More...
 One exchange for the caller to make. More...
 The state of the KST link module. More...

Macros

#define KST_LINK_MINOR   LINK_MINOR_PROG
 The protocol minor whose KST page names programming ports.
#define KST_LINK_POLL_MS   50u
 Registers 0 to 3 are due this long after the last read while an operation runs or the port is out of PWM.
#define KST_LINK_IDLE_MS   500u
 And this long after it while the port is in PWM.
#define KST_LINK_RETRIES   3u
 Exchanges without an answer, in a row, after which an operation is given up.
#define KST_LINK_NO_ANSWER   (-1)
 What came of an exchange: ACK or DATA, a NACK's reason, or none.
#define KST_LINK_ACK   0

Enumerations

enum  kst_link_phase_t {
  KST_LINK_DOWN = 0 , KST_LINK_NO_PAGE , KST_LINK_SYNC , KST_LINK_READY ,
  KST_LINK_SENDING , KST_LINK_RUNNING , KST_LINK_FETCHING , KST_LINK_PLANNING
}
 Where the module is. More...
enum  kst_link_start_t {
  KST_LINK_START_OK = 0 , KST_LINK_START_DOWN , KST_LINK_START_NO_PAGE , KST_LINK_START_BUSY ,
  KST_LINK_START_ARG , KST_LINK_START_NO_ENABLE , KST_LINK_START_NO_IMAGE , KST_LINK_START_NO_OP
}
 What kst_link_start() and kst_link_fetch() answer. More...
enum  kst_link_outcome_kind_t {
  KST_LINK_OUT_NONE = 0 , KST_LINK_OUT_DONE , KST_LINK_OUT_REFUSED , KST_LINK_OUT_NACK ,
  KST_LINK_OUT_NO_ANSWER , KST_LINK_OUT_RESTARTED , KST_LINK_OUT_DROPPED
}
 How an operation went. More...

Functions

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.
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.
void kst_link_abort (kst_link_t *k)
 STOP, or the operator's cancel.
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.
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.
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 (0x32) link page, protocol 4.13 to 4.15: the programming ports for KST and Chaservo servos.

The session with the servo runs at the IOmcu (shared/outputs/kst_port.h). The panel names an operation, and for a write the image the servo is to hold; it reads back where the port is, how the operation ended and the servo's 32 registers. An IOmcu whose protocol minor is below KST_LINK_MINOR has no programming port (minor 12 has the page and takes an output channel where this module names a port) and nothing is sent to it: not a write and not a read.

One operation at a time, kst_link_start():

  1. for a write, a restore, a release and a verify the staged registers 4 to 24 are written, 6 frames; for an ENTER the supply registers 26 and 27, 1 frame; for a LEAVE the wait, register 28, 1 frame;
  2. the command, registers 0 to 3, one frame, with SEQ one above the page's. A command without an answer is sent again as it was; the page takes it once. After kst_link_abort() it is not sent again: the next read of registers 0 to 3 says whether the page took it;
  3. registers 0 to 3 are read: the command started the operation or the page says why not;
  4. registers 0 to 3 are read every KST_LINK_POLL_MS until the operation has ended. A 4.14 IOmcu plans a WRITE and a RESTORE first, for 2,161 of its passes at most: the phase is KST_LINK_PLANNING while the page says so, and KST_LINK_RUNNING after it;
  5. registers 4 to 15 are read, the backup when the page holds one, and the image. The page is left showing the image.

kst_link_outcome() then hands out how it went, once.

A request with no order of writes ends differently by the IOmcu's minor. 4.14: KST_LINK_OUT_DONE with the result LINK_KST_RESULT_NO_PATH, or LINK_KST_RESULT_TOO_COMPLEX when the planner's work was spent before it knew. 4.13: KST_LINK_OUT_REFUSED with LINK_KST_REF_PLAN_NO_PATH. Nothing was sent to the servo in each case.

A LEAVE takes the port from PROGRAMMING to PWM without a supply cycle (LINK_MINOR_KST_LEAVE, 4.15). The request carries the wait with the line low, leave_ms. While the IOmcu waits the port reads LINK_KST_LEAVING and the phase is KST_LINK_RUNNING; the page has no register for the time left. To an IOmcu below 4.15 nothing of a LEAVE is sent: kst_link_start() answers KST_LINK_START_NO_OP.

A write to the servo is sent only with write_enabled set in the request: the state of the switch ENABLE WRITE TO SERVO. Without it the request is refused here and nothing is sent. The IOmcu refuses a write without the key on its own.

kst_link_abort() is for STOP and for the operator's cancel: a request whose command the page has not taken is dropped, and the command ABORT follows whenever the page is known. A command sent without an answer is never sent again after it; the page's SEQ tells whether it was taken.

Between operations registers 0 to 3 are read every KST_LINK_POLL_MS while the port is out of PWM and every KST_LINK_IDLE_MS while it is not.

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

SPDX-License-Identifier: MIT

Enumeration Type Documentation

◆ kst_link_outcome_kind_t

How an operation went.

Enumerator
KST_LINK_OUT_DONE 

it ran; result says how it ended

KST_LINK_OUT_REFUSED 

the page took the command and started nothing; refusal says why

KST_LINK_OUT_NACK 

the page refused a frame; nack says why

KST_LINK_OUT_NO_ANSWER 

KST_LINK_RETRIES exchanges unanswered, or the link went

KST_LINK_OUT_RESTARTED 

the page's SEQ is not the panel's, or its operation went back to NONE: the IOmcu started again

KST_LINK_OUT_DROPPED 

kst_link_abort() before the page took the command; nothing of it ran

◆ kst_link_phase_t

Where the module is.

Enumerator
KST_LINK_DOWN 

no IOmcu answers

KST_LINK_NO_PAGE 

the IOmcu has no KST page

KST_LINK_SYNC 

the page has not been read yet

KST_LINK_READY 

kst_link_start() is taken

KST_LINK_SENDING 

the staged registers and the command go out

KST_LINK_RUNNING 

the operation runs at the IOmcu

KST_LINK_FETCHING 

the results and the images are read

KST_LINK_PLANNING 

the operation runs at the IOmcu and has sent no frame yet: its plan is being built. KST_LINK_RUNNING follows

◆ kst_link_start_t

What kst_link_start() and kst_link_fetch() answer.

Enumerator
KST_LINK_START_DOWN 

no IOmcu answers

KST_LINK_START_NO_PAGE 

the IOmcu has no KST page

KST_LINK_START_BUSY 

the phase is not KST_LINK_READY

KST_LINK_START_ARG 

no such operation or port

KST_LINK_START_NO_ENABLE 

a write with write_enabled clear

KST_LINK_START_NO_IMAGE 

a write or a release with no image read to plan from

KST_LINK_START_NO_OP 

the IOmcu's minor does not have the operation: a LEAVE below 4.15

Function Documentation

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