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

SPDX-License-Identifier: MIT. More...

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

Enumerations

enum  parse_result_t { PARSE_INVALID = -1 , PARSE_INCOMPLETE = 0 , PARSE_OK = 1 }
 Outcome of examining one sync candidate. More...

Functions

static uint16_t rd16 (const uint8_t *p)
 Little-endian, assembled byte by byte rather than cast; see the header.
static void wr16 (uint8_t *p, uint16_t v)
 Write a little-endian 16-bit field.
static bool type_is_known (uint8_t t)
 Whether a type byte is one of the frame types this speaks.
static bool type_carries_telemetry (uint8_t t)
 A frame from the ESC (electronic speed controller) carries telemetry; one from the master carries the 4-byte control payload.
static uint8_t header_bytes (uint8_t version)
 Header length for a protocol version.
uint16_t openyge_crc (uint16_t crc, const void *data, size_t len)
 Fold len bytes at data into crc and return the new accumulator.
void openyge_decoder_reset (openyge_decoder_t *d)
 Clear a decoder, buffer and counters.
static parse_result_t parse_at (const openyge_decoder_t *d, size_t at, openyge_frame_t *out, size_t *total_out, bool *crc_failed, bool *rejected)
 Examine the candidate frame starting at at without modifying the decoder, so several candidates can be weighed before one is committed to.
static void drop (openyge_decoder_t *d, size_t n)
 Discard the first n bytes of the decoder buffer.
bool openyge_decode_byte (openyge_decoder_t *d, uint8_t byte, openyge_frame_t *out)
 Feed one received byte; returns true when out holds a whole good frame.
bool openyge_frame_has_telemetry (const openyge_frame_t *f)
 True if this frame is one an ESC sends, i.e. one carrying telemetry.
bool openyge_telemetry_parse (const openyge_frame_t *f, openyge_telemetry_t *out)
 Parse the telemetry payload.
bool openyge_control_parse (const openyge_frame_t *f, uint16_t *index, uint16_t *param)
 Parse the 4-byte control payload of a request.
size_t openyge_encode (uint8_t *out, size_t cap, uint8_t type, uint8_t device, uint8_t seq, const void *payload, size_t payload_len)
 Build a frame.
size_t openyge_build_telemetry_request (uint8_t *out, size_t cap, uint8_t device, uint8_t seq)
 A telemetry request: the control payload, both words zero.
size_t openyge_build_param_write (uint8_t *out, size_t cap, uint8_t device, uint8_t seq, uint16_t index, uint16_t value)
 A single parameter write.

Detailed Description

SPDX-License-Identifier: MIT.

Enumeration Type Documentation

◆ parse_result_t

Outcome of examining one sync candidate.

Enumerator
PARSE_INVALID 

not a frame: bad type, length, CRC, payload

PARSE_INCOMPLETE 

the buffer ends before the frame does

PARSE_OK 

a whole, verified frame

Function Documentation

◆ drop()

void drop ( openyge_decoder_t * d,
size_t n )
static

Discard the first n bytes of the decoder buffer.

Parameters
dDecoder holding the buffer.
nBytes to discard; more than the buffer holds empties it.

◆ header_bytes()

uint8_t header_bytes ( uint8_t version)
static

Header length for a protocol version.

Parameters
versionVersion byte from the header.
Returns
OPENYGE_HDR_V3 for version 3 and above, else OPENYGE_HDR_LEGACY.

◆ openyge_build_param_write()

size_t openyge_build_param_write ( uint8_t * out,
size_t cap,
uint8_t device,
uint8_t seq,
uint16_t index,
uint16_t value )

A single parameter write.

One parameter per frame; there is no page write.

Parameters
outBuffer to write the frame into.
capSize of out in bytes.
deviceDevice address, without the master bit.
seqSequence number.
indexParameter index.
valueValue to write.
Returns
Length of the frame, or 0 if it does not fit.

◆ openyge_build_telemetry_request()

size_t openyge_build_telemetry_request ( uint8_t * out,
size_t cap,
uint8_t device,
uint8_t seq )

A telemetry request: the control payload, both words zero.

Parameters
outBuffer to write the frame into.
capSize of out in bytes.
deviceDevice address, without the master bit.
seqSequence number.
Returns
Length of the frame, or 0 if it does not fit.

◆ openyge_control_parse()

bool openyge_control_parse ( const openyge_frame_t * f,
uint16_t * index,
uint16_t * param )

Parse the 4-byte control payload of a request.

Parameters
fDecoded frame.
indexReceives the parameter index; NULL to skip.
paramReceives the parameter value; NULL to skip.
Returns
true when parsed; false for a telemetry frame or a payload of the wrong length.

◆ openyge_crc()

uint16_t openyge_crc ( uint16_t crc,
const void * data,
size_t len )

Fold len bytes at data into crc and return the new accumulator.

A frame's CRC is openyge_crc(OPENYGE_CRC_INIT, frame, total - 2), stored little-endian in the frame's last 2 bytes. Incremental: folding a buffer in pieces gives what folding it whole gives. A len of 0 returns crc and reads nothing.

Parameters
crcAccumulator from an earlier call, or OPENYGE_CRC_INIT.
dataBytes to fold.
lenNumber of bytes in data.
Returns
The new accumulator.

◆ openyge_decode_byte()

bool openyge_decode_byte ( openyge_decoder_t * d,
uint8_t byte,
openyge_frame_t * out )

Feed one received byte; returns true when out holds a whole good frame.

Resynchronising: noise carrying a plausible sync byte in front of a real frame must not swallow the real one. Every sync byte in the buffer is a candidate and the earliest complete candidate wins.

Parameters
dDecoder state.
byteReceived byte.
outReceives the frame when true is returned.
Returns
true when a whole good frame was decoded.

◆ openyge_decoder_reset()

void openyge_decoder_reset ( openyge_decoder_t * d)

Clear a decoder, buffer and counters.

Parameters
dDecoder to clear; NULL does nothing.

◆ openyge_encode()

size_t openyge_encode ( uint8_t * out,
size_t cap,
uint8_t type,
uint8_t device,
uint8_t seq,
const void * payload,
size_t payload_len )

Build a frame.

Returns its length, or 0 if it would not fit or the type is not one this speaks.

The length byte is written from what was assembled, after the bounds check, so a frame that does not fit leaves the buffer untouched.

Parameters
outBuffer to write the frame into.
capSize of out in bytes.
typeOne of openyge_frame_type_t.
deviceDevice address, without the master bit.
seqSequence number.
payloadPayload bytes.
payload_lenPayload length; must match the type's payload size.
Returns
Length of the frame, or 0 if it would not fit or the type is not one this speaks.

◆ openyge_frame_has_telemetry()

bool openyge_frame_has_telemetry ( const openyge_frame_t * f)

True if this frame is one an ESC sends, i.e. one carrying telemetry.

Parameters
fDecoded frame.
Returns
true for an ESC frame with a telemetry-length payload.

◆ openyge_telemetry_parse()

bool openyge_telemetry_parse ( const openyge_frame_t * f,
openyge_telemetry_t * out )

Parse the telemetry payload.

False if the frame does not carry one.

Parameters
fDecoded frame.
outReceives the telemetry.
Returns
true when parsed; false if the frame does not carry telemetry or out is NULL.

◆ parse_at()

parse_result_t parse_at ( const openyge_decoder_t * d,
size_t at,
openyge_frame_t * out,
size_t * total_out,
bool * crc_failed,
bool * rejected )
static

Examine the candidate frame starting at at without modifying the decoder, so several candidates can be weighed before one is committed to.

Parameters
dDecoder holding the buffer.
atIndex of the sync byte of the candidate.
outReceives the frame when PARSE_OK; NULL to skip.
total_outReceives the frame length when PARSE_OK.
crc_failedSet to true when the CRC does not match.
rejectedSet to true when the CRC holds but the payload length does not fit the frame type.
Returns
PARSE_OK, PARSE_INCOMPLETE or PARSE_INVALID.

◆ rd16()

uint16_t rd16 ( const uint8_t * p)
inlinestatic

Little-endian, assembled byte by byte rather than cast; see the header.

Parameters
pTwo bytes, least significant first.
Returns
The 16-bit value.

◆ type_carries_telemetry()

bool type_carries_telemetry ( uint8_t t)
static

A frame from the ESC (electronic speed controller) carries telemetry; one from the master carries the 4-byte control payload.

The parameter-write acknowledgement is an ESC frame and carries telemetry too.

Parameters
tType byte from the header.
Returns
true for a telemetry-carrying type.

◆ type_is_known()

bool type_is_known ( uint8_t t)
static

Whether a type byte is one of the frame types this speaks.

Parameters
tType byte from the header.
Returns
true for a known type.

◆ wr16()

void wr16 ( uint8_t * p,
uint16_t v )
inlinestatic

Write a little-endian 16-bit field.

Parameters
pTwo bytes to write, least significant first.
vThe 16-bit value.