rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
servo_screen_int.h
Go to the documentation of this file.
1
22#pragma once
23
24#include <stdbool.h>
25#include <stddef.h>
26#include <stdint.h>
27
28#include "gfx.h"
29#include "kst_panel.h"
30#include "servo_limrun.h"
31#include "servo_screen.h"
32#include "servo_sweep.h"
33#include "settings.h"
34#include "supply_screen.h"
35#include "touch_types.h"
36#include "ui_keypad.h"
37#include "ui_plot.h"
38#include "ui_slider.h"
39#include "ui_tabs.h"
40#include "ui_textkey.h"
41#include "ui_target_row.h"
42#include "ui_value_gate.h"
43#include "ui_widgets.h"
44#include "ui_workbench.h"
45
46#define W UI_PANEL_W
47#define H UI_BODY_H
48
49#define PAD UI_MARGIN
55#define LCARD_W 620
56#define RCARD_X (PAD + LCARD_W + 8)
57#define RCARD_W (W - RCARD_X - PAD)
67#define SV_STRIP_X UI_WB_STRIP_X
68#define SV_STRIP_Y (UI_WB_STRIP_Y + 2)
69#define SV_STRIP_H (UI_WB_STRIP_H + 16)
70#define SV_TAB_W (UI_WB_TAB_W + 38)
71#define SV_TAB_GAP UI_WB_TAB_GAP
72#define SV_PAGE_Y (UI_WB_PAGE_Y + 18)
74#define CARD_Y SV_PAGE_Y
75#define CARD_H (H - CARD_Y - PAD)
81#define RCARD_Y PAD
82#define RCARD_H (H - 2 * PAD)
87#define STOP_FLOOR (UI_ALERT_Y - UI_BAND_H - 4)
88
98#define SV_FONT_LABEL (&gfx_font_10x20)
99#define SV_FONT_BODY UI_FONT_BODY
100#define SV_FONT_HEAD (&gfx_font_20x36)
101#define SV_FONT_NUM (&gfx_font_num_32x44)
102#define SV_CELL 10
103
104/*
105 * The output card, top to bottom: the type and frame rate in force, the
106 * servo rail's live power and its plot, the supply's set points and output
107 * switch, SPEED, the TARGET row, CENTRE / SWEEP / RELEASE and ARM. Every
108 * row tapped is UI_TAP_MIN or taller; ARM ends above the alert band.
109 */
110#define RC_X (RCARD_X + 12)
111#define RC_W (RCARD_W - 24)
112#define TAG_Y (RCARD_Y + 12)
113#define TAG_H 44
115#define PWR_TXT_Y (TAG_Y + TAG_H + 8)
120#define PWR_LAB_W 90
121#define PWR_LAB_W_INA 134
122#define PWR_Y (PWR_TXT_Y + 24)
123#define PWR_H 70
131#define SUP_Y (PWR_Y + PWR_H + 8)
132#define SUP_H UI_TAP_MIN
133#define SUP_VAL_X (RC_X + 48)
134#define SUP_VAL_W 84
135#define SUP_GAP 8
137#define SUP_OUT_X (SUP_VAL_X + 2 * (SUP_VAL_W + SUP_GAP))
138#define SPEED_Y (SUP_Y + SUP_H + 10)
139#define SLIDER_Y (SPEED_Y + 24)
140#define SLIDER_H 40
146#define TARGET_Y (SLIDER_Y + SLIDER_H + UI_SLIDER_OVERHANG + 7)
147#define TARGET_H UI_TAP_MIN
148#define BTN_Y (TARGET_Y + TARGET_H + 10)
149#define BTN_H UI_TAP_MIN
150#define BTN_GAP 8
151#define ARM_Y (BTN_Y + BTN_H + 10)
152#define ARM_H 60
153_Static_assert(SV_STRIP_X + 4 * SV_TAB_W + 3 * SV_TAB_GAP + 3 <= RCARD_X,
154 "SERVO's strip ends left of the output card");
155_Static_assert(SV_STRIP_Y + SV_STRIP_H + 3 <= SV_PAGE_Y,
156 "SERVO's strip ends above its page");
157_Static_assert(ARM_Y + ARM_H <= STOP_FLOOR,
158 "DISARM ends above the alert band");
159_Static_assert(SUP_Y + SUP_H <= STOP_FLOOR,
160 "OUTPUT OFF ends above the alert band");
161_Static_assert(ARM_Y + ARM_H <= RCARD_Y + RCARD_H,
162 "ARM ends inside the output card");
163
164/*
165 * LIVE's card: the horn's angle in the bench's numerals top left, ARM
166 * FIRST under it, the dial in the middle and, along the bottom, the three
167 * readings in SV_FONT_NUM, a third of the card each.
168 */
169#define READ_W ((LCARD_W - 24) / 3)
171#define READ_X(k) (PAD + 12 + (k) * READ_W)
172#define READ_NUM_H 44
173#define READ_NUM_Y (H - PAD - 12 - READ_NUM_H)
174#define READ_LBL_Y (READ_NUM_Y - 26)
175#define SEG_X (PAD + 16)
176#define SEG_Y (CARD_Y + 14)
177#define ARM_NOTE_Y (CARD_Y + 58)
178
181#define STD_SERVO_V_MAX 6.0f
182_Static_assert(KST_PANEL_STD_MV == 6000,
183 "the programmer's standard-servo ceiling is STD_SERVO_V_MAX");
184
185/*
186 * The panels: the keypad, keyboard, list, warnings, question and the servo
187 * programmer cover the whole left column, the strip's tabs with it, so a
188 * panel is answered before the task changes. The output card -- ARM,
189 * CENTRE, RELEASE and the readings -- stays where it is and works.
190 */
191#define OV_X PAD
192#define OV_Y PAD
193#define OV_W LCARD_W
194#define OV_H (H - 2 * PAD)
195/*
196 * The pages of rows, in the page area under the strip. SETTINGS' pages
197 * under their own tabs (OUTPUT, SWEEP, DUT): two columns, each row its
198 * label on the left and its value on the right. A run's settings, one
199 * level down from its card on TEST, under the run's name: three columns,
200 * each row its label over its value, so the automatic test's 15 rows fit
201 * in 5 rows of UI_TAP_MIN.
202 */
203#define OV_TAB_Y (CARD_Y + 8)
204#define OV_TAB_H 40
205#define OV_TAB_W (OV_W - 20)
206#define OV_ROW0 (CARD_Y + 52)
207#define OV_PITCH 52
208#define OV_ROW_H UI_TAP_MIN
209#define OV_COL_W ((OV_W - 30) / 2)
210#define OV_VAL_W 140
212#define OV_NOTE_Y (OV_ROW0 + 4 * OV_PITCH + OV_ROW_H + 2)
213#define NOTE_PITCH 21
214#define RL_ROW0 (CARD_Y + 56)
215#define RL_PITCH 71
216#define RL_LBL_H 21
217#define RL_COL_W ((OV_W - 40) / 3)
218#define RL_ROWS 5
221#define RL_NOTE_Y (RL_ROW0 + RL_ROWS * RL_PITCH + 2)
224#define OV_SAVE_Y (STOP_FLOOR - 20)
225_Static_assert(OV_NOTE_Y + 4 * NOTE_PITCH + 20 <= OV_SAVE_Y,
226 "the OUTPUT page's five note lines end above the save line");
227_Static_assert(RL_NOTE_Y + 20 <= STOP_FLOOR,
228 "a run's note ends above the alert band");
229
230/*
231 * A pulse needs a pause before the next frame. STANDARD PWM, WIDE and
232 * NARROW 760 keep one of at least 1ms -- a 100% margin on the 1ms a
233 * standard servo's own decoder needs -- so their fastest frame rate is
234 * 1 / (longest pulse + 1ms): 333Hz for 2000us. The heli profiles run
235 * at their published rates, which leave less, so theirs is set by the
236 * profile and a pause of at least 0.5ms.
237 */
238#define PWM_MIN_PAUSE_US 1000u
239#define HELI_MIN_PAUSE_US 500u
240/* Above this a frame rate needs the warning: an analogue servo overheats. */
241#define SAFE_RATE_HZ 60u
242
243/* A profile the bench drives; k_types in servo_screen.c holds them. */
244typedef struct {
245 const char *name;
246 uint16_t min_us, centre_us, max_us;
247 const uint16_t *rates; /* the frame rates offered, Hz */
248 uint8_t rate_count;
249 uint16_t default_hz;
250 uint16_t max_hz; /* the profile's ceiling; 0 is the pause */
251 bool heli; /* choosing it needs the warning */
253
254/* The profiles, in servo_screen.c. */
255#define TYPE_COUNT 5
256extern const servo_type_t k_types[TYPE_COUNT];
257
258/* SETTINGS' pages, under its own tabs, and the two runs' settings, each
259 * opened from its card's SETTINGS on TEST. */
260enum { PG_OUTPUT = 0, PG_SWEEP, PG_DUT, PG_COUNT,
261 PG_AUTO = PG_COUNT, PG_LIMRUN };
262
263/* Which run's settings TEST shows, one level down from its card. */
264enum { RL_NONE = 0, RL_AUTO, RL_LIMIT };
265
266/* What a settings row edits. */
267enum { R_TYPE = 0, R_RATE, R_MIN, R_CENTRE, R_MAX, R_TRIM, R_TRAVEL,
268 R_REVERSE, R_SETTING, R_TEXT, R_HV, R_ENC_CENTRE, R_LIM_MODE,
269 R_LIM_PULSES };
270
271typedef struct {
272 uint8_t page;
273 uint8_t kind;
274 setting_id_t id; /* R_SETTING */
275 ui_text_id_t label;
276 uint8_t col, row;
277 bool wide; /* the value takes both columns' width */
278} ov_row_t;
279
280/* What a press is on, in the pages and the panels they open. */
281enum { OP_NONE = 0, OP_TAB, OP_ROW, OP_TRIM_DN, OP_TRIM_UP, OP_KEYPAD,
282 OP_TEXT, OP_CHOICE, OP_CHOICE_CANCEL, OP_WARN_APPLY, OP_WARN_CANCEL,
283 OP_SUP_V, OP_SUP_I, OP_ASK_APPLY, OP_ASK_CANCEL, OP_TEST_START,
284 OP_LIM_START, OP_RUN_SET, OP_RUN_CLOSE };
285
286/* What the list chooses, and what the keypad types. */
287enum { CH_NONE = 0, CH_TYPE, CH_RATE, CH_ENUM };
288enum { KT_NONE = 0, KT_MIN, KT_CENTRE, KT_MAX, KT_TRAVEL, KT_RATE,
289 KT_SETTING, KT_SUP_V, KT_SUP_I, KT_TRIM };
290
291/* What the question or the HV warning applies: a typed set point, the
292 * supply's output switched on, or the automatic test started with steps
293 * above 6.0V. */
294enum { ASK_SET = 0, ASK_ON, ASK_TEST };
295
296#define CHOICE_MAX 10
297
298/* What a command means as a pulse and an angle: the profile's pulses, trim,
299 * reverse and travel, as they were when a command was sent. */
300typedef struct {
301 uint16_t min_us, centre_us, max_us;
302 int16_t trim_us;
303 bool reverse;
304 float travel_deg;
306
307/* A curve the far end runs and this screen no longer does; see s.dr. */
308typedef struct {
309 bool on;
310 sweep_t sw;
311 uint32_t from_ms;
312 int speed_pct;
313 servo_map_t map;
314 float out;
316
317/* The newest start or resume sent, as sent; see s.start_rec. */
318typedef struct {
319 bool live;
320 uint16_t seq;
321 sweep_cfg_t cfg;
322 int speed_pct;
324
336#define SV_DRAG_TAU_MS 20.0f
337
340#define SV_DRAG_SNAP_DEG 0.01f
341
350typedef struct {
351 bool on;
352 bool posting;
354 float goal;
355 float out;
357
358/* The screen's state, the pages' with it. */
359typedef struct {
360 /* The profile in force, for this session only: STANDARD PWM at 50Hz
361 * at every restart. */
362 int type;
363 uint16_t min_us, centre_us, max_us;
364 uint16_t frame_hz;
365 bool reverse;
366 int16_t trim_us;
369
370 float commanded_deg;
371 float shown_deg;
372 float shown_cmd;
373 float measured_deg;
374 bool have_feedback;
375 /* The output encoder's last reading (servo_screen_encoder()). */
376 bool enc_valid;
378 uint16_t enc_raw;
380
381 bool dragging;
382 int drag_id;
383
385 bool driving;
386 float pulse;
387 int drawn_pulse[2];
388
389 servo_cmd_t pending;
390 /* The knob's position command waiting in `pending`: valid while
391 * post_count is still knob_post, with what to put back if it is
392 * withdrawn -- the commanded angle before the knob, and whether a
393 * position was pending before it. */
394 bool knob_live;
395 bool knob_had_cmd;
396 bool knob_had_driving;
397 uint32_t knob_post;
398 float knob_prev_deg;
399 /* A finger owned the dial at some point since knob_frame(). */
400 bool knob_finger;
401 /* The settings, a sweep or a test owned the horn at some point since
402 * knob_frame(), even if it let go again before the turn is applied. */
403 bool knob_owned;
404
405 /*
406 * Arming, which this screen needs as much as MOTOR & ESC does: until the
407 * bench is armed the IOmcu writes a pulse of length zero to every
408 * PWM pin, so dragging the horn moves nothing and shows nothing on a
409 * scope. The gesture is ui_widgets' -- the same two seconds and the same
410 * fade as the other screen's, because it is the same control.
411 */
412 /* Whether the commanded value follows its controls (ui_value_gate.h):
413 * the bench's report, an ARM posted whose arm has not landed yet --
414 * collected by the panel, which arms only once the release it owes has
415 * been written -- and a DISARM or STOP not yet answered. gate.armed is
416 * what the ARM button reads. */
417 ui_value_gate_t gate;
418 /* The bench is armed for any role, the motor's included: what keeps the
419 * programmer off the port while the motor is armed and this screen's
420 * surfaces are not (servo_screen_set_bench_armed()). */
421 bool bench_armed;
422 /* The commanded value is the surface's rest and nothing has been
423 * commanded since: it follows the rest through a change of profile. */
424 bool at_rest;
425 ui_hold_t arm;
426 bool arm_down;
427 int arm_id;
428 uint32_t arm_rev;
429 uint32_t drawn_arm[2];
430
431 gfx_rect_t arm_btn, centre_btn, sweep_btn, release_btn;
432 bool kst_shown; /* a session had the left column */
433 bool kst_held; /* and a port: ARM takes no press */
434 bool sup_held; /* the port holds the supply: SET is dim */
435 uint32_t drawn_kst[2], drawn_kst_hold[2];
436 ui_slider_t speed;
437
438 /* The servo rail's live power, from its meter (rail_now()): the line
439 * of readings and the plot under it. */
440 ui_plot_t power;
441 supply_state_t sup;
442 bool have_sup;
443 uint32_t power_rev;
444 uint32_t drawn_power[2];
445 /* The supply was the panel's model when the line was drawn: the pill. */
446 bool model_shown;
447 /* The meter, as the panel last said it (servo_screen_source()), and the
448 * INA3221's last CH1 window (servo_screen_window()). */
449 servo_source_id_t source;
450 /* The change count the meter in force was decided at
451 * (servo_source_changes()): an answer from an earlier poll is not taken
452 * over it. */
453 bool have_changes;
454 uint32_t changes;
456 bool have_win;
457 /* Why the INA3221 is not the meter now, and why and at which change
458 * count it last stopped being it (servo_screen_source_why(),
459 * servo_screen_source_dropped()). */
460 servo_source_why_t src_why;
461 bool have_drop;
462 servo_source_why_t drop_why;
463 uint32_t drop_at;
464 /* The CURRENT row: what it shows (cur_key_of()), and its own count of
465 * changes, so a changed digit repaints its value and not the card. */
466 int32_t cur_key;
467 uint32_t cur_rev;
468 uint32_t drawn_cur[2];
469
470 /*
471 * The supply's set points and output, SUPPLY's own: OUTPUT ON is the
472 * same two-second hold, OFF the same tap. What is drawn is compared
473 * with SUPPLY every frame, so a change made there, a cap that moved or
474 * the output going off shows here at once.
475 */
476 gfx_rect_t out_btn;
477 ui_hold_t out_hold;
478 bool out_down;
479 int out_id;
481 bool out_on;
482 float sup_v, sup_i;
483 uint32_t sup_rev;
484 uint32_t drawn_sup[2];
485 /* A set point waiting for APPLY: typed while the output is live, or a
486 * voltage raised past a standard servo's rating (hv), which takes the
487 * two-second hold the profile warning takes. OUTPUT ON with a set
488 * point past that rating waits on the same hold (ASK_ON). */
489 struct {
490 bool open;
491 bool hv;
492 int purpose;
493 int target;
494 uint32_t off_count;
495 uint32_t stops;
496 float v, i;
497 ui_hold_t hold;
498 bool down;
499 uint32_t rev;
500 } ask;
501 uint32_t drawn_ask[2];
502 /* Stops seen (servo_screen_cancel_arm()), for the question above. */
503 uint32_t stops;
504
505 /*
506 * The task strip (ui_workbench.h): LIVE, TEST, PROGRAM, SETTINGS. A
507 * tile opens LIVE; each task keeps its state for the session: SETTINGS
508 * its page (tabs), TEST the run whose settings are open (run_list),
509 * PROGRAM its list. The strip's count of changes repaints it.
510 */
511 ui_wb_strip_t wb;
512 uint8_t run_list; /* RL_*: a run's settings open on TEST */
513 uint32_t strip_rev;
514 uint32_t drawn_strip[2];
515 /* PROGRAM's list (prog_registry.h): its view, and the rows last drawn. */
516 prog_view_t prog_view;
517 uint32_t prog_sig;
518 /* Whether a panel or the programmer covered the left column when the
519 * buffer was last drawn: a change repaints it whole. */
520 bool drawn_cover[2];
521 /* The TARGET row on the right card: what the tester drives, and the
522 * control that opens the choice of target. */
523 ui_target_row_t trow;
524 /* SETTINGS' pages and the panels they open. */
525 ui_tabs_t tabs;
526 int ov_pressed;
527 int ov_row;
528 uint8_t ov_id;
529 bool ov_have;
530 ui_keypad_t kp;
531 int kp_target;
532 setting_id_t kp_setting;
533 ui_textkey_t tk;
534 struct {
535 bool open;
536 int target;
537 setting_id_t id;
538 char title[48];
539 char labels[CHOICE_MAX][32];
540 int values[CHOICE_MAX];
541 int count;
542 int pressed;
543 } ch;
544 struct {
545 bool open;
546 int type;
547 uint16_t hz;
548 ui_hold_t hold;
549 bool down;
550 uint32_t rev;
551 } warn;
552 uint32_t drawn_warn[2];
553 uint8_t drawn_save[2];
554
555 servo_rate_state_t rate_st; /* what became of the rate rate_hz */
556 uint16_t rate_hz;
557
558 /* The sweep: the same curve the IOmcu runs, on this screen's own
559 * clock, to draw the horn by. */
560 bool sweep_able; /* the IOmcu speaks 4.2 or later */
561 /*
562 * The pause whose HOLD what the screen expects of the far end rests on,
563 * or 0. Set by a PAUSE of a sweep the far end is known to run. Kept
564 * by everything that carries that pause on: its resume and the resume
565 * said again, a position said again under a changed profile, and a
566 * further PAUSE before the resume is acknowledged -- that HOLD holds
567 * what the first pause left. Ended by the acknowledgement of a start
568 * or a resume (the far end then moves on its own), and by anything
569 * that sets a new origin: stop_sweep() -- a drag, CENTRE, RELEASE, a
570 * curve restarted, a disarm, leaving, the link going -- and
571 * start_sweep() -- SWEEP, or a PAUSED that starts a changed curve.
572 * Every command carries it (from_pause); the panel drops those of a
573 * pause it lets go of, and the screen takes that let-go exactly while
574 * it is still set to that pause (servo_screen_released()).
575 */
576 uint16_t lineage;
577 bool surfaces; /* a surface is bound to sweep */
578 /* The tap's phase of the pause in force, and for a resume asked before
579 * that pause's HOLD was acknowledged, where its replay starts: the
580 * output the far end held, once that acknowledgement says it. */
581 uint32_t pause_tap_ms;
582 bool resume_from_set;
583 uint16_t resume_pause_seq;
584 float resume_from_cmd;
585 bool sweeping;
586 bool paused; /* a sweep held by PAUSE: HOLD posted */
587 /* SPEED as the sweep ran when PAUSE was tapped: the far end slews at it
588 * until the HOLD reaches it, whatever the slider says meanwhile, since
589 * a paused slider sends nothing. */
590 int pause_speed_pct;
591 /* And where the output was drawn at the tap, which the replay of the
592 * acknowledgement interval starts from. */
593 float pause_from_cmd;
594 /* Which pause stands, so an acknowledgement is applied to its own. */
595 uint16_t pause_seq;
596 bool sweep_ended; /* the next command ends it */
597 sweep_t sw;
598 uint32_t clock_ms;
599 float clock_frac_ms;
600 /* Without feedback: the last second and a half of where the output
601 * has been drawn, to start from where the far end's output starts. */
602 struct { uint32_t t; float cmd; } trail[64];
603 uint8_t trail_head, trail_n;
604 /*
605 * A start or a resume asked for and not yet acknowledged: the far end
606 * is not known to move yet, so the curve is not drawn; the output goes
607 * on as it was (servo_screen_sweep_started()). The phase the curve
608 * would begin moving from: 0 for a start, the kept one for a resume.
609 */
610 bool awaiting;
611 uint32_t await_phase_ms;
612 /*
613 * The far end runs a curve this screen has stopped drawing as its own:
614 * a PAUSE whose HOLD is not yet acknowledged, or a curve replaced by a
615 * start not yet acknowledged. It is drawn on as the far end runs it --
616 * its curve, SPEED and the pulse mapping its commands were sent under
617 * -- for at most OUT_DEFAULT_TIMEOUT_MS, the longest the far end runs a
618 * sweep it has not heard. out is the output in that mapping's command
619 * units, chased as the far end slews it.
620 */
621 sweep_drain_t dr;
622 /* The mapping the last sweep command was sent under. */
623 servo_map_t posted_map;
624 /*
625 * Sweep commands are numbered; the newest start or resume is kept with
626 * the curve it was sent with, and the wait for it is ended by its own
627 * acknowledgement or a later repeat's (servo_screen_sweep_started()).
628 * The SPEED each of the last 8 sweep commands was sent with, by
629 * number, for the one acknowledged.
630 */
631 uint16_t start_seq;
632 start_rec_t start_rec;
633 struct { uint16_t seq; int16_t speed_pct; } sent_speed[8];
634 /*
635 * The sweep button's last tap and the screen as it was before it, while
636 * its command has not left: a second tap in the same pass undoes both,
637 * since the far end never heard the first. post_count counts commands
638 * posted, so another command posted since makes the tap's command gone.
639 */
640 struct {
641 servo_cmd_t pending;
642 sweep_t sw;
643 bool sweeping, paused, awaiting, sweep_ended, driving;
644 uint32_t await_phase_ms;
645 float commanded_deg;
646 sweep_drain_t dr;
647 start_rec_t start_rec;
648 uint16_t pause_seq, resume_pause_seq, lineage;
649 uint32_t pause_tap_ms;
650 float pause_from_cmd, resume_from_cmd;
651 int pause_speed_pct;
652 bool resume_from_set;
653 } undo;
654 bool toggle_live;
655 servo_cmd_kind_t toggle_kind;
656 uint32_t toggle_post;
657 uint32_t post_count;
658
659 /* Changes to what a command carries -- the profile, the pulses, trim,
660 * travel -- and how many there had been when ARM was asked for. */
661 uint32_t profile_rev;
662 uint32_t arm_profile_rev;
663
664 /*
665 * The automatic test: the run, START TEST's hold, HV SERVO, and what the
666 * left card shows of it. HV SERVO is for the session only and off at
667 * every restart, as a profile that can destroy a servo is.
668 */
669 servo_test_t test;
670 bool test_hv;
671 ui_hold_t test_hold;
672 bool test_down;
673 uint32_t test_rev;
674 uint32_t drawn_test[2];
675 uint32_t now_ms;
676 bool have_now;
677 bool link_up;
678 bool enc_held;
683 bool test_off;
686 bool test_box;
689 /*
690 * SUPPLY's set points go back to what they were before a run once it
691 * is over, whichever screen is up (servo_screen_service()): only once
692 * its OFF has gone, a sample taken after that shows the output off,
693 * nothing would switch it on, and nobody has set them since it ended.
694 */
695 bool test_restore;
697 uint32_t restore_ms;
698 float test_v0, test_i0;
699 float test_v1, test_i1;
700 uint32_t test_sig;
701
702 /*
703 * The limit run (servo_limrun.h): the limit search on the INA3221's
704 * windows, and with LIMIT RUN at SEARCH+PROG, LEFT ANGLE and RIGHT
705 * ANGLE of a KST or Chaservo servo on the programming port lowered.
706 * Its START is the LIMIT RUN card's, held 2s; its box is the test's
707 * place on LIVE's card. One of the two runs at a time.
708 */
709 servo_limrun_t lim;
710 bool lim_prog;
712 ui_hold_t lim_hold;
713 bool lim_down;
714 bool lim_box;
715 bool lim_seen;
720 bool lim_end_due;
723 bool lim_off;
724 const char *lim_note;
725 uint32_t lim_changes;
726 uint32_t lim_sig;
727 /* The outbox the logger last peeked, and whose files' number comes
728 * back (servo_screen_test_files()). */
729 bool peek_lim;
730 servo_test_out_t peek_kind;
731 bool files_lim;
732 /* The logger has an OPEN or an END of the last run not answered yet
733 * (servo_screen_test_logger_busy()). */
734 bool logger_busy;
735
736 uint32_t ctrl_rev;
737 uint8_t drive_target; /* 0 the outputs, 1 + n programming port n */
738 uint8_t drive_pin; /* that port's GPIO, or SERVO_SCREEN_NO_PIN */
739 bool drive_pwm; /* that port renders its pulse */
740 uint64_t pins; /* GPIOs bound as SERVO PWM, bit n = GPIO n */
741 bool pins_known; /* a binding was read */
742 uint32_t drawn_ctrl[2];
743 unsigned drawn_mask;
751 uint32_t dial_rev;
752 uint32_t drawn_dial[2];
753 float drawn_deg[2];
754 float drawn_cmd[2];
755 bool drawn_ghost[2];
758
759/* The state, in servo_screen.c. */
761
762/* --- the screen's side, servo_screen*.c, which the other four files call */
763
764/* The profile in force (apply_profile()) and the one asked for, which
765 * opens the warning first where it can destroy a servo (ask_profile()). */
766void apply_profile(int t, uint16_t hz);
767void ask_profile(int t, uint16_t hz);
768/* The commanded position said again under a changed profile. */
769void reissue(void);
784int wrap_text(gfx_canvas_t *c, int x, int y, int pitch, const char *text,
785 int cells, gfx_color_t ink, const gfx_font_t *f);
786
787/* A pulse as an angle (us_to_deg() below), and the commands a run posts
788 * as a finger's: a command (post()), RELEASE (release()), and the sweep
789 * ended (stop_sweep()) or as SETUP sets it (sweep_cfg_now()). */
790float us_to_deg_f(float us);
791void post(servo_cmd_kind_t kind, uint16_t us);
792void release(void);
793void stop_sweep(void);
795
796/* Whether a run is under way, told to the panel where it changes, and a
797 * supply sample as a run reads it: both runs' (servo_screen_on_testing()). */
798void test_tell(void);
800
801/* What an edge of the value's state does: into LIVE, the value is the
802 * rest; out of LIVE, a run ends as @p why, and so does every motion. */
803void value_edge(ui_value_edge_t edge, servo_test_abort_t why);
804
805/* --- servo_settings_panel.c's side, which the screen calls --------------- */
806
807/* Every panel shut: the keypad, the keyboard, the list, the warning and the
808 * question (close_panels()); and, once a set point's keypad is done, the
809 * page under them repainted (close_alone()). */
810static inline void close_panels(void)
811{
812 ui_keypad_close(&s.kp);
813 ui_textkey_close(&s.tk);
814 s.kp_target = KT_NONE;
815 s.ch.open = false;
816 s.warn.open = false;
817 s.warn.down = false;
818 ui_hold_reset(&s.warn.hold);
819 s.ask.open = false; /* a set point not applied is dropped */
820 s.ask.down = false;
821 ui_hold_reset(&s.ask.hold);
822}
823
824/* A set point's keypad, or the question after it, is done: the task's page
825 * shows again under the panel that went. */
826static inline void close_alone(void)
827{
828 close_panels();
830}
831
833extern const ov_row_t k_rows[];
834extern const int k_row_count;
835
842gfx_rect_t row_rect(int i);
856gfx_rect_t trim_rect(int i, bool up);
879bool target_locked(const ov_row_t *r);
880
881/* OUTPUT ON with a set point past a standard servo's rating: the HV
882 * warning. The question or the warning answered: what it was about. */
883void ask_hv_on(void);
884void ask_apply(void);
885/* A press on a page or a panel: its DOWN, and its moves and its release. */
886void ov_down(const touch_event_t *evt);
887void ov_rest(const touch_event_t *evt);
888/* The panel open over the left column, and the parts a frame repaints by
889 * themselves. */
894
895
896/* --- servo_test_panel.c's side, which the other files call -------------- */
897
898/* The restore's stages: the OFF the run's end posted not yet taken; taken,
899 * waiting for the next frame; waiting for a sample taken since; a sample
900 * showed the output off. */
901enum { RS_OFF_POSTED = 0, RS_OFF_SENT, RS_SAMPLE, RS_OFF_SEEN };
902
903/* The automatic test. */
904int test_blocked(void);
905float test_top_v(void);
906void test_begin(void);
907void test_end_now(servo_test_abort_t why);
908void ask_hv_test(void);
911/* A STALL AT no reading can pass, at (@p x, @p y), or nothing. */
912void draw_test_stall(gfx_canvas_t *c, int x, int y);
913
914/* The run against the meter in force (test_meter_follow()); every frame
915 * (test_tick()) and whichever screen is up (test_restore_service()); what
916 * the box shows of it, as one number (test_signature()); and the box. */
917void test_meter_follow(servo_source_id_t id, uint32_t changes);
918void test_restore_service(void);
919uint32_t test_signature(void);
920void test_tick(void);
922
923/* A run that was running is over, however it ended: its OFF is posted
924 * (test_apply()), and the restore of the set points starts waiting. */
925static inline void test_ended(void)
926{
927 if (!s.test_seen || servo_test_running(&s.test)) {
928 return;
929 }
930 s.test_seen = false;
931 s.test_restore = true;
932 s.restore_stage = RS_OFF_POSTED;
933 s.test_v1 = supply_screen_set_v();
934 s.test_i1 = supply_screen_set_i();
935 ++s.test_rev;
936 ++s.ctrl_rev;
937}
938
939/* --- servo_limit_panel.c's side, which the other three files call -------- */
940
941/* Why the programming is not offered, why a run cannot start now, or
942 * NULL; the run ended now. */
943const char *lim_prog_why(void);
944const char *lim_blocked(void);
945void lim_end_now(servo_test_abort_t why);
946/* START LIMIT RUN's hold completed; the run every frame; the ended run's
947 * LEAVE, whichever screen is up; the meter changed under the run. */
948void lim_begin(void);
949void lim_tick(void);
950void lim_leave_follow(void);
951void lim_meter_follow(servo_source_id_t id, uint32_t changes);
952/* What the box and the LIMIT RUN card show of the run, as one number. */
953uint32_t lim_signature(void);
954/* The run's box on LIVE's card; START LIMIT RUN and its card's lines on
955 * TEST; the mode's note on the run's settings at (@p x, @p y). */
959void draw_lim_mode_note(gfx_canvas_t *c, int x, int y);
960
961/* --- helpers the four files inline --------------------------------------- */
962
963static inline const servo_type_t *type(void) { return &k_types[s.type]; }
964
965/*
966 * The range a command carries: the narrowest one centred on CENTRE that
967 * holds MIN and MAX. The IOmcu knows a channel only by its two
968 * endpoints and rests a surface at their midpoint -- on RELEASE, before an
969 * arm, after a silence -- so MIN..MAX itself would rest a servo whose CENTRE
970 * is not midway between them away from its centre. Commands never leave
971 * MIN..MAX: svs_deg_to_us() clamps them. The PULSE keypads keep this
972 * range inside OUT_FLOOR_US..OUT_CEILING_US.
973 */
974static inline void cmd_range(uint16_t *lo, uint16_t *hi)
975{
976 const unsigned below = (unsigned)s.centre_us - (unsigned)s.min_us;
977 const unsigned above = (unsigned)s.max_us - (unsigned)s.centre_us;
978 const unsigned half = (below > above) ? below : above;
979 *lo = (uint16_t)((unsigned)s.centre_us - half);
980 *hi = (uint16_t)((unsigned)s.centre_us + half);
981}
982
983/*
984 * The longest pulse the far end can render: the top of the range a command
985 * carries, which is past PULSE MAX when CENTRE is off the middle. A pulse
986 * of an old span under a new range reaches it between two transactions, so
987 * the frame rate's pause is kept from it rather than from PULSE MAX.
988 */
989static inline uint16_t cmd_top(void)
990{
991 uint16_t lo, hi;
992 cmd_range(&lo, &hi);
993 return hi;
994}
995
996static inline float us_to_deg(uint16_t us)
997{
998 return us_to_deg_f((float)us);
999}
1000
1001static inline float clamp_travel(float deg)
1002{
1003 if (deg < -s.travel_deg) { return -s.travel_deg; }
1004 if (deg > s.travel_deg) { return s.travel_deg; }
1005 return deg;
1006}
1007
1008/*
1009 * Whether the commanded value follows its controls: only in UI_VALUE_LIVE.
1010 * The one question every input, the drawing, a run and a late callback ask:
1011 * not on a disarmed bench, whose pins carry no pulse, not while an ARM is
1012 * on its way, and not from a DISARM or a STOP until the bench reports
1013 * itself disarmed.
1014 */
1015static inline bool value_live(void)
1016{
1017 return ui_value_live(&s.gate);
1018}
1019
1020/* The fastest frame rate the profile in force allows with these pulses:
1021 * the pause rule, under the profile's own ceiling. */
1022static inline uint16_t max_rate_for(int t, uint16_t max_us)
1023{
1024 const servo_type_t *ty = &k_types[t];
1025 const unsigned pause = ty->heli ? HELI_MIN_PAUSE_US : PWM_MIN_PAUSE_US;
1026 unsigned hz = 1000000u / ((unsigned)max_us + pause);
1027 if (ty->max_hz != 0u && hz > ty->max_hz) {
1028 hz = ty->max_hz;
1029 }
1030 return (uint16_t)hz;
1031}
1032
1033/* A type or a rate that needs the warning before it is applied. */
1034static inline bool dangerous(int t, uint16_t hz)
1035{
1036 return k_types[t].heli || hz > SAFE_RATE_HZ;
1037}
1038
1039static inline bool in_force_dangerous(void)
1040{
1041 return dangerous(s.type, s.frame_hz);
1042}
1043
1044/* Whether the encoder's last reading is on show and may be used: one the
1045 * link carried, with the encoder on in SETUP. A link that goes down takes
1046 * the reading with it (servo_screen_set_link()). */
1047static inline bool enc_shown(void)
1048{
1049 return s.enc_valid && s.link_up && settings_get_bool(SET_ENC_EN);
1050}
1051
1052static inline gfx_rect_t overlay_area(void)
1053{
1054 return (gfx_rect_t){ OV_X, OV_Y, OV_W, OV_H };
1055}
1056
1062static inline gfx_rect_t sup_val_rect(int k)
1063{
1064 return (gfx_rect_t){ (int16_t)(SUP_VAL_X + k * (SUP_VAL_W + SUP_GAP)),
1065 SUP_Y, SUP_VAL_W, SUP_H };
1066}
1067
1070#define WARN_BTN_Y (STOP_FLOOR - 56)
1071
1076static inline gfx_rect_t warn_apply_rect(void)
1077{
1078 return (gfx_rect_t){ (int16_t)(OV_X + 20), WARN_BTN_Y, 240, 56 };
1079}
1080
1081/* The automatic test's and the limit run's: the clock they and the
1082 * supply's readings share, the abort for what took the INA3221 off the
1083 * rail, and the box on the left card both draw in. */
1084
1085/* The clock the run and the supply's readings share. */
1086static inline uint32_t test_now(void)
1087{
1088 return s.have_now ? s.now_ms : s.clock_ms;
1089}
1090
1091/* A run's abort for the condition that took the INA3221 off the rail. */
1092static inline servo_test_abort_t test_abort_of(servo_source_why_t why)
1093{
1094 switch (why) {
1095 case SERVO_SOURCE_WHY_NO_LINK: return SERVO_TEST_AB_LINK;
1102 default: return SERVO_TEST_AB_INA_METER;
1103 }
1104}
1105
1114#define BOX_W 346
1115#define BOX_CELLS ((BOX_W - 20) / SV_CELL)
1116#define BOX_PITCH 24
1117#define BOX_BTN_DY 112
1118
1120static inline gfx_rect_t test_box_rect(void)
1121{
1122 return (gfx_rect_t){ PAD + 10, ARM_NOTE_Y + 28, BOX_W,
1123 BOX_BTN_DY + UI_TAP_MIN + 10 };
1124}
1125
1126_Static_assert(ARM_NOTE_Y + 28 + BOX_BTN_DY + UI_TAP_MIN + 10
1127 <= READ_LBL_Y - 8,
1128 "the run's box ends above LIVE's readings");
1129
1131static inline gfx_rect_t test_btn_rect(void)
1132{
1133 const gfx_rect_t b = test_box_rect();
1134 return (gfx_rect_t){ (int16_t)(b.x + 10), (int16_t)(b.y + BOX_BTN_DY),
1135 150, UI_TAP_MIN };
1136}
1137
1138/* A run with a step past a standard servo's rating starts only through the
1139 * HV warning. */
1140static inline bool test_needs_hv(void)
1141{
1142 return test_top_v() > STD_SERVO_V_MAX + 0.001f;
1143}
1144
1145/* The run drives the programming port: a KST or Chaservo servo is read
1146 * first and searched within its own pulses. */
1147static inline bool lim_reads(void)
1148{
1149 return s.drive_target != 0u
1150 && s.drive_target != SERVO_SCREEN_TARGET_UNKNOWN
1151 && s.drive_target != SERVO_SCREEN_TARGET_NO_LINK;
1152}
1153
1154/* SERVO PULSES is there only for the programming port. */
1155static inline bool row_hidden(const ov_row_t *r)
1156{
1157 return r->kind == R_LIM_PULSES && !lim_reads();
1158}
1159
1160/* SEARCH+PROG chosen and offered. */
1161static inline bool lim_programs(void)
1162{
1163 return s.lim_prog && lim_prog_why() == NULL;
1164}
1165
1166/* Whether the voltage set point in force is past a standard servo's
1167 * rating, which OUTPUT ON on this screen applies only through the HV
1168 * warning. */
1169static inline bool hv_set_point(void)
1170{
1171 return supply_screen_set_v() > STD_SERVO_V_MAX + 0.001f;
1172}
1173
1174/* Whether the question about a live output still stands: the output on
1175 * or coming, not gone off since it was asked -- an OFF and a new ON
1176 * between two frames start a run the question was not about -- and no
1177 * stop since. A stop switches the output off, but the supply reports
1178 * that a sample later; an APPLY drained in the frame of the stop finds
1179 * the output still live and is refused by the count. */
1180static inline bool ask_stands(void)
1181{
1183 && supply_screen_off_count() == s.ask.off_count
1184 && s.stops == s.ask.stops;
1185}
1186
1187static inline void ov_take(const touch_event_t *evt, int code, int which)
1188{
1189 s.ov_have = true;
1190 s.ov_id = evt->point.id;
1191 s.ov_pressed = code;
1192 s.ov_row = which;
1193 ++s.ctrl_rev;
1194}
1195
1196static inline void ov_let_go(void)
1197{
1198 if (s.ov_have) {
1199 s.ov_have = false;
1200 s.ov_pressed = OP_NONE;
1201 ++s.ctrl_rev;
1202 }
1203}
1204
1205/* Whether the settings reached the medium: 0 saved, 1 waiting for a quiet
1206 * moment, 2 refused, 3 changed on SETUP and not asked to be saved. */
1207static inline uint8_t save_state(void)
1208{
1209 if (settings_save_failed()) {
1210 return 2u;
1211 }
1212 if (settings_save_asked()) {
1213 return 1u;
1214 }
1215 return settings_dirty() ? 3u : 0u;
1216}
1217
1218/* --- helpers the screen and the limit run inline ------------------------- */
1219
1220/* The encoder's angle from its centre, degrees, in the direction of the
1221 * commanded angle: negated with REVERSE on, as us_to_deg() is. */
1222static inline float enc_deg_now(void)
1223{
1224 const float d = servo_test_enc_deg(
1225 s.enc_raw, (uint16_t)settings_get_int(SET_ENC_CENTRE));
1226 return s.reverse ? -d : d;
1227}
1228
1229/* Armed, asked to arm, or a finger on ARM, or the bench armed for the
1230 * motor: the programmer takes no port. */
1231static inline bool bench_arming(void)
1232{
1233 return s.gate.armed || s.gate.arm_asked || s.arm_down || s.bench_armed;
1234}
1235
1236/* The workbench's own: the strip, the TARGET row, TEST's run cards. */
1237#include "servo_workbench_int.h"
#define PAD
Definition analyser_screen.c:26
#define RCARD_X
Definition analyser_screen.c:51
#define NOTE_PITCH
Definition battery_screen.c:76
#define s
Short name for esc_stick_s inside the five stick-class files.
Definition esc_stick_panel_int.h:295
gfx: an RGB565 (16-bit red, green, blue) rasteriser with no dependencies.
The KST and Chaservo programmer's overlay on SERVO: its interface.
#define KST_PANEL_STD_MV
The highest supply voltage a standard servo is rated for, mV: a programming voltage above it needs HV...
Definition kst_panel.h:48
#define k
Short name for kst_panel_k inside the overlay's seven files.
Definition kst_panel_int.h:238
#define STOP_FLOOR
The lowest row a control that stops what the bench drives, or a line of text, may reach: 4px above th...
Definition motor_screen_int.h:75
#define BOX_W
Definition motor_settings_page.c:74
servo_rate_state_t
What became of a frame rate the panel wrote to the SERVO page.
Definition servo_cmd.h:134
servo_cmd_kind_t
The kind of a command of the SERVO screen.
Definition servo_cmd.h:23
void draw_lim_lines(gfx_canvas_t *c)
The LIMIT RUN card's lines: over START LIMIT RUN the mode, and under it what the run drives and reads...
Definition servo_limit_panel.c:685
void draw_lim_start(gfx_canvas_t *c)
START LIMIT RUN, on the LIMIT RUN card under the AUTOMATIC TEST one: green, fading to the danger red ...
Definition servo_limit_panel.c:623
void draw_lim_box(gfx_canvas_t *c)
The limit run on the left card, in the automatic test's place: while it runs, the values written,...
Definition servo_limit_panel.c:504
void draw_lim_mode_note(gfx_canvas_t *c, int x, int y)
Why SEARCH+PROG is not offered, or what the mode does: the LIMIT RUN settings' note,...
Definition servo_limit_panel.c:646
The limit run: the limit search (servo_limit.h) run on the SERVO screen against the INA3221's windows...
void ask_profile(int t, uint16_t hz)
A profile asked for: one that can destroy a servo not made for it opens the warning,...
Definition servo_screen.c:474
void apply_profile(int t, uint16_t hz)
A profile goes into force: a type with its own pulse widths when it is a different type,...
Definition servo_screen.c:453
The servo bench: the outputs the binding marks as surfaces, commanded together by dragging one horn.
#define SERVO_SCREEN_TARGET_UNKNOWN
Definition servo_screen.h:364
#define SERVO_SCREEN_TARGET_NO_LINK
Definition servo_screen.h:367
void servo_invalidate(void)
Definition servo_screen.c:496
int wrap_text(gfx_canvas_t *c, int x, int y, int pitch, const char *text, int cells, gfx_color_t ink, const gfx_font_t *f)
text in lines of at most cells cells of face f, from (x, y) down by pitch px, each broken at the last...
Definition servo_screen_draw.c:289
#define READ_LBL_Y
Definition servo_screen_int.h:174
gfx_rect_t choice_rect(int i)
The list's choice i: two columns of CHOICE_MAX / 2.
Definition servo_settings_panel.c:121
#define SV_STRIP_Y
Definition servo_screen_int.h:68
#define RCARD_H
Definition servo_screen_int.h:82
#define SV_STRIP_X
SERVO's task strip at the 1024 x 600 sizes: four tabs of 150 x 40px, 4px apart, from y 8,...
Definition servo_screen_int.h:67
#define OV_X
Definition servo_screen_int.h:191
sweep_cfg_t sweep_cfg_now(void)
The sweep the SWEEP page describes, under the profile in force: CURVE, SPEED and DWELL as they are,...
Definition servo_screen_sweep.c:42
bool target_locked(const ov_row_t *r)
Whether a row is a TARGET or PORT PWM setting under its lock.
Definition servo_settings_panel.c:316
void draw_ask_apply(gfx_canvas_t *c)
The HV warning's HOLD TO APPLY.
Definition servo_settings_draw.c:464
#define SUP_H
Definition servo_screen_int.h:132
void draw_save_line(gfx_canvas_t *c)
Whether the settings reached the card, along the bottom of a page.
Definition servo_settings_draw.c:36
static gfx_rect_t sup_val_rect(int k)
The voltage's value or the current limit's on the SET row.
Definition servo_screen_int.h:1062
void draw_overlay(gfx_canvas_t *c)
The panel open over the left column, if any: the keypad, the keyboard, the question or the HV warning...
Definition servo_settings_draw.c:575
#define WARN_BTN_Y
The bottom row of a warning or the question: its buttons' top, so they end with ARM above the alert b...
Definition servo_screen_int.h:1070
#define RL_NOTE_Y
A run's note under its rows: the automatic test's stall note, 4px under the last value.
Definition servo_screen_int.h:221
void stop_sweep(void)
The sweep ended, running or paused. A pause is ended by the command that follows; the button reads SW...
Definition servo_screen_sweep.c:85
#define SV_STRIP_H
Definition servo_screen_int.h:69
gfx_rect_t trim_rect(int i, bool up)
TRIM's two steps, inside its value, UI_TAP_MIN px wide each.
Definition servo_settings_panel.c:114
const ov_row_t k_rows[]
The rows of the pages, page by page, and their count.
Definition servo_settings_panel.c:46
static gfx_rect_t test_btn_rect(void)
The box's button.
Definition servo_screen_int.h:1131
void draw_test_start(gfx_canvas_t *c)
START TEST: green, fading to the danger red across its hold, as ARM; STOP TEST in red while a run is ...
Definition servo_test_panel.c:594
const int k_row_count
The rows k_rows holds.
Definition servo_settings_panel.c:85
#define SV_TAB_GAP
Definition servo_screen_int.h:71
void draw_test_lines(gfx_canvas_t *c)
The AUTOMATIC TEST card's lines: over START TEST the steps and the length of each,...
Definition servo_test_panel.c:663
void draw_test_box(gfx_canvas_t *c)
The run on LIVE's card: the step and phase while it runs, with STOP TEST; PASS, FAIL or ABORTED and w...
Definition servo_test_panel.c:503
#define ARM_NOTE_Y
Definition servo_screen_int.h:177
#define RCARD_Y
The output card's top: the body's margin. The strip spans the left card only, so the output card,...
Definition servo_screen_int.h:81
gfx_rect_t warn_cancel_rect(void)
A warning's or the question's CANCEL, bottom right.
Definition servo_settings_panel.c:137
#define OV_W
Definition servo_screen_int.h:193
void value_edge(ui_value_edge_t edge, servo_test_abort_t why)
What an edge of the value's state does, in one place.
Definition servo_screen_link.c:45
#define SUP_Y
The supply's set points, each a value the keypad opens on, and OUTPUT ON and OFF: the same set points...
Definition servo_screen_int.h:131
#define SV_TAB_W
Definition servo_screen_int.h:70
static gfx_rect_t test_box_rect(void)
The run's box.
Definition servo_screen_int.h:1120
servo_test_reading_t test_reading_of(const supply_state_t *st)
Gives the servo test the supply's reading.
Definition servo_screen_link.c:409
int decimals_of(setting_id_t id)
The decimals a setting's value is typed and drawn with.
Definition servo_settings_panel.c:143
gfx_rect_t choice_cancel_rect(void)
The list's CANCEL, bottom right.
Definition servo_settings_panel.c:131
#define SV_PAGE_Y
Definition servo_screen_int.h:72
#define SUP_VAL_W
Definition servo_screen_int.h:134
#define STD_SERVO_V_MAX
The top of a standard servo's rating. A set point raised past it is applied only after the HV warning...
Definition servo_screen_int.h:181
void draw_test_stall(gfx_canvas_t *c, int x, int y)
A STALL AT the run's readings cannot pass, in the warning colour: the current limit first,...
Definition servo_test_panel.c:646
#define SUP_GAP
Definition servo_screen_int.h:135
gfx_rect_t value_rect(int i)
Where row i's value is drawn: right in its row on SETTINGS' pages, under its label on a run's.
Definition servo_settings_panel.c:104
void ov_down(const touch_event_t *evt)
A press on a page of rows or a panel: on whichever is up; on TRIM, beside its steps,...
Definition servo_settings_panel.c:527
#define SUP_VAL_X
Definition servo_screen_int.h:133
#define OV_SAVE_Y
The save line under SETTINGS' rows and notes, 20px tall, ending 4px above the alert band.
Definition servo_screen_int.h:224
gfx_rect_t row_rect(int i)
Row i's rectangle: on SETTINGS' pages its column, or both for a wide one, UI_TAP_MIN tall; on a run's...
Definition servo_settings_panel.c:89
void draw_warn_apply(gfx_canvas_t *c)
The profile warning's HOLD TO APPLY.
Definition servo_settings_draw.c:392
#define OV_Y
Definition servo_screen_int.h:192
#define OV_NOTE_Y
The OUTPUT page's notes, 2px under its fifth row.
Definition servo_screen_int.h:212
#define BOX_BTN_DY
Definition servo_screen_int.h:1117
#define OV_H
Definition servo_screen_int.h:194
static gfx_rect_t warn_apply_rect(void)
HOLD TO APPLY, or APPLY, bottom left of a warning or the question.
Definition servo_screen_int.h:1076
servo_source_id_t
The servo rail's meter.
Definition servo_source.h:70
servo_source_why_t
Why the INA3221 is not the meter: the first condition that fails.
Definition servo_source.h:77
@ SERVO_SOURCE_WHY_NO_LINK
Definition servo_source.h:79
@ SERVO_SOURCE_WHY_OFF
Definition servo_source.h:80
@ SERVO_SOURCE_WHY_RESET
Definition servo_source.h:86
@ SERVO_SOURCE_WHY_NOT_HELD
Definition servo_source.h:82
@ SERVO_SOURCE_WHY_SILENT
Definition servo_source.h:83
@ SERVO_SOURCE_WHY_OLD
Definition servo_source.h:81
@ SERVO_SOURCE_WHY_NO_WINDOW
Definition servo_source.h:85
A servo swept through a curve: square, sine or triangle about its centre.
servo_test_abort_t
Definition servo_test.h:442
@ SERVO_TEST_AB_INA_RESET
Definition servo_test.h:462
@ SERVO_TEST_AB_INA_METER
Definition servo_test.h:467
@ SERVO_TEST_AB_INA_NO_WINDOW
Definition servo_test.h:464
@ SERVO_TEST_AB_INA_SILENT
Definition servo_test.h:463
@ SERVO_TEST_AB_INA_SETUP
Definition servo_test.h:465
bool servo_test_running(const servo_test_t *t)
Tell whether a run is under way.
Definition servo_test.c:216
float servo_test_enc_deg(uint16_t raw, uint16_t centre)
raw from centre on the circle, degrees, -180 to just under 180: 360 / 4096 a count....
Definition servo_test.c:52
servo_test_out_t
Definition servo_test_io.h:136
The SERVO workbench's internals, which servo_screen_int.h takes in at its end: which task and which p...
Device settings: a typed schema, a value per entry, and a persistence seam.
bool settings_save_failed(void)
Definition settings.c:1123
setting_id_t
Every setting's id, in schema order.
Definition settings.h:67
bool settings_dirty(void)
Definition settings.c:1039
bool settings_save_asked(void)
Definition settings.c:1142
Definition gfx.h:129
Definition gfx.h:250
Definition gfx.h:81
Definition servo_screen_int.h:271
Definition prog_registry.h:364
A command of the SERVO screen, as the servo link takes it.
Definition servo_cmd.h:58
Definition servo_limrun.h:364
Definition servo_screen_int.h:300
Definition servo_screen_int.h:359
bool test_report
Definition servo_screen_int.h:682
int speed_pct
Definition servo_screen_int.h:368
int arm_id
Definition servo_screen_int.h:427
float drawn_cmd[2]
Definition servo_screen_int.h:754
int test_blocked_seen
Definition servo_screen_int.h:684
int16_t trim_us
Definition servo_screen_int.h:366
bool lim_leaving
Definition servo_screen_int.h:719
float shown_deg
Definition servo_screen_int.h:371
bool test_hv
Definition servo_screen_int.h:670
bool lim_pulses
Definition servo_screen_int.h:711
bool out_press_on
Definition servo_screen_int.h:480
int lim_file
Definition servo_screen_int.h:721
bool enc_no_magnet
Definition servo_screen_int.h:377
bool lim_report
Definition servo_screen_int.h:722
uint32_t drawn_dial[2]
Definition servo_screen_int.h:752
bool test_online_seen
Definition servo_screen_int.h:685
bool driving
Definition servo_screen_int.h:385
bool arm_down
Definition servo_screen_int.h:426
int test_note
Definition servo_screen_int.h:679
uint32_t restore_ms
Definition servo_screen_int.h:697
float pulse
Definition servo_screen_int.h:386
int shown_q_deg
Definition servo_screen_int.h:384
bool test_box
Definition servo_screen_int.h:686
bool test_off
Definition servo_screen_int.h:683
bool lim_seen
Definition servo_screen_int.h:715
bool enc_held
Definition servo_screen_int.h:678
uint32_t test_sig
Definition servo_screen_int.h:700
bool drawn_ghost[2]
Definition servo_screen_int.h:755
bool lim_off
Definition servo_screen_int.h:723
uint32_t now_ms
Definition servo_screen_int.h:675
float shown_cmd
Definition servo_screen_int.h:372
float travel_deg
Definition servo_screen_int.h:367
uint32_t lim_changes
Definition servo_screen_int.h:725
svs_drag_filter_t df
Definition servo_screen_int.h:756
bool out_on
Definition servo_screen_int.h:481
bool test_on_ina
Definition servo_screen_int.h:688
int shown_q_enc
Definition servo_screen_int.h:379
bool lim_prog
Definition servo_screen_int.h:710
bool test_seen
Definition servo_screen_int.h:687
float sup_i
Definition servo_screen_int.h:482
const char * lim_note
Definition servo_screen_int.h:724
int test_file
Definition servo_screen_int.h:681
float test_i0
Definition servo_screen_int.h:698
float drawn_deg[2]
Definition servo_screen_int.h:753
float test_i1
Definition servo_screen_int.h:699
uint8_t restore_stage
Definition servo_screen_int.h:696
bool lim_box
Definition servo_screen_int.h:714
uint32_t dial_rev
The dial's own count of changes: the horn's angle, the commanded angle and the MEASURED reading,...
Definition servo_screen_int.h:751
One reading of the supply, as SUPPLY has it (supply_state_t).
Definition servo_test_io.h:25
Definition servo_test.h:548
Definition servo_screen_int.h:244
Definition servo_screen_int.h:318
A supply's readings, set points, mode and trip state.
Definition supply.h:69
The drag's filtered target (svs_drag_tick()).
Definition servo_screen_int.h:350
float goal
Definition servo_screen_int.h:354
float out
Definition servo_screen_int.h:355
bool restating
Definition servo_screen_int.h:353
bool posting
Definition servo_screen_int.h:352
bool on
Definition servo_screen_int.h:351
Definition servo_sweep.h:55
Definition servo_screen_int.h:308
Definition servo_sweep.h:63
A DOWN, MOVE or UP of one contact.
Definition touch_types.h:69
touch_point_t point
Definition touch_types.h:71
uint8_t id
Definition touch_types.h:24
Definition ui_widgets.h:415
A numeric keypad: what it was opened with, what is typed, and the press it holds.
Definition ui_keypad.h:61
Definition ui_plot.h:56
Definition ui_slider.h:42
A row of tabs: their labels, where they are, which is selected and the press under way.
Definition ui_tabs.h:27
A TARGET row: where it is and the press it holds.
Definition ui_target_row.h:47
A keyboard: what it was opened for, what is typed, and the press it holds.
Definition ui_textkey.h:114
Definition ui_value_gate.h:40
Definition ui_workbench.h:63
The SUPPLY screen: a programmable supply set, switched and watched.
uint32_t supply_screen_off_count(void)
Definition supply_screen.c:694
bool supply_screen_output_live(void)
Definition supply_screen.c:692
float supply_screen_set_v(void)
Definition supply_screen.c:489
float supply_screen_set_i(void)
The current limit's set point as the screen holds it, snapped to the caps.
Definition supply_screen.c:490
Plain data types shared by the touch controller driver, the coordinate mapper and the event tracker....
A numeric keypad over part of a screen, for a value a slider is too coarse to place.
#define UI_TAP_MIN
The smallest touch target for a control, in pixels: 48px, 7.2mm.
Definition ui_layout.h:71
A multi-series plot on one time base, with a scale per series.
A draggable value with presets: the throttle, and any other control that needs coarse reach and fine ...
The pane selector: one bench, several views of it.
The TARGET row of a workbench's output card: what the screen drives now, read as protocol pins ("SERV...
ui_text_id_t
The screens' strings, TX_<ID> for each UI_TEXT() of ui_text.def.
Definition ui_text.h:43
An on-screen keyboard for a short name: capitals, digits, space and the marks a name or a file needs,...
void ui_textkey_close(ui_textkey_t *k)
Close, dropping a press under way.
Definition ui_textkey.c:152
Stateless drawing helpers shared by every screen.
void ui_hold_reset(ui_hold_t *h)
Definition ui_widgets.c:501
A workbench's task strip: one device, its tasks as tabs under the band.