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

Receive a D series answer by precharge and sample. More...

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

Macros

#define SAMPLE_RATE   (HITEC_D_BIT_RATE * HITEC_PRE_SAMPLES_PER_BIT)
 Samples a second the period aims at.
#define PIO_DELAY(d)
 PIO instruction words, without side-set: the delay in bits 8 to 12.
#define PIO_SET_PINDIRS(v, d)
#define PIO_IN_PINS_1(d)
#define PIO_NOP(d)
#define PIO_DELAY_MAX   31u
 Largest delay a PIO instruction carries: 31 cycles.

Functions

static uint32_t ns_cycles (uint32_t sys_hz, uint32_t ns)
 ns at sys_hz in cycles, rounded to nearest.
uint32_t hitec_pre_cycles_ns (const hitec_pre_timing_t *t, uint64_t cycles)
 cycles system clock cycles of t in ns, rounded to nearest.
bool hitec_pre_timing (uint32_t sys_hz, hitec_pre_timing_t *out)
 The counts for a system clock of sys_hz.
unsigned hitec_pre_program (const hitec_pre_timing_t *t, uint16_t *words, unsigned max)
 The sampler's program: precharge, release, wait, sample, then the rest of the period, as PIO instruction words: set pindirs, 1 [charge - 1], set pindirs, 0 [wait - 1], in pins, 1, and nop with delays up to the period.
uint32_t hitec_pre_window_samples (const hitec_pre_timing_t *t, uint32_t window_us)
 Samples a window of window_us waits, rounded to nearest.
uint32_t hitec_pre_words (const hitec_pre_timing_t *t, uint32_t window_us, uint8_t max_rx)
 Sample words a run with a window of window_us and max_rx bytes takes: the window, every byte from its start to its stop bit's middle, and one word.
void hitec_pre_dec_init (hitec_pre_dec_t *d, const hitec_pre_timing_t *t, uint32_t window_us, uint8_t max_rx)
 Prepare d for a window of window_us and up to max_rx bytes (1 to HITEC_RX_MAX).
static void dec_end (hitec_pre_dec_t *d, hitec_pre_end_t why)
 Mark the decoder done and record why it ended.
static void dec_byte (hitec_pre_dec_t *d, const hitec_pre_timing_t *t, const uint32_t *words)
 The byte whose start bit is at d->start[d->n], all of its samples in.
bool hitec_pre_dec_feed (hitec_pre_dec_t *d, const hitec_pre_timing_t *t, const uint32_t *words, uint32_t n_words)
 Decode the samples of the first n_words words of words that it has not seen.
void hitec_pre_dec_close (hitec_pre_dec_t *d)
 No more samples come: a decoder that has not ended ends with HITEC_PRE_END_SHORT, dropping a byte whose samples are not all in.
hitec_pre_plan_t hitec_pre_begin (hitec_pre_run_t *r, const hitec_pre_timing_t *t, const hitec_xfer_t *x)
 Plan x on a PRECHARGE line.
void hitec_pre_tx_xfer (const hitec_xfer_t *x, hitec_xfer_t *out)
 The transaction the line sends for a HITEC_PRE_PLAN_SEND: x with no window and no byte to receive.
void hitec_pre_tx_done (hitec_pre_run_t *r)
 The request has ended: HITEC_PRE_TX to HITEC_PRE_SAMPLE.
bool hitec_pre_step (hitec_pre_run_t *r, const hitec_pre_timing_t *t, const uint32_t *words, uint32_t n_words, bool all_in)
 Feed the first n_words sample words.
void hitec_pre_abort (hitec_pre_run_t *r, const hitec_pre_timing_t *t, const uint32_t *words, uint32_t n_words)
 Cut the run in any phase but idle: what n_words words hold is decoded, a byte not whole is dropped, and the run is done, aborted.
void hitec_pre_lost (hitec_pre_run_t *r)
 Samples went missing (the sampler stalled) or the sampler ran past its time: the capture is marked overflowed.
void hitec_pre_capture (const hitec_pre_run_t *r, const hitec_pre_timing_t *t, int32_t offset_ns, hitec_capture_t *out)
 The capture of a done run.

Detailed Description

Receive a D series answer by precharge and sample.

See include/hitec_pre.h.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ PIO_DELAY

#define PIO_DELAY ( d)
Value:
((uint16_t)((d) << 8))

PIO instruction words, without side-set: the delay in bits 8 to 12.

◆ PIO_IN_PINS_1

#define PIO_IN_PINS_1 ( d)
Value:
((uint16_t)(0x4001u | PIO_DELAY(d)))
#define PIO_DELAY(d)
PIO instruction words, without side-set: the delay in bits 8 to 12.
Definition hitec_pre.c:23

◆ PIO_NOP

#define PIO_NOP ( d)
Value:
((uint16_t)(0xA042u | PIO_DELAY(d)))

◆ PIO_SET_PINDIRS

#define PIO_SET_PINDIRS ( v,
d )
Value:
((uint16_t)(0xE080u | (v) | PIO_DELAY(d)))

Function Documentation

◆ hitec_pre_abort()

void hitec_pre_abort ( hitec_pre_run_t * r,
const hitec_pre_timing_t * t,
const uint32_t * words,
uint32_t n_words )

Cut the run in any phase but idle: what n_words words hold is decoded, a byte not whole is dropped, and the run is done, aborted.

Nothing on an idle or a done run.

Parameters
rRun state.
tCounts of the clock.
wordsSample words, from sample 0.
n_wordsWords of the buffer that are written.

◆ hitec_pre_begin()

hitec_pre_plan_t hitec_pre_begin ( hitec_pre_run_t * r,
const hitec_pre_timing_t * t,
const hitec_xfer_t * x )

Plan x on a PRECHARGE line.

For HITEC_PRE_PLAN_SEND the run is in HITEC_PRE_TX, for HITEC_PRE_PLAN_LISTEN in HITEC_PRE_SAMPLE; otherwise it is idle.

Parameters
rRun state to set up.
tCounts of the clock.
xTransaction to plan.
Returns
The plan of the transaction.

◆ hitec_pre_capture()

void hitec_pre_capture ( const hitec_pre_run_t * r,
const hitec_pre_timing_t * t,
int32_t offset_ns,
hitec_capture_t * out )

The capture of a done run.

offset_ns: the sampler's start from the receiver's time 0 (the release and one bit time after a SEND, the start of a LISTEN), negative when it started before. A start bit's time is the middle between its first high sample and the sample before it.

Parameters
rDone run state.
tCounts of the clock.
offset_nsOffset of the sampler start from the receiver time 0, in ns.
outReceives the capture.

◆ hitec_pre_cycles_ns()

uint32_t hitec_pre_cycles_ns ( const hitec_pre_timing_t * t,
uint64_t cycles )

cycles system clock cycles of t in ns, rounded to nearest.

Parameters
tCounts of the clock.
cyclesCycle count.
Returns
cycles converted to ns, rounded to nearest.

◆ hitec_pre_dec_close()

void hitec_pre_dec_close ( hitec_pre_dec_t * d)

No more samples come: a decoder that has not ended ends with HITEC_PRE_END_SHORT, dropping a byte whose samples are not all in.

Parameters
dDecoder state.

◆ hitec_pre_dec_feed()

bool hitec_pre_dec_feed ( hitec_pre_dec_t * d,
const hitec_pre_timing_t * t,
const uint32_t * words,
uint32_t n_words )

Decode the samples of the first n_words words of words that it has not seen.

words is the whole buffer from sample 0; a call may pass the same words again with more after them. Returns true once the decoder has ended (max_rx bytes or the window). A start bit whose samples are not all in waits for the next call.

Parameters
dDecoder state.
tCounts of the clock.
wordsSample words, from sample 0.
n_wordsWords of the buffer that are written.
Returns
true once the decoder has ended.

◆ hitec_pre_dec_init()

void hitec_pre_dec_init ( hitec_pre_dec_t * d,
const hitec_pre_timing_t * t,
uint32_t window_us,
uint8_t max_rx )

Prepare d for a window of window_us and up to max_rx bytes (1 to HITEC_RX_MAX).

Parameters
dDecoder to prepare.
tCounts of the clock.
window_usWindow, in us.
max_rxBytes to receive, 1 to HITEC_RX_MAX.

◆ hitec_pre_lost()

void hitec_pre_lost ( hitec_pre_run_t * r)

Samples went missing (the sampler stalled) or the sampler ran past its time: the capture is marked overflowed.

The run is done. After hitec_pre_abort() it marks the aborted capture overflowed as well.

Parameters
rRun state.

◆ hitec_pre_program()

unsigned hitec_pre_program ( const hitec_pre_timing_t * t,
uint16_t * words,
unsigned max )

The sampler's program: precharge, release, wait, sample, then the rest of the period, as PIO instruction words: set pindirs, 1 [charge - 1], set pindirs, 0 [wait - 1], in pins, 1, and nop with delays up to the period.

The pad's SET and IN pin is the line; the output latch is high; autopush at 32 bits, shifting left; no side-set. The program wraps from its last word to its first. Returns the words written, 0 when max is too small.

Parameters
tCounts of the clock.
wordsReceives the instruction words.
maxCapacity of words, in words.
Returns
Words written; 0 when max is too small.

◆ hitec_pre_step()

bool hitec_pre_step ( hitec_pre_run_t * r,
const hitec_pre_timing_t * t,
const uint32_t * words,
uint32_t n_words,
bool all_in )

Feed the first n_words sample words.

all_in: the sampler has written every word it takes (r->words) or stopped. Returns true when the run is in HITEC_PRE_DONE: the decoder ended, or every word is in. Nothing outside HITEC_PRE_SAMPLE.

Parameters
rRun state.
tCounts of the clock.
wordsSample words, from sample 0.
n_wordsWords of the buffer that are written.
all_intrue when every word the run takes is written.
Returns
true when the run is in HITEC_PRE_DONE.

◆ hitec_pre_timing()

bool hitec_pre_timing ( uint32_t sys_hz,
hitec_pre_timing_t * out )

The counts for a system clock of sys_hz.

False, and out left as it was, for a clock outside HITEC_PRE_MIN_HZ to HITEC_PRE_MAX_HZ or one whose rounded precharge or wait falls outside the measured window. At 150MHz: a period of 163 cycles (1086.7ns, 7.99 samples a bit), a precharge of 15 cycles (100.0ns) and the sample 17 cycles (113.3 ns) after the release.

Parameters
sys_hzSystem clock, in Hz.
outReceives the cycle counts; left unchanged when false is returned.
Returns
true when the clock gives usable counts.

◆ hitec_pre_tx_done()

void hitec_pre_tx_done ( hitec_pre_run_t * r)

The request has ended: HITEC_PRE_TX to HITEC_PRE_SAMPLE.

Nothing in another phase.

Parameters
rRun state.

◆ hitec_pre_tx_xfer()

void hitec_pre_tx_xfer ( const hitec_xfer_t * x,
hitec_xfer_t * out )

The transaction the line sends for a HITEC_PRE_PLAN_SEND: x with no window and no byte to receive.

Parameters
xTransaction the plan was made for.
outReceives x with no window and no byte to receive.

◆ hitec_pre_window_samples()

uint32_t hitec_pre_window_samples ( const hitec_pre_timing_t * t,
uint32_t window_us )

Samples a window of window_us waits, rounded to nearest.

Parameters
tCounts of the clock.
window_usWindow, in us.
Returns
Number of samples in the window, rounded to nearest.

◆ hitec_pre_words()

uint32_t hitec_pre_words ( const hitec_pre_timing_t * t,
uint32_t window_us,
uint8_t max_rx )

Sample words a run with a window of window_us and max_rx bytes takes: the window, every byte from its start to its stop bit's middle, and one word.

0 when the window is above HITEC_PRE_WINDOW_MAX_US or the words would not fit HITEC_PRE_WORDS.

Parameters
tCounts of the clock.
window_usWindow, in us.
max_rxBytes to receive.
Returns
Sample words the run takes, or 0 when the window is too long or the words do not fit.