|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
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) |
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
| #define MOTOR_PROTO_MIXED 0xFFu |
The throttle's pins are bound as more than one protocol.
| enum motor_cmd_kind_t |
| enum motor_plot_state_t |
| 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.
| 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.
| 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.
| 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.
| 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_screen_keypad_setting | ( | void | ) |
The setting SETTINGS' keypad types, or -1 while it is closed.
| 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.
| 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.
| 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.
| int motor_screen_pane | ( | void | ) |
LIVE's view shown, a motor_pane_t: PLOT or TABLE.
| 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.
| channel | 0 voltage, 1 current, 2 power, 3rpm |
| 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.
| bool motor_screen_poll_cmd | ( | motor_cmd_t * | out | ) |
True when a command was waiting; clears it.
| 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.
| bool motor_screen_session_shown | ( | void | ) |
Whether PROGRAM's session is shown, full width with the output strip over it.
| 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.
| 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.
| 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.
| 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.
| 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.
| 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.
| 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()).
| gfx_rect_t motor_settings_box | ( | int | row | ) |
Row row's value box, which a tap opens the keypad on.
| int motor_settings_heading | ( | int | row | ) |
The heading row row sits under, a ui_text_id_t; -1 out of range.
| 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.
| unsigned motor_target_cells | ( | void | ) |
The TARGET row's value box in 8-pixel cells (ui_target_row_cells()).
| 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.
| out | takes the text |
| size | bytes at out |
| proto | the throttle's protocol, a catalogue index or MOTOR_PROTO_MIXED; 0 for none known |
| pins | the throttle pins, bit n for GPIO n |
| known | whether the binding is read |
| cells | the characters the value box holds |