REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
mode.cpp
Go to the documentation of this file.
1// Copyright (c) 2024 anabrid GmbH
2// Contact: https://www.anabrid.com/licensing/
3// SPDX-License-Identifier: MIT OR GPL-2.0-or-later
4
5#include <Arduino.h>
6#include <FlexIO_t4.h>
7
8#include <mode/counters.h>
9#include <mode/mode.h>
10#include <mode/teensy/mode.h>
11#include <utils/factorize.h>
12#include <utils/logging.h>
13
14bool mode::is_global_overload_active() {
15 // TODO: This is probably inverted.
16 return digitalReadFast(PIN_MODE_OVERLOAD);
17}
18
19void mode::ManualControl::init() {
20 digitalWriteFast(PIN_MODE_IC, HIGH);
21 digitalWriteFast(PIN_MODE_OP, HIGH);
22 pinMode(PIN_MODE_IC, OUTPUT);
23 pinMode(PIN_MODE_OP, OUTPUT);
24 digitalWriteFast(PIN_MODE_IC, HIGH);
25 digitalWriteFast(PIN_MODE_OP, HIGH);
26}
27
28void mode::ManualControl::to_ic() {
29 digitalWriteFast(PIN_MODE_OP, HIGH);
30 digitalWriteFast(PIN_MODE_IC, LOW);
31 mode::PerformanceCounter::get().to(mode::Mode::IC);
32}
33
34void mode::ManualControl::to_op() {
35 digitalWriteFast(PIN_MODE_IC, HIGH);
36 digitalWriteFast(PIN_MODE_OP, LOW);
37 mode::PerformanceCounter::get().to(mode::Mode::OP);
38}
39
40void mode::ManualControl::to_halt() {
41 digitalWriteFast(PIN_MODE_IC, HIGH);
42 digitalWriteFast(PIN_MODE_OP, HIGH);
43 mode::PerformanceCounter::get().to(mode::Mode::HALT);
44}
45
46void mode::RealManualControl::enable() {
50 }
51 }
52}
53
54void mode::RealManualControl::disable() {
58 } else {
59 // this should not happen.
60 }
61 }
62}
63
64void mode::RealManualControl::to_ic() {
65 enable();
68 } else {
69 mode::ManualControl::to_ic();
70 }
71}
72
73void mode::RealManualControl::to_op() {
74 enable();
77 } else {
78 mode::ManualControl::to_op();
79 }
80}
81
82void mode::RealManualControl::to_halt() {
83 enable();
86 } else {
87 mode::ManualControl::to_halt();
88 }
89}
90
91// storage and default values for static class members
92bool mode::FlexIOControl::_is_initialized = false;
93bool mode::FlexIOControl::_is_enabled = false;
94
95bool mode::FlexIOControl::init(unsigned long long ic_time_ns, unsigned long long op_time_ns,
96 mode::OnOverload on_overload, mode::OnExtHalt on_ext_halt, mode::Sync sync) {
97 // Initialize and reset QTMR
100
101 // Get FlexIO handler for initialization
102 auto flexio = FlexIOHandler::flexIOHandler_list[2];
103
104 // Set clock settings
105 // For (3, 0, 0) the clock frequency is 480'000'000
106 flexio->setClockSettings(CLK_SEL, 0, 0);
107 auto CLK_FREQ = flexio->computeClockRate();
108 auto CLK_FREQ_MHz = CLK_FREQ / 1'000'000;
109 // Enable fast access?
110 // flexio->port().CTRL |= FLEXIO_CTRL_FASTACC;
111
112 //
113 // Configure sync matcher
114 //
115
116 // Get internal FlexIO pins from external pins
117 uint8_t _sck_flex_pin = flexio->mapIOPinToFlexPin(PIN_SYNC_CLK);
118 if (_sck_flex_pin == 0xff)
119 return false;
120
121 // Configure a timer to track signal of PIN_SYNC_CLK
122 flexio->port().TIMCTL[t_sync_clk] = FLEXIO_TIMCTL_PINSEL(_sck_flex_pin) | FLEXIO_TIMCTL_TIMOD(1);
123 flexio->port().TIMCFG[t_sync_clk] = FLEXIO_TIMCFG_TIMOUT(1) | FLEXIO_TIMCFG_TIMDEC(2);
124 flexio->port().TIMCMP[t_sync_clk] = 0x0000'FF'00;
125
126 // Select a shifter for monitoring PIN_SYNC_ID
127 auto _flexio_pin_data_in = flexio->mapIOPinToFlexPin(PIN_SYNC_ID);
128 if (_flexio_pin_data_in == 0xff)
129 return false;
130 // Configure the shifter into continuous match mode, monitoring SYNC_CLK_ID
131 flexio->port().SHIFTCTL[z_sync_match] = FLEXIO_SHIFTCTL_TIMSEL(t_sync_clk) |
132 FLEXIO_SHIFTCTL_PINSEL(_flexio_pin_data_in) |
133 FLEXIO_SHIFTCTL_SMOD(0b101);
134 flexio->port().SHIFTCFG[z_sync_match] = 0;
135 // Set compare value in SHIFTBUF[31:16] and mask in SHIFTBUF[15:0] (1=mask, 0=no mask)
136 flexio->port().SHIFTBUF[z_sync_match] = 0b01010101'00001111'00000000'00000000;
137
138 // Get a timer which is enabled when there is a match
139 // Configure timer
140 flexio->port().TIMCTL[t_sync_trigger] =
141 FLEXIO_TIMCTL_TRGSEL(4 * z_sync_match + 1) | FLEXIO_TIMCTL_TRGSRC | FLEXIO_TIMCTL_TIMOD(1);
142 flexio->port().TIMCFG[t_sync_trigger] = FLEXIO_TIMCFG_TIMDIS(2) | FLEXIO_TIMCFG_TIMENA(6);
143 flexio->port().TIMCMP[t_sync_trigger] = 0x0000'01'00;
144
145 //
146 // Configure IDLE state
147 //
148
149 switch (sync) {
150 case Sync::NONE:
151 flexio->port().SHIFTCTL[s_idle] = FLEXIO_SHIFTCTL_PINCFG(3) | FLEXIO_SHIFTCTL_SMOD_STATE;
152 flexio->port().SHIFTBUF[s_idle] = FLEXIO_STATE_SHIFTBUF(0b11111111, s_idle);
153 case Sync::MASTER:
154 case Sync::SLAVE:
155 flexio->port().SHIFTCTL[s_idle] =
156 FLEXIO_SHIFTCTL_TIMSEL(t_sync_trigger) | FLEXIO_SHIFTCTL_PINCFG(3) | FLEXIO_SHIFTCTL_SMOD_STATE;
157 flexio->port().SHIFTBUF[s_idle] = FLEXIO_STATE_SHIFTBUF(0b11111111, s_ic);
158 }
159 flexio->port().SHIFTCFG[s_idle] = 0;
160
161 //
162 // Configure state check timer
163 //
164
165 // Some states are changed not by timer triggers, but by continuously checking of the inputs
166 // Configure state change check timer as fast as possible
167 flexio->port().TIMCTL[t_state_check] = FLEXIO_TIMCTL_TIMOD(3);
168 flexio->port().TIMCFG[t_state_check] = FLEXIO_TIMCFG_TIMDIS(0) | FLEXIO_TIMCFG_TIMENA(0);
169 flexio->port().TIMCMP[t_state_check] = 0x0000'0001;
170
171 //
172 // Configure IC state
173 //
174
175 // Sanity check ic_time_ns
176 if (ic_time_ns < 100 or ic_time_ns >= 9'000'000'000) {
177 LOG_ERROR("FlexIOControl: Requested ic_time_ns cannot be represented by 32bit.");
178 return false;
179 }
180
181 /*
182 if (ic_time_ns < 0xFFFFull * 1000ull / CLK_FREQ_MHz) {
183 // One 16bit timer is enough actually
184 flexio->port().TIMCTL[t_ic] = FLEXIO_TIMCTL_TRGSEL_STATE(s_ic) | FLEXIO_TIMCTL_TIMOD(3) |
185 FLEXIO_TIMCTL_PINCFG(3) | FLEXIO_TIMCTL_PINSEL(17);
186 flexio->port().TIMCFG[t_ic] =
187 FLEXIO_TIMCFG_TIMRST(6) | FLEXIO_TIMCFG_TIMDIS(0b110) | FLEXIO_TIMCFG_TIMENA(6) |
188 FLEXIO_TIMCFG_TIMOUT(1); flexio->port().TIMCMP[t_ic] = ic_time_ns * CLK_FREQ_MHz / 1000;
189
190 // Reset second timer used when going towards higher times
191 flexio->port().TIMCTL[t_ic_second] = 0;
192 flexio->port().TIMCFG[t_ic_second] = 0;
193 flexio->port().TIMCMP[t_ic_second] = 0;
194 } else {*/
195 // We split counting to two chained timers
196 auto factors = utils::factorize(ic_time_ns * CLK_FREQ_MHz / 1000);
197 if (factors.first >= 1 << 16 || factors.second >= 1 << 16) // Factror even is too big for two cascaded timers
198 return false;
199
200 // Configure state timer
201 flexio->port().TIMCTL[t_ic] =
202 FLEXIO_TIMCTL_TRGSEL_STATE(s_ic) | FLEXIO_TIMCTL_TIMOD(3) | FLEXIO_TIMCTL_PINPOL;
203 flexio->port().TIMCFG[t_ic] = FLEXIO_TIMCFG_TIMRST(6) | FLEXIO_TIMCFG_TIMDIS(6) | FLEXIO_TIMCFG_TIMENA(6);
204 flexio->port().TIMCMP[t_ic] = factors.first - 1;
205 // Configure second timer
206 flexio->port().TIMCTL[t_ic_second] = FLEXIO_TIMCTL_TRGSEL(4 * t_ic + 3) | FLEXIO_TIMCTL_TRGSRC |
207 FLEXIO_TIMCTL_TIMOD(3) | FLEXIO_TIMCTL_PINCFG(3) |
208 FLEXIO_TIMCTL_PINSEL(17);
209 flexio->port().TIMCFG[t_ic_second] = FLEXIO_TIMCFG_TIMDEC(1) | FLEXIO_TIMCFG_TIMRST(0) |
210 FLEXIO_TIMCFG_TIMDIS(1) | FLEXIO_TIMCFG_TIMENA(1) |
211 FLEXIO_TIMCFG_TIMOUT(1);
212 flexio->port().TIMCMP[t_ic_second] = factors.second;
213 //}
214
215 // Configure state shifter
216 flexio->port().SHIFTCTL[s_ic] = FLEXIO_SHIFTCTL_TIMSEL(t_state_check) | FLEXIO_SHIFTCTL_PINCFG(3) |
217 FLEXIO_SHIFTCTL_PINSEL(15) | FLEXIO_SHIFTCTL_SMOD_STATE;
218 flexio->port().SHIFTCFG[s_ic] = 0;
219 flexio->port().SHIFTBUF[s_ic] =
220 FLEXIO_STATE_SHIFTBUF(0b11101111, s_ic, s_ic, s_ic, s_ic, s_op, s_op, s_op, s_op);
221
222 //
223 // Configure OP state.
224 //
225 // State changes are triggered continuously as fast as possible,
226 // but we only leave OP when the correct input is set.
227 //
228
229 // Sanity check op_time_ns, which we will count with two 16bit timers (=32bit) at CLK_FREQ
230 // Also, we don't really want to do extremely short OP times (for now?)
231 if (op_time_ns < 100 or op_time_ns > 9'000'000'000) {
232 LOG_ERROR("FlexIOControl: Requested op_time_ns cannot be represented by 32bit.");
233 return false;
234 }
235
236 // Configure a timer to set an input pin high, signaling end of op_time
237 if (op_time_ns < 0xFFFFull * 1000ull / CLK_FREQ_MHz) {
238 // One 16bit timer is enough actually
239 flexio->port().TIMCTL[t_op] = FLEXIO_TIMCTL_TRGSEL_STATE(s_op) | FLEXIO_TIMCTL_TIMOD(3) |
240 FLEXIO_TIMCTL_PINCFG(3) | FLEXIO_TIMCTL_PINSEL(12);
241 flexio->port().TIMCFG[t_op] = FLEXIO_TIMCFG_TIMRST(6) | FLEXIO_TIMCFG_TIMDIS(0b110) |
242 FLEXIO_TIMCFG_TIMENA(6) | FLEXIO_TIMCFG_TIMOUT(1);
243 flexio->port().TIMCMP[t_op] = op_time_ns * CLK_FREQ_MHz / 1000;
244
245 // Reset second timer used when going towards higher op_times
246 flexio->port().TIMCTL[t_op_second] = 0;
247 flexio->port().TIMCFG[t_op_second] = 0;
248 flexio->port().TIMCMP[t_op_second] = 0;
249 } else {
250 // Configure first timer as pre-scaler
251 // But we want to pre-scale as much as possible, even though we then lose resolution
252 // But for op times in the range of seconds, we don't need microseconds resolution
253
254 auto factors = utils::factorize(op_time_ns * CLK_FREQ_MHz / 1000);
255 if (factors.first >= 1 << 16 ||
256 factors.second >= 1 << 16) // Factror even is too big for two cascaded timers
257 return false;
258
259 flexio->port().TIMCTL[t_op] =
260 FLEXIO_TIMCTL_TRGSEL_STATE(s_op) | FLEXIO_TIMCTL_TIMOD(3) | FLEXIO_TIMCTL_PINPOL;
261 flexio->port().TIMCFG[t_op] =
262 FLEXIO_TIMCFG_TIMRST(6) | FLEXIO_TIMCFG_TIMDIS(0b110) | FLEXIO_TIMCFG_TIMENA(6);
263 flexio->port().TIMCMP[t_op] = factors.first - 1;
264 // Configure second timer for 32bit total
265 flexio->port().TIMCTL[t_op_second] = FLEXIO_TIMCTL_TRGSEL(4 * t_op + 3) | FLEXIO_TIMCTL_TRGSRC |
266 FLEXIO_TIMCTL_TIMOD(3) | FLEXIO_TIMCTL_PINCFG(3) |
267 FLEXIO_TIMCTL_PINSEL(12);
268 flexio->port().TIMCFG[t_op_second] = FLEXIO_TIMCFG_TIMDEC(1) | FLEXIO_TIMCFG_TIMRST(0) |
269 FLEXIO_TIMCFG_TIMDIS(1) | FLEXIO_TIMCFG_TIMENA(1) |
270 FLEXIO_TIMCFG_TIMOUT(1);
271 flexio->port().TIMCMP[t_op_second] = factors.second;
272 }
273
274 // Configure state shifter
275 flexio->port().SHIFTCTL[s_op] = FLEXIO_SHIFTCTL_TIMSEL(t_state_check) | FLEXIO_SHIFTCTL_PINCFG(3) |
276 FLEXIO_SHIFTCTL_PINSEL(10) | FLEXIO_SHIFTCTL_SMOD_STATE;
277 flexio->port().SHIFTCFG[s_op] = 0;
278 // Next state after OP depends on FlexIO inputs 10 (0 if overload), 11 (0 if exthalt), 12 (1 if op time over)
279 // Check with priority op-time-over > overload > ext halt
280 // Comments are t/T whether op-time-over, o/O whether overload active, e/E wether ext halt is true
281 uint8_t next_if_overload_and_exthalt = s_op, next_if_overload = s_op, next_if_exthalt = s_op;
282 switch (on_ext_halt) {
283 case OnExtHalt::IGNORE:
284 next_if_exthalt = s_op;
285 break;
286 case OnExtHalt::PAUSE_THEN_RESTART:
287 next_if_exthalt = s_exthalt;
288 break;
289 }
290 switch (on_overload) {
291 case OnOverload::IGNORE:
292 next_if_overload = s_op;
293 next_if_overload_and_exthalt = next_if_exthalt;
294 break;
295 case OnOverload::HALT:
296 next_if_overload = s_overload;
297 next_if_overload_and_exthalt = s_overload;
298 break;
299 }
300 flexio->port().SHIFTBUF[s_op] = FLEXIO_STATE_SHIFTBUF(0b11011111, // Inputs [12-11-10]
301 next_if_overload_and_exthalt, // [0-0-0] = [t-E-O]
302 next_if_exthalt, // [0-0-1] = [t-E-o]
303 next_if_overload, // [0-1-0] = [t-e-O]
304 s_op, // [0-1-1] = [t-e-o]
305 s_end, // [1-0-0] = [T-E-O]
306 s_end, // [1-0-1] = [T-E-o]
307 s_end, // [1-1-0] = [T-e-O]
308 s_end // [1-1-1] = [T-e-o]
309 );
310
311 //
312 // Configure END state.
313 //
314
315 flexio->port().SHIFTCTL[s_end] = FLEXIO_SHIFTCTL_PINCFG(3) | FLEXIO_SHIFTCTL_SMOD_STATE;
316 flexio->port().SHIFTCFG[s_end] = 0;
317 flexio->port().SHIFTBUF[s_end] = FLEXIO_STATE_SHIFTBUF(0b11111111, s_end);
318
319 //
320 // Configure OVERLOAD state.
321 //
322
323 flexio->port().SHIFTCTL[s_overload] = FLEXIO_SHIFTCTL_PINCFG(3) | FLEXIO_SHIFTCTL_SMOD_STATE;
324 flexio->port().SHIFTCFG[s_overload] = 0;
325 flexio->port().SHIFTBUF[s_overload] = FLEXIO_STATE_SHIFTBUF(0b11111111, s_overload);
326
327 //
328 // Configure EXT HALT state.
329 //
330
331 // EXT HALT is a paused state which resumes as soon as the signal is no longer active.
332 // But "resuming" is only partially correct, since the full op time is restarted.
333 // Thus, the OP state after EXT HALT runs for the full OP time, not just the remainder.
334 // This can be solved similarly to the ADC by gating a timer with the OP signal,
335 // but that requires additional connections on the PCB.
336 // For all currently envisioned EXT HALT applications (e.g. control-systems), this is okay.
337 flexio->port().SHIFTCTL[s_exthalt] = FLEXIO_SHIFTCTL_TIMSEL(t_state_check) | FLEXIO_SHIFTCTL_PINCFG(3) |
338 FLEXIO_SHIFTCTL_PINSEL(10) | FLEXIO_SHIFTCTL_SMOD_STATE;
339 flexio->port().SHIFTCFG[s_exthalt] = 0;
340 // When selecting next state based on inputs [12-11-10], ignore anything but EXT HALT (11).
341 flexio->port().SHIFTBUF[s_exthalt] =
342 FLEXIO_STATE_SHIFTBUF(0b11111111, s_exthalt, s_exthalt, s_op, s_op, s_exthalt, s_exthalt, s_op, s_op);
343
344 //
345 // Configure miscellaneous flexio stuff
346 //
347
348 // Put relevant pins into FlexIO mode
350 if (flexio->mapIOPinToFlexPin(pin) == 0xff) {
351 return false;
352 }
353 flexio->setIOPinToFlexMode(pin);
354 }
355
356 enable();
357 _is_initialized = true;
358 return true;
359}
360
362 auto flexio = FlexIOHandler::flexIOHandler_list[2];
363 flexio->port().CTRL &= ~FLEXIO_CTRL_FLEXEN;
364 _is_enabled = false;
365}
366
368 auto flexio = FlexIOHandler::flexIOHandler_list[2];
369 flexio->port().CTRL |= FLEXIO_CTRL_FLEXEN;
370 _is_enabled = true;
371}
372
374
376 auto flexio = FlexIOHandler::flexIOHandler_list[2];
377 flexio->port().SHIFTSTATE = s_idle;
378 mode::PerformanceCounter::get().to(mode::Mode::HALT);
379}
380
382 auto flexio = FlexIOHandler::flexIOHandler_list[2];
383 flexio->port().SHIFTSTATE = s_ic;
384 mode::PerformanceCounter::get().to(mode::Mode::IC);
385}
386
388 auto flexio = FlexIOHandler::flexIOHandler_list[2];
389 flexio->port().SHIFTSTATE = s_op;
390 mode::PerformanceCounter::get().to(mode::Mode::OP);
391}
392
394 auto flexio = FlexIOHandler::flexIOHandler_list[2];
395 flexio->port().SHIFTSTATE = s_exthalt;
396 mode::PerformanceCounter::get().to(mode::Mode::HALT);
397}
398
400 auto flexio = FlexIOHandler::flexIOHandler_list[2];
401 flexio->port().SHIFTSTATE = s_end;
402 mode::PerformanceCounter::get().to(mode::Mode::HALT);
403}
404
406 disable();
407 delayMicroseconds(1);
408 auto flexio = FlexIOHandler::flexIOHandler_list[2];
409 flexio->port().CTRL |= FLEXIO_CTRL_SWRST;
410 delayMicroseconds(1);
411 flexio->port().CTRL &= ~FLEXIO_CTRL_SWRST;
412 delayMicroseconds(1);
413}
414
416 while (!is_done()) {
417 }
418}
419
421 TMR1_CNTR1 = 0;
422 TMR1_CNTR2 = 0;
423}
424
426 CCM_CCGR6 |= CCM_CCGR6_QTIMER1(CCM_CCGR_ON);
427
428 // Configure timer 1 of first QTMR module to do input-gated counting
429 TMR1_CTRL1 = 0; // stop
430 TMR1_CNTR1 = 0; // reset counter
431 TMR1_SCTRL1 = 0;
432 TMR1_LOAD1 = 0;
433 TMR1_CSCTRL1 = 0;
434 TMR1_LOAD1 = 0; // start val after compare
435 TMR1_COMP11 = 0xffff; // count up to this val, interrupt, and start again
436 TMR1_CMPLD11 = 0xffff;
437 // Set CM=0 for now, enable later, select fastest clock with PCS, select gating signal with SCS
438 TMR1_CTRL1 = TMR_CTRL_CM(0) | TMR_CTRL_PCS(8) | TMR_CTRL_SCS(1);
439 // Invert secondary signal (gating when HIGH, counting when LOW)
440 TMR1_SCTRL1 = TMR_SCTRL_IPS;
441
442 // Configure timer 2 of first QTMR module to cascade from timer 1
443 TMR1_CTRL2 = 0;
444 TMR1_CNTR2 = 0; // reset counter
445 TMR1_SCTRL2 = 0;
446 TMR1_LOAD2 = 0;
447 TMR1_CSCTRL2 = 0;
448 TMR1_LOAD2 = 0; // start val after compare
449 TMR1_COMP12 = 0xffff; // count up to this val and start again
450 TMR1_CMPLD12 = 0xffff;
451 // Set CM=0 for now, enable later, select first timer with PCS
452 TMR1_CTRL2 = TMR_CTRL_CM(0) | TMR_CTRL_PCS(4 + 1);
453
454 // Put PIN_QTMR_OP_GATE in QTimer mode
455 *(portConfigRegister(PIN_QTMR_OP_GATE)) = 1; // ALT 1
456 // Enable timers in reverse order
457 TMR1_CTRL2 |= TMR_CTRL_CM(7);
458 TMR1_CTRL1 |= TMR_CTRL_CM(3);
459}
460
462 // TODO: This is currently measured, but of course it can be calculated
463 return (TMR1_CNTR2 * 0xFFFF + TMR1_CNTR1) * 671 / 100;
464}
465
467 auto flexio = FlexIOHandler::flexIOHandler_list[2];
468 return flexio->port().SHIFTSTATE == s_idle;
469}
470
472 auto flexio = FlexIOHandler::flexIOHandler_list[2];
473 return flexio->port().SHIFTSTATE == s_op;
474}
475
477 auto flexio = FlexIOHandler::flexIOHandler_list[2];
478 auto state = flexio->port().SHIFTSTATE;
479 return state == s_end or state == s_overload;
480}
481
483 auto flexio = FlexIOHandler::flexIOHandler_list[2];
484 return flexio->port().SHIFTSTATE == s_overload;
485}
486
488 auto flexio = FlexIOHandler::flexIOHandler_list[2];
489 return flexio->port().SHIFTSTATE == s_exthalt;
490}
static void to_exthalt()
Definition mode.cpp:393
static void disable()
Definition mode.cpp:361
static void to_end()
Definition mode.cpp:399
static void _reset_qtmr_op()
Definition mode.cpp:420
static bool is_op()
Definition mode.cpp:471
static bool is_idle()
Definition mode.cpp:466
static bool is_initialized()
Definition mode.h:88
static unsigned long long get_actual_op_time()
Definition mode.cpp:461
static bool is_done()
Definition mode.cpp:476
static void reset()
Definition mode.cpp:405
static bool is_enabled()
Definition mode.h:93
static void to_ic()
Definition mode.cpp:381
static void to_op()
Definition mode.cpp:387
static void delay_till_done()
Definition mode.cpp:415
static void force_start()
Definition mode.cpp:373
static void to_idle()
Definition mode.cpp:375
static bool is_overloaded()
Definition mode.cpp:482
static void enable()
Definition mode.cpp:367
static void _init_qtmr_op()
Definition mode.cpp:425
static bool init(unsigned long long ic_time_ns, unsigned long long op_time_ns, mode::OnOverload on_overload=mode::OnOverload::HALT, mode::OnExtHalt on_ext_halt=mode::OnExtHalt::IGNORE, mode::Sync sync=mode::Sync::NONE)
Definition mode.cpp:95
static bool is_exthalt()
Definition mode.cpp:487
constexpr uint8_t PIN_MODE_OP
Definition mode.h:17
constexpr uint8_t PIN_SYNC_CLK
Definition mode.h:20
constexpr uint8_t PIN_MODE_IC
Definition mode.h:16
constexpr uint8_t PIN_QTMR_OP_GATE
Definition mode.h:22
constexpr uint8_t PIN_MODE_EXTHALT
Definition mode.h:19
constexpr uint8_t PIN_MODE_OVERLOAD
Definition mode.h:18
constexpr uint8_t PIN_SYNC_ID
Definition mode.h:21