|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
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 | |
| struct | kst_link_request_t |
| An operation as the screen asks for it. More... | |
| struct | kst_link_outcome_t |
| The outcome of an operation that ended, as the link module reports it. More... | |
| struct | kst_link_readout_t |
| The screen's copy: a plain value the control task fills and the renderer reads. More... | |
| struct | kst_link_xfer_t |
| One exchange for the caller to make. More... | |
| struct | kst_link_t |
| 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. | |
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():
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
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 |
| enum 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 |
| enum kst_link_start_t |
What kst_link_start() and kst_link_fetch() answer.
| 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.
| k | The link state. |
| bool kst_link_backup | ( | const kst_link_t * | k, |
| kst_image_t * | out ) |
The backup the IOmcu's session holds, as last fetched.
| k | The link state. |
| out | Receives the backup image. |
| 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.
| k | The link state. |
| minor | The IOmcu's protocol minor version. |
| 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.
| k | The link state. |
| result | The result: an acknowledgement, a NACK's reason or KST_LINK_NO_ANSWER. |
| regs | The registers read, or NULL for a write. |
| 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.
| k | The link state. |
| bool kst_link_has_page | ( | const kst_link_t * | k | ) |
Whether the IOmcu has the page: false while none answers.
| k | The link state. |
| 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.
| k | The link state. |
| out | Receives the servo's image. |
| void kst_link_init | ( | kst_link_t * | k | ) |
Sets up the link state for the KST link page.
| k | The link state to set up. |
| 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.
| k | The link state. |
| 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().
| k | The link state. |
| now_ms | The time, in ms. |
| x | Receives the exchange owed. |
| 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.
| k | The link state. |
| out | Receives the outcome. |
| 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.
| k | The link state. |
| void kst_link_readout | ( | const kst_link_t * | k, |
| kst_link_readout_t * | r ) |
The screen's copy of the page.
| k | The link state. |
| r | Receives the copy of the page. |
| 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.
| k | The link state. |
| r | The request to start. |