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

The pin picker: the board itself, with a button on every pin an output may have. More...

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "gfx.h"
#include "link_pages.h"
#include "out_bind.h"
#include "outputs_screen.h"
#include "ui_screen.h"

Go to the source code of this file.

Data Structures

struct  picker_row_t
struct  picker_use_t

Macros

#define PICKER_NO_PIN   0xFFu
#define PICKER_USE_PROG   0xFFu
#define PICKER_USE_IFACE(f)
#define PICKER_USE_IS_IFACE(g)
#define PICKER_USE_IFACE_PINS   5u
#define PICKER_USE_MAX

Typedefs

typedef void(*) picker_select_fn(uint8_t proto)
typedef void(*) picker_apply_fn(const outbind_t *b)
typedef void(*) picker_drawing_fn(uint16_t board)

Enumerations

enum  picker_pin_t {
  PICKER_PIN_NONE = 0 , PICKER_PIN_FREE , PICKER_PIN_TICKED , PICKER_PIN_HELD ,
  PICKER_PIN_REFUSED , PICKER_PIN_LOCKED , PICKER_PIN_RESERVED
}
enum  picker_use_kind_t { PICKER_USE_NAME = 0 , PICKER_USE_PIN , PICKER_USE_MORE }
 The kinds of a line of the IN USE table. More...
enum  picker_area_t { PICKER_AREA_HEAD = 0 , PICKER_AREA_PINS , PICKER_AREA_IN_USE }

Functions

const ui_screen_t * picker_screen (void)
 The pin picker.
void picker_screen_invalidate (void)
const outbind_t * picker_screen_binding (void)
void picker_screen_set_binding (const outbind_t *b)
void picker_screen_follow (uint8_t proto, bool editable)
void picker_screen_set_select (picker_select_fn fn)
 Name the function a pick in the list tells the Outputs screen by.
void picker_screen_set_prog_pin (uint8_t gpio)
void picker_screen_set_prog_ports (uint8_t count, const uint8_t *pins)
void picker_screen_open_on_port (uint8_t port)
int picker_screen_port_shown (void)
uint8_t picker_screen_prog_listed (void)
picker_pin_t picker_screen_pin (uint8_t index, char *holder, size_t cap)
 The state of catalogue entry index, as the screen draws it.
bool picker_screen_button_rect (uint8_t index, gfx_rect_t *out)
bool picker_screen_marker_rect (uint8_t entry, gfx_rect_t *out)
bool picker_screen_row (uint8_t k, picker_row_t *out)
bool picker_screen_in_use (uint8_t k, picker_use_t *out)
void picker_screen_count (char *buf, size_t cap)
bool picker_screen_reason (char *buf, size_t cap)
gfx_rect_t picker_screen_area (picker_area_t area)
 Gives the rectangle of one of the screen's tables.
gfx_rect_t picker_screen_list_face (void)
gfx_rect_t picker_screen_list_row (uint8_t proto)
 Row proto: a protocol in the first column, PROG PORT entry proto - OUTBIND_PROTOS in the second, from the same top.
bool picker_screen_list_open (void)
 Returns whether the protocol list is open.
bool picker_screen_editable (void)
void picker_screen_set_apply (picker_apply_fn fn)
 Name the function a tick or untick applies the binding through.
bool picker_screen_set_drawing (const uint8_t *data, uint32_t bytes, const char **why)
void picker_screen_set_drawing_source (picker_drawing_fn fn)
 Name the function that asks for the drawing of a board.
void picker_board_fit (uint16_t ow, uint16_t oh, int *w, int *h)
 The size in pixels a board outline draws at.
bool picker_screen_cat (gfx_rect_t *box, int *pose)
 The cat the last frame drew (picker_cat.c): one pose, picked at random on a visit's first frame among the ones with a clear spot, bottom left or bottom right. It takes no touch.
bool picker_screen_has_drawing (void)
bool picker_screen_can_draw (void)

Detailed Description

The pin picker: the board itself, with a button on every pin an output may have.

The outputs screen lists pins in a grid, which answers "which GPIO (general-purpose input/output) is bound" and not "where do I put the lead". This screen answers the second one: a picture of the board with a straight trace from each pad to a button large enough to press.

The buttons are not the pads. At any size that fits a 1024 x 600 panel a pad is under 40 pixels across, which is smaller than a fingertip; so the pads are drawn where they are and the touching happens on staggered rows of buttons beside the board, each wired to its own pad.

Where the pads are comes from the board, not from this file: the shape page carries the outline, the pitch and the corner pad 1 sits at, and outbind_pad_xy() turns a pad number into a position on it; the board's drawing carries every pad's position itself. A board with neither is not drawn at all, because a picture from a guessed shape points at the wrong pad as confidently as the right one; its pins are still offered on the outputs screen.

The IOmcu's drawing of its board is optional in the same way. With one, the board on screen shows the parts of the board in the operator's hands, to scale; without one, its outline and pads are drawn from the shape. The drawing is checked against the catalogue before it is shown (board_drawing_agrees()), so the pads it draws are the pads the buttons bind.

The protocol a tap binds to is chosen here or on the outputs screen, with the same list; the two screens show one selection. Every visit opens with OFF selected, the overview: no key acts until a protocol is picked.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ PICKER_NO_PIN

#define PICKER_NO_PIN   0xFFu

◆ PICKER_USE_IFACE

#define PICKER_USE_IFACE ( f)
Value:
(0xF0u + (unsigned)(f))

The group of an interface's lines, outputs_iface_t f.

◆ PICKER_USE_IFACE_PINS

#define PICKER_USE_IFACE_PINS   5u

Pins SETUP > INTERFACES can hold: SDA and SCL, TX and RX, the tap.

◆ PICKER_USE_IS_IFACE

#define PICKER_USE_IS_IFACE ( g)
Value:
((g) > 0xF0u && (g) < 0xF0u + OUTPUTS_IFACE_COUNT)

Whether group g is an interface's, and which.

◆ PICKER_USE_MAX

#define PICKER_USE_MAX
Value:
(1u + LINK_PG_PORTS_MAX + (OUTPUTS_IFACE_COUNT - 1u) \
+ PICKER_USE_IFACE_PINS + (OUTBIND_PROTOS - 1u) + LINK_OUT_SLOTS)
#define OUTBIND_PROTOS
Entries in the protocol table, OFF included.
Definition out_bind.h:408
#define PICKER_USE_IFACE_PINS
Definition picker_screen.h:221

The most lines the table can list: the PROG PORT name and a pin for each port, a name and the pins for each interface, a name for each protocol but OFF, and a pin for each slot.

◆ PICKER_USE_PROG

#define PICKER_USE_PROG   0xFFu

The group of the programming port's lines, in picker_use_t.proto.

Typedef Documentation

◆ picker_apply_fn

typedef void(*) picker_apply_fn(const outbind_t *b)

Called after any change the operator makes, as on the outputs screen.

◆ picker_drawing_fn

typedef void(*) picker_drawing_fn(uint16_t board)

Asked on entering the screen, for the board the binding names.

The function calls picker_screen_set_drawing(), with NULL when there is no drawing for that board, so a drawing that arrived since the last visit is the one shown and one for a board that has been swapped is not.

◆ picker_select_fn

typedef void(*) picker_select_fn(uint8_t proto)

Called with the protocol picked in this screen's list, so the outputs screen selects the same one (outputs_screen_select()). A pick writes nothing; the apply function is not called for it. Entering this screen calls it with OFF (0), so every visit opens on the overview: OFF selected on both screens, and a tap on a key changes nothing until a protocol is picked.

Enumeration Type Documentation

◆ picker_area_t

The areas the screen draws text in, for tests and the renderer.

Enumerator
PICKER_AREA_HEAD 

the protocol list's face, the count, the reason

PICKER_AREA_PINS 

the PINS table, left of the board

PICKER_AREA_IN_USE 

the IN USE table, right of the board

◆ picker_pin_t

What a pin's button shows and does.

Enumerator
PICKER_PIN_NONE 

no such pin, or a board this screen cannot draw

PICKER_PIN_FREE 

ivory or ebony: a tap binds it

PICKER_PIN_TICKED 

accented: bound in the protocol selected; a tap frees it

PICKER_PIN_HELD 

grey: another protocol or the programming port has it, or the PWM generator cannot take it beside the port's slice or a bound pin's compare register (outbind_pwm_clash())

PICKER_PIN_REFUSED 

grey: free, and the protocol selected can take no more pins; the reason line says why

PICKER_PIN_LOCKED 

grey: the binding is not confirmed, or the board's pins are soldered

PICKER_PIN_RESERVED 

no button: the IOmcu's own, crossed red on the pad

◆ picker_use_kind_t

The kinds of a line of the IN USE table.

A line of the IN USE table, right of the board: the programming ports' pins first, under one PROG PORT name, then the pins SETUP > INTERFACES holds, each function's under its name (outputs_iface_name()), then each other protocol's pins under its name, groups in the order their first pin falls.

The rows are 20px for a name and 28px for a pin, with the GPIO in the 16 x 28 face: OFF selected, the port listed and 8 pins over 6 protocols take 392px of the 432 the table has under its heading. When that runs past the table's foot, as with 4 ports beside that binding (7 names and 12 pins), every pin row is 20px with the GPIO in the label face, and 16px in 8 x 16 where 20px still runs past it. Where 16px pin rows still run past it, the names are 16px too: 4 ports, 6 protocols and every interface on take 27 lines, the whole 432px. Where even that runs past it the table holds the lines that fit and ends in a PICKER_USE_MORE line, "+N", N the lines left out.

Enumerator
PICKER_USE_NAME 

a protocol's name, PROG PORT or a function of SETUP > INTERFACES

PICKER_USE_PIN 

a pin of the group named above it

PICKER_USE_MORE 

"+N": gpio holds N, the lines left out

Function Documentation

◆ picker_board_fit()

void picker_board_fit ( uint16_t ow,
uint16_t oh,
int * w,
int * h )

The size in pixels a board outline draws at.

600 wide and the height its aspect gives, or, when that is taller than 240, 240 high and the width its aspect gives. A zero side gives 600 x 240.

Parameters
owThe outline's width, any unit.
ohIts height, in the same unit.
wThe width drawn, px.
hThe height drawn, px.

◆ picker_screen()

const ui_screen_t * picker_screen ( void )

The pin picker.

Returns
its hooks

◆ picker_screen_area()

gfx_rect_t picker_screen_area ( picker_area_t area)

Gives the rectangle of one of the screen's tables.

Parameters
areathe table
Returns
its rectangle

◆ picker_screen_binding()

const outbind_t * picker_screen_binding ( void )

The current choice, for anything that has to write it.

◆ picker_screen_button_rect()

bool picker_screen_button_rect ( uint8_t index,
gfx_rect_t * out )

The rectangle of the button of catalogue entry index; false for a pin with none.

◆ picker_screen_can_draw()

bool picker_screen_can_draw ( void )

Whether this board can be drawn at all: it has a catalogue, and a drawing or a shape.

◆ picker_screen_cat()

bool picker_screen_cat ( gfx_rect_t * box,
int * pose )

The cat the last frame drew (picker_cat.c): one pose, picked at random on a visit's first frame among the ones with a clear spot, bottom left or bottom right. It takes no touch.

Parameters
boxthe box it covers, empty for none; may be NULL
poseits index into ui_cat_poses[], UI_CAT_NONE for none; may be NULL
Returns
true when a cat is drawn

◆ picker_screen_count()

void picker_screen_count ( char * buf,
size_t cap )

The count under the protocol list: slots in use of 8, every protocol.

◆ picker_screen_editable()

bool picker_screen_editable ( void )

Whether a tap on a button can change the binding.

◆ picker_screen_follow()

void picker_screen_follow ( uint8_t proto,
bool editable )

Follow the outputs screen: the protocol selected there is the group a tap here joins, and a binding that is not confirmed there (outputs_screen_editable() false) is not edited here either. Called every frame; it repaints only on a change.

While editable is false every button is drawn as not offered, NOT READ stands under the protocol list, and a tap changes nothing and calls nothing.

◆ picker_screen_has_drawing()

bool picker_screen_has_drawing ( void )

Whether the board is drawn from the IOmcu's drawing.

◆ picker_screen_in_use()

bool picker_screen_in_use ( uint8_t k,
picker_use_t * out )

Line k of the IN USE table; false past the last.

◆ picker_screen_invalidate()

void picker_screen_invalidate ( void )

Repaint the cached chrome in every framebuffer.

◆ picker_screen_list_face()

gfx_rect_t picker_screen_list_face ( void )

The protocol list: its face, and the row of proto when it is open.

◆ picker_screen_list_open()

bool picker_screen_list_open ( void )

Returns whether the protocol list is open.

Returns
true when open

◆ picker_screen_list_row()

gfx_rect_t picker_screen_list_row ( uint8_t proto)

Row proto: a protocol in the first column, PROG PORT entry proto - OUTBIND_PROTOS in the second, from the same top.

Parameters
protothe protocol index, or OUTBIND_PROTOS + n for PROG PORT entry n
Returns
the row's rectangle

◆ picker_screen_marker_rect()

bool picker_screen_marker_rect ( uint8_t entry,
gfx_rect_t * out )

The round marker of entry entry of the board's pad list (outbind_pads()), with its dark ring: a G for a ground, the voltage for a rail. False for a pad with no marker.

◆ picker_screen_open_on_port()

void picker_screen_open_on_port ( uint8_t port)

The next entry to this screen opens on PROG PORT port (0 for port 1), as the OUTPUTS entry's PIN button asks, instead of on OFF; once.

With a port picked, in this list or on OUTPUTS, a button is the port's pin: its own pin is ticked and a tap on it asks the IOmcu for no pin, a tap on a free pin asks for that pin (port_view_ask()). A SERVO PWM port is refused the slice of a bound PWM output and the compare register of another SERVO PWM port; a NONE port takes any free pin. The pins are the IOmcu's to take: the ask waits for a bench at rest, and the line under the count says how it stands.

◆ picker_screen_pin()

picker_pin_t picker_screen_pin ( uint8_t index,
char * holder,
size_t cap )

The state of catalogue entry index, as the screen draws it.

Parameters
indexthe pin's catalogue entry
holderNULL, or takes what holds the pin: the protocol's name, PROG PORT, or the pin a PWM pin clashes with (outputs_clash_label(): "SLICE OF GPIO 13", "PWM CH OF GPIO 0") for PICKER_PIN_HELD, the reserving function for PICKER_PIN_RESERVED, and an empty string otherwise
capbytes at holder
Returns
the pin's state

◆ picker_screen_port_shown()

int picker_screen_port_shown ( void )

The port picked, 0 for port 1, or -1 for a protocol.

◆ picker_screen_prog_listed()

uint8_t picker_screen_prog_listed ( void )

The first GPIO IN USE lists under PROG PORT, or PICKER_NO_PIN.

◆ picker_screen_reason()

bool picker_screen_reason ( char * buf,
size_t cap )

The amber line under the count: NOT READ while the binding is not confirmed, else the reason the protocol selected can take no more pins (outputs_reason_of()), else why the PWM generator cannot take the pin last tapped (outputs_clash_reason()), until another pick or tick. False and an empty string when there is none.

◆ picker_screen_row()

bool picker_screen_row ( uint8_t k,
picker_row_t * out )

Line k of the PINS table, in catalogue order; false past the last.

◆ picker_screen_set_apply()

void picker_screen_set_apply ( picker_apply_fn fn)

Name the function a tick or untick applies the binding through.

Parameters
fnthe function, or NULL for none

◆ picker_screen_set_binding()

void picker_screen_set_binding ( const outbind_t * b)

Set the choice: this screen and the outputs screen are two views of one. A binding that names another board asks the drawing source (picker_screen_set_drawing_source()) for that board's drawing.

◆ picker_screen_set_drawing()

bool picker_screen_set_drawing ( const uint8_t * data,
uint32_t bytes,
const char ** why )

The IOmcu's drawing of the board the binding names (LINK_ART_DRAWING bytes, link_drawing.h), or NULL to draw its outline instead.

Parsed and checked against the board's catalogue, pads and shape here; a drawing that fails either is not shown, and why (may be NULL) names the first thing found. The bytes are not copied and must stay unchanged until the next call. Returns whether the drawing is shown.

◆ picker_screen_set_drawing_source()

void picker_screen_set_drawing_source ( picker_drawing_fn fn)

Name the function that asks for the drawing of a board.

Parameters
fnthe function, or NULL for none

◆ picker_screen_set_prog_pin()

void picker_screen_set_prog_pin ( uint8_t gpio)

The GPIO the IOmcu's programming port is bound to, as its page reads it, or PICKER_NO_PIN (the start value): picker_screen_set_prog_ports() with that one port. While no protocol holds that pin its button is drawn held, a tap on it does nothing, and IN USE lists it first under PROG PORT. A pin a slot holds is that slot's: the IOmcu gives the port no pin then. It stays across a reset of the screen.

◆ picker_screen_set_prog_ports()

void picker_screen_set_prog_ports ( uint8_t count,
const uint8_t * pins )

Every programming port's pin: count of them (at most LINK_PG_PORTS_MAX are kept) from pins, PICKER_NO_PIN for a port without one; NULL or 0 for none. Each pin is held as picker_screen_set_prog_pin() holds one, IN USE lists them all under the one PROG PORT name, and a PWM pin is refused beside any of them (outbind_pwm_clash_ports()). It stays across a reset of the screen.

◆ picker_screen_set_select()

void picker_screen_set_select ( picker_select_fn fn)

Name the function a pick in the list tells the Outputs screen by.

Parameters
fnthe function, or NULL for none