rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
panel.h
Go to the documentation of this file.
1
12#pragma once
13
14#include <stdatomic.h>
15#include <stdbool.h>
16#include <stddef.h>
17#include <stdint.h>
18#include <stdio.h>
19
20#include "art_store.h"
21#include "esp_timer.h"
22#include "freertos/FreeRTOS.h"
23#include "freertos/queue.h"
24#include "freertos/semphr.h"
25
26#include "arming.h"
27#include "bench_state.h"
28#include "log_cols.h"
29#include "bind_link.h"
30#include "card_tree.h"
31#include "busfault_screen.h"
33#include "endpoints_link.h"
34#include "files_screen.h"
35#include "hitec_link.h"
36#include "hitec_prog.h"
37#include "hitec_rx_link.h"
38#include "kst_link.h"
39#include "kst_prog.h"
40#include "link_bringup.h"
41#include "link_host.h"
42#include "link_pages.h"
43#include "link_port.h"
44#include "link_update_host.h"
45#include "log_cadence.h"
46#include "log_take.h"
47#include "log_writer.h"
48#include "log_viewer_screen.h"
49#include "motor_screen.h"
50#include "out_bind.h"
51#include "outputs.h"
52#include "prog_link.h"
53#include "safety_gate.h"
54#include "sense_link.h"
55#include "sense_map_link.h"
56#include "servo_link.h"
57#include "servo_page.h"
58#include "servo_screen.h"
59#include "servo_source.h"
60#include "servo_test_io.h"
61#include "supply.h"
62#include "supply_link.h"
63#include "supply_screen.h"
64#include "telemetry_sim.h"
65#include "tone_link.h"
66#include "touch_loss.h"
67#include "touch_types.h"
68#include "ui_alert_slot.h"
69#include "ui_screen.h"
70
71/* ------------------------------------------------------------------ main.c */
72
73static inline uint32_t now_ms(void)
74{
75 return (uint32_t)(esp_timer_get_time() / 1000);
76}
77
78/*
79 * The panel's throttle, as a channel in an output bank.
80 *
81 * The ramp is a proportion of travel per second rather than a percentage, so
82 * the same number means the same speed on an output whose travel is not
83 * measured in percent.
84 */
85#define PANEL_CH_THROTTLE 0u
86
87#define ALERT_MAX UI_ALERT_MAX
88
89/* The control task's period; see "the two loops' plumbing" in main.c. */
90#define CONTROL_PERIOD_MS 5u
91
92/* The link to the IOmcu, used during bring-up and in the loop. */
93extern link_host_t s_host;
94/* A link_cap_t bitmap from the IOmcu's identity page; see main.c. */
95extern atomic_uint s_capabilities;
96extern link_bringup_t s_bring;
97
98/* When the link went, 0 while it is up; whether the screen has had its
99 * turn; the recoveries of this outage and since boot. See main.c. */
100extern atomic_uint s_link_lost_ms;
101extern bool s_link_lost_shown;
102extern uint32_t s_recoveries;
103extern uint32_t s_recoveries_total;
104
105/* The panel's die temperature, read by the control task. */
106extern float s_mcu_c;
107
108/* What the IOmcu says its outputs are, both under s_snap_lock; the
109 * state of the last reading, for the control task alone. */
110extern bind_reading_t s_outputs_read;
111extern bool s_outputs_read_fresh;
112extern bind_read_t s_bind_read;
113/* The IOmcu's protocol minor, and its board identity. */
114extern uint16_t s_far_minor;
115extern uint16_t s_board;
116
117extern QueueHandle_t s_kst_q;
118extern QueueHandle_t s_hitec_q;
119extern QueueHandle_t s_sample_q;
120extern QueueHandle_t s_enc_q;
121
122/* The INA3221's CH1 windows from the ring, each number once and in order,
123 * each with the servo rail's meter and its change count as decided in the
124 * poll that took it (servo_screen_window()). Full means the renderer is
125 * SAMPLE_Q_LEN windows behind, and the oldest is dropped. */
126typedef struct {
128 servo_source_id_t source;
129 uint32_t changes;
130 servo_source_why_t dropped; /* as supply_item_t's */
131 uint32_t dropped_at;
133extern QueueHandle_t s_win_q;
134extern SemaphoreHandle_t s_snap_lock;
135
136/*
137 * The IOmcu's update as the render side needs it: an offer, numbered,
138 * with the version the IOmcu runs; while an update runs, its step and
139 * blocks; and the STARTs the control task has taken, so a progress screen
140 * whose START was spent leaves.
141 */
142typedef struct {
143 uint32_t offer_gen;
144 bool offered;
145 cu_version_t running;
146 bool active;
147 uint8_t step; /* a cu_step_t */
148 uint16_t block;
149 uint16_t blocks;
150 uint32_t starts_taken;
151 uint8_t check; /* a cu_check_t: the last build check */
152 bool mismatch; /* an IOmcu of another protocol major
153 answers its identity (the link stays down) */
154} cu_snap_t;
155
156/* What the screen reads. Written by the control task, copied by app_main. */
157typedef struct {
158 bench_state_t bench;
159 supply_state_t supply;
160 uint32_t supply_gen;
161 bool link_up;
162 bool armed;
164 uint8_t armed_roles;
166 uint32_t arm_gen;
167 float mcu_temp_c;
168 bool stopped;
169 uint32_t stops;
170 uint32_t pressed;
171 uint16_t faults;
172 uint32_t link_errors;
173 uint32_t link_refused;
174 uint32_t run_seconds;
175 /* The control task's alert, numbered: an alert posted and replaced
176 * before a frame took it was never shown (sense_link_alerts()), and one
177 * whose cause is over is taken back (control_alert_withdraw()). */
178 ui_alert_slot_t alert;
179 /* The phase tap as the control task last read it, for the stick run's
180 * page. */
181 tone_readout_t tone;
182 /* The servo rail's meter as of the last poll (servo_source.h), and the
183 * CH1 windows that left the ring untaken since boot. */
184 servo_source_id_t servo_source;
185 uint32_t servo_source_changes;
186 /* Why the INA3221 is not the meter, and why and when it last stopped
187 * being it (servo_source_why(), servo_source_dropped()). */
188 servo_source_why_t servo_source_why;
189 servo_source_why_t servo_source_dropped;
190 uint32_t servo_source_dropped_at;
191 uint32_t servo_win_lost;
192 /* What the servo programmer's model is fed; see kst_publish(). */
193 kst_prog_feed_t kst;
197 /* The IOmcu's update; see cu_service(). */
198 cu_snap_t cu;
200extern panel_snap_t s_snap;
201
202static inline void snap_lock(void) { xSemaphoreTake(s_snap_lock, portMAX_DELAY); }
203static inline void snap_unlock(void) { xSemaphoreGive(s_snap_lock); }
204
205/* Called from the control task, which must not touch the router. The
206 * slot holds one alert; a later one replaces it. Returns its number. */
207uint32_t control_alert_numbered(const char *text);
208
219
220/* Take back alert number @p gen, whose cause is over: one not yet taken
221 * by a frame is dropped, and the last one a frame took is cleared from the
222 * band if it is still showing (ui_router_withdraw_alert()). An older
223 * alert is left alone, so withdrawals of several causes in one frame do
224 * not hide each other (ui_alert_slot.h). Control task only. */
225void control_alert_withdraw(uint32_t gen);
226
227/* The same, for the callers that do not follow it. Inlined where it is
228 * called, as the compiler chose before the numbering: a frame of its own
229 * puts 32 bytes on the control task's deepest chain (drv_lost() through
230 * control_pump()) and moves stack_check's walk onto a deeper path through
231 * ESP-IDF's logging. */
232__attribute__((always_inline)) static inline void
233control_alert(const char *text)
234{
235 snap_lock();
236 snprintf(s_snap.alert.text, sizeof(s_snap.alert.text), "%s", text);
237 s_snap.alert.pending = true;
238 /* ui_alert_slot_post(), written out for the same reason. */
239 ++s_snap.alert.posted;
240 if (s_snap.alert.posted == 0u) {
241 s_snap.alert.posted = 1u;
242 }
243 snap_unlock();
244}
245
246/* The safety loop's own state and the arming policy; see main.c. */
247extern outputs_t s_out;
248extern arming_t s_arm;
249extern uint16_t s_throttle_hundredths; /* 0..LINK_THROTTLE_MAX */
250extern atomic_bool s_disarm_request;
251
252/*
253 * A disarm returns the command to zero, here and in the output bank.
254 *
255 * The throttle used to survive a disarm, so the next arm wrote the previous
256 * position to the control page in the same transaction that armed: the bench
257 * went from stopped to whatever it was last set to, with the ramp on the far
258 * side of the arm rather than in front of it. An arm starts from nothing.
259 */
260static inline void throttle_to_zero(void)
261{
262 s_throttle_hundredths = 0u;
263 (void)outputs_set(&s_out, PANEL_CH_THROTTLE, 0u, now_ms());
264}
265
266/* The PD mini's input in mV and its UART rate in baud, as its page last
267 * read; 0 while not known. */
268extern atomic_uint s_supply_vin_mv;
269extern atomic_uint s_supply_baud;
270
271/* Which arm, for the render side's ack. */
272extern uint32_t s_arm_gen;
273
274/* The pole count the IOmcu holds, and whether it is current. */
275extern atomic_bool s_poles_owed;
276extern atomic_uint s_poles_value;
277
278/* The throttle endpoints the IOmcu holds (endpoints_link.h): owed, held
279 * disarmed at a link-up, the pair and the time of the last edit. The debt
280 * is paid once the pair has rested ENDPOINTS_SETTLE_MS, and a switch to
281 * ARMED with the link up is refused while it stands. */
283
284/* Where the PD mini is wired, from SETUP INTERFACES, in one word; see
285 * main.c. */
286extern atomic_uint s_pdmini_wiring;
287
288static inline supply_wiring_t wiring_of(unsigned word)
289{
290 const supply_wiring_t w = {
291 .en = (word & (1u << 24)) != 0u,
292 .tx = (int8_t)((int)((word >> 16) & 0xFFu) - 1),
293 .rx = (int8_t)((int)((word >> 8) & 0xFFu) - 1),
294 .baud = (uint8_t)(word & 0xFFu),
295 };
296 return w;
297}
298
299static inline supply_wiring_t pdmini_wiring(void)
300{
301 return wiring_of(atomic_load(&s_pdmini_wiring));
302}
303
304/* What SETUP INTERFACES and SETUP > SENSORS left for the current monitors
305 * and the phase tap, read by the control task; panel_sense.c publishes the
306 * monitors' from the settings observer. */
307void publish_sense(void);
308sense_setup_t sense_wanted(void);
310
311/* False until the control task owns the safety state. */
312extern bool s_pump_live;
313/* The safety loop, from the top of the control task and from inside every
314 * exchange. */
315void control_pump(void);
316
317
318/* The GPIOs of the slots of the channels the SERVO screen's horn drives
319 * (servo_link_binding()), and whether a binding was read; see main.c. */
320extern atomic_ullong s_servo_pins;
321extern atomic_bool s_servo_pins_known;
322/* For the SERVO screen's runs: the SENSE page holds the encoder enabled. */
323extern atomic_bool s_enc_held;
324
325/* ----------------------------------------------------------- panel_files.c */
326
328extern const files_io_t k_files_io;
329
330/* ------------------------------------------------------------ panel_card.c */
331
332/* Read once at start-up, from bring_up(). */
333void esc_profiles_load(void);
334/* The log viewer's way to the card. */
335extern const log_viewer_io_t k_card_io;
336
337/* The runs the logger has open, held back from the viewer: the automatic
338 * log's in AUTO LOG FOLDER, a test's CSV and report in USER LOG FOLDER,
339 * each in the folder it was opened in (log_open_marks()). */
340extern atomic_uint s_log_open_run;
341extern atomic_uint s_test_open_run;
342extern atomic_uint s_test_open_txt;
343/* The files the logger has created since the start, and the LOGS tab of
344 * the last one (log_viewer_tab_t): stored by the logger, the tab first. */
345extern atomic_uint s_card_written;
346extern atomic_int s_card_written_tab;
347
348/* One level of a folder of the card (card_make_fn, card_tree.h): the
349 * logs', the fault log's and the servo files' folders are made with it. */
350card_dir_t panel_card_make_dir(void *ctx, const char *level);
351
352/* The programmer's record, KST.TXT: filled by the render loop, written by
353 * the logger. */
354extern char s_kst_file[KST_PROG_FILE_MAX];
355extern size_t s_kst_file_len;
356/* The mount whose record the model holds (storage_mount_count()): the
357 * record is written to that volume or not at all. */
358extern unsigned s_kst_file_mount;
359extern atomic_uint s_kst_file_sent;
360extern atomic_uint s_kst_file_done;
361extern atomic_bool s_kst_file_ok;
362void kst_record_write(void);
363void kst_record_load(bool late);
364
365/* The Hitec programmer's record, HITEC.TXT (hitec_record.c): filled by
366 * the render loop, written by the logger, read at the start. */
370extern size_t s_hitec_file_len;
372extern unsigned s_hitec_file_mount;
375extern atomic_uint s_hitec_file_sent;
377extern atomic_uint s_hitec_file_done;
379extern atomic_bool s_hitec_file_ok;
384void hitec_record_write(void);
389void hitec_record_load(void);
390
391/* A servo file request: taken from the model by the render loop, run on
392 * the card by the logger. */
393extern kst_prog_card_req_t s_kst_card_req;
394/* The mount the request was taken under (storage_mount_count()): it is
395 * run on that volume or finds no card. */
396extern unsigned s_kst_card_mount;
397extern kst_prog_card_done_t s_kst_card_done;
398extern atomic_uint s_kst_card_sent;
399extern atomic_uint s_kst_card_answered;
400void kst_card_serve(void);
401
402/* ------------------------------------------------------------- panel_log.c */
403
404/* A run is one arming of the bench, or one switch-on of the supply's output
405 * while the bench is not armed; log_run_kind_t and the rule of which run
406 * the log records are in log_cadence.h. One run is one file, and a file
407 * holds one kind of row, so its header names every column it has. All
408 * runs are written to AUTO LOG FOLDER, none while AUTO LOGS is off. */
409
410/* The two folders SETUP > SD CARD names, AUTO LOG FOLDER and USER LOG
411 * FOLDER. */
412typedef enum {
413 LOG_FOLDER_AUTO = 0,
414 LOG_FOLDER_USER,
415 LOG_FOLDERS
416} log_folder_t;
417
418/* The folder the next file of @p kind is written to: one card_folder_check()
419 * takes (card_folder_use()). Called by the text observer on app_main;
420 * the logger reads it at each take, so a file open stays where it is and
421 * the next one is numbered in the new folder. */
422void log_set_folder(log_folder_t kind, const char *dir);
423
424/* The open markers and the folder each was opened in, read as one, for the
425 * viewer's card_busy(): @p run_dir and @p test_dir take CARD_DIR_MAX bytes
426 * and @p marks points into them. */
427void log_open_marks(log_marks_t *marks, char *run_dir, char *test_dir);
428
435bool log_fault_busy(void);
436
444void log_fault_lock(void);
445
447void log_fault_unlock(void);
448
457typedef struct {
458 uint32_t run;
459 float t_s;
460 log_run_kind_t kind;
471} log_row_t;
472
473/*
474 * Sixty-four rows is 3.2s of run at PANEL_SAMPLE_HZ, against the 250ms an
475 * SD card may take over one write: a card that pauses costs no rows.
476 */
477#define LOG_Q_LEN 64
478
479/* The report link_report() writes to the card, and how many may be in
480 * flight. The report is made every 5s at its fastest. */
481#define LOG_NOTE_MAX 208
482#define LOG_NOTE_Q_LEN 4
483
484/* One line of a servo test's files, render loop -> logger. */
485typedef struct {
486 uint8_t kind; /* servo_test_out_t */
487 char text[SERVO_TEST_LINE_MAX];
489
490#define TEST_Q_LEN 24
491
492extern QueueHandle_t s_log_q;
493extern QueueHandle_t s_note_q;
495extern SemaphoreHandle_t s_note_mx;
496extern QueueHandle_t s_test_q;
497/* The run being recorded, or 0: the control task's level, which the logger
498 * follows. */
499extern atomic_uint s_log_run_now;
500
501/* A servo test's OPENs and ENDs, queued by the render loop and taken by
502 * the logger, and what the logger made of them. */
503extern atomic_uint s_test_opens_sent;
504extern atomic_uint s_test_opens_done;
505extern unsigned s_test_ends_sent;
506extern atomic_uint s_test_ends_done;
507extern atomic_int s_test_file;
508extern atomic_bool s_test_report;
509
510/* The runlog task: every fopen, fwrite, fsync and fclose on the card. */
511void log_task(void *arg);
512
513/* main.c: the control task's side of the log, which numbers the runs and
514 * posts the rows. */
515extern log_cadence_t s_log_cad;
516extern log_run_kind_t s_log_kind;
517extern atomic_bool s_servo_testing;
518void log_post(log_row_t *row);
519
520/* ------------------------------------------------------------ panel_link.c */
521
522/* Exchanges that ended unanswered; a far end held to be answering; an
523 * exchange that ended unanswered with the link up. See panel_link.c. */
524extern uint32_t s_unanswered;
525extern bool s_link_is_up;
526extern bool s_link_quiet;
527
528/* Put a built request on the wire and wait for its answer. */
529bool exchange(link_host_t *host, const link_msg_t *req, link_msg_t *reply);
530
531static inline bool poll_page(link_host_t *host, uint8_t page, uint8_t count,
532 link_msg_t *reply)
533{
534 link_msg_t req;
535 if (!link_host_read(host, page, 0, count, now_ms(), &req)) {
536 return false;
537 }
538 return exchange(host, &req, reply);
539}
540
541/* A window of a page from @p offset; the reply's registers start there. */
542static inline bool read_regs(link_host_t *host, uint8_t page, uint8_t offset,
543 uint8_t count, link_msg_t *reply)
544{
545 link_msg_t req;
546 if (!link_host_read(host, page, offset, count, now_ms(), &req)) {
547 return false;
548 }
549 return exchange(host, &req, reply);
550}
551
552/* exchange() and the clock, as shared/link asks for them. */
553uint32_t port_now(void *ctx);
554void port_between(void *ctx);
555extern const link_port_t k_port;
556
557/*
558 * A write of any width goes out one frame per exchange, each acknowledged
559 * before the next is sent (link_write_acked()): the far end's controller
560 * buffers 2 frames and is polled, so frames sent back to back can find it
561 * full. A write of up to 4 registers is one exchange.
562 */
563static inline bool write_regs(link_host_t *host, uint8_t page, uint8_t offset,
564 uint8_t count, const uint16_t *regs,
565 link_msg_t *reply)
566{
567 return link_write_acked(host, &k_port, page, offset, count, regs, reply);
568}
569
570/* The control page: ARM and THROTTLE, the frame that arms, CLEAR, the pole
571 * count and the throttle's endpoints. See panel_link.c. */
572extern uint16_t s_arm_value;
573
574/*
575 * ARM and THROTTLE, the write every 50ms poll and every disarm makes.
576 *
577 * Two registers rather than the three the frame that arms carries. This
578 * write keeps a running bench running and stops a stopping one, and the
579 * pole count is neither: while a run is on, an edit to it is a correction
580 * paid on its own transaction by poles_service(), and a disarm has nothing
581 * to convert. Kept apart so a count the far end refuses -- or one that has
582 * not changed -- never stands between the throttle and the wire.
583 *
584 * True when the IOmcu acknowledged; a NACK (negative acknowledge) or
585 * no answer is false.
586 */
587static inline bool control_write(bool armed, link_msg_t *reply)
588{
589 /* The value the far end was armed with, written again: a different
590 * non-zero ARM is refused while it is armed (LINK_MINOR_ARM_ROLE). */
591 const uint16_t regs[2] = { armed ? s_arm_value : 0u,
592 s_throttle_hundredths };
593 return write_regs(&s_host, LINK_PAGE_CONTROL, LINK_CT_ARM, 2u, regs, reply)
594 && reply->op == LINK_OP_ACK;
595}
596
597bool control_arm(link_msg_t *reply);
598bool poles_service(void);
599void endpoints_service(bool far_disarmed);
600
601/*
602 * Whether the far end trusts the heartbeat, asked of its STATUS page.
603 *
604 * An arm waits for this before CLEAR is written. The heartbeat is withheld
605 * while a stop is latched, and after it resumes the far end's monitor needs
606 * five edges, 100 to 125ms at a 5ms pass and longer on a slower one: a
607 * fixed wait is right for one pass period and refused at the next. One
608 * register, one frame each way.
609 *
610 * @p answered is false when nobody answered. That exchange has then waited
611 * LINK_HOST_TIMEOUT_MS (1000ms), past the arm's whole bound, and it is the
612 * link that is gone and not the line that is distrusted.
613 */
614static inline bool far_line_trusted(bool *answered)
615{
616 link_msg_t st = { 0 };
617 *answered = read_regs(&s_host, LINK_PAGE_STATUS, LINK_ST_FAULTS, 1u, &st);
618 return *answered && st.op == LINK_OP_DATA
620}
621
622void far_end_stop_here(void);
623void arm_write_failed(uint32_t quiet_before, const char *alert);
624
625static inline bool control_clear_failsafe(link_msg_t *reply)
626{
627 const uint16_t magic = LINK_CLEAR_MAGIC;
628 return write_regs(&s_host, LINK_PAGE_CONTROL, LINK_CT_CLEAR, 1u, &magic,
629 reply)
630 && reply->op == LINK_OP_ACK;
631}
632
633/* What the panel knows about a link that stopped; the link report, every
634 * 5s while the link is down and every 60s while it is up. */
635void link_lost_report(busfault_report_t *r);
636void link_report(void);
637
638/*
639 * The seam between measured and modelled numbers. When the IOmcu
640 * answers, its numbers are used, and the LINK_BN_SIMULATED flag travels with
641 * them. When it does not, the panel models locally and sets the same flag.
642 * Nothing above this function knows the difference.
643 */
644static inline bool read_bench(link_host_t *host, bench_state_t *out)
645{
646 link_msg_t reply;
647 if (!poll_page(host, LINK_PAGE_BENCH, LINK_BN_COUNT, &reply)) {
648 return false;
649 }
650 if (reply.op == LINK_OP_NACK) {
651 return false;
652 }
653 bench_state_from_regs(out, reply.regs, reply.offset, reply.count);
654 return true;
655}
656
657/* -------------------------------------------------------- panel_services.c */
658
659/* The link modules, SENSE (4.7), TONE (4.8), KST (4.12) and PROG (4.13),
660 * and the servo rail's meter. Control task only. */
661extern sense_link_t s_sense_link;
662extern servo_source_t s_servo_source;
663extern tone_link_t s_tone_link;
664extern kst_link_t s_kst_link;
665extern prog_link_t s_prog_link;
666/* What the SERVO screen wants of the PROG page, and the pin of port 0. */
667extern atomic_uint s_prog_want_target;
668extern atomic_bool s_prog_want_pwm;
669extern atomic_uint s_prog_pin;
670/* The ports the PROG page reports (prog_link_count(), 0xFF while not
671 * known) in bits 0 to 7, and the pins of ports 1, 2 and 3 in bits 8 to 15,
672 * 16 to 23 and 24 to 31, for the OUTPUTS screen's PROG PORT entries and
673 * the pin picker; one word, so the screens never read one page's count
674 * with another's pins. */
675#define PROG_PORTS_NONE 0xFFFFFFFFu
676extern atomic_uint s_prog_ports;
677/* panel_ports.c: the ports' view and the screens' asks (port_view.h).
678 * prog_ports_publish() and prog_ports_lost() on the control task, the
679 * other two on the render loop. */
680void prog_ports_publish(void);
681void prog_ports_lost(void);
682void prog_ports_init_screens(void);
683void prog_ports_to_screens(void);
684/* Where the tester's commands go, for the SERVO screen's TARGET row:
685 * prog_link_drive()'s pin in bits 0 to 7, its target in bits 8 to 15 and its
686 * pulse in bit 16. One word, so the screen never reads one drive's target
687 * with another's pin or pulse. No link until an IOmcu answers. */
688#define DRIVE_PWM_BIT (1u << 16)
689/* Bits 20 to 23 of s_drive: the ports the HITEC page holds
690 * (prog_link_hitec_held()), for the PROGRAM list's PORT IN USE. */
691#define DRIVE_HELD_SHIFT 20u
692extern atomic_uint s_drive;
696extern bool s_prog_taken;
697extern kst_prog_gate_t s_kst_gate;
698/* The SENSE and TONE set-ups that are not held at the far end. */
699extern atomic_uint s_sense_unheld;
700extern atomic_uint s_tone_unheld;
701/* Hitec D receive (HITEC, 4.24): the module, the mode SETUP asks
702 * (link_hitec_rx_t, from the render loop) and what its row says
703 * (hitec_rx_link_mark_t, to the render loop). */
704extern hitec_rx_link_t s_hitec_rx_link;
705extern atomic_uint s_hitec_rx_want;
706extern atomic_uint s_hitec_rx_mark;
707
708void kst_port_look(void);
709void sense_link_alerts(void);
710void sense_link_service(bool idle, bench_state_t *bench);
711
712/* ----------------------------------------------------------- panel_sense.c */
713
714/* The SENSE_MAP page (4.25) and the INA3221 parts' states for SETUP >
715 * SENSORS (sense_map_link_status()'s word). Control task only, but
716 * s_sense_parts, which app_main reads. */
717extern sense_map_link_t s_sense_map;
718extern atomic_uint s_sense_parts;
719/* SENSE_LIMIT (4.27, panel_limit.c): SETUP > SENSORS' LIMIT rows taken on
720 * app_main by publish_limits(), the page served by the control task, and
721 * s_sense_limits, sensors_rows_set_limits()'s word, for app_main. */
722
725void publish_limits(void);
731void sense_limit_came_up(uint16_t minor);
733void sense_limit_lost(void);
736void sense_limit_service(void);
739extern atomic_uint s_sense_limits;
740void sense_map_came_up(uint16_t minor);
741void sense_map_lost(void);
742void sense_map_service(bool idle);
743/* SENSE_WIN_A and SENSE_WIN_B (4.25): read on every poll after SERVO_WIN;
744 * the window number @p b's servo_window names attached as its chw, FAST's
745 * channel from the ring's window with @p ring. Control task. */
746void sense_win_service(void);
747void sense_win_attach(bench_state_t *b, bool ring);
748/* The log's INA3221 columns for a file opened now (log_cols.h); false for
749 * CH1 to CH3. Any task. */
750bool sense_log_cols(log_cols_t *out);
751void tone_link_alerts(void);
752void tone_link_service(void);
753void kst_commands(void);
754void kst_link_service(void);
755void prog_link_service(void);
756void hitec_rx_service(void);
757void kst_publish(kst_prog_feed_t *f);
758
759/* ------------------------------------------------------------ panel_hitec.c */
760
767void hitec_commands(void);
770void hitec_pass(bool link_up);
773bool hitec_taken(void);
778
779/* Where the tester's commands go, into s_drive for the SERVO screen: from
780 * each pass of prog_link_service() and from the link-lost edge. */
781static inline void prog_drive_publish(void)
782{
783 const prog_link_drive_t drive = prog_link_drive(&s_prog_link);
784 atomic_store(&s_drive, ((unsigned)drive.target << 8) | drive.pin
785 | (drive.pwm ? DRIVE_PWM_BIT : 0u)
786 | ((unsigned)prog_link_hitec_held(&s_prog_link)
787 << DRIVE_HELD_SHIFT));
788}
789
790/* ------------------------------------------------------------ panel_poll.c */
791
792/* The GPIOs of the throttle's slots, whether a binding was read, and the
793 * protocol they are bound as (outbind_role_proto()). */
794extern atomic_ullong s_throttle_pins;
795extern atomic_bool s_throttle_pins_known;
796extern atomic_uint s_throttle_proto;
797
798/* The OUTPUTS page as the IOmcu holds it; the OUTPUTS screen's write
799 * asks for one straight afterwards. */
800void read_outputs_binding(void);
801void post_no_reading(void);
802
803/* One pass of the poll: the bench page while the far end answers, the
804 * identity page while it does not. */
805bool poll_far_end(bool *link_up, bench_state_t *bench,
806 uint32_t *last_poll, uint32_t *last_status);
807void advance_model_and_log(bool link_up, float emitted,
808 telemetry_sim_t *sim, bench_state_t *bench,
809 bool *new_sample);
810void publish_snapshot(const bench_state_t *bench, bool link_up,
811 bool new_sample);
812
813/* ------------------------------------------------------- main.c, continued */
814
815/* The throttle's ramp, published by app_main for the control task. */
816extern atomic_uint s_throttle_ramp;
817void publish_throttle_ramp(void);
818static inline uint16_t panel_throttle_ramp(void)
819{
820 return (uint16_t)atomic_load(&s_throttle_ramp);
821}
822
823/*
824 * The bench page is polled every 50ms, so a sample is 1/20s of plot. The
825 * motor screen scales its time axis by the same number; the two have to
826 * agree or the axis lies about how long ago something happened.
827 */
828#define PANEL_SAMPLE_HZ 20.0f
829
830typedef enum { PANEL_CMD_MOTOR = 0, PANEL_CMD_SERVO,
831 PANEL_CMD_STOP, PANEL_CMD_OUTPUTS,
832 PANEL_CMD_SUPPLY } panel_cmd_kind_t;
833
834typedef struct {
835 panel_cmd_kind_t kind;
836 motor_cmd_t motor;
837 servo_cmd_t servo;
850 uint32_t stops;
852 uint32_t lets_go;
855 uint32_t supply_offs;
859 uint32_t pdmini_edits;
873 uint32_t loss_gen;
874 uint32_t consumed_seq;
876
877/* What became of the last output-page write. */
878extern atomic_int s_outputs_result;
879
880/* The queues between the two tasks, and their items; see main.c. */
881typedef struct {
882 touch_event_t evt;
883 uint32_t seq;
884 bool lost;
886extern QueueHandle_t s_touch_q;
887typedef struct {
889 servo_source_id_t source;
890 uint32_t changes;
891 /* Why the INA3221 last stopped being the meter, and at which count
892 * (servo_source_dropped()), as of the same poll. */
893 servo_source_why_t dropped;
894 uint32_t dropped_at;
896extern QueueHandle_t s_supply_q;
897
898/* STOP's request and its count; the let-goes asked for. */
899extern atomic_bool s_stop_request;
900extern atomic_uint s_stop_counted;
901extern atomic_uint s_lets_go;
902
903/* The supply's switch and set points, from the render side. */
904extern atomic_bool s_supply_off_request;
905extern atomic_uint s_supply_offs;
906extern atomic_uint s_supply_set_mv;
907extern atomic_uint s_supply_set_ma;
908extern atomic_uint s_supply_vmax_mv;
909extern atomic_uint s_supply_imax_ma;
910extern atomic_uint s_supply_trip_ma;
911extern atomic_uint s_supply_trip_mv;
912extern atomic_uint s_supply_trip_ms;
913extern atomic_uint s_supply_ack;
914extern atomic_bool s_supply_live;
915extern atomic_uint s_supply_ons_sent;
916extern atomic_uint s_supply_ons_taken;
917extern atomic_uint s_pdmini_edits;
918extern atomic_bool s_supply_real;
919
920/* The touch stream's numbering and losses, and the arm watch; see
921 * touch_loss.h. */
922extern atomic_uint s_drv_gaps;
923extern atomic_uint s_tq_published;
924extern uint32_t s_lost_notice_seq;
925extern atomic_uint s_loss_gen;
926extern atomic_uint s_arm_ack;
929extern atomic_uint s_render_progress;
930
935static inline void render_progress(void)
936{
937 atomic_fetch_add(&s_render_progress, 1u);
938}
939extern uint32_t s_arm_take_gen;
940extern uint32_t s_arm_take_drv;
941extern arm_watch_t s_arm_watch;
942
943/* A supply run's row timestamp, and the log's run edges; see main.c. */
944extern float s_log_t;
945void log_follow_runs(void);
946
947/* The screens' commands, app_main -> control task; see main.c. */
948extern QueueHandle_t s_cmd_q;
949
950/* ---------------------------------------------------------- panel_supply.c */
951
952/* The modelled supply and the PD mini's link. */
953extern supply_sim_t s_supply_sim;
954extern supply_link_t s_supply_link;
955/* Set points the supply reported, for the screen to adopt. */
956extern atomic_uint s_supply_adopt_mv;
957extern atomic_uint s_supply_adopt_ma;
958extern atomic_uint s_supply_adopt_gen;
959extern atomic_uint s_supply_adopt_done;
960/* The ESC (electronic speed controller) model's profile and its runs. */
961extern atomic_uintptr_t s_escsim_profile;
962extern atomic_uint s_escsim_runs;
963extern bool s_supply_page;
964extern bool s_supply_auto;
965extern bool s_supply_is_real;
966extern supply_state_t s_supply;
967extern uint32_t s_supply_ms;
968extern uint32_t s_supply_stops_served;
969extern uint32_t s_supply_step_ms;
970extern uint32_t s_supply_gen;
971
972void supply_log_tail(void);
973void supply_switch(bool on);
974void supply_follow_set(void);
975/*
976 * Every stop switches the output off: STOP, touch that died, an arm the
977 * watch undid, the far end's refusal. Called from control_pump(), which
978 * runs inside every exchange's wait, and again wherever the supply is
979 * stepped or switched, so a stop counted anywhere cuts the output before
980 * the next reading is taken or logged.
981 */
982static inline void supply_follow_stops(void)
983{
984 const uint32_t stops = arming_stop_count(&s_arm);
985 if (stops != s_supply_stops_served) {
986 s_supply_stops_served = stops;
987 supply_switch(false);
988 }
989}
990
991/*
992 * An OFF asked for, whether or not its queue entry survived; applying it
993 * twice costs nothing. Called before the drain, so an OFF is never left
994 * waiting behind the queue's backlog. And the set points, every pass.
995 */
996static inline void supply_service(void)
997{
998 if (atomic_exchange(&s_supply_off_request, false)) {
999 supply_switch(false);
1000 }
1001 supply_follow_set();
1002}
1003
1004void apply_supply_cmd(const panel_cmd_t *pc);
1005/* The supply's service, from control_pump(). */
1006void supply_pump(void);
1007void supply_link_service(void);
1008
1009/* ------------------------------------------------------------- panel_arm.c */
1010
1011void control_setup(telemetry_sim_t *sim, bench_state_t *bench);
1012/* The bench's totals, and when they last counted. */
1013extern bench_totals_t s_totals;
1014extern uint32_t s_totals_ms;
1017extern log_rail_t s_rail;
1023extern atomic_uint s_servo_log;
1024void arm_watch_service(bool link_up);
1025/* The latched stop, and the act the arming policy asks for. */
1026void service_arming(bool link_up);
1027bool disarm_here(bool link_up);
1028/* What the screens asked for, in the order they asked it. */
1029void drain_commands(bool link_up, bench_state_t *bench);
1030
1031/* ---------------------------------------------------------- panel_render.c */
1032
1033void kst_ui_service(void);
1035void hitec_ui_service(void);
1036extern unsigned s_tq_lost;
1037bool supply_live_or_coming(void);
1038void publish_supply_levels(void);
1039void test_lines_service(void);
1040typedef struct {
1041 int steps;
1042 ui_screen_id_t route;
1043 uint32_t navigations;
1044} knob_turn_t;
1045
1046knob_turn_t knob_take(void);
1047void knob_apply(const knob_turn_t *turn, bool frame_lost);
1048void flush_screen_commands(uint32_t stops_now);
1049bool drain_touch(uint32_t stops_now);
1050void outputs_apply(const outbind_t *b);
1051
1052/* ------------------------------------------------------------- panel_art.c */
1053
1054extern const art_flash_t *s_artflash;
1055/* A drawing fetch is under way; see art_begin(). */
1056extern bool s_artbusy;
1057extern atomic_bool s_keeping;
1058extern SemaphoreHandle_t s_draw_lock;
1059extern uint8_t *s_drawpub;
1060extern uint8_t *s_drawshow;
1061void drawing_for_picker(uint16_t board);
1062void drawing_follow(void);
1063void art_keep_service(void);
1064/* The board drawing, a slice of a poll at a time. */
1065void art_stop(const char *why);
1066void art_begin(uint16_t board);
1067void art_slice(void);
1068
1069/* ---------------------------------------------------------- panel_update.c */
1070
1071/* An install about to write the flash asks the control task to stand
1072 * still (s_fw_quiet_req), and the control task says it does
1073 * (s_fw_quiet_ack). False when wifi_access_init() failed (s_wifi_ok). */
1074extern atomic_bool s_fw_quiet_req;
1075extern atomic_bool s_fw_quiet_ack;
1076extern bool s_wifi_ok;
1077
1078/* An IOmcu of another protocol major answering the probe; control
1079 * task. panel_poll.c. */
1080extern link_uph_mismatch_t s_mismatch;
1081
1082/* Whether the IOmcu's update may start: see fw_coproc_may_start().
1083 * From any task. */
1084bool cu_may_start(void);
1085/* The IOmcu update's check, for an IOmcu that just answered. */
1086void cu_link_up(const link_msg_t *reply);
1087/* One pass of the IOmcu's update, before the poll: true while the
1088 * update holds the link. Control task. */
1089bool cu_service(bool *link_up, bench_state_t *bench,
1090 uint32_t *last_poll, uint32_t *last_status);
1091
1092/* Once a frame on app_main: WI-FI, the reminder, SETUP > UPDATES
1093 * and the IOmcu update's screen. */
1094void wifi_service(bool armed, uint32_t stops_now);
1095void upd_remind_service(bool armed, bool unsafe, const cu_snap_t *cs);
1104void upd_service(bool armed, bool unsafe, uint32_t stops_now,
1105 const cu_snap_t *cs);
1106void cu_render_service(bool unsafe, bool link_up, const cu_snap_t *cs);
uint32_t arming_stop_count(const arming_t *a)
How many stops have been applied.
Definition arming.c:95
When the bench is allowed to be armed, and what the panel must tell the IOmcu about it.
Keeping a board's drawing, so it is fetched once and not every time the link comes up.
void bench_state_from_regs(bench_state_t *b, const uint16_t *regs, uint8_t offset, uint8_t count)
Decode a BENCH page into b.
Definition bench_state.c:81
The bench readings, in the units a person reads: V, A, W, rpm (revolutions per minute),...
The folders of the panel's SD (Secure Digital) card, and the files in them with a fixed name.
card_dir_t
What making a folder came to.
Definition card_tree.h:118
The IOmcu's firmware update, as the panel offers and shows it.
FILES: the SD (Secure Digital) card in two panes, commander style, and the operations on its files an...
#define HITEC_CARD_TEXT_MAX
The text's size, with its terminator: a D series record takes 234 bytes.
Definition hitec_card.h:56
The programmer for servos by Hitec as the SERVO screen runs it: the session with one servo,...
void hitec_record_write(void)
Write the text the render loop handed over (panel.h).
Definition hitec_record.c:79
atomic_uint s_hitec_file_sent
Texts handed over (panel.h).
Definition hitec_record.c:54
void hitec_record_load(void)
Read the record from the card at the start (panel.h).
Definition hitec_record.c:140
char s_hitec_file[HITEC_CARD_TEXT_MAX]
The record's text (panel.h).
Definition hitec_record.c:48
atomic_uint s_hitec_file_done
Texts written or given up on (panel.h).
Definition hitec_record.c:56
unsigned s_hitec_file_mount
The mount the text is written to (panel.h).
Definition hitec_record.c:52
atomic_bool s_hitec_file_ok
Whether the card took the last text whole (panel.h).
Definition hitec_record.c:58
size_t s_hitec_file_len
The bytes of s_hitec_file to write (panel.h).
Definition hitec_record.c:50
uint8_t control_write(void *ctx, uint8_t off, uint8_t n, const uint16_t *in)
Writes the CONTROL page.
Definition iomcu_pages.c:542
The programmer for KST and Chaservo servos as the SERVO screen runs it: what is read from a servo,...
#define KST_PROG_FILE_MAX
The file text's size, with its terminator.
Definition kst_prog.h:98
The run log's cadence: which pass of the control loop writes a row, and the time that row carries.
The bench log's INA3221 columns with SENSE_MAP in force (protocol 4.25): one group of three per chann...
Taking a run's number in a folder of the card, and which open file keeps a listed name out of reach.
Log viewer: browse the card, review the import, plot the file.
Writes a run as CSV (comma-separated values) in the format shared/logfile reads.
The motor and ESC (electronic speed controller) bench screen.
Binding a protocol to pins: what the operator chooses, and the OUTPUTS page that comes out of it.
The intermediary every output goes through: one set of rules for arming, clamping,...
bool outputs_set(outputs_t *o, uint8_t ch, uint16_t command, uint32_t now_ms)
Command a channel.
Definition outputs.c:219
QueueHandle_t s_enc_q
Definition main.c:290
QueueHandle_t s_kst_q
Definition main.c:272
QueueHandle_t s_sample_q
Definition main.c:284
atomic_uint s_render_progress
The render loop's progress: moved once a pass of panel_frame_loop() and once per card read the loop m...
Definition main.c:466
atomic_uint s_stop_counted
Definition main.c:348
QueueHandle_t s_cmd_q
Definition main.c:268
QueueHandle_t s_win_q
Definition main.c:291
QueueHandle_t s_touch_q
Definition main.c:267
QueueHandle_t s_supply_q
Definition main.c:288
void log_fault_lock(void)
Take the fault log's lock, which the logger holds across each line's open, write and close....
Definition panel_log.c:734
atomic_uint s_servo_log
The SERVO screen's pulse and angle for a SERVO run's rows, packed (log_servo_pack()): stored by the r...
Definition panel_poll.c:791
void hitec_ui_service(void)
The Hitec programmer's model, once a frame on app_main.
Definition panel_render.c:127
gfx_canvas_t * panel_canvas(void)
The canvas the next frame is drawn on (display_canvas()), after what Screen rotation asks of the UI: ...
Definition panel_frame.c:63
void control_pump(void)
Drains the touch driver's queue, answers sequence gaps, applies a STOP at its press and passes the ev...
Definition panel_control.c:240
endpoints_debt_t s_endpoints
The throttle's pulse endpoints, Idle pulse and Full pulse, on their way to the IOmcu.
Definition panel_settings.c:77
void sense_limit_lost(void)
The link went; control task. Clears s_sense_limits.
Definition panel_limit.c:64
hitec_prog_gate_t s_hitec_gate
The gate the Hitec programmer's commands are claimed at; the one part both tasks touch.
Definition panel_hitec.c:45
QueueHandle_t s_hitec_q
The model's commands, app_main -> control task.
Definition panel_hitec.c:48
void sense_limit_service(void)
Serves SENSE_LIMIT, at most 2 exchanges, and sends the next band alert; control task,...
Definition panel_limit.c:102
bool s_prog_taken
Whether a servo programmer, KST or Hitec, has a port or an operation under way: the bench takes no ar...
Definition panel_services.c:96
void sense_limit_came_up(uint16_t minor)
The link came up; control task.
Definition panel_limit.c:59
void upd_service(bool armed, bool unsafe, uint32_t stops_now, const cu_snap_t *cs)
SETUP > UPDATES, the reminder and the download, once a frame.
Definition panel_update.c:833
atomic_uint s_sense_limits
sensors_rows_set_limits()'s word; control task writes, app_main reads.
Definition panel_limit.c:43
QueueHandle_t s_log_q
Definition panel_log.c:74
QueueHandle_t s_note_q
Definition panel_log.c:75
bench_totals_t s_rail_totals
The run's totals of s_rail since the arm. Control task only.
Definition panel_arm.c:135
bool drain_touch(uint32_t stops_now)
Hand the screens what the control task saw of the panel. Render loop only.
Definition panel_render.c:506
void service_arming(bool link_up)
The latched stop and the act the arming policy asks for, once a pass of the control task: the router'...
Definition panel_arm.c:249
void publish_limits(void)
Takes the LIMIT and WATCHES rows for the control task; app_main, from the SENSORS observer.
Definition panel_limit.c:45
static void render_progress(void)
The render task made progress: a pass of its loop, or one card read inside a pass....
Definition panel.h:935
void hitec_commands(void)
The Hitec programmer's commands, at most 4 a pass; control task.
Definition panel_hitec.c:109
void hitec_pass(bool link_up)
One pass of the HITEC page's module; control task, every pass.
Definition panel_hitec.c:169
QueueHandle_t s_test_q
Definition panel_log.c:517
tone_setup_t tone_wanted(void)
Returns the phase tap's set-up as SETUP INTERFACES left it, copied under the spinlock.
Definition panel_settings.c:136
void hitec_publish(hitec_prog_feed_t *f)
What the Hitec programmer's model is fed; under the snapshot's lock.
Definition panel_hitec.c:185
void link_report(void)
One block naming the most fundamental fault rather than the loudest. Printed every 5s while the link ...
Definition panel_link.c:582
void log_task(void *arg)
Everything that touches the card.
Definition panel_log.c:852
const files_io_t k_files_io
FILES' way to the card: its requests run on the task cardjob.
Definition panel_files.c:736
void log_fault_unlock(void)
Give the fault log's lock back.
Definition panel_log.c:741
float s_mcu_c
Read and published by the control task; app_main takes it from the snapshot with everything else that...
Definition panel_control.c:88
log_rail_t s_rail
The supply's last reading for a SERVO run's rows (log_rail_t). Control task only.
Definition panel_arm.c:134
bool hitec_taken(void)
Whether the HITEC page holds a port or a request runs.
Definition panel_hitec.c:176
hitec_link_t s_hitec_link
The HITEC page's module (4.23); control task only.
Definition panel_hitec.c:42
bool log_fault_busy(void)
Whether the logger may write a fault log line now: one queued in s_note_q, or under way....
Definition panel_log.c:728
SemaphoreHandle_t s_note_mx
The fault log's lock (log_fault_lock()).
Definition panel_log.c:76
The IOmcu's decision to arm, once a pass and at every CONTROL write.
bool safety_gate_line_trusted(uint16_t faults)
The panel's reading of a STATUS fault bitmap: whether the far end trusts the heartbeat.
Definition safety_gate.c:126
The SERVO link page at the IOmcu: the frame rate of the tester's target and the sweep that drives it ...
The servo bench: the outputs the binding marks as surfaces, commanded together by dragging one horn.
Which meter measures the servo rail: the INA3221's CH1, the PD mini (the WeAct PD Power Mini supply) ...
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
What the automatic servo test reads and what it hands out: the supply's readings, the INA3221's windo...
#define SERVO_TEST_LINE_MAX
The longest line a log row or a report line takes, terminator included: the CSV's header with the enc...
Definition servo_test_io.h:134
Whether an arm stands until the render loop has seen it.
Definition touch_loss.h:126
Definition arming.h:102
The flash a store lives in.
Definition art_store.h:52
The bench readings in the units a person reads: V, A, W and rpm, with their peaks.
Definition bench_state.h:54
A run's charge and energy, counted by the panel.
Definition bench_state.h:332
One reading of the two output pages, and the binding it gives.
Definition bind_link.h:105
Definition busfault_screen.h:69
Definition panel.h:142
Definition coproc_update_screen.h:51
The debt.
Definition endpoints_link.h:162
The card's task as the screen reaches it. Every function may be called on the task that renders; none...
Definition files_screen.h:64
Definition gfx.h:129
What the task that owns the link module publishes, every frame.
Definition hitec_prog.h:311
The pass a command needs to be carried out, as kst_prog.h's gate.
Definition hitec_prog.h:275
Definition panel.h:1040
The card side's answer to a request.
Definition kst_prog.h:380
A request to the card side.
Definition kst_prog.h:366
What the task that owns the link module publishes, every frame.
Definition kst_prog.h:500
The pass a START needs to be carried out.
Definition kst_prog.h:441
The cadence state of the run log: its clocks and row counts.
Definition log_cadence.h:62
The log's columns: their number, targets and names.
Definition log_cols.h:45
The files the logger has open, each with the folder it is in: the automatic log's run in run_dir,...
Definition log_take.h:203
The servo rail's supply on a SERVO run's row: the supply's last reading and the run's totals of it,...
Definition log_writer.h:188
One sample on its way to the card, filled by the control task.
Definition panel.h:457
float t_s
Definition panel.h:459
log_run_kind_t kind
Definition panel.h:460
log_servo_t servo
The pulse and angle, on the same rows as rail.
Definition panel.h:470
log_rail_t rail
The supply's reading and the run's totals of it, on a SERVO run's row that carries the sample; all 0 ...
Definition panel.h:468
uint32_t run
Definition panel.h:458
A SERVO run's commanded pulse and measured angle on its row.
Definition log_writer.h:257
Definition log_viewer_screen.h:137
Definition motor_screen.h:44
The selection: which board, the protocol being edited, and each protocol's pins.
Definition out_bind.h:423
The state of a bank of channels and slots.
Definition outputs.h:143
Definition panel.h:834
uint32_t supply_offs
Definition panel.h:855
uint32_t loss_gen
Definition panel.h:873
outbind_t bind
Definition panel.h:838
uint32_t lets_go
Definition panel.h:852
supply_cmd_t supply
Definition panel.h:839
uint32_t stops
Definition panel.h:850
uint32_t pdmini_edits
Definition panel.h:859
Definition panel.h:157
bool arm_wanted
Definition panel.h:165
uint32_t arm_gen
Definition panel.h:166
uint32_t pressed
Definition panel.h:170
hitec_prog_feed_t hitec
What the Hitec programmer's model is fed; see hitec_publish().
Definition panel.h:196
uint32_t link_refused
Definition panel.h:173
uint32_t supply_gen
Definition panel.h:160
uint8_t armed_roles
Definition panel.h:164
The set-up as SETUP INTERFACES has it.
Definition sense_link.h:196
A command of the SERVO screen, as the servo link takes it.
Definition servo_cmd.h:58
The state of which meter measures the servo rail.
Definition servo_source.h:104
Definition panel.h:126
Definition supply_screen.h:69
Definition panel.h:887
The state of the supply model.
Definition supply.h:264
A supply's readings, set points, mode and trip state.
Definition supply.h:69
Where the PD mini is wired, as SETUP INTERFACES has it.
Definition supply_link.h:85
The state of the telemetry model.
Definition telemetry_sim.h:57
Definition panel.h:485
The screen's copy: a plain value the control task fills and the renderer reads.
Definition tone_link.h:217
The set-up as SETUP INTERFACES has it.
Definition tone_link.h:134
A DOWN, MOVE or UP of one contact.
Definition touch_types.h:69
Definition panel.h:881
bool lost
Definition panel.h:884
Definition ui_alert_slot.h:36
A programmable supply: what it can be set to, what it was set to, and what it delivers.
The SUPPLY screen: a programmable supply set, switched and watched.
A pack, a motor and a propeller, modelled, so every screen runs without a measurement front end.
Touch events that never arrived, and an arm that must not outlive one.
Plain data types shared by the touch controller driver, the coordinate mapper and the event tracker....
Screen router.
bench_state_t bench
supply_state_t supply