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

The registry of programmers and runs: one static table that the PROGRAM (and later TEST) lists of a workbench are built from. More...

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "gfx.h"
#include "touch_types.h"
#include "ui_text.h"
#include "ui_workbench.h"

Go to the source code of this file.

Data Structures

struct  prog_page_set_t
struct  prog_reg_row_t
struct  prog_list_entry_t
struct  prog_list_t
struct  prog_view_t

Macros

#define PROG_REG_NO_PORT   0xFFu
#define PROG_REG_NO_PIN   0xFFu
#define PROG_REG_PORTS   4u
#define PROG_REG_TESTER_PORT   0xFEu
#define PROG_ONE_CALL   __attribute__((noinline))
#define PROG_FULL_STRIP_X   12
 A full-width session's layout, in the host's body coordinates (1024 x 540px under the band): the output strip's line at the top, one line of PROG_FULL_STRIP_FONT, the type scale's LABEL face (10 x 20), from PROG_FULL_STRIP_Y, and the session's own area from PROG_FULL_Y to the foot of the body.
#define PROG_FULL_STRIP_Y   4
#define PROG_FULL_STRIP_H   20
#define PROG_FULL_Y   28
#define PROG_FULL_STRIP_FONT   (&gfx_font_10x20)
#define PROG_FULL_STRIP_CELLS   100
 The cells the output strip's line holds: 1000px of 10px cells.
#define PROG_LIST_SEARCH_OVER   9
#define PROG_LIST_HEADINGS_OVER   8
#define PROG_LIST_MAX   48
#define PROG_LIST_QUERY_MAX   16
#define PROG_VIEW_PAD   10
 A list drawn into a rectangle: a bar on top while the list offers SEARCH or does not fit (SEARCH, "^", "v"), then its entries.
#define PROG_VIEW_BAR_H   48
#define PROG_VIEW_ROW_H   48
#define PROG_VIEW_ROW_P   56
#define PROG_VIEW_HEAD_H   28
#define PROG_VIEW_HEAD_P   32
#define PROG_VIEW_SEARCH_W   260
#define PROG_VIEW_KEY_W   56
#define PROG_VIEW_FONT   (&gfx_font_10x20)

Enumerations

enum  prog_device_t { PROG_DEV_SERVO = 0 , PROG_DEV_MOTOR , PROG_DEVICES }
enum  prog_reg_fault_t {
  PROG_REG_OK = 0 , PROG_REG_BAD_DEVICE , PROG_REG_BAD_TASK , PROG_REG_NO_NAME ,
  PROG_REG_NO_GROUP , PROG_REG_NO_TRANSPORT , PROG_REG_BAD_PORT , PROG_REG_NO_PAGE_SET ,
  PROG_REG_SAME_NAME , PROG_REG_TOO_MANY , PROG_REG_BAD_WIDTH
}
enum  prog_row_state_t { PROG_ROW_LIVE = 0 , PROG_ROW_NO_CAP , PROG_ROW_PORT_BUSY }
enum  { PROG_VIEW_P_NONE = -1 , PROG_VIEW_P_SEARCH = -2 , PROG_VIEW_P_UP = -3 , PROG_VIEW_P_DOWN = -4 }
enum  prog_view_ev_t { PROG_VIEW_NONE = 0 , PROG_VIEW_TAKEN , PROG_VIEW_ROW , PROG_VIEW_SEARCH }

Functions

const prog_reg_row_t * prog_registry (size_t *count)
void prog_registry_use (const prog_reg_row_t *rows, size_t count)
void prog_registry_set_ports (uint8_t tester_port, uint8_t held)
uint8_t prog_reg_port (const prog_reg_row_t *r)
bool prog_reg_servo_holds (void)
 Whether a servo programmer holds a port: the KST programmer's session, or the Hitec programmer's, whose word counts a port the HITEC page names held by another session too. ARM, the motor's TARGET row and a run that arms the bench wait for neither.
prog_reg_fault_t prog_reg_check (const prog_reg_row_t *rows, size_t n, size_t *at)
int prog_reg_sets (uint8_t device, const prog_page_set_t *out[PROG_LIST_MAX])
bool prog_reg_full_width (const prog_page_set_t *ps)
void prog_ps_init (const prog_page_set_t *ps, gfx_rect_t area)
void prog_ps_entry (const prog_page_set_t *ps)
void prog_ps_open (const prog_page_set_t *ps)
bool prog_ps_is_open (const prog_page_set_t *ps)
void prog_ps_back (const prog_page_set_t *ps)
bool prog_ps_holds (const prog_page_set_t *ps)
void prog_ps_armed (const prog_page_set_t *ps, bool armed)
void prog_ps_tick (const prog_page_set_t *ps, float dt_s)
bool prog_ps_has_press (const prog_page_set_t *ps, uint8_t id)
void prog_ps_event (const prog_page_set_t *ps, const touch_event_t *evt)
void prog_ps_render (const prog_page_set_t *ps, gfx_canvas_t *c)
uint32_t prog_ps_revision (const prog_page_set_t *ps)
uint32_t prog_ps_hold_revision (const prog_page_set_t *ps)
gfx_rect_t prog_ps_hold_rect (const prog_page_set_t *ps)
void prog_ps_leave (const prog_page_set_t *ps)
void prog_ps_cancel (const prog_page_set_t *ps)
uint8_t prog_ps_pin (const prog_page_set_t *ps)
bool prog_ps_safe_at (const prog_page_set_t *ps, int x, int y)
prog_row_state_t prog_reg_state (const prog_reg_row_t *rows, size_t n, size_t i, uint16_t caps)
uint16_t prog_reg_missing (const prog_reg_row_t *row, uint16_t caps)
const char * prog_reg_cap_name (uint16_t bit)
bool prog_reg_detail (const prog_reg_row_t *rows, size_t n, size_t i, uint16_t caps, char *out, size_t size)
 The text right of row i's name: for a live row on a port its number and the session's pin ("PROG PORT 2 GPIO 14", "PROG PORT 2" with the pin not known), its transport and the pin for any other ("PROG PORT GPIO 13", "PROG PORT" with the tester's port not known); its reason for a dimmed one ("IOMCU HAS NO SERVO PWM", "PORT IN USE").
void prog_list_build (prog_list_t *l, const prog_reg_row_t *rows, size_t n, uint8_t device, uint8_t task, const char *query)
void prog_view_init (prog_view_t *v, gfx_rect_t area)
void prog_view_top (prog_view_t *v)
bool prog_view_has_bar (const prog_view_t *v, const prog_list_t *l)
int prog_view_shown (const prog_view_t *v, const prog_list_t *l)
gfx_rect_t prog_view_entry_rect (const prog_view_t *v, const prog_list_t *l, int k)
gfx_rect_t prog_view_search_rect (const prog_view_t *v, const prog_list_t *l)
 SEARCH on the bar, PROG_VIEW_SEARCH_W wide from the left.
gfx_rect_t prog_view_up_rect (const prog_view_t *v, const prog_list_t *l)
 "^" on the bar, PROG_VIEW_KEY_W wide, 8px left of "v".
gfx_rect_t prog_view_down_rect (const prog_view_t *v, const prog_list_t *l)
 "v" on the bar, PROG_VIEW_KEY_W wide at the right.
prog_view_ev_t prog_view_event (prog_view_t *v, const prog_list_t *l, const touch_event_t *evt, uint8_t *row)
void prog_view_cancel (prog_view_t *v)
void prog_view_render (const prog_view_t *v, const prog_list_t *l, const prog_reg_row_t *rows, size_t n, uint16_t caps, const char *query, gfx_canvas_t *c)
 Draws the list in PROG_VIEW_FONT: query in the SEARCH box ("SEARCH" while empty), each row's name and prog_reg_detail(), a live row with ">" at its right end, a dimmed one in the dim colour with its reason in the warning colour.

Detailed Description

The registry of programmers and runs: one static table that the PROGRAM (and later TEST) lists of a workbench are built from.

A row is { device, task, name, group, transport, port, needs_capability, page_set, full_width }:

  • device and task pick the list: SERVO > PROGRAM and MOTOR & ESC > PROGRAM.
  • name is the row's descriptive text ("KST and Chaservo servos"), never a screen title; a maker's name is a row label only.
  • group is the heading the row sits under once the list has headings.
  • transport is what the row's line says it drives ("PROG PORT"), as the TARGET row on the output card says it.
  • port is the IOmcu programming port the row's session holds, PROG_REG_TESTER_PORT for the port the SERVO screen's tester drives (prog_registry_set_ports()), or PROG_REG_NO_PORT. Two rows on one port are exclusive: while one holds the port the other is drawn dimmed, PORT IN USE, and opens nothing. A port another page of the IOmcu holds (a HITEC session the bench console opened) dims every row on it the same way.
  • needs_capability holds link_cap_t bits. A row whose bits the IOmcu does not report is drawn dimmed with its reason, not hidden, and opens nothing.
  • page_set is the session the row opens one level down: the hooks the host screen drives it through (prog_page_set_t).
  • full_width says how the host lays the session out. Not full width, it opens over the host's left column and the output card stays on the right (SERVO's sessions). Full width, it takes the whole body under the strip row, and the host draws a one-line output strip in that row in place of the card: what the session drives, TARGET DSHOT300 GPIO 0 GPIO 1 SUPPLY 7.60V 1.00A SAFE (MOTOR & ESC's sessions, ESC STICK). The owner grants each full-width page set; prog_reg_check() holds each device to the one layout its host draws.

A new maker adds one row to k_rows in prog_registry.c and one page_set (a session laid out for the host's left column, as kst_panel_pages is, or for the full body, as esc_stick_pages is). A new maker never adds a home tile, a SETUP tile or a tab. SERVO's second PROGRAM row is the programmer for servos by Hitec (hitec_panel.h). A modelled protocol with no transport on the IOmcu gets no row.

The list rules: a list of more than PROG_LIST_SEARCH_OVER rows offers SEARCH (the existing keyboard, "*" for any text); a list showing more than PROG_LIST_HEADINGS_OVER rows draws its rows under their group headings; a list that does not fit its area pages with "^" and "v". A list holds at most PROG_LIST_MAX rows (prog_reg_check()).

The table, its checks and the list model are pure; the view draws a list into a rectangle and turns touches into row taps.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ PROG_FULL_STRIP_FONT

#define PROG_FULL_STRIP_FONT   (&gfx_font_10x20)

the strip's face

◆ PROG_FULL_STRIP_H

#define PROG_FULL_STRIP_H   20

its line's height, px

◆ PROG_FULL_STRIP_X

#define PROG_FULL_STRIP_X   12

A full-width session's layout, in the host's body coordinates (1024 x 540px under the band): the output strip's line at the top, one line of PROG_FULL_STRIP_FONT, the type scale's LABEL face (10 x 20), from PROG_FULL_STRIP_Y, and the session's own area from PROG_FULL_Y to the foot of the body.

the strip's left, px

◆ PROG_FULL_STRIP_Y

#define PROG_FULL_STRIP_Y   4

its top, px

◆ PROG_FULL_Y

#define PROG_FULL_Y   28

the session's area's top, px

◆ PROG_LIST_QUERY_MAX

#define PROG_LIST_QUERY_MAX   16

The characters a search takes, as ESC STICK's does.

◆ PROG_LIST_SEARCH_OVER

#define PROG_LIST_SEARCH_OVER   9

The list rules (see the top of this file).

◆ PROG_REG_NO_PIN

#define PROG_REG_NO_PIN   0xFFu

A session's pin that is not known.

◆ PROG_REG_NO_PORT

#define PROG_REG_NO_PORT   0xFFu

A row that holds no programming port.

◆ PROG_REG_PORTS

#define PROG_REG_PORTS   4u

The IOmcu's programming ports a row may name: 0 to 3 (protocol LINK_PG_PORTS_MAX).

◆ PROG_REG_TESTER_PORT

#define PROG_REG_TESTER_PORT   0xFEu

A row on the port the SERVO screen's tester drives, whichever that is: PORT 1 to PORT 4 of SERVO TESTER, none with OUTPUTS.

◆ PROG_VIEW_BAR_H

#define PROG_VIEW_BAR_H   48

the bar's height, px

◆ PROG_VIEW_FONT

#define PROG_VIEW_FONT   (&gfx_font_10x20)

the text's face

◆ PROG_VIEW_HEAD_H

#define PROG_VIEW_HEAD_H   28

a heading's height, px

◆ PROG_VIEW_HEAD_P

#define PROG_VIEW_HEAD_P   32

a heading's pitch, px

◆ PROG_VIEW_KEY_W

#define PROG_VIEW_KEY_W   56

the width of "^" and of "v", px

◆ PROG_VIEW_PAD

#define PROG_VIEW_PAD   10

A list drawn into a rectangle: a bar on top while the list offers SEARCH or does not fit (SEARCH, "^", "v"), then its entries.

A row is 48px (UI_TAP_MIN) with 8px under it, a heading 28px with 4px under it; the bar is 48px, SEARCH 260px wide and "^" and "v" 56px each. The text is in PROG_VIEW_FONT, the type scale's LABEL face (10 x 20). A row's press is taken on its DOWN and is a tap on its release over the same row. the area's inset, px

◆ PROG_VIEW_ROW_H

#define PROG_VIEW_ROW_H   48

a row's height, px

◆ PROG_VIEW_ROW_P

#define PROG_VIEW_ROW_P   56

a row's pitch, px

◆ PROG_VIEW_SEARCH_W

#define PROG_VIEW_SEARCH_W   260

SEARCH's width, px

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

What a press is on: an entry from 0, or one of these.

◆ prog_device_t

The devices a row belongs to: the workbench whose list shows it.

◆ prog_reg_fault_t

Enumerator
PROG_REG_BAD_DEVICE 

device past PROG_DEVICES

PROG_REG_BAD_TASK 

task neither PROGRAM nor TEST

PROG_REG_NO_NAME 

name empty in the language in force

PROG_REG_NO_GROUP 

group empty

PROG_REG_NO_TRANSPORT 

transport empty

PROG_REG_BAD_PORT 

a port past PROG_REG_PORTS

PROG_REG_NO_PAGE_SET 

page_set NULL, or a hook of it NULL

PROG_REG_SAME_NAME 

two rows of one list with one name

PROG_REG_TOO_MANY 

a list over PROG_LIST_MAX rows

PROG_REG_BAD_WIDTH 

A layout the device's host does not draw: a full-width SERVO row, or a MOTOR row that is not full width.

◆ prog_row_state_t

Enumerator
PROG_ROW_LIVE 

a tap opens its session

PROG_ROW_NO_CAP 

the IOmcu lacks a needed capability

PROG_ROW_PORT_BUSY 

another row's session holds the port

◆ prog_view_ev_t

Enumerator
PROG_VIEW_NONE 

not the view's

PROG_VIEW_TAKEN 

the view's, nothing to do

PROG_VIEW_ROW 

a row tapped: *row is the table's row

PROG_VIEW_SEARCH 

SEARCH tapped

Function Documentation

◆ prog_list_build()

void prog_list_build ( prog_list_t * l,
const prog_reg_row_t * rows,
size_t n,
uint8_t device,
uint8_t task,
const char * query )

The list of device's task from n rows of rows, narrowed to the names query finds (esc_text_matches(): letters without regard to case, "*" any text; NULL or "" finds all). SEARCH stays offered while a search narrows the list. With headings, the groups come in the order the table first names them and the rows keep the table's order inside each. Rows past PROG_LIST_MAX are not listed.

◆ prog_reg_cap_name()

const char * prog_reg_cap_name ( uint16_t bit)

A capability bit's name as the link names it ("SERVO PWM"), the same in every language; "" for a bit with no name, or for 0.

◆ prog_reg_check()

prog_reg_fault_t prog_reg_check ( const prog_reg_row_t * rows,
size_t n,
size_t * at )

Checks n rows of rows: every field filled and in range, names in the language in force, no two rows of one list named alike, no list over PROG_LIST_MAX, each row laid out as its device's host draws it. The first fault found, with its row in at (may be NULL); PROG_REG_OK with at untouched for a sound table.

◆ prog_reg_detail()

bool prog_reg_detail ( const prog_reg_row_t * rows,
size_t n,
size_t i,
uint16_t caps,
char * out,
size_t size )

The text right of row i's name: for a live row on a port its number and the session's pin ("PROG PORT 2 GPIO 14", "PROG PORT 2" with the pin not known), its transport and the pin for any other ("PROG PORT GPIO 13", "PROG PORT" with the tester's port not known); its reason for a dimmed one ("IOMCU HAS NO SERVO PWM", "PORT IN USE").

Parameters
rowsthe registry's rows
nrows at rows
ithe row
capsthe IOmcu's capability bits
outtakes at most size - 1 characters
sizebytes at out
Returns
whether the row is dimmed

◆ prog_reg_full_width()

bool prog_reg_full_width ( const prog_page_set_t * ps)

Whether a row that opens ps is full width.

◆ prog_reg_missing()

uint16_t prog_reg_missing ( const prog_reg_row_t * row,
uint16_t caps )

The lowest link_cap_t bit row i needs and caps lacks; 0 none.

◆ prog_reg_port()

uint8_t prog_reg_port ( const prog_reg_row_t * r)

Row r's port as it stands: its own, the tester's for PROG_REG_TESTER_PORT, or PROG_REG_NO_PORT.

◆ prog_reg_servo_holds()

bool prog_reg_servo_holds ( void )

Whether a servo programmer holds a port: the KST programmer's session, or the Hitec programmer's, whose word counts a port the HITEC page names held by another session too. ARM, the motor's TARGET row and a run that arms the bench wait for neither.

Returns
true while either holds one

◆ prog_reg_sets()

int prog_reg_sets ( uint8_t device,
const prog_page_set_t * out[PROG_LIST_MAX] )

The page sets device's rows open, each once in the table's order, into out: at most PROG_LIST_MAX. Their count.

◆ prog_reg_state()

prog_row_state_t prog_reg_state ( const prog_reg_row_t * rows,
size_t n,
size_t i,
uint16_t caps )

Row i of rows with the IOmcu reporting caps (link_cap_t).

◆ prog_registry()

const prog_reg_row_t * prog_registry ( size_t * count)

The table, and its row count in count.

◆ prog_registry_set_ports()

void prog_registry_set_ports ( uint8_t tester_port,
uint8_t held )

The ports as the panel last read them: tester_port, the port the SERVO screen's tester drives (0 to 3), PROG_REG_NO_PORT with the standard outputs or the target not known; held, bit n for port n held by an IOmcu page no row's session drives (the HITEC page, opened from the bench console). Both start as none.

◆ prog_registry_use()

void prog_registry_use ( const prog_reg_row_t * rows,
size_t count )

For the tests: the lists are built from count rows of rows; NULL goes back to the table as it ships.

◆ prog_view_cancel()

void prog_view_cancel ( prog_view_t * v)

Drop a press under way.

◆ prog_view_down_rect()

gfx_rect_t prog_view_down_rect ( const prog_view_t * v,
const prog_list_t * l )

"v" on the bar, PROG_VIEW_KEY_W wide at the right.

Parameters
vthe view
lthe list it shows
Returns
its rectangle; empty when the list does not page

◆ prog_view_entry_rect()

gfx_rect_t prog_view_entry_rect ( const prog_view_t * v,
const prog_list_t * l,
int k )

Entry k's rectangle, empty when it is not shown.

◆ prog_view_event()

prog_view_ev_t prog_view_event ( prog_view_t * v,
const prog_list_t * l,
const touch_event_t * evt,
uint8_t * row )

A touch event. "^" and "v" page the list themselves. A heading takes a press and does nothing. A row tap is reported whatever its state: the host opens a live row only (prog_reg_state()).

◆ prog_view_has_bar()

bool prog_view_has_bar ( const prog_view_t * v,
const prog_list_t * l )

Whether the bar is drawn: SEARCH, or a list longer than the area.

◆ prog_view_render()

void prog_view_render ( const prog_view_t * v,
const prog_list_t * l,
const prog_reg_row_t * rows,
size_t n,
uint16_t caps,
const char * query,
gfx_canvas_t * c )

Draws the list in PROG_VIEW_FONT: query in the SEARCH box ("SEARCH" while empty), each row's name and prog_reg_detail(), a live row with ">" at its right end, a dimmed one in the dim colour with its reason in the warning colour.

Parameters
vthe view
lthe list
rowsthe registry's rows the list's entries index
ntheir count
capsthe IOmcu's capabilities, for each row's state
querythe search typed, NULL or "" for none
cthe canvas

◆ prog_view_search_rect()

gfx_rect_t prog_view_search_rect ( const prog_view_t * v,
const prog_list_t * l )

SEARCH on the bar, PROG_VIEW_SEARCH_W wide from the left.

Parameters
vthe view
lthe list it shows
Returns
its rectangle; empty when not drawn

◆ prog_view_shown()

int prog_view_shown ( const prog_view_t * v,
const prog_list_t * l )

The entries shown from the top, at least 1 for a list that has one.

◆ prog_view_top()

void prog_view_top ( prog_view_t * v)

The list was rebuilt (a search, another language): back to its top.

◆ prog_view_up_rect()

gfx_rect_t prog_view_up_rect ( const prog_view_t * v,
const prog_list_t * l )

"^" on the bar, PROG_VIEW_KEY_W wide, 8px left of "v".

Parameters
vthe view
lthe list it shows
Returns
its rectangle; empty when the list does not page