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

The arithmetic of the Hitec PIO pin driver. More...

#include "hitec_pio.h"
#include <stddef.h>
#include <string.h>

Macros

#define PAIR(dir, level)
 The longest window, lead and level fit their fields at the fastest bit rate, with the divider 0.05% short.
#define RELEASED   PAIR(0u, 0u)
#define MAX_BITS   ((HITEC_PIO_TX_WORDS - 3u) * 16u)
 Bit times of the longest SEND, padded.

Functions

bool hitec_pio_clock (uint32_t sys_hz, uint8_t family, hitec_pio_clock_t *out)
 The divider for family at a system clock of sys_hz.
uint32_t hitec_pio_bit_ns (const hitec_pio_clock_t *clock)
 The bit time clock gives, in ns, rounded to nearest.
uint32_t hitec_pio_cycles_ns (const hitec_pio_clock_t *clock, uint64_t cycles)
 cycles state machine cycles of clock, in ns, rounded down.
static uint32_t cycles_us_up (const hitec_pio_clock_t *clock, uint64_t cycles)
 cycles state machine cycles of clock, in us, rounded up and held at UINT32_MAX.
static uint64_t us_cycles (const hitec_pio_clock_t *clock, uint32_t us, bool up)
 us as state machine cycles of clock, rounded to nearest, or up with up.
static uint8_t pair_of (uint8_t family, uint8_t drive, unsigned bit)
 The bit time of logical bit (1 the idle level) for family and drive.
static unsigned put_byte (uint8_t family, uint8_t drive, uint8_t value, bool stop, uint8_t *pairs, unsigned at)
 Start bit, 8 data bits least significant first, the stop bit.
static uint32_t pair_word (const uint8_t *pairs)
 16 bit times from pairs as one word.
static uint32_t lead_word (uint8_t pair, uint64_t count)
 Build the word of a lead: level, direction and count.
unsigned hitec_pio_tx (const hitec_pio_clock_t *clock, uint8_t drive, const hitec_xfer_t *xfer, uint32_t *words, hitec_pio_run_t *run)
 The word stream for xfer on a line with drive (hitec_drive_t).
bool hitec_pio_answer_due (const hitec_pio_run_t *run, unsigned n, unsigned pc)
 Whether the answer of run is still to go out with n bytes received and the state machine at pc, counted from the program's first word.
void hitec_pio_capture (const hitec_pio_clock_t *clock, const hitec_pio_run_t *run, const uint32_t *stamps, unsigned n, bool full, bool lost, bool aborted, bool cut, hitec_capture_t *out)
 The capture from the n words the program pushed, in their order.

Detailed Description

The arithmetic of the Hitec PIO pin driver.

See include/hitec_pio.h.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ PAIR

#define PAIR ( dir,
level )
Value:
((uint8_t)((dir) | ((level) << 1)))

The longest window, lead and level fit their fields at the fastest bit rate, with the divider 0.05% short.

A bit time as the pad makes it: bit 0 the direction (1 drives), bit 1 the output level.

Function Documentation

◆ cycles_us_up()

uint32_t cycles_us_up ( const hitec_pio_clock_t * clock,
uint64_t cycles )
static

cycles state machine cycles of clock, in us, rounded up and held at UINT32_MAX.

The seconds come apart from the rest, so no product leaves 64 bits for any count a uint64_t holds times a divider.

◆ hitec_pio_answer_due()

bool hitec_pio_answer_due ( const hitec_pio_run_t * run,
unsigned n,
unsigned pc )

Whether the answer of run is still to go out with n bytes received and the state machine at pc, counted from the program's first word.

True only for a run with an answer, n of 1 and pc at ASK, at ANSWER to ANSWER + 2, or in the bit times. A receive that has its count waits for this to turn false before the driver restarts the machine, so a LISTEN for 1 byte sends its whole answer.

Parameters
runLayout of the transaction.
nBytes received so far.
pcState machine address, counted from the first program word.
Returns
true while the answer is still to go out.

◆ hitec_pio_bit_ns()

uint32_t hitec_pio_bit_ns ( const hitec_pio_clock_t * clock)

The bit time clock gives, in ns, rounded to nearest.

Parameters
clockDivider and counts.
Returns
The bit time in ns, rounded to nearest.

◆ hitec_pio_capture()

void hitec_pio_capture ( const hitec_pio_clock_t * clock,
const hitec_pio_run_t * run,
const uint32_t * stamps,
unsigned n,
bool full,
bool lost,
bool aborted,
bool cut,
hitec_capture_t * out )

The capture from the n words the program pushed, in their order.

full says the receive ended at max_rx bytes, lost that the driver ended a program that ran past run->span_us, aborted that the transaction was cut, cut that the driver restarted the machine while hitec_pio_answer_due() was true, so the answer did not go out whole. A counter above the window or above the one before sets overflow and ends the capture there; so does lost. answered is set for a run with an answer, 1 byte or more and no cut.

Parameters
clockDivider and counts.
runLayout of the transaction.
stampsWords the program pushed, in order.
nNumber of words in stamps.
fulltrue when the receive ended at max_rx bytes.
losttrue when the driver ended a program that ran past its span.
abortedtrue when the transaction was cut.
cuttrue when the answer was due at a restart.
outReceives the capture.

◆ hitec_pio_clock()

bool hitec_pio_clock ( uint32_t sys_hz,
uint8_t family,
hitec_pio_clock_t * out )

The divider for family at a system clock of sys_hz.

False when the divider is below HITEC_PIO_MIN_DIV (a clock below 1.2282MHz classic, 7.3692MHz D series: 64 bit rates less half a step of the divider), its integer part above HITEC_PIO_MAX_DIV, or the bit time it gives more than HITEC_PIO_MAX_ERROR_PPM from the family's. out is left as it was on false.

Parameters
sys_hzSystem clock, in Hz.
familyhitec_family_t value.
outReceives the divider; left unchanged when false is returned.
Returns
true when the clock gives a usable divider.

◆ hitec_pio_cycles_ns()

uint32_t hitec_pio_cycles_ns ( const hitec_pio_clock_t * clock,
uint64_t cycles )

cycles state machine cycles of clock, in ns, rounded down.

Parameters
clockDivider and counts.
cyclesState machine cycle count.
Returns
cycles converted to ns, rounded down.

◆ hitec_pio_tx()

unsigned hitec_pio_tx ( const hitec_pio_clock_t * clock,
uint8_t drive,
const hitec_xfer_t * xfer,
uint32_t * words,
hitec_pio_run_t * run )

The word stream for xfer on a line with drive (hitec_drive_t).

Returns the number of words written to words, at most HITEC_PIO_TX_WORDS, or 0 when xfer is not valid, is of another family than clock, asks classic for push-pull, or asks an open-drain line to hold a high level.

Parameters
clockDivider and counts.
drivehitec_drive_t value of the line.
xferTransaction to lay out.
wordsReceives the word stream.
runReceives the layout of the transaction.
Returns
Number of words written, or 0 when the transaction is not valid for this clock.

◆ pair_of()

uint8_t pair_of ( uint8_t family,
uint8_t drive,
unsigned bit )
static

The bit time of logical bit (1 the idle level) for family and drive.

Classic: the wire carries the bit. D series: the wire carries it inverted. Open drain drives a low wire and releases a high one.