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

The motor and ESC (electronic speed controller) bench screen. More...

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "bench_state.h"
#include "endpoints_link.h"
#include "gfx.h"
#include "settings.h"
#include "ui_keypad.h"
#include "ui_screen.h"

Go to the source code of this file.

Data Structures

struct  motor_cmd_t

Macros

#define MOTOR_PROTO_MIXED   0xFFu

Enumerations

enum  motor_pane_t { MOTOR_PANE_PLOT = 0 , MOTOR_PANE_TABLE , MOTOR_PANE_COUNT }
enum  motor_cmd_kind_t {
  MOTOR_CMD_NONE = 0 , MOTOR_CMD_ARM , MOTOR_CMD_DISARM , MOTOR_CMD_THROTTLE ,
  MOTOR_CMD_RESET_PEAKS
}
enum  motor_plot_state_t { MOTOR_PLOT_EMPTY = 0 , MOTOR_PLOT_RECORDING , MOTOR_PLOT_HELD }

Functions

void motor_screen_push (const bench_state_t *b)
void motor_screen_set_armed (bool armed)
 What the bench is doing, which is what bounds a run.
motor_plot_state_t motor_screen_plot_state (void)
int motor_screen_plot_samples (void)
bool motor_screen_peak_shown (int channel)
 Whether channel channel's peak is drawn as a value – 0 voltage, 1 current, 2 power, 3rpm: a valid reading of it has arrived since the run started or the peaks were reset. It stays drawn when the live reading goes empty, as when a source stops answering mid-run and the run's peaks it measured stand.
void motor_screen_cancel_arm (void)
void motor_screen_set_esc_kv (int kv)
void motor_screen_set_throttle_pins (uint64_t gpio_mask, bool known)
void motor_screen_set_throttle_protocol (uint8_t proto)
bool motor_throttle_target (char *out, size_t size, uint8_t proto, uint64_t pins, bool known, unsigned cells)
 The TARGET row's value, protocol pins ("DSHOT300 GPIO 0 GPIO 1"), in at most cells characters.
uint8_t motor_dshot_ports (void)
unsigned motor_target_cells (void)
size_t motor_output_strip (char *out, size_t size, uint8_t proto, uint64_t pins, bool known, bool armed, bool *warn)
int motor_screen_task (void)
bool motor_screen_session_shown (void)
int motor_screen_pane (void)
bool motor_screen_target_locked (void)
int motor_screen_keypad_setting (void)
const ui_keypad_t * motor_screen_keypad (void)
 SETTINGS' keypad, open or closed, for a test to read what it opened with and where its keys are.
int motor_settings_rows (setting_id_t *out, int max)
int motor_settings_heading (int row)
gfx_rect_t motor_settings_box (int row)
const char * motor_endpoints_alert (endpoints_block_t why)
float motor_screen_throttle (void)
void motor_screen_set_throttle (float pct)
void motor_screen_knob (float span_fraction)
void motor_screen_knob_frame (void)
void motor_screen_knob_cancel (void)
bool motor_screen_poll_cmd (motor_cmd_t *out)
void motor_invalidate (void)
const ui_screen_t * motor_screen (void)

Detailed Description

The motor and ESC (electronic speed controller) bench screen.

Owns no hardware and performs no I/O (input/output). It is handed a bench_state_t and touch events, and commands are read back out, so the same code renders to a PNG (Portable Network Graphics) file on the host and is tested for what it decides as well as for what it draws.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ MOTOR_PROTO_MIXED

#define MOTOR_PROTO_MIXED   0xFFu

The throttle's pins are bound as more than one protocol.

Enumeration Type Documentation

◆ motor_cmd_kind_t

What the screen asks the application to do. One slot, coalescing.

Enumerator
MOTOR_CMD_THROTTLE 

value carries the percentage

◆ motor_plot_state_t

Enumerator
MOTOR_PLOT_EMPTY 

no run recorded since the screen reset

MOTOR_PLOT_RECORDING 

the bench is armed; the trace advances

MOTOR_PLOT_HELD 

the last run, held as it ended

Function Documentation

◆ motor_dshot_ports()

uint8_t motor_dshot_ports ( void )

The programming ports the bench throttle drives, bit n for port n: FUNC DSHOT150 to DSHOT600 and a pin the IOmcu holds, as port_view.h last read them.

◆ motor_endpoints_alert()

const char * motor_endpoints_alert ( endpoints_block_t why)

What the alert band says for a switch to ARMED refused because the pair of Idle pulse and Full pulse is not in force at the IOmcu, by endpoints_block(); NULL for ENDPOINTS_BLOCK_NONE and for a value outside the enum.

◆ motor_output_strip()

size_t motor_output_strip ( char * out,
size_t size,
uint8_t proto,
uint64_t pins,
bool known,
bool armed,
bool * warn )

The output strip a full-width session on PROGRAM shows in the strip row, in place of the tabs and the output card, as one line: TARGET protocol pins SUPPLY v V i A SAFE ("ARMED" for an armed bench), the target as motor_throttle_target() puts it in 26 cells, the supply as it reads now (supply_screen_reading()): its voltage and current with the output on, OFF, ON without both readings, "--" while it does not answer. Into out of size bytes; warn (may be NULL) gets whether the target is a warning. Returns the length written.

◆ motor_screen_cancel_arm()

void motor_screen_cancel_arm ( void )

Abandon a hold that is under way, because the bench has been stopped. A stop on a bench that was not armed changes nothing about whether it is armed, and the gesture must end all the same.

◆ motor_screen_keypad()

const ui_keypad_t * motor_screen_keypad ( void )

SETTINGS' keypad, open or closed, for a test to read what it opened with and where its keys are.

Returns
The keypad; never NULL.

◆ motor_screen_keypad_setting()

int motor_screen_keypad_setting ( void )

The setting SETTINGS' keypad types, or -1 while it is closed.

◆ motor_screen_knob()

void motor_screen_knob ( float span_fraction)

Move the throttle by span_fraction of the slider's span, from the rotary knob (knob.h). Relative: the value changes by how far the knob turned. Nothing happens for a zero fraction, while a finger is dragging the slider, while the bench is not armed, or on a task other than LIVE, where the throttle is out of sight: a turn made then is not kept for the next arm. It posts the same throttle command a touch does and never arms. It posts only into an empty slot or over a throttle: any other pending command (an arm, a disarm, a peak reset) stays and the knob's motion is dropped.

◆ motor_screen_knob_cancel()

void motor_screen_knob_cancel ( void )

Withdraw the knob's throttle command if it is still waiting to be taken: the slider returns to its value from before the knob, and a throttle that was pending before the knob moved it is pending again with that value. A command posted by a touch since, or already taken, is left alone.

◆ motor_screen_knob_frame()

void motor_screen_knob_frame ( void )

Start of a frame, before its touch events: forget that a finger owned the slider. The knob moves nothing in a frame in which a finger owned the slider at any point, including a press and release inside it, because the touch has already set the value the knob would move.

◆ motor_screen_pane()

int motor_screen_pane ( void )

LIVE's view shown, a motor_pane_t: PLOT or TABLE.

◆ motor_screen_peak_shown()

bool motor_screen_peak_shown ( int channel)

Whether channel channel's peak is drawn as a value – 0 voltage, 1 current, 2 power, 3rpm: a valid reading of it has arrived since the run started or the peaks were reset. It stays drawn when the live reading goes empty, as when a source stops answering mid-run and the run's peaks it measured stand.

Parameters
channel0 voltage, 1 current, 2 power, 3rpm
Returns
true while that peak is drawn as a value

◆ motor_screen_plot_samples()

int motor_screen_plot_samples ( void )

Samples in the trace, capped at UI_PLOT_HISTORY. The plot is narrower than that, so a longer run is drawn truncated to its newest columns.

◆ motor_screen_poll_cmd()

bool motor_screen_poll_cmd ( motor_cmd_t * out)

True when a command was waiting; clears it.

◆ motor_screen_push()

void motor_screen_push ( const bench_state_t * b)

Called per sample, so the plot's time base is the sample rate. The readouts take every sample; the plot takes them only while armed.

◆ motor_screen_session_shown()

bool motor_screen_session_shown ( void )

Whether PROGRAM's session is shown, full width with the output strip over it.

◆ motor_screen_set_armed()

void motor_screen_set_armed ( bool armed)

What the bench is doing, which is what bounds a run.

Arming clears the plot and starts it; disarming holds it as it stood. The caller reports the bench's own arm state, not a request made of it: a disarm that has been asked for and not yet answered must not erase the run it is ending.

The throttle follows the bench, through ui_value_gate.h. Outside UI_VALUE_LIVE no control changes the value: the slider, its -1 and +1 buttons and motor_screen_knob() post nothing and move nothing, from the first frame to the bench's answer to an ARM, and from a MOTOR_CMD_DISARM being posted or motor_screen_cancel_arm() on an armed bench until this is called with false. The change to disarmed returns the slider to 0%, drops a throttle command waiting to be polled and ends a drag under way.

The hold that posts MOTOR_CMD_ARM does the same. The change to armed does it for an arm that hold did not ask for; after the hold's ask it leaves the slider, which only motor_screen_set_throttle() can have moved since, as it is. Reporting the same state again changes nothing.

◆ motor_screen_set_esc_kv()

void motor_screen_set_esc_kv ( int kv)

The kV the connected ESC reports, or 0 when it reports none. Preferred over the SET_MOTOR_KV setting when it is non-zero.

◆ motor_screen_set_throttle()

void motor_screen_set_throttle ( float pct)

The application's hook: sets the slider on an armed or a disarmed bench and posts nothing. Not a control, and not held to the armed state.

◆ motor_screen_set_throttle_pins()

void motor_screen_set_throttle_pins ( uint64_t gpio_mask,
bool known )

The GPIOs the throttle drives now: every pin bound as MOTOR PWM or DShot, bit n for GPIO n, from the binding the application last read. known is false while no binding was read; the mask is then taken as empty. The CONTROL card's TARGET row names them, or says there are none or that the binding is not read.

◆ motor_screen_set_throttle_protocol()

void motor_screen_set_throttle_protocol ( uint8_t proto)

The protocol the throttle's pins are bound as, an index into outbind_protos() (outbind_role_proto()): 0 when none is known, MOTOR_PROTO_MIXED when they are bound as several. The TARGET row puts its name before the pins.

◆ motor_screen_target_locked()

bool motor_screen_target_locked ( void )

Whether the TARGET row takes no press now: the bench is not SAFE (an ARM held, asked or in force, or a DISARM not yet answered), or the servo programmer holds its port.

◆ motor_screen_task()

int motor_screen_task ( void )

The task shown, a ui_wb_task_t: LIVE, PROGRAM or SETTINGS. A tile opens LIVE; the home tag over SETTINGS' keypad closes the keypad, and in PROGRAM's session climbs it one level (back()).

◆ motor_settings_box()

gfx_rect_t motor_settings_box ( int row)

Row row's value box, which a tap opens the keypad on.

◆ motor_settings_heading()

int motor_settings_heading ( int row)

The heading row row sits under, a ui_text_id_t; -1 out of range.

◆ motor_settings_rows()

int motor_settings_rows ( setting_id_t * out,
int max )

SETTINGS' rows in their order, at most max into out (NULL counts them). Returns how many there are.

◆ motor_target_cells()

unsigned motor_target_cells ( void )

The TARGET row's value box in 8-pixel cells (ui_target_row_cells()).

◆ motor_throttle_target()

bool motor_throttle_target ( char * out,
size_t size,
uint8_t proto,
uint64_t pins,
bool known,
unsigned cells )

The TARGET row's value, protocol pins ("DSHOT300 GPIO 0 GPIO 1"), in at most cells characters.

The protocol's catalogue name for proto, MIXED for MOTOR_PROTO_MIXED, the pins alone for a protocol not known, and as many pins as fit, then "+N" (ui_target_text()). The DShot programming ports the throttle reaches (motor_dshot_ports()) follow the pins as PORT n. A port alone is DSHOT300 PROG PORT 2 GPIO 14 where that fits, DSHOT300 PORT 2 GPIO 14 where that fits (the CONTROL card's 25 cells), and DSHOT300 PORT 2 where neither does; slots and ports of different rates read MIXED.

Parameters
outtakes the text
sizebytes at out
protothe throttle's protocol, a catalogue index or MOTOR_PROTO_MIXED; 0 for none known
pinsthe throttle pins, bit n for GPIO n
knownwhether the binding is read
cellsthe characters the value box holds
Returns
true when the value is a warning (the binding is not read, or neither a pin nor a port is bound as a motor), which the row draws in the warning colour