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

The KST programming session on a programming port: the way into and out of PWM. More...

#include "kst_port.h"
#include <stddef.h>
#include <string.h>
#include "kst_plan.h"

Macros

#define NO_REG   0xFFu
 The page carries the session's result as the core numbers it.
#define FRAMES_MAX   0x0FFFu
 The frame count stops at this value (12 bits).

Enumerations

enum  { SUP_NONE = 0 , SUP_OFF , SUP_ON , SUP_TIMED }
 Where a wait for the supply is.
enum  { LEAVE_NONE = 0 , LEAVE_ASKED , LEAVE_FORCED }
 Why PROGRAMMING is left once the session has ended.

Functions

static bool drv_start (void *ctx, const kst_frame_t *frame, uint32_t window_ns)
 A frame starts only on a channel in PROGRAMMING and while the bench is safe. The first one marks the servo as possibly in programming mode.
static bool drv_poll (void *ctx, kst_capture_t *out)
 The session's poll, through the port's wire driver.
static uint32_t drv_now (void *ctx)
 The session's clock, through the port's wire driver.
static void session_fresh (kst_port_t *p)
 Start the session on a fresh model whose driver frames through this port.
static void image_to_regs (const kst_image_t *img, uint16_t *regs)
 Pack an image into LINK_KS_IMAGE_REGS registers, low byte first.
static void image_from_regs (const uint16_t *regs, kst_image_t *img)
 Unpack LINK_KS_IMAGE_REGS registers into an image, low byte first.
static uint8_t lowest_bit (uint32_t mask)
 The index of the lowest set bit of a register mask.
static bool supply_view (const kst_port_t *p, supply_port_view_t *v)
 What the supply says; false with no PD mini answering.
static void supply_off (kst_port_t *p)
 Ask the supply off, when the build has one to switch.
static uint16_t supply_runs_at (const supply_port_view_t *v, uint16_t mv)
 The voltage a session asked for at mv runs at: an output that is on is lowered to it or left, never raised.
static bool supply_range_ok (const supply_port_view_t *v, uint16_t mv, uint16_t ma)
 Whether the PD mini gives a servo in programming mode mv and ma.
static void op_begin (kst_port_t *p, link_kst_op_t op)
 Start an operation: record its code and set the result to BUSY.
static void op_end (kst_port_t *p, kst_ses_t result)
 End the running operation with its result.
static void session_done (kst_port_t *p, kst_ses_t r)
 The session's operation ended with r.
static void session_started (kst_port_t *p, kst_ses_t r)
 What a session function returned when asked to start.
static void go_pwm (kst_port_t *p)
 Back to PWM: the driver closed, the pin the generator's.
static void back_out (kst_port_t *p, uint8_t result)
 The way in ended before a frame went out: the supply as it was found.
static void cut (kst_port_t *p)
 End the running operation.
static void on_stop (kst_port_t *p)
 Apply a stop to the port, by its state.
static link_kst_refusal_t enter_from_pwm (kst_port_t *p, uint8_t port, uint32_t now_ms)
 Start ENTER from PWM: check the port and its pin, then take the supply and the pin.
static void rail_off (kst_port_t *p, const supply_port_view_t *v, bool again, uint32_t now_ms)
 The supply switched off for RAIL_OFF; again: and on after it, at what it was set to.
static link_kst_refusal_t reboot (kst_port_t *p, uint8_t port, uint32_t now_ms)
 Start REBOOT: a supply cycle, from PWM or from PROGRAMMING.
static link_kst_refusal_t plan_refusal (uint8_t plan_result)
 Why the planner took a request without a search.
static link_kst_refusal_t start_plan (kst_port_t *p, link_kst_op_t op, bool confirm)
 A write to the servo.
static bool writes_servo (link_kst_op_t op)
 Whether an operation writes to the servo.
static link_kst_refusal_t dispatch (kst_port_t *p, link_kst_op_t op, uint8_t port, const uint16_t *in, uint32_t now_ms)
 Route one command to its operation, judged against the port's state.
static uint8_t command (kst_port_t *p, const uint16_t *in, uint32_t now_ms)
 Handle the command frame, registers 0 to 3.
uint8_t kst_port_write (kst_port_t *p, uint8_t off, uint8_t n, const uint16_t *in, uint32_t now_ms)
 A write of the page: 0, or the LINK_NACK_* reason with nothing changed.
static uint16_t clamp16 (uint32_t v)
 Hold a 32-bit count to 16 bits.
static uint16_t state_reg (const kst_port_t *p)
 The STATE register: the state, the port and the flags.
static bool plans (const kst_port_t *p)
 The operation the page names is a write whose plan the session still builds: no frame of it has gone out.
void kst_port_read (const kst_port_t *p, uint8_t off, uint8_t n, uint16_t *out)
 A read of the page, LINK_KS_*.
static void start_session (kst_port_t *p)
 The servo is asked to enter programming mode.
static void low_begin (kst_port_t *p)
 The pin is the driver's: what the supply has to do before the servo is spoken to.
static void step_low (kst_port_t *p, uint32_t now_ms)
 The pass of a LOW port: hold the line low for KST_PORT_LOW_MS, then settle the supply.
static void step_programming (kst_port_t *p, uint32_t now_ms)
 The pass of a PROGRAMMING port: step the session, or end the mode when the supply went off.
static void step_leaving (kst_port_t *p, uint32_t now_ms)
 A LEAVE waits with the line low.
static void step_rail_off (kst_port_t *p, uint32_t now_ms)
 The pass of RAIL_OFF: wait for the supply to read off and its off time, then the switch-on.
static void step_rail_wait (kst_port_t *p, uint32_t now_ms)
 The pass of RAIL_WAIT: wait for the supply to read on, then the rail wait.
void kst_port_step (kst_port_t *p, bool safe, bool stop, uint32_t now_ms)
 One pass.
bool kst_port_init (kst_port_t *p, const kst_port_hw_t *hw)
 Prepare a port in LINK_KST_PWM.
link_kst_state_t kst_port_state (const kst_port_t *p)
 Where the port is.
uint8_t kst_port_quiet_mask (const kst_port_t *p)
 Bit n: programming port n renders no PWM pulse.
bool kst_port_frame_out (const kst_port_t *p)
 An operation of the session runs: a frame may be on the wire.
void kst_port_bench_armed (kst_port_t *p, bool armed)
 Whether the bank is armed.
void kst_port_other_mask (kst_port_t *p, uint8_t mask)
 Bit n: the HITEC page holds programming port n (hitec_port_quiet_mask()).
uint8_t kst_port_pin_mask (const kst_port_t *p)
 Bit n: programming port n's pin is the wire driver's, not the PWM generator's.

Detailed Description

The KST programming session on a programming port: the way into and out of PWM.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ NO_REG

#define NO_REG   0xFFu

The page carries the session's result as the core numbers it.

No register: the value of fail_reg when none failed.

Function Documentation

◆ back_out()

void back_out ( kst_port_t * p,
uint8_t result )
static

The way in ended before a frame went out: the supply as it was found.

Parameters
pThe port.
resultThe result to report, a KST_SES_* value.

◆ clamp16()

uint16_t clamp16 ( uint32_t v)
static

Hold a 32-bit count to 16 bits.

Parameters
vThe count.
Returns
v, or 65535 when v is larger.

◆ command()

uint8_t command ( kst_port_t * p,
const uint16_t * in,
uint32_t now_ms )
static

Handle the command frame, registers 0 to 3.

Parameters
pThe port.
inThe command frame's four registers.
now_msCurrent time in milliseconds.
Returns
0 when the frame is acknowledged; LINK_NACK_BAD_VALUE for a bad frame or SEQ.

◆ cut()

void cut ( kst_port_t * p)
static

End the running operation.

A frame on the wire is finished first; the session ends at one of the next steps.

Parameters
pThe port.

◆ dispatch()

link_kst_refusal_t dispatch ( kst_port_t * p,
link_kst_op_t op,
uint8_t port,
const uint16_t * in,
uint32_t now_ms )
static

Route one command to its operation, judged against the port's state.

Parameters
pThe port.
opThe operation.
portProgramming port index.
inThe command frame's registers.
now_msCurrent time in milliseconds.
Returns
LINK_KST_REF_NONE when the operation is taken; otherwise the refusal.

◆ drv_now()

uint32_t drv_now ( void * ctx)
static

The session's clock, through the port's wire driver.

Parameters
ctxThe port, as the driver's context.
Returns
The driver's time in microseconds.

◆ drv_poll()

bool drv_poll ( void * ctx,
kst_capture_t * out )
static

The session's poll, through the port's wire driver.

Parameters
ctxThe port, as the driver's context.
outReceives the capture.
Returns
The driver's result: true when a capture is ready.

◆ drv_start()

bool drv_start ( void * ctx,
const kst_frame_t * frame,
uint32_t window_ns )
static

A frame starts only on a channel in PROGRAMMING and while the bench is safe. The first one marks the servo as possibly in programming mode.

Parameters
ctxThe port, as the driver's context.
frameThe frame to send.
window_nsThe listen window in nanoseconds.
Returns
true when the driver takes the frame in PROGRAMMING with the bench safe.

◆ enter_from_pwm()

link_kst_refusal_t enter_from_pwm ( kst_port_t * p,
uint8_t port,
uint32_t now_ms )
static

Start ENTER from PWM: check the port and its pin, then take the supply and the pin.

Parameters
pThe port.
portProgramming port index.
now_msCurrent time in milliseconds.
Returns
LINK_KST_REF_NONE when ENTER starts; otherwise the refusal.

◆ go_pwm()

void go_pwm ( kst_port_t * p)
static

Back to PWM: the driver closed, the pin the generator's.

Parameters
pThe port.

◆ image_from_regs()

void image_from_regs ( const uint16_t * regs,
kst_image_t * img )
static

Unpack LINK_KS_IMAGE_REGS registers into an image, low byte first.

Parameters
regsThe registers.
imgReceives the image.

◆ image_to_regs()

void image_to_regs ( const kst_image_t * img,
uint16_t * regs )
static

Pack an image into LINK_KS_IMAGE_REGS registers, low byte first.

Parameters
imgThe image.
regsReceives the registers.

◆ kst_port_bench_armed()

void kst_port_bench_armed ( kst_port_t * p,
bool armed )

Whether the bank is armed.

An ENTER is refused with LINK_KST_REF_BUSY while it is; the caller arms no output while kst_port_quiet_mask() is not 0.

Parameters
pThe port, or NULL; a NULL p is ignored.
armedtrue when the bank is armed.

◆ kst_port_frame_out()

bool kst_port_frame_out ( const kst_port_t * p)

An operation of the session runs: a frame may be on the wire.

False from the pass in which an operation, or its cut, has ended.

Parameters
pThe port, or NULL.
Returns
true while an operation of the session may have a frame on the wire; false for a NULL p.

◆ kst_port_init()

bool kst_port_init ( kst_port_t * p,
const kst_port_hw_t * hw )

Prepare a port in LINK_KST_PWM.

False when hw names no port, lacks a function other than the supply's two, or has one of those two.

Parameters
pThe port to prepare.
hwThe hardware hooks, copied into the port.
Returns
true when the port is prepared; false for a NULL p, or a hw that fails the checks above.

◆ kst_port_other_mask()

void kst_port_other_mask ( kst_port_t * p,
uint8_t mask )

Bit n: the HITEC page holds programming port n (hitec_port_quiet_mask()).

An ENTER on it, and a REBOOT taken in PWM, are refused with LINK_KST_REF_BUSY.

Parameters
pThe port, or NULL; a NULL p is ignored.
maskBit n: the HITEC page holds programming port n.

◆ kst_port_pin_mask()

uint8_t kst_port_pin_mask ( const kst_port_t * p)

Bit n: programming port n's pin is the wire driver's, not the PWM generator's.

The held port from LINK_KST_LOW until it is back in LINK_KST_PWM; never for a REBOOT taken in PWM.

Parameters
pThe port, or NULL.
Returns
Bit n set for port n while the wire driver holds its pin; 0 for a NULL p.

◆ kst_port_quiet_mask()

uint8_t kst_port_quiet_mask ( const kst_port_t * p)

Bit n: programming port n renders no PWM pulse.

The held port in every state but LINK_KST_PWM.

Parameters
pThe port, or NULL.
Returns
Bit n set for port n while the port is not in PWM; 0 for a NULL p.

◆ kst_port_read()

void kst_port_read ( const kst_port_t * p,
uint8_t off,
uint8_t n,
uint16_t * out )

A read of the page, LINK_KS_*.

Parameters
pThe port.
offFirst register of the window.
nNumber of registers to read.
outReceives n register values; left unchanged for a NULL p or out, or a window past LINK_KS_COUNT.

◆ kst_port_state()

link_kst_state_t kst_port_state ( const kst_port_t * p)

Where the port is.

Parameters
pThe port, or NULL.
Returns
The state of the port; LINK_KST_PWM for a NULL p.

◆ kst_port_step()

void kst_port_step ( kst_port_t * p,
bool safe,
bool stop,
uint32_t now_ms )

One pass.

safe: the heartbeat is trusted and the link is not silent. stop: the bank was switched off or disarmed since the last pass. Steps the session and the port's timers; a pass every 1ms or faster keeps the session's pacing. A pass does one slice of planning at most and never a whole search.

Parameters
pThe port.
safetrue when the heartbeat is trusted and the link is not silent.
stoptrue when the bank was switched off or disarmed since the last pass.
now_msCurrent time in milliseconds.

◆ kst_port_write()

uint8_t kst_port_write ( kst_port_t * p,
uint8_t off,
uint8_t n,
const uint16_t * in,
uint32_t now_ms )

A write of the page: 0, or the LINK_NACK_* reason with nothing changed.

A window that starts in registers 0 to 3 is a command and has to be exactly those 4. Registers 4 to 28 are taken in any windows; 29 and up are LINK_NACK_READ_ONLY.

Parameters
pThe port.
offFirst register of the window.
nNumber of registers in the window.
inThe n register values to write.
now_msCurrent time in milliseconds.
Returns
0 when the write is applied or acknowledged; otherwise the LINK_NACK_* reason.

◆ low_begin()

void low_begin ( kst_port_t * p)
static

The pin is the driver's: what the supply has to do before the servo is spoken to.

The voltage of an output that is on is lowered or left, never raised.

Parameters
pThe port.

◆ lowest_bit()

uint8_t lowest_bit ( uint32_t mask)
static

The index of the lowest set bit of a register mask.

Parameters
maskOne bit per register.
Returns
The index, 0 to KST_REG_COUNT - 1; NO_REG for an empty mask.

◆ on_stop()

void on_stop ( kst_port_t * p)
static

Apply a stop to the port, by its state.

Parameters
pThe port.

◆ op_begin()

void op_begin ( kst_port_t * p,
link_kst_op_t op )
static

Start an operation: record its code and set the result to BUSY.

Parameters
pThe port.
opThe operation.

◆ op_end()

void op_end ( kst_port_t * p,
kst_ses_t result )
static

End the running operation with its result.

Parameters
pThe port.
resultThe session result.

◆ plan_refusal()

link_kst_refusal_t plan_refusal ( uint8_t plan_result)
static

Why the planner took a request without a search.

Parameters
plan_resultThe planner's result, a kst_plan_result_t value.
Returns
The LINK_KST_REF_* refusal the planner's result maps to.

◆ plans()

bool plans ( const kst_port_t * p)
static

The operation the page names is a write whose plan the session still builds: no frame of it has gone out.

Parameters
pThe port.
Returns
true when the operation is a write or restore whose plan the session still builds.

◆ rail_off()

void rail_off ( kst_port_t * p,
const supply_port_view_t * v,
bool again,
uint32_t now_ms )
static

The supply switched off for RAIL_OFF; again: and on after it, at what it was set to.

Parameters
pThe port.
vThe supply's view.
againtrue to switch the supply on again afterwards.
now_msCurrent time in milliseconds.

◆ reboot()

link_kst_refusal_t reboot ( kst_port_t * p,
uint8_t port,
uint32_t now_ms )
static

Start REBOOT: a supply cycle, from PWM or from PROGRAMMING.

Parameters
pThe port.
portProgramming port index.
now_msCurrent time in milliseconds.
Returns
LINK_KST_REF_NONE when REBOOT starts; otherwise the refusal.

◆ session_done()

void session_done ( kst_port_t * p,
kst_ses_t r )
static

The session's operation ended with r.

Parameters
pThe port.
rThe session's result.

◆ session_fresh()

void session_fresh ( kst_port_t * p)
static

Start the session on a fresh model whose driver frames through this port.

Parameters
pThe port.

◆ session_started()

void session_started ( kst_port_t * p,
kst_ses_t r )
static

What a session function returned when asked to start.

Parameters
pThe port.
rWhat the session function returned.

◆ start_plan()

link_kst_refusal_t start_plan ( kst_port_t * p,
link_kst_op_t op,
bool confirm )
static

A write to the servo.

The session plans it, from the image it read to what is staged, one slice of the planner in each pass, and runs its own plan. This call checks the request and prepares the job: no search runs in the command's frame.

Parameters
pThe port.
opThe write or restore operation.
confirmtrue to confirm a restore.
Returns
LINK_KST_REF_NONE when the plan starts; otherwise the refusal.

◆ start_session()

void start_session ( kst_port_t * p)
static

The servo is asked to enter programming mode.

Parameters
pThe port.

◆ state_reg()

uint16_t state_reg ( const kst_port_t * p)
static

The STATE register: the state, the port and the flags.

Parameters
pThe port.
Returns
The STATE register value.

◆ step_leaving()

void step_leaving ( kst_port_t * p,
uint32_t now_ms )
static

A LEAVE waits with the line low.

The supply is read for one thing: a servo found without power ends as it does in PROGRAMMING.

Parameters
pThe port.
now_msCurrent time in milliseconds.

◆ step_low()

void step_low ( kst_port_t * p,
uint32_t now_ms )
static

The pass of a LOW port: hold the line low for KST_PORT_LOW_MS, then settle the supply.

Parameters
pThe port.
now_msCurrent time in milliseconds.

◆ step_programming()

void step_programming ( kst_port_t * p,
uint32_t now_ms )
static

The pass of a PROGRAMMING port: step the session, or end the mode when the supply went off.

Parameters
pThe port.
now_msCurrent time in milliseconds.

◆ step_rail_off()

void step_rail_off ( kst_port_t * p,
uint32_t now_ms )
static

The pass of RAIL_OFF: wait for the supply to read off and its off time, then the switch-on.

Parameters
pThe port.
now_msCurrent time in milliseconds.

◆ step_rail_wait()

void step_rail_wait ( kst_port_t * p,
uint32_t now_ms )
static

The pass of RAIL_WAIT: wait for the supply to read on, then the rail wait.

Parameters
pThe port.
now_msCurrent time in milliseconds.

◆ supply_off()

void supply_off ( kst_port_t * p)
static

Ask the supply off, when the build has one to switch.

Parameters
pThe port.

◆ supply_range_ok()

bool supply_range_ok ( const supply_port_view_t * v,
uint16_t mv,
uint16_t ma )
static

Whether the PD mini gives a servo in programming mode mv and ma.

The cap under the input holds for the voltage the output runs at.

Parameters
vThe supply's view.
mvThe voltage in mV.
maThe current limit in mA.
Returns
true when mv and ma are in range and the cap holds at the voltage the output runs at.

◆ supply_runs_at()

uint16_t supply_runs_at ( const supply_port_view_t * v,
uint16_t mv )
static

The voltage a session asked for at mv runs at: an output that is on is lowered to it or left, never raised.

Parameters
vThe supply's view.
mvThe requested voltage in mV.
Returns
The voltage the output runs at, in mV.

◆ supply_view()

bool supply_view ( const kst_port_t * p,
supply_port_view_t * v )
static

What the supply says; false with no PD mini answering.

Parameters
pThe port.
vReceives the supply's view.
Returns
true when the PD mini is online.

◆ writes_servo()

bool writes_servo ( link_kst_op_t op)
static

Whether an operation writes to the servo.

Parameters
opThe operation.
Returns
true for an operation that writes.