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

The panel's half of the SERVO screen on the link: a command onto the IOmcu's CHAN_CFG, CHANNELS, SERVO and PROG pages, the position said again every SERVO_HOLD_MS (100ms), the release owed while a surface holds a position, the frame rate and the sweep. More...

#include <stdbool.h>
#include <stdint.h>
#include "link_host.h"
#include "link_port.h"
#include "prog_link.h"
#include "servo_cmd.h"

Go to the source code of this file.

Data Structures

 What the module reaches of the panel. More...
 The last sweep start the far end acknowledged. More...

Macros

#define SERVO_HZ_UNKNOWN   0xFFFFu
 servo_link_hz_sent() while the rate the PWM target runs at is not known: perhaps a faster rate.

Enumerations

enum  servo_link_alert_t { SERVO_LINK_ALERT_RESUME_OLD = 0 , SERVO_LINK_ALERT_RESUME_REFUSED , SERVO_LINK_ALERT_RESUME_UNTIMED }
 The alerts a sweep's resume can raise, for servo_link_ctx_t.alert. More...

Functions

void servo_link_init (const servo_link_ctx_t *ctx)
 Start over with ctx: nothing held, no release owed, no binding read, the rate not known, no sweep.
void servo_link_came_up (uint16_t minor)
 An IOmcu of protocol minor minor started answering.
void servo_link_lost (void)
 The link went down: a sweep or a hold held to be said again is dropped (servo_cmd_survives_link_loss()).
void servo_link_binding (uint8_t channels, bool known)
 The binding read back: channels the surfaces' channel mask, bit n channel n, and known whether the pages read.
void servo_link_forget_binding (void)
 A binding was written: the mask is unknown until the next read.
bool servo_link_binding_known (void)
 Whether a binding has been read since the last servo_link_init(), servo_link_forget_binding() or unknown servo_link_binding().
void servo_link_surfaces_publish (void)
 For the screen's SWEEP and its horn: a programming port as target, or a binding read with a surface in it (servo_link_surfaces()).
void servo_link_apply (const servo_cmd_t sv, bool link_up, uint32_t stops)
 One command from the screen, with the link state link_up and the stop count stops its sender had seen.
void servo_link_let_go (void)
 Stop holding the servo.
void servo_link_service (bool link_up)
 Every pass: settle a rate not known while a release is owed or the bank is armed, pay an owed release, and say a held position again once SERVO_HOLD_MS (100ms) has passed.
bool servo_link_rate_settled (void)
 Whether the rate the surfaces run at is known, after one more reset when it is not. Asked before every arm.
void servo_link_rate_reset_note (bool page, bool landed)
 What a rate reset left behind: page whether the IOmcu has the SERVO page, landed whether the reset was acknowledged.
void servo_link_prog_service (void)
 The SERVO screen's half of the programming ports' service, after the page's read: a position still out is let go first while the bench is at rest and a target change is pending, then at most one write towards what the screen wants (prog_link_next()), a pulse that comes on preceded by the range the screen names; then what a TARGET change means for the rate (prog_link_rate()).
bool servo_link_release_owed (void)
 Whether a release is owed: a surface may still hold a position.
uint16_t servo_link_hz_sent (void)
 The rate the IOmcu acknowledged, 0 for each slot's own, or SERVO_HZ_UNKNOWN.
bool servo_link_take_release (void)
 A release the screen asked for through servo_link_ask_release(): taken, it drops the position held and owes the release.
void servo_link_ask_release (void)
 From the screens' task: a release, or a disarm with one, asked for. A sweep being written gives way to it.
void servo_link_ask_hold (void)
 From the screens' task: a HOLD, or a command that ends a sweep, asked for.
unsigned servo_link_rate_shown (void)
 The rate's state and its Hz, as (servo_rate_state_t << 16) | Hz.
bool servo_link_sweep_able (void)
 Whether the IOmcu can sweep: protocol 4.2 or later.
bool servo_link_surfaces (void)
 What servo_link_surfaces_publish() last published.
bool servo_link_take_sweep_refused (void)
 A sweep found no surface to sweep, once.
bool servo_link_take_hold_lost (uint16_t *pause_seq)
 The far end let go of a hold, once, with its pause in pause_seq.
bool servo_link_take_sweep_held (uint16_t *pause_seq, uint32_t *kept_ms)
 The far end took the HOLD of pause pause_seq and kept its curve kept_ms in, once.
bool servo_link_take_sweep_start (void)
 The far end started a sweep, once.
servo_link_start_t servo_link_sweep_start (void)
 Read the last sweep start the far end acknowledged.

Detailed Description

The panel's half of the SERVO screen on the link: a command onto the IOmcu's CHAN_CFG, CHANNELS, SERVO and PROG pages, the position said again every SERVO_HOLD_MS (100ms), the release owed while a surface holds a position, the frame rate and the sweep.

Every exchange runs over a link_port_t, so the sequences the panel sends run in the host suite against a modelled bus. What belongs to the panel – the output bank, the arming policy, the alerts, the disarm – is reached through the callbacks of a servo_link_ctx_t.

The control task owns the state. Three groups of calls cross to the task that runs the screens, each over atomics: servo_link_ask_release() and servo_link_ask_hold() in, and the readings from servo_link_rate_shown() to servo_link_sweep_start() out.

SPDX-License-Identifier: MIT

Enumeration Type Documentation

◆ servo_link_alert_t

The alerts a sweep's resume can raise, for servo_link_ctx_t.alert.

Enumerator
SERVO_LINK_ALERT_RESUME_OLD 

the IOmcu is older than 4.6

SERVO_LINK_ALERT_RESUME_REFUSED 

it refused the resume

SERVO_LINK_ALERT_RESUME_UNTIMED 

the hold's phase is not known

Function Documentation

◆ servo_link_apply()

void servo_link_apply ( const servo_cmd_t sv,
bool link_up,
uint32_t stops )

One command from the screen, with the link state link_up and the stop count stops its sender had seen.

ARM centres the surfaces and asks the policy to arm, unless a stop came in between; DISARM and RELEASE centre them; a sweep waits for an owed release to be paid; a command asked during a pause let go of is not sent.

Parameters
svThe command.
link_upWhether the link is up now.
stopsThe stop count the sender had seen, from the policy's stop_count callback.

◆ servo_link_ask_hold()

void servo_link_ask_hold ( void )

From the screens' task: a HOLD, or a command that ends a sweep, asked for.

A sweep being written gives way to it; cleared when servo_link_apply() takes the next command.

◆ servo_link_binding()

void servo_link_binding ( uint8_t channels,
bool known )

The binding read back: channels the surfaces' channel mask, bit n channel n, and known whether the pages read.

An unknown binding is not an empty one: no command reaches the standard outputs and a release stays owed until a read succeeds. Publishes servo_link_surfaces().

Parameters
channelsSurface channel mask: bit n set when channel n is a surface.
knowntrue when the pages were read; false marks the binding unknown.

◆ servo_link_binding_known()

bool servo_link_binding_known ( void )

Whether a binding has been read since the last servo_link_init(), servo_link_forget_binding() or unknown servo_link_binding().

Returns
true when the binding is known.

◆ servo_link_came_up()

void servo_link_came_up ( uint16_t minor)

An IOmcu of protocol minor minor started answering.

Whether it has a SERVO rate (4.1), a sweep (4.2) and a resume (4.6); each slot back at its own rate, one exchange; the sweep's state not known until the next command writes a stop.

Parameters
minorThe protocol minor the IOmcu reports: 1 for the SERVO rate, 2 for the sweep, 6 for the resume.

◆ servo_link_forget_binding()

void servo_link_forget_binding ( void )

A binding was written: the mask is unknown until the next read.

Does not publish servo_link_surfaces().

◆ servo_link_hz_sent()

uint16_t servo_link_hz_sent ( void )

The rate the IOmcu acknowledged, 0 for each slot's own, or SERVO_HZ_UNKNOWN.

Returns
The acknowledged frame rate in Hz, 0, or SERVO_HZ_UNKNOWN.

◆ servo_link_init()

void servo_link_init ( const servo_link_ctx_t * ctx)

Start over with ctx: nothing held, no release owed, no binding read, the rate not known, no sweep.

ctx is kept and must outlive the module's use. Before any other call.

Parameters
ctxThe panel's callbacks. Kept by pointer, not copied.

◆ servo_link_let_go()

void servo_link_let_go ( void )

Stop holding the servo.

A position written or held leaves a release owed.

◆ servo_link_rate_reset_note()

void servo_link_rate_reset_note ( bool page,
bool landed )

What a rate reset left behind: page whether the IOmcu has the SERVO page, landed whether the reset was acknowledged.

For the reset a binding's own sequence sends (bind_link_write()) and a TARGET change (prog_link_rate()).

Parameters
pagetrue when the IOmcu has the SERVO page.
landedtrue when the reset was acknowledged.

◆ servo_link_rate_settled()

bool servo_link_rate_settled ( void )

Whether the rate the surfaces run at is known, after one more reset when it is not. Asked before every arm.

Returns
true when the rate is known.

◆ servo_link_rate_shown()

unsigned servo_link_rate_shown ( void )

The rate's state and its Hz, as (servo_rate_state_t << 16) | Hz.

Returns
The packed state and rate.

◆ servo_link_release_owed()

bool servo_link_release_owed ( void )

Whether a release is owed: a surface may still hold a position.

Returns
true when a release is owed.

◆ servo_link_service()

void servo_link_service ( bool link_up)

Every pass: settle a rate not known while a release is owed or the bank is armed, pay an owed release, and say a held position again once SERVO_HOLD_MS (100ms) has passed.

Nothing while link_up is false.

Parameters
link_upWhether the link is up now.

◆ servo_link_surfaces()

bool servo_link_surfaces ( void )

What servo_link_surfaces_publish() last published.

Returns
true when there is something to move.

◆ servo_link_sweep_able()

bool servo_link_sweep_able ( void )

Whether the IOmcu can sweep: protocol 4.2 or later.

Returns
true when it can.

◆ servo_link_sweep_start()

servo_link_start_t servo_link_sweep_start ( void )

Read the last sweep start the far end acknowledged.

Returns
The start sequence, phase 0 on the clock, the origin and the freeze or resume time, each read from its own atomic.

◆ servo_link_take_hold_lost()

bool servo_link_take_hold_lost ( uint16_t * pause_seq)

The far end let go of a hold, once, with its pause in pause_seq.

Parameters
pause_seqReceives the sequence number of the pause.
Returns
true once for each release; false when none is pending.

◆ servo_link_take_release()

bool servo_link_take_release ( void )

A release the screen asked for through servo_link_ask_release(): taken, it drops the position held and owes the release.

True when one was asked for.

Returns
true when a release was asked for, and this call took it.

◆ servo_link_take_sweep_held()

bool servo_link_take_sweep_held ( uint16_t * pause_seq,
uint32_t * kept_ms )

The far end took the HOLD of pause pause_seq and kept its curve kept_ms in, once.

Parameters
pause_seqReceives the sequence number of the pause.
kept_msReceives the phase the curve kept, in milliseconds.
Returns
true once for each hold; false when none is pending.

◆ servo_link_take_sweep_refused()

bool servo_link_take_sweep_refused ( void )

A sweep found no surface to sweep, once.

Returns
true once for each refusal; the flag is cleared by the call.

◆ servo_link_take_sweep_start()

bool servo_link_take_sweep_start ( void )

The far end started a sweep, once.

Its details: servo_link_sweep_start().

Returns
true once for each start.