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

Frame building and reply decoding for the KST wire. More...

#include "kst_wire.h"
#include <string.h>

Macros

#define PREFIX_READ   0x200u
 The 10 bits after the start bit: 10 00000000 reads, 00 10000000 writes.
#define PREFIX_WRITE   0x080u

Functions

static void put_level (kst_frame_t *f, bool high)
 Append one half-cell level to a frame.
static void build (uint32_t word, kst_frame_kind_t kind, kst_frame_t *out)
 27 bits, most significant first, as 54 half-cells.
static uint32_t frame_word (uint32_t prefix, uint8_t reg, uint8_t data)
 Build the 27-bit word of a frame from its prefix, register and data.
bool kst_frame_read (uint8_t reg, kst_frame_t *out)
 Read frame for register reg.
bool kst_frame_write (uint8_t reg, uint8_t value, kst_frame_t *out)
 Write frame.
void kst_frame_sync (kst_frame_t *out)
 The sync burst that puts a servo into programming mode.
bool kst_frame_level (const kst_frame_t *frame, unsigned index)
 Level of half-cell index; false past the end.
uint32_t kst_frame_duration_ns (const kst_frame_t *frame)
 Time the frame takes on the wire, in ns.
uint32_t kst_reply_window_ns (kst_expect_t expect)
 Accept window and capture length for expect.
static unsigned filter (const kst_capture_t *cap, uint32_t *e, uint8_t *removed)
 The glitch rule: a level change counts once the new level has lasted KST_GLITCH_NS.
static unsigned edges_upto (const uint32_t *e, unsigned n, uint32_t t)
 Edges at or before t.
static bool halves_differ (const uint32_t *e, unsigned n, uint32_t t)
 The two halves of the cell whose mid-cell edge is at t differ.
static unsigned find_mid_edge (const uint32_t *e, unsigned n, unsigned last, uint32_t pred)
 Index of the edge after last nearest to pred and within KST_RX_SEARCH_NS of it; n when there is none.
static kst_rx_t track (const uint32_t *e, unsigned n, uint32_t window_ns, kst_expect_t expect, kst_reply_t *out)
 Track the mid-cell edges of a reply and decode its bits.
static kst_rx_t decode (const kst_capture_t *cap, kst_expect_t expect, kst_reply_t *out)
 Run the checks of kst_reply_decode() in their order.
kst_rx_t kst_reply_decode (const kst_capture_t *cap, kst_expect_t expect, kst_reply_t *out)
 Decode a reply window.

Detailed Description

Frame building and reply decoding for the KST wire.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ PREFIX_READ

#define PREFIX_READ   0x200u

The 10 bits after the start bit: 10 00000000 reads, 00 10000000 writes.

No other prefix is known.

Function Documentation

◆ build()

void build ( uint32_t word,
kst_frame_kind_t kind,
kst_frame_t * out )
static

27 bits, most significant first, as 54 half-cells.

The first half-cell is the low half of the start bit and is left out; a trailing low is cut, so the sequence ends on the frame's last high.

◆ edges_upto()

unsigned edges_upto ( const uint32_t * e,
unsigned n,
uint32_t t )
static

Edges at or before t.

The line starts low, so an odd count is high.

◆ filter()

unsigned filter ( const kst_capture_t * cap,
uint32_t * e,
uint8_t * removed )
static

The glitch rule: a level change counts once the new level has lasted KST_GLITCH_NS.

On timestamps that is a pair of edges closer than that, and both go. An edge that follows a removed pair is compared with the edge before the pair, so a burst of chatter ends on its last edge.

◆ kst_frame_duration_ns()

uint32_t kst_frame_duration_ns ( const kst_frame_t * frame)

Time the frame takes on the wire, in ns.

Parameters
frameFrame to measure.
Returns
Time the frame takes on the wire, in ns; 0 for a NULL frame.

◆ kst_frame_level()

bool kst_frame_level ( const kst_frame_t * frame,
unsigned index )

Level of half-cell index; false past the end.

Parameters
frameFrame to read.
indexHalf-cell index, counted from 0.
Returns
The level, 1 high or 0 low; false past the end.

◆ kst_frame_read()

bool kst_frame_read ( uint8_t reg,
kst_frame_t * out )

Read frame for register reg.

False, and no frame, for an address above KST_REG_MAX.

Parameters
regRegister address, up to KST_REG_MAX.
outReceives the frame.
Returns
true when a frame was built; false for an address above KST_REG_MAX.

◆ kst_frame_sync()

void kst_frame_sync ( kst_frame_t * out)

The sync burst that puts a servo into programming mode.

Parameters
outReceives the frame; NULL is ignored.

◆ kst_frame_write()

bool kst_frame_write ( uint8_t reg,
uint8_t value,
kst_frame_t * out )

Write frame.

False, and no frame, for register 0x00 and for an address above KST_REG_MAX: neither is ever written.

Parameters
regRegister address.
valueValue to write.
outReceives the frame.
Returns
true when a frame was built.

◆ kst_reply_decode()

kst_rx_t kst_reply_decode ( const kst_capture_t * cap,
kst_expect_t expect,
kst_reply_t * out )

Decode a reply window.

The decoder tracks the mid-cell edge of each of the 10 cells after the start cell and re-centres on every edge it finds. It does not classify run lengths: the last high of a reply is stretched by the release of the line. The value after a write is not a dependable echo; the caller reads the register back.

out is filled in every case; out->delay_ns and out->half_cell_ns are 0 where the check that failed comes before they are known.

Parameters
capCapture to decode.
expectWhat the master sent.
outReceives the decoded reply; NULL uses a scratch buffer.
Returns
KST_RX_OK, or the code of the first failed check.

◆ kst_reply_window_ns()

uint32_t kst_reply_window_ns ( kst_expect_t expect)

Accept window and capture length for expect.

Parameters
expectWhat the master sent.
Returns
Capture length in ns.