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

A binding on the link, from the panel's side. More...

#include "bind_link.h"
#include <stddef.h>
#include <string.h>
#include "out_stage.h"

Functions

static bool page_written (link_host_t *h, const link_port_t *port, uint8_t page, uint8_t count, const uint16_t *regs, bind_write_t *res)
 page_written() writes from register 0.
bind_write_t bind_link_write (link_host_t *h, const link_port_t *port, uint16_t minor, const uint16_t *cfg, const uint16_t *slots, bind_rate_t *rate)
 Write a CHAN_CFG page cfg and an OUTPUTS page slots, each frame its own acknowledged exchange (link_write_acked()).
bool bind_link_may_write (bind_read_t last, uint16_t board, const outbind_t *b)
 Whether a binding b may be written while the last reading is last and the IOmcu answering is board board.
bind_read_t bind_link_classify (bind_reading_t *out, uint16_t board, const uint16_t *slots, const uint16_t *cfg)
 Tell the four states apart from two replies.
bind_read_t bind_link_read (link_host_t *h, const link_port_t *port, uint16_t board, bind_reading_t *out)
 Read OUTPUTS and then CHAN_CFG, two exchanges, and classify them.

Detailed Description

A binding on the link, from the panel's side.

See bind_link.h.

SPDX-License-Identifier: MIT

Function Documentation

◆ bind_link_classify()

bind_read_t bind_link_classify ( bind_reading_t * out,
uint16_t board,
const uint16_t * slots,
const uint16_t * cfg )

Tell the four states apart from two replies.

slots and cfg are the OUTPUTS and CHAN_CFG pages read, or NULL for one that did not read.

Parameters
outReceives the reading. NULL gives BIND_READ_NONE and nothing is stored.
boardThe board the IOmcu answers as.
slotsThe OUTPUTS page, LINK_OS_COUNT registers, or NULL.
cfgThe CHAN_CFG page, LINK_CC_COUNT registers, or NULL.
Returns
BIND_READ_NONE when either page is NULL. BIND_READ_NO_BOARD when this build has no pin map for board. BIND_READ_OK when the pages render to a binding. BIND_READ_ODD otherwise.

◆ bind_link_may_write()

bool bind_link_may_write ( bind_read_t last,
uint16_t board,
const outbind_t * b )

Whether a binding b may be written while the last reading is last and the IOmcu answering is board board.

Never a binding made for another board: a pin index belongs to one board's catalogue.

BIND_READ_OK: yes. BIND_READ_ODD: only a binding that holds no pin, the one way out of pages no binding describes. BIND_READ_NONE and BIND_READ_NO_BOARD: no – a binding built on pages nobody read would replace whatever the IOmcu holds with what a screen happened to show.

Parameters
lastThe state of the last reading.
boardThe board the IOmcu answers as.
bThe binding to write.
Returns
true when b may be written, false when b is NULL, made for another board, or last does not allow it.

◆ bind_link_read()

bind_read_t bind_link_read ( link_host_t * h,
const link_port_t * port,
uint16_t board,
bind_reading_t * out )

Read OUTPUTS and then CHAN_CFG, two exchanges, and classify them.

The second is not sent when the first did not read.

Parameters
hThe link host to read through.
portThe link port the IOmcu answers on.
boardThe board the IOmcu answers as.
outReceives the reading. NULL gives BIND_READ_NONE.
Returns
The state from bind_link_classify(), or BIND_READ_NONE when h or port is NULL or an exchange did not return a data frame.

◆ bind_link_write()

bind_write_t bind_link_write ( link_host_t * h,
const link_port_t * port,
uint16_t minor,
const uint16_t * cfg,
const uint16_t * slots,
bind_rate_t * rate )

Write a CHAN_CFG page cfg and an OUTPUTS page slots, each frame its own acknowledged exchange (link_write_acked()).

First, to an IOmcu of minor 1 or later, SERVO's FRAME_HZ = 0: each slot back at its own rate. A refusal ends the sequence BIND_REFUSED and no answer ends it BIND_NO_LINK, with no page written. rate, when not NULL, takes what became of it.

Then, to an IOmcu whose protocol minor minor is LINK_MINOR_BIND (10) or later: 8 frames to BIND_CFG, 8 to BIND_OUT, and LINK_BD_COMMIT with the CRC (cyclic redundancy check) of the two pages, 17 exchanges. The pages in force change at the commit and not before, both or neither, so a sequence that ends BIND_NO_LINK or BIND_REFUSED before the commit is taken leaves the binding in force as it was. A commit whose acknowledgement alone is lost ends BIND_NO_LINK with the binding written, whole.

To an older IOmcu: 8 frames to CHAN_CFG and 8 to OUTPUTS, 16 exchanges, each in force as it is acknowledged. A sequence that stops part way leaves the frames before it applied.

The exchanges stop at the first one refused or unanswered.

Parameters
hThe link host to write through.
portThe link port the IOmcu answers on.
minorThe IOmcu's protocol minor version.
cfgThe CHAN_CFG page, LINK_CC_COUNT registers.
slotsThe OUTPUTS page, LINK_OS_COUNT registers.
rateReceives what became of the SERVO rate reset, set to BIND_RATE_NOT_SENT first. NULL discards it.
Returns
BIND_WRITTEN when every exchange was acknowledged. BIND_NO_LINK when an exchange was unanswered, or when h, port, cfg or slots is NULL. BIND_REFUSED when the far end answered and refused one.

◆ page_written()

bool page_written ( link_host_t * h,
const link_port_t * port,
uint8_t page,
uint8_t count,
const uint16_t * regs,
bind_write_t * res )
static

page_written() writes from register 0.

One page, a frame per exchange. True when it was acknowledged whole; otherwise res says which way it ended.

Parameters
hThe link host to write through.
portThe link port the IOmcu answers on.
pageThe page to write.
countNumber of registers written, from register 0.
regsThe registers to write, count of them.
resReceives BIND_NO_LINK for an unanswered exchange and BIND_REFUSED for a reply other than an ACK. Set only when false is returned.
Returns
true when the write was acknowledged whole, false otherwise.