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

The RECEIVER screen (analyser_*: the code's name for it). More...

#include "analyser_screen.h"
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "ui_tabs.h"
#include "ui_text.h"
#include "ui_theme.h"
#include "ui_widgets.h"

Data Structures

struct  [struct].s
 Driver state of the UART: the claimed machines and the pins. More...

Macros

#define W   UI_PANEL_W
#define H   UI_BODY_H
#define PAD   UI_MARGIN
#define TAB_X   (PAD + 3)
 The pane tabs, CHANNELS | RAW DATA: two tabs of 150 x 48px, 4px apart, from x 11 and y 8, a finger tall.
#define TAB_Y   8
#define TAB_H   UI_TAP_MIN
#define TAB_W   150
#define TAB_ROW_W   (2 * TAB_W + 4)
#define LCARD_Y   64
#define TEXT_FLOOR   (UI_ALERT_Y - UI_BAND_H - 4)
 The lowest row a line of text or a lane may reach: 4px above the alert band, body y 492.
#define RCARD_W   260
 The state card's width, px: the word KEIN SIGNAL in the 20 x 36 face is 220px, inside the card's 12px margins. The rest of the width goes to the traces.
#define RCARD_X   (W - PAD - RCARD_W)
#define LCARD_W   (RCARD_X - 8 - PAD)
#define LCARD_H   (H - PAD - LCARD_Y)
#define AN_FONT_LABEL   (&gfx_font_10x20)
 The faces of the 1024 x 600 type scale this screen draws in: AN_FONT_LABEL (10 x 20) for the channel names, rows and labels, AN_FONT_FINE (8 x 16) for the channel values and RAW DATA's bytes and counts, AN_FONT_BODY (12 x 24) for the state's line and AN_FONT_HEAD (20 x 36) for the state word.
#define AN_FONT_FINE   UI_FONT_FINE
#define AN_FONT_BODY   UI_FONT_BODY
#define AN_FONT_HEAD   (&gfx_font_20x36)
#define HIST   200
 Samples a lane keeps: one pixel a sample, about 2.8s of S.BUS frames 14ms apart.
#define PITCH   1
#define COLS   2
#define ROWS   8
#define COL_W   ((LCARD_W - 16) / COLS)
#define LANE_H   52
#define LANE_TOP   (LCARD_Y + 8)
#define LAB_W   48
#define TRACE_W   (HIST * PITCH)
#define BAR_GAP   8
#define BAR_W   56
#define VAL_GAP   6
#define VAL_W   32
#define LANE_W   (LAB_W + TRACE_W + BAR_GAP + BAR_W + VAL_GAP + VAL_W)
 A lane's width from its column's left edge: 350px.
#define BADGE_Y   20
#define BADGE_H   64
#define WHY_Y   (BADGE_Y + BADGE_H + 8)
#define WHY_PITCH   26
#define WHY_LINES   3
#define RULE1_Y   (WHY_Y + WHY_LINES * WHY_PITCH + 4)
#define ROW_Y0   (RULE1_Y + 8)
#define ROW_H   32
#define RULE2_Y   (ROW_Y0 + 5 * ROW_H + 4)
#define DIG_Y   (RULE2_Y + 10)
#define CHN_Y   (DIG_Y + 28)
#define CHN_H   44
#define CHN_GAP   8
#define CHN_INSET   40
#define RAW_Y   (LCARD_Y + 48)
 RAW DATA's bytes: the first row's top, px.
#define RAW_PITCH_X   32
#define RAW_PITCH_Y   24

Functions

void analyser_invalidate (void)
static void reset (void)
 The screen's state cleared: CHANNELS shown, nothing decoded, the tabs laid out.
void analyser_screen_push (const sbus_frame_t *frame, const sbus_decoder_t *dec, const uint8_t *raw, unsigned raw_len, uint32_t now_ms)
 A decoded frame, with the decoder's own counters and the bytes it came from – the raw view is not a separate capture, it is this same frame.
void analyser_screen_silent (uint32_t now_ms)
 No frame has arrived for long enough that the link is presumed dead.
static void event (const touch_event_t *evt)
 One touch event: the tabs are the screen's one control.
static gfx_color_t live (void)
 The traces' colour: danger in failsafe, the accent otherwise.
static void draw_lane (gfx_canvas_t *c, int ch)
 One channel's lane: its name, its trace, and its current value.
static void draw_channels (gfx_canvas_t *c)
 CHANNELS: the sixteen lanes.
static void draw_raw (gfx_canvas_t *c)
 RAW DATA: the last frame's bytes, eight to a row, the header and footer in the accent colour, then the byte count and the decoder's counters.
static size_t line_len (const char *at, int cells)
 The bytes of the next line of at that fit cells: up to the last space in it, or the whole width where no space falls after its start.
static int why_wrap (gfx_canvas_t *c, const char *why, gfx_color_t ink)
 The state's line in the 12 x 24 face, broken after a space into lines as wide as the state card's inner column, each centred, at most WHY_LINES of them.
int analyser_screen_why_lines (const char *why)
 The lines a state's line takes on the state card, in the 12 x 24 face broken after a space; the card shows three.
static void draw_state (gfx_canvas_t *c)
 The state block, sized to be the first thing read: the word in its box and its line under it.
static void stat_row (gfx_canvas_t *c, int i, const char *label, const char *value)
 One counter row of the state card: its label at the left, its value at the right, in a row ROW_H tall.
static void draw_right (gfx_canvas_t *c)
 The state card: the state, the bus and its counters, and the two digital channels, lit while set.
static void render (gfx_canvas_t *c, int buffer_index)
 The screen drawn on a revision not yet drawn: both cards once per framebuffer, then the tabs, the pane shown and the state card.
static void cancel (void)
 The panel could not hand over every touch event, so this screen's record of the glass is stale.
const ui_screen_t * analyser_screen (void)
 The RECEIVER screen.

Variables

static const ui_text_id_t k_tab_labels []
 The pane tabs' labels, CHANNELS and RAW DATA.
static struct  s
static const ui_screen_t k_screen
 The screen, as the router takes it.

Detailed Description

The RECEIVER screen (analyser_*: the code's name for it).

A receiver in failsafe sends sixteen well-formed channel values, so the state block (NO SIGNAL, FAILSAFE, FRAME LOST, LIVE) is the largest element on the screen and the channels are small.

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ AN_FONT_BODY

#define AN_FONT_BODY   UI_FONT_BODY

12 x 24.

◆ AN_FONT_FINE

#define AN_FONT_FINE   UI_FONT_FINE

8 x 16.

◆ AN_FONT_HEAD

#define AN_FONT_HEAD   (&gfx_font_20x36)

20 x 36.

◆ BADGE_H

#define BADGE_H   64

Its height, px.

◆ BADGE_Y

#define BADGE_Y   20

The state box's top, px.

◆ BAR_GAP

#define BAR_GAP   8

Between the trace and the bar.

◆ BAR_W

#define BAR_W   56

The bar, px.

◆ CHN_GAP

#define CHN_GAP   8

Between them, px.

◆ CHN_H

#define CHN_H   44

CH17 and CH18, px.

◆ CHN_INSET

#define CHN_INSET   40

A lamp's label from its left, px.

◆ CHN_Y

#define CHN_Y   (DIG_Y + 28)

CH17's top: y 384.

◆ COL_W

#define COL_W   ((LCARD_W - 16) / COLS)

A column's pitch: 362px.

◆ COLS

#define COLS   2

Lane columns.

◆ DIG_Y

#define DIG_Y   (RULE2_Y + 10)

DIGITAL's line: y 356.

◆ H

#define H   UI_BODY_H

The body's height under the band, px.

◆ LAB_W

#define LAB_W   48

The channel's name, CH01 at 10 x 20, and a gap.

◆ LANE_H

#define LANE_H   52

A lane's height, px.

◆ LANE_TOP

#define LANE_TOP   (LCARD_Y + 8)

The first lane's top: y 72.

◆ LCARD_H

#define LCARD_H   (H - PAD - LCARD_Y)

468px, to y 532.

◆ LCARD_W

#define LCARD_W   (RCARD_X - 8 - PAD)

740px.

◆ LCARD_Y

#define LCARD_Y   64

The left card's top, px.

◆ PAD

#define PAD   UI_MARGIN

The screen's outer margin, px.

◆ PITCH

#define PITCH   1

Pixels a sample.

◆ RAW_PITCH_X

#define RAW_PITCH_X   32

A byte's column, 4 cells of 8 x 16, px.

◆ RAW_PITCH_Y

#define RAW_PITCH_Y   24

A row of eight bytes, px.

◆ RCARD_X

#define RCARD_X   (W - PAD - RCARD_W)

x 756.

◆ ROW_H

#define ROW_H   32

A counter row, px.

◆ ROW_Y0

#define ROW_Y0   (RULE1_Y + 8)

The first counter row: y 182.

◆ ROWS

#define ROWS   8

Lanes a column.

◆ RULE1_Y

#define RULE1_Y   (WHY_Y + WHY_LINES * WHY_PITCH + 4)

y 174.

◆ RULE2_Y

#define RULE2_Y   (ROW_Y0 + 5 * ROW_H + 4)

y 346.

◆ TAB_H

#define TAB_H   UI_TAP_MIN

A tab's height: 48px.

◆ TAB_ROW_W

#define TAB_ROW_W   (2 * TAB_W + 4)

The row: 304px.

◆ TAB_W

#define TAB_W   150

A tab's width, px.

◆ TAB_Y

#define TAB_Y   8

The tabs' top, px.

◆ TRACE_W

#define TRACE_W   (HIST * PITCH)

The trace: 200px.

◆ VAL_GAP

#define VAL_GAP   6

Between the bar and the value.

◆ VAL_W

#define VAL_W   32

The value: 4 cells of 8 x 16.

◆ W

#define W   UI_PANEL_W

The panel's width, px.

◆ WHY_LINES

#define WHY_LINES   3

The most lines it takes.

◆ WHY_PITCH

#define WHY_PITCH   26

A wrapped line under the last.

◆ WHY_Y

#define WHY_Y   (BADGE_Y + BADGE_H + 8)

The state's line: y 92.

Function Documentation

◆ analyser_invalidate()

void analyser_invalidate ( void )

Drop the cached chrome, so the next frame repaints it.

◆ analyser_screen()

const ui_screen_t * analyser_screen ( void )

The RECEIVER screen.

Returns
The screen.

◆ analyser_screen_push()

void analyser_screen_push ( const sbus_frame_t * frame,
const sbus_decoder_t * dec,
const uint8_t * raw,
unsigned raw_len,
uint32_t now_ms )

A decoded frame, with the decoder's own counters and the bytes it came from – the raw view is not a separate capture, it is this same frame.

Parameters
frameThe frame; NULL does nothing.
decThe decoder after it; NULL does nothing.
rawIts bytes, or NULL to keep the last.
raw_lenTheir count; at most SBUS_FRAME_BYTES are kept.
now_msIts arrival, ms.

◆ analyser_screen_silent()

void analyser_screen_silent ( uint32_t now_ms)

No frame has arrived for long enough that the link is presumed dead.

Parameters
now_msThe time, ms.

◆ analyser_screen_why_lines()

int analyser_screen_why_lines ( const char * why)

The lines a state's line takes on the state card, in the 12 x 24 face broken after a space; the card shows three.

Parameters
whyThe line, as the screen shows it.
Returns
The lines, 0 for NULL or an empty line.

◆ cancel()

void cancel ( void )
static

The panel could not hand over every touch event, so this screen's record of the glass is stale.

The tab row is the one control here that holds state between a press and its release: a press it kept would own a track id the controller reuses, and a later contact that began elsewhere and lifts over the tab would switch the pane on a tap nobody made.

◆ draw_channels()

void draw_channels ( gfx_canvas_t * c)
static

CHANNELS: the sixteen lanes.

Parameters
cThe canvas.

◆ draw_lane()

void draw_lane ( gfx_canvas_t * c,
int ch )
static

One channel's lane: its name, its trace, and its current value.

Parameters
cThe canvas.
chThe channel, 0 to 15: columns of eight, top down.

◆ draw_raw()

void draw_raw ( gfx_canvas_t * c)
static

RAW DATA: the last frame's bytes, eight to a row, the header and footer in the accent colour, then the byte count and the decoder's counters.

Parameters
cThe canvas.

◆ draw_right()

void draw_right ( gfx_canvas_t * c)
static

The state card: the state, the bus and its counters, and the two digital channels, lit while set.

Parameters
cThe canvas.

◆ draw_state()

void draw_state ( gfx_canvas_t * c)
static

The state block, sized to be the first thing read: the word in its box and its line under it.

Parameters
cThe canvas.

◆ event()

void event ( const touch_event_t * evt)
static

One touch event: the tabs are the screen's one control.

Parameters
evtThe event.

◆ line_len()

size_t line_len ( const char * at,
int cells )
static

The bytes of the next line of at that fit cells: up to the last space in it, or the whole width where no space falls after its start.

Parameters
atThe text from the line's start.
cellsThe line's width, in cells.
Returns
The line's length, in bytes.

◆ live()

gfx_color_t live ( void )
static

The traces' colour: danger in failsafe, the accent otherwise.

Returns
The colour.

◆ render()

void render ( gfx_canvas_t * c,
int buffer_index )
static

The screen drawn on a revision not yet drawn: both cards once per framebuffer, then the tabs, the pane shown and the state card.

Parameters
cThe canvas.
buffer_indexThe framebuffer, whose revision it follows.

◆ stat_row()

void stat_row ( gfx_canvas_t * c,
int i,
const char * label,
const char * value )
static

One counter row of the state card: its label at the left, its value at the right, in a row ROW_H tall.

Parameters
cThe canvas.
iThe row, 0 for the first.
labelThe label.
valueThe value.

◆ why_wrap()

int why_wrap ( gfx_canvas_t * c,
const char * why,
gfx_color_t ink )
static

The state's line in the 12 x 24 face, broken after a space into lines as wide as the state card's inner column, each centred, at most WHY_LINES of them.

Parameters
cThe canvas, or NULL to count the lines only.
whyThe line.
inkIts colour.
Returns
The lines why takes, drawn or not; past WHY_LINES none is drawn.

Variable Documentation

◆ k_screen

const ui_screen_t k_screen
static
Initial value:
= {
.title = "RECEIVER",
.reset = reset,
.enter = NULL,
.leave = NULL,
.tick = NULL,
.event = event,
.cancel = cancel,
.render = render,
}
static void event(const touch_event_t *evt)
One touch event: the tabs are the screen's one control.
Definition analyser_screen.c:242
static void cancel(void)
The panel could not hand over every touch event, so this screen's record of the glass is stale.
Definition analyser_screen.c:658
static void reset(void)
The screen's state cleared: CHANNELS shown, nothing decoded, the tabs laid out.
Definition analyser_screen.c:176
static void render(gfx_canvas_t *c, int buffer_index)
The screen drawn on a revision not yet drawn: both cards once per framebuffer, then the tabs,...
Definition analyser_screen.c:618

The screen, as the router takes it.

◆ k_tab_labels

const ui_text_id_t k_tab_labels[]
static
Initial value:
= { TX_AN_TAB_CHANNELS,
TX_AN_TAB_RAW }

The pane tabs' labels, CHANNELS and RAW DATA.

◆ s

struct [struct].s s

The screen's state.