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

Stick programming: the run. More...

#include "esc_stick.h"
#include "esc_stick_int.h"
#include <string.h>

Functions

void esc_stick_timing_defaults (esc_stick_timing_t *t)
 The defaults the settings start from.
uint32_t esc_stick_read_max_ms (const esc_stick_timing_t *t)
 The longest interval between two readings the timing allows: the shorter of a beep and a gap, so every beep and every gap holds at least one reading.
static uint32_t since (uint32_t now, uint32_t then)
 The time from then to now, 0 when then is later.
static bool powered_phase (esc_stick_phase_t ph)
 Whether the supply is on in a phase.
void esc_stick_light_reset (esc_stick_light_t *l, const esc_stick_t *e)
 Start watching e: pulses already counted do not light it.
bool esc_stick_light_green (esc_stick_light_t *l, const esc_stick_t *e, uint32_t now_ms)
 Whether the green light is on at now_ms.
static void enter (esc_stick_t *e, esc_stick_phase_t ph)
 Enter a phase and stamp when it began.
static void finish (esc_stick_t *e, esc_stick_phase_t ph, esc_stick_reason_t why)
 The run is over: the throttle at its rest, the supply off, disarmed.
void esc_stick_abort (esc_stick_t *e, esc_stick_reason_t why)
 End the run now, for why: throttle to its rest, supply off, disarmed.
static bool all_done (const esc_stick_t *e)
 Whether every change of the run is made.
static void bounds (esc_stick_t *e, bool items, int item)
 The lowest and highest number a loop of items or of one item's values sounds; item < 0 for every value of every item.
static void listen (esc_stick_t *e, esc_stick_phase_t ph)
 Start listening for a group in a phase.
static esc_throttle_t next_entry (const esc_stick_t *e)
 The menu begins: the stick to its rest, and the first loop.
static esc_throttle_t rest_of (const esc_stick_t *e)
 Where the stick rests while the menu sounds: the profile's listen move, else where this power-up entered.
static void begin_menu (esc_stick_t *e)
 Begin the menu: stick to its rest and the first loop.
static int hand_due (const esc_stick_t *e, unsigned from, bool powered)
 The first manual step from from that is due at this point of the run, or -1.
static void ask (esc_stick_t *e, int i, esc_stick_phase_t ph)
 Ask the operator for a manual step.
static void power_on (esc_stick_t *e)
 Ask the supply on and wait for its output.
static void before_power (esc_stick_t *e, unsigned from)
 The supply comes on once every step due before it is done.
static void before_menu (esc_stick_t *e, unsigned from)
 The menu begins once every step due before it is done.
static bool hand_phase (esc_stick_phase_t ph)
 Whether a phase waits for a manual step.
const esc_manual_t * esc_stick_hand (const esc_stick_t *e)
 The manual step the run waits for, or NULL when it waits for none.
uint32_t esc_stick_change_entry_ms (const esc_profile_t *p, const esc_stick_change_t *c, const esc_stick_timing_t *t)
 Power-on to the menu for change c, ms, as the run waits it: its value's entry_hold_ms where the manual gives one (Kontronik SUN PLUS modes 4 to 6, 5s), else t's entry, and no less than the longest hold of the profile's at_power_up steps. c NULL: the entry's.
uint32_t esc_stick_entry_ms (const esc_stick_t *e)
 Power-on to the menu at this power-up, ms: esc_stick_change_entry_ms() of the change it makes.
bool esc_stick_hand_ready (const esc_stick_t *e)
 Whether DONE would count now: ESC_STICK_HAND_MIN_MS after the step was asked.
uint32_t esc_stick_hand_left_ms (const esc_stick_t *e)
 The time left to confirm the step asked, ms; 0 when none is.
bool esc_stick_confirm (esc_stick_t *e)
 DONE: the step asked is done.
esc_throttle_t esc_stick_store_move (const esc_stick_t *e, unsigned k)
 The k-th move after a selection, from 0, or ESC_THR_NONE past the last: the profile's store move, then the moves the stored value asks for (esc_value_t's after: Kontronik's car modes go to the brake after full throttle).
static void supply_off (esc_stick_t *e)
 The supply off, the stick where it is; see the top of this file.
static void before_off (esc_stick_t *e, unsigned from)
 The supply goes off once every before_power_off step from from is done: each is asked with the ESC powered and the stick where the store left it, and DONE goes on to the next or switches the supply off.
bool esc_stick_cut_short (const esc_stick_t *e)
 Whether the run ended between a selection and the DONE of the profile's before_power_off steps, or before the last of the moves that store the value (esc_stick_store_move()) – while the ESC stored or confirmed: the value may not be stored.
bool esc_stick_end_locks (const esc_stick_t *e)
 Whether a before_power_off step of the run's profile marks locks: a cut before every such step is confirmed may lock the ESC, whichever step is asked.
bool esc_stick_lock_risk (const esc_stick_t *e)
 esc_stick_cut_short() and esc_stick_end_locks(): the ESC may have locked itself.
static void hand_menu_done (esc_stick_t *e)
 The action that starts the menu is done: by DONE, or by the menu heard in order.
static uint8_t wanted_value (const esc_stick_t *e)
 Number of the value the active change wants.
static void selected (esc_stick_t *e)
 Record that the active change is selected.
static void on_group (esc_stick_t *e, uint8_t count, bool valid)
 Judge one counted group of beeps.
bool esc_stick_start (esc_stick_t *e, const esc_profile_t *p, const esc_stick_change_t *ch, size_t n, const esc_stick_timing_t *t, uint32_t mv, uint32_t ma, const esc_stick_bench_t *b, const char **why)
 Start a run. mv and ma are the supply's set points, already held to the caps by the caller.
static bool off_phase (esc_stick_phase_t ph)
 One reading while the run waits for the output to go off.
static bool entry_made (const esc_stick_t *e)
 Whether the stick has gone to the entry position, or a step at the ESC is asked, with the supply off: the moves made only on the supply read off, and so the ones a live reading has to end at once.
static void off_reading (esc_stick_t *e, const esc_stick_sample_t *s)
 Judge one supply reading taken while the output is to be off.
void esc_stick_sample (esc_stick_t *e, const esc_stick_sample_t *s)
 One supply sample, as it arrives.
void esc_stick_step (esc_stick_t *e, const esc_stick_bench_t *b)
 Advance to b->now_ms and judge the bench.

Detailed Description

Stick programming: the run.

See esc_stick.h. What can run is in esc_stick_rules.c, the beep detector in esc_det.c, and the readouts of a run in esc_stick_read.c.

Three rules carry the safety of the count, because a beep missed between two readings turns one number into another:

  • A group is in order when it follows the group before it in the menu's order: one more than it, the loop's lowest after its highest, or – where the profile repeats each group – the same again, after a group that was itself in order and no more times than the profile repeats it. A group is acted on only when it is in order and the group before it was too: three groups in a row agree. A count made wrong by a missed beep is one below the truth, so it breaks the order unless the groups before it were wrong as well; a single missed beep is passed, and the menu's next loop is used.
  • Listening starts on a quiet line: no group is counted until GROUP GAP of quiet, so the first group heard is whole and not the tail of one.
  • A reading that comes later than the shortest beep or gap allows breaks the order too, since a beep may have fallen in the hole. ESC_STICK_LATE_RUN late readings in a row end the run: the supply reads too slowly for the timing the settings describe.

A run ends safely in one step when it is aborted: throttle to its rest, supply off, disarmed. A run that ends as planned, or cycles the power between two changes, switches the supply off first and moves the stick only once the supply itself reports the output off with the current under ESC_STICK_OFF_MA for ESC_STICK_OFF_SETTLE_MS. Neither the module's off-state current nor the ESC's run-on from its input capacitors is measured; docs/StickProgramming.md states both.

SPDX-License-Identifier: MIT

Function Documentation

◆ all_done()

bool all_done ( const esc_stick_t * e)
static

Whether every change of the run is made.

Parameters
eThe run.
Returns
true when every change is selected.

◆ ask()

void ask ( esc_stick_t * e,
int i,
esc_stick_phase_t ph )
static

Ask the operator for a manual step.

Parameters
eThe run.
iIndex of the manual step.
phThe waiting phase.

◆ before_menu()

void before_menu ( esc_stick_t * e,
unsigned from )
static

The menu begins once every step due before it is done.

A step the profile marks starts_menu is the action that starts the menu – the jumper pulled, the button pressed: the ESC answers with its tones and sounds the series at once – so the run listens from the moment it asks for it, with the stick where the power-up left it, and DONE is only a way to say so early. Every other step waits for DONE. The first group the order rule finds in order with the one before it is the menu running, and takes the step as done. Where the menu rests elsewhere the stick would move under the operator's hand, so the run waits for DONE before listening, as for every earlier step.

Parameters
eThe run.
fromIndex of the first manual step to consider.

◆ before_off()

void before_off ( esc_stick_t * e,
unsigned from )
static

The supply goes off once every before_power_off step from from is done: each is asked with the ESC powered and the stick where the store left it, and DONE goes on to the next or switches the supply off.

Parameters
eThe run.
fromIndex of the first manual step to consider.

◆ before_power()

void before_power ( esc_stick_t * e,
unsigned from )
static

The supply comes on once every step due before it is done.

A step at an unpowered ESC is asked for, and the supply switched on, only while the supply itself reads off (off_seen): a run started with the output still live, or a module that came on by itself, ends here with SUPPLY STAYS ON rather than send a hand to a powered ESC.

Parameters
eThe run.
fromIndex of the first manual step to consider.

◆ begin_menu()

void begin_menu ( esc_stick_t * e)
static

Begin the menu: stick to its rest and the first loop.

The menu begins: the stick to its rest, and the first loop.

Parameters
eThe run.

◆ bounds()

void bounds ( esc_stick_t * e,
bool items,
int item )
static

The lowest and highest number a loop of items or of one item's values sounds; item < 0 for every value of every item.

Parameters
eThe run.
itemstrue for the item loop, false for a value loop.
itemIndex of the item whose values are sounded, or -1.

◆ enter()

void enter ( esc_stick_t * e,
esc_stick_phase_t ph )
static

Enter a phase and stamp when it began.

Parameters
eThe run.
phThe new phase.

◆ entry_made()

bool entry_made ( const esc_stick_t * e)
static

Whether the stick has gone to the entry position, or a step at the ESC is asked, with the supply off: the moves made only on the supply read off, and so the ones a live reading has to end at once.

Parameters
eThe run.
Returns
true when such a move or step is under way.

◆ esc_stick_abort()

void esc_stick_abort ( esc_stick_t * e,
esc_stick_reason_t why )

End the run now, for why: throttle to its rest, supply off, disarmed.

A run already over is left as it ended.

Parameters
eThe run.
whyThe end reason.

◆ esc_stick_change_entry_ms()

uint32_t esc_stick_change_entry_ms ( const esc_profile_t * p,
const esc_stick_change_t * c,
const esc_stick_timing_t * t )

Power-on to the menu for change c, ms, as the run waits it: its value's entry_hold_ms where the manual gives one (Kontronik SUN PLUS modes 4 to 6, 5s), else t's entry, and no less than the longest hold of the profile's at_power_up steps. c NULL: the entry's.

Parameters
pThe profile.
cThe change, or NULL for the entry.
tThe timing.
Returns
The power-on to menu time, ms.

◆ esc_stick_confirm()

bool esc_stick_confirm ( esc_stick_t * e)

DONE: the step asked is done.

The run asks the next step due at the same point, or goes on. Ignored, returning false, when no step is asked or the step was asked less than ESC_STICK_HAND_MIN_MS ago.

Parameters
eThe run.
Returns
true when the step was confirmed.

◆ esc_stick_cut_short()

bool esc_stick_cut_short ( const esc_stick_t * e)

Whether the run ended between a selection and the DONE of the profile's before_power_off steps, or before the last of the moves that store the value (esc_stick_store_move()) – while the ESC stored or confirmed: the value may not be stored.

False while the run is under way, and for a value stored by its selection on a profile without such a step.

Parameters
eThe run.
Returns
true when the value may not be stored.

◆ esc_stick_end_locks()

bool esc_stick_end_locks ( const esc_stick_t * e)

Whether a before_power_off step of the run's profile marks locks: a cut before every such step is confirmed may lock the ESC, whichever step is asked.

Parameters
eThe run.
Returns
true when a cut may lock the ESC.

◆ esc_stick_entry_ms()

uint32_t esc_stick_entry_ms ( const esc_stick_t * e)

Power-on to the menu at this power-up, ms: esc_stick_change_entry_ms() of the change it makes.

Parameters
eThe run.
Returns
The power-on to menu time, ms.

◆ esc_stick_hand()

const esc_manual_t * esc_stick_hand ( const esc_stick_t * e)

The manual step the run waits for, or NULL when it waits for none.

A run stops for a step a person does at the ESC where the profile says it is due, and goes on only on esc_stick_confirm():

  • before the supply comes on (ESC_STICK_HAND_OFF): each at_power_up step, and from the second power-up on each before_power step too – the first power-up's are on the warning a run starts from. The supply is off and the stick at the entry position; DONE switches the supply on. Such a step is asked only once the supply itself reads off (ESC_STICK_OFF_MA for ESC_STICK_OFF_SETTLE_MS, in readings taken since the run asked it off); a reading with the output on or the current up while it is asked ends the run with SUPPLY STAYS ON, and readings that stop end it with NO READINGS.
  • once the entry has had its time: each before_menu step, with the ESC powered and the stick at the power-up position (MIN, or MID where the value names it). One marked starts_menu is the action that starts the menu, and the run counts groups from the moment it asks for it (phase ITEMS or VALUES, the step still returned here): the first group in order with the one before it, or DONE, takes it as done. Any other, or one whose menu rests elsewhere, waits in ESC_STICK_HAND_ON for DONE, which goes on to the next step or the menu.
  • after the last move of a store, before the supply goes off: each before_power_off step (ESC_STICK_HAND_END). The ESC stays powered and the stick where the store left it; nobody touches the ESC, the operator watches it confirm the value (tones, LED) and taps DONE. DONE switches the supply off. An end while such a step is asked is told by esc_stick_cut_short(): the value may not be stored. Where the step marks locks – a Kontronik ESC that takes the programming as broken off and locks itself – esc_stick_lock_risk() says so.

STOP, ABORT, a disarm and every supply rule end a waiting run as any other: throttle to MIN, supply off, disarmed. No DONE within ESC_STICK_HAND_WAIT_MS ends it with ESC_STICK_R_HAND.

Parameters
eThe run.
Returns
The step asked, or NULL.

◆ esc_stick_hand_left_ms()

uint32_t esc_stick_hand_left_ms ( const esc_stick_t * e)

The time left to confirm the step asked, ms; 0 when none is.

Parameters
eThe run.
Returns
The time left, ms; 0 when no step is asked.

◆ esc_stick_hand_ready()

bool esc_stick_hand_ready ( const esc_stick_t * e)

Whether DONE would count now: ESC_STICK_HAND_MIN_MS after the step was asked.

Parameters
eThe run.
Returns
true when DONE counts.

◆ esc_stick_light_green()

bool esc_stick_light_green ( esc_stick_light_t * l,
const esc_stick_t * e,
uint32_t now_ms )

Whether the green light is on at now_ms.

Parameters
lThe light state.
eThe run.
now_msTime of the look, ms.
Returns
true when the green light is on at now_ms.

◆ esc_stick_light_reset()

void esc_stick_light_reset ( esc_stick_light_t * l,
const esc_stick_t * e )

Start watching e: pulses already counted do not light it.

Parameters
lThe light state.
eThe run.

◆ esc_stick_lock_risk()

bool esc_stick_lock_risk ( const esc_stick_t * e)

esc_stick_cut_short() and esc_stick_end_locks(): the ESC may have locked itself.

Parameters
eThe run.
Returns
true when the ESC may have locked itself.

◆ esc_stick_read_max_ms()

uint32_t esc_stick_read_max_ms ( const esc_stick_timing_t * t)

The longest interval between two readings the timing allows: the shorter of a beep and a gap, so every beep and every gap holds at least one reading.

Parameters
tThe timing.
Returns
The longest allowed interval between readings, ms.

◆ esc_stick_sample()

void esc_stick_sample ( esc_stick_t * e,
const esc_stick_sample_t * s )

One supply sample, as it arrives.

Parameters
eThe run.
sThe sample.

◆ esc_stick_start()

bool esc_stick_start ( esc_stick_t * e,
const esc_profile_t * p,
const esc_stick_change_t * ch,
size_t n,
const esc_stick_timing_t * t,
uint32_t mv,
uint32_t ma,
const esc_stick_bench_t * b,
const char ** why )

Start a run. mv and ma are the supply's set points, already held to the caps by the caller.

Refused with why when esc_stick_check() refuses, and the run stays idle.

Parameters
eThe run to start.
pThe profile.
chThe changes to make, in order.
nNumber of changes in ch.
tThe timing.
mvSupply set point, mV.
maSupply current limit, mA.
bThe bench state at the start.
whyReceives the reason when refused, or NULL.
Returns
true when the run started.

◆ esc_stick_step()

void esc_stick_step ( esc_stick_t * e,
const esc_stick_bench_t * b )

Advance to b->now_ms and judge the bench.

Parameters
eThe run.
bThe bench state.

◆ esc_stick_store_move()

esc_throttle_t esc_stick_store_move ( const esc_stick_t * e,
unsigned k )

The k-th move after a selection, from 0, or ESC_THR_NONE past the last: the profile's store move, then the moves the stored value asks for (esc_value_t's after: Kontronik's car modes go to the brake after full throttle).

The run makes each STORE after the one before, then switches the supply off.

Parameters
eThe run.
kIndex of the move, from 0.
Returns
The throttle position of that move, or ESC_THR_NONE.

◆ esc_stick_timing_defaults()

void esc_stick_timing_defaults ( esc_stick_timing_t * t)

The defaults the settings start from.

Parameters
tReceives the default timing.

◆ finish()

void finish ( esc_stick_t * e,
esc_stick_phase_t ph,
esc_stick_reason_t why )
static

The run is over: the throttle at its rest, the supply off, disarmed.

Parameters
eThe run.
phThe phase the run ends in.
whyThe end reason.

◆ hand_due()

int hand_due ( const esc_stick_t * e,
unsigned from,
bool powered )
static

The first manual step from from that is due at this point of the run, or -1.

Before a power-up: each at_power_up step, and the before_power steps from the second power-up on – the warning the run started from asked for the first power-up's. Once the ESC is powered and entered: each before_menu step.

Parameters
eThe run.
fromIndex of the first manual step to consider.
poweredtrue once the ESC is powered and entered.
Returns
Index into the profile's manual steps, or -1 when none is due.

◆ hand_menu_done()

void hand_menu_done ( esc_stick_t * e)
static

The action that starts the menu is done: by DONE, or by the menu heard in order.

SILENCE and TIMEOUT count from now.

Parameters
eThe run.

◆ hand_phase()

bool hand_phase ( esc_stick_phase_t ph)
static

Whether a phase waits for a manual step.

Parameters
phThe phase.
Returns
true for HAND_OFF, HAND_ON and HAND_END.

◆ listen()

void listen ( esc_stick_t * e,
esc_stick_phase_t ph )
static

Start listening for a group in a phase.

Parameters
eThe run.
phThe phase: ITEMS or VALUES.

◆ next_entry()

esc_throttle_t next_entry ( const esc_stick_t * e)
static

The menu begins: the stick to its rest, and the first loop.

The position the next power-up enters from: the first change still to make, which in a one-stage menu is the one this power-up makes, and in any other is every change's (entry_refused()).

Parameters
eThe run.
Returns
The entry position of the next change.

◆ off_phase()

bool off_phase ( esc_stick_phase_t ph)
static

One reading while the run waits for the output to go off.

Only a reading taken after the run asked it off counts – a new count, stamped after the request – and only one in which the supply itself reports the output off with the current at or under ESC_STICK_OFF_MA; such readings have to run on for ESC_STICK_OFF_SETTLE_MS. The panel's own flag says only that it asked: the module switches off a link exchange and a module transaction later, and until then the ESC is powered and in its menu.

The phases in which the supply is to be off and its readings are judged for it: before the first power-up, while a step at an unpowered ESC is asked, and after the run asked the output off.

Parameters
phThe phase.
Returns
true for ARMING, SIGNAL, HAND_OFF, CYCLE and OFF.

◆ off_reading()

void off_reading ( esc_stick_t * e,
const esc_stick_sample_t * s )
static

Judge one supply reading taken while the output is to be off.

Only a reading taken after the run asked the output off counts – a new count, stamped after the request – and only one in which the supply itself reports the output off with the current at or under ESC_STICK_OFF_MA; such readings have to run on for ESC_STICK_OFF_SETTLE_MS. The panel's own flag says only that it asked: the module switches off a link exchange and a module transaction later, and until then the ESC is powered and in its menu.

Parameters
eThe run.
sThe supply sample.

◆ on_group()

void on_group ( esc_stick_t * e,
uint8_t count,
bool valid )
static

Judge one counted group of beeps.

Acts on the group only when it is in order and the group before it was too.

Parameters
eThe run.
countBeeps in the group.
validtrue when the detector judged the group valid.

◆ power_on()

void power_on ( esc_stick_t * e)
static

Ask the supply on and wait for its output.

Parameters
eThe run.

◆ powered_phase()

bool powered_phase ( esc_stick_phase_t ph)
static

Whether the supply is on in a phase.

Parameters
phThe phase.
Returns
true for the phases in which the ESC is powered.

◆ rest_of()

esc_throttle_t rest_of ( const esc_stick_t * e)
static

Where the stick rests while the menu sounds: the profile's listen move, else where this power-up entered.

Parameters
eThe run.
Returns
The rest position.

◆ selected()

void selected ( esc_stick_t * e)
static

Record that the active change is selected.

Starts the store, or returns the ESC to its items when more changes follow.

Parameters
eThe run.

◆ since()

uint32_t since ( uint32_t now,
uint32_t then )
static

The time from then to now, 0 when then is later.

A reading is stamped by the task that took it and the bench's time by the one that steps the run, so a reading can carry a time a little after the step's.

Parameters
nowLater time, ms.
thenEarlier time, ms.
Returns
now - then in ms, or 0 when then is later.

◆ supply_off()

void supply_off ( esc_stick_t * e)
static

The supply off, the stick where it is; see the top of this file.

A pulse under way is dropped with the group: no reading reaches the detector until the next power-up starts it afresh.

Parameters
eThe run.

◆ wanted_value()

uint8_t wanted_value ( const esc_stick_t * e)
static

Number of the value the active change wants.

Parameters
eThe run.
Returns
The value number.