|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
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) |
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
| #define PICKER_NO_PIN 0xFFu |
No pin, for picker_screen_set_prog_pin().
| #define PICKER_USE_IFACE | ( | f | ) |
The group of an interface's lines, outputs_iface_t f.
| #define PICKER_USE_IFACE_PINS 5u |
Pins SETUP > INTERFACES can hold: SDA and SCL, TX and RX, the tap.
| #define PICKER_USE_IS_IFACE | ( | g | ) |
Whether group g is an interface's, and which.
| #define PICKER_USE_MAX |
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.
| #define PICKER_USE_PROG 0xFFu |
The group of the programming port's lines, in picker_use_t.proto.
| typedef void(*) picker_apply_fn(const outbind_t *b) |
Called after any change the operator makes, as on the outputs screen.
| 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.
| 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.
| enum picker_area_t |
| enum 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 |
| enum 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 |
| 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.
| ow | The outline's width, any unit. |
| oh | Its height, in the same unit. |
| w | The width drawn, px. |
| h | The height drawn, px. |
| const ui_screen_t * picker_screen | ( | void | ) |
The pin picker.
| gfx_rect_t picker_screen_area | ( | picker_area_t | area | ) |
Gives the rectangle of one of the screen's tables.
| area | the table |
| const outbind_t * picker_screen_binding | ( | void | ) |
The current choice, for anything that has to write it.
| 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.
| bool picker_screen_can_draw | ( | void | ) |
Whether this board can be drawn at all: it has a catalogue, and a drawing or a shape.
| 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.
| box | the box it covers, empty for none; may be NULL |
| pose | its index into ui_cat_poses[], UI_CAT_NONE for none; may be NULL |
| void picker_screen_count | ( | char * | buf, |
| size_t | cap ) |
The count under the protocol list: slots in use of 8, every protocol.
| bool picker_screen_editable | ( | void | ) |
Whether a tap on a button can change the binding.
| 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.
| bool picker_screen_has_drawing | ( | void | ) |
Whether the board is drawn from the IOmcu's drawing.
| bool picker_screen_in_use | ( | uint8_t | k, |
| picker_use_t * | out ) |
Line k of the IN USE table; false past the last.
| void picker_screen_invalidate | ( | void | ) |
Repaint the cached chrome in every framebuffer.
| gfx_rect_t picker_screen_list_face | ( | void | ) |
The protocol list: its face, and the row of proto when it is open.
| bool picker_screen_list_open | ( | void | ) |
Returns whether the protocol list is open.
| 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.
| proto | the protocol index, or OUTBIND_PROTOS + n for PROG PORT entry n |
| 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.
| 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_pin_t picker_screen_pin | ( | uint8_t | index, |
| char * | holder, | ||
| size_t | cap ) |
The state of catalogue entry index, as the screen draws it.
| index | the pin's catalogue entry |
| holder | NULL, 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 |
| cap | bytes at holder |
| int picker_screen_port_shown | ( | void | ) |
The port picked, 0 for port 1, or -1 for a protocol.
| uint8_t picker_screen_prog_listed | ( | void | ) |
The first GPIO IN USE lists under PROG PORT, or PICKER_NO_PIN.
| 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.
| bool picker_screen_row | ( | uint8_t | k, |
| picker_row_t * | out ) |
Line k of the PINS table, in catalogue order; false past the last.
| void picker_screen_set_apply | ( | picker_apply_fn | fn | ) |
Name the function a tick or untick applies the binding through.
| fn | the function, or NULL for none |
| 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.
| 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.
| void picker_screen_set_drawing_source | ( | picker_drawing_fn | fn | ) |
Name the function that asks for the drawing of a board.
| fn | the function, or NULL for none |
| 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.
| 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.
| void picker_screen_set_select | ( | picker_select_fn | fn | ) |
Name the function a pick in the list tells the Outputs screen by.
| fn | the function, or NULL for none |