96 mode::OnOverload on_overload, mode::OnExtHalt on_ext_halt,
97 SyncConfig sync_config) {
104 auto flexio = FlexIOHandler::flexIOHandler_list[2];
108 flexio->setClockSettings(CLK_SEL, 1, 1);
109 auto CLK_FREQ = flexio->computeClockRate();
110 auto CLK_FREQ_MHz = CLK_FREQ / 1'000'000;
118 if (!sync_config.enabled) {
119 flexio->port().TIMCTL[t_sync_clk] = 0;
120 flexio->port().TIMCFG[t_sync_clk] = 0;
121 flexio->port().TIMCMP[t_sync_clk] = 0;
122 flexio->port().SHIFTCTL[z_sync_match] = 0;
123 flexio->port().SHIFTCFG[z_sync_match] = 0;
124 flexio->port().SHIFTBUF[z_sync_match] = 0;
125 flexio->port().TIMCTL[t_sync_trigger] = 0;
126 flexio->port().TIMCFG[t_sync_trigger] = 0;
127 flexio->port().TIMCMP[t_sync_trigger] = 0;
129 flexio->port().SHIFTCTL[s_idle] = FLEXIO_SHIFTCTL_PINCFG(3) | FLEXIO_SHIFTCTL_SMOD_STATE;
130 flexio->port().SHIFTBUF[s_idle] = FLEXIO_STATE_SHIFTBUF(0b11111111, s_idle);
133 uint8_t _sck_flex_pin = flexio->mapIOPinToFlexPin(
PIN_SYNC_CLK);
134 if (_sck_flex_pin == 0xff)
138 flexio->port().TIMCTL[t_sync_clk] = FLEXIO_TIMCTL_PINSEL(_sck_flex_pin) | FLEXIO_TIMCTL_TIMOD(1);
139 flexio->port().TIMCFG[t_sync_clk] = FLEXIO_TIMCFG_TIMOUT(1) | FLEXIO_TIMCFG_TIMDEC(2);
140 flexio->port().TIMCMP[t_sync_clk] = 0x0000'FF'00;
143 auto _flexio_pin_data_in = flexio->mapIOPinToFlexPin(
PIN_SYNC_ID);
144 if (_flexio_pin_data_in == 0xff)
147 flexio->port().SHIFTCTL[z_sync_match] = FLEXIO_SHIFTCTL_TIMSEL(t_sync_clk) |
148 FLEXIO_SHIFTCTL_PINSEL(_flexio_pin_data_in) |
149 FLEXIO_SHIFTCTL_SMOD(0b101);
150 flexio->port().SHIFTCFG[z_sync_match] = 0;
153 flexio->port().SHIFTBUFBIS[z_sync_match] = 0b00000000'00000000'11110000'00000000 | sync_config.id;
157 flexio->port().TIMCTL[t_sync_trigger] =
158 FLEXIO_TIMCTL_TRGSEL(4 * z_sync_match + 1) | FLEXIO_TIMCTL_TRGSRC | FLEXIO_TIMCTL_TIMOD(1);
159 flexio->port().TIMCFG[t_sync_trigger] = FLEXIO_TIMCFG_TIMDIS(2) | FLEXIO_TIMCFG_TIMENA(6);
160 flexio->port().TIMCMP[t_sync_trigger] = 0x0000'01'00;
162 flexio->port().SHIFTCTL[s_idle] =
163 FLEXIO_SHIFTCTL_TIMSEL(t_sync_trigger) | FLEXIO_SHIFTCTL_PINCFG(3) | FLEXIO_SHIFTCTL_SMOD_STATE;
164 flexio->port().SHIFTBUF[s_idle] = FLEXIO_STATE_SHIFTBUF(0b11111111, s_ic);
166 flexio->port().SHIFTCFG[s_idle] = 0;
174 flexio->port().TIMCTL[t_state_check] = FLEXIO_TIMCTL_TIMOD(3);
175 flexio->port().TIMCFG[t_state_check] = FLEXIO_TIMCFG_TIMDIS(0) | FLEXIO_TIMCFG_TIMENA(0);
176 flexio->port().TIMCMP[t_state_check] = 0x0000'0001;
183 if (ic_time_ns < 100) {
184 LOG_ERROR(
"FlexIOControl: ic_time_ns < 100 not implemented.");
189 auto factors = utils::factorize(ic_time_ns * CLK_FREQ_MHz / 1000);
190 if (factors.first >= 1 << 16 || factors.second >= 1 << 16) {
192 LOG_ERROR(
"FlexIOControl: Requested ic_time_ns cannot be represented by 32bit.");
197 flexio->port().TIMCTL[t_ic] =
198 FLEXIO_TIMCTL_TRGSEL_STATE(s_ic) | FLEXIO_TIMCTL_TIMOD(3) | FLEXIO_TIMCTL_PINPOL;
199 flexio->port().TIMCFG[t_ic] = FLEXIO_TIMCFG_TIMRST(6) | FLEXIO_TIMCFG_TIMDIS(6) | FLEXIO_TIMCFG_TIMENA(6);
200 flexio->port().TIMCMP[t_ic] = factors.first - 1;
202 flexio->port().TIMCTL[t_ic_second] = FLEXIO_TIMCTL_TRGSEL(4 * t_ic + 3) | FLEXIO_TIMCTL_TRGSRC |
203 FLEXIO_TIMCTL_TIMOD(3) | FLEXIO_TIMCTL_PINCFG(3) |
204 FLEXIO_TIMCTL_PINSEL(17);
205 flexio->port().TIMCFG[t_ic_second] = FLEXIO_TIMCFG_TIMDEC(1) | FLEXIO_TIMCFG_TIMRST(0) |
206 FLEXIO_TIMCFG_TIMDIS(1) | FLEXIO_TIMCFG_TIMENA(1) |
207 FLEXIO_TIMCFG_TIMOUT(1);
208 flexio->port().TIMCMP[t_ic_second] = factors.second;
212 flexio->port().SHIFTCTL[s_ic] = FLEXIO_SHIFTCTL_TIMSEL(t_state_check) | FLEXIO_SHIFTCTL_PINCFG(3) |
213 FLEXIO_SHIFTCTL_PINSEL(15) | FLEXIO_SHIFTCTL_SMOD_STATE;
214 flexio->port().SHIFTCFG[s_ic] = 0;
215 flexio->port().SHIFTBUF[s_ic] =
216 FLEXIO_STATE_SHIFTBUF(0b11101111, s_ic, s_ic, s_ic, s_ic, s_op, s_op, s_op, s_op);
225 if (op_time_ns < 100) {
226 LOG_ERROR(
"FlexIOControl: op_time_ns < 100 not implemented.");
230 uint32_t op_a, op_b, op_c;
231 bool op_three_stage =
false;
233 if (op_time_ns < 0xFFFFull * 1000ull / CLK_FREQ_MHz) {
235 op_a = op_time_ns * CLK_FREQ_MHz / 1000;
238 uint64_t op_counts = op_time_ns * CLK_FREQ_MHz / 1000;
239 if (!utils::factorize3(op_counts, op_a, op_b, op_c)) {
240 LOG_ERROR(
"FlexIOControl: Requested op_time_ns cannot be represented (exceeds 48-bit counter).");
243 op_three_stage = (op_c > 1);
246 auto& port = flexio->port();
247 if (op_b == 1 && op_c == 1) {
249 port.TIMCTL[t_op] = FLEXIO_TIMCTL_TRGSEL_STATE(s_op) | FLEXIO_TIMCTL_TIMOD(3) |
250 FLEXIO_TIMCTL_PINCFG(3) | FLEXIO_TIMCTL_PINSEL(12);
251 port.TIMCFG[t_op] = FLEXIO_TIMCFG_TIMRST(6) | FLEXIO_TIMCFG_TIMDIS(0b110) |
252 FLEXIO_TIMCFG_TIMENA(6) | FLEXIO_TIMCFG_TIMOUT(1);
253 port.TIMCMP[t_op] = op_a;
254 port.TIMCTL[t_op_second] = 0;
255 port.TIMCFG[t_op_second] = 0;
256 port.TIMCMP[t_op_second] = 0;
257 port.TIMCTL[t_op_third] = 0;
258 port.TIMCFG[t_op_third] = 0;
259 port.TIMCMP[t_op_third] = 0;
260 }
else if (!op_three_stage) {
262 port.TIMCTL[t_op] = FLEXIO_TIMCTL_TRGSEL_STATE(s_op) | FLEXIO_TIMCTL_TIMOD(3) | FLEXIO_TIMCTL_PINPOL;
263 port.TIMCFG[t_op] = FLEXIO_TIMCFG_TIMRST(6) | FLEXIO_TIMCFG_TIMDIS(0b110) | FLEXIO_TIMCFG_TIMENA(6);
264 port.TIMCMP[t_op] = op_a - 1;
265 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 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 port.TIMCMP[t_op_second] = op_b;
272 port.TIMCTL[t_op_third] = 0;
273 port.TIMCFG[t_op_third] = 0;
274 port.TIMCMP[t_op_third] = 0;
277 port.TIMCTL[t_op] = FLEXIO_TIMCTL_TRGSEL_STATE(s_op) | FLEXIO_TIMCTL_TIMOD(3) | FLEXIO_TIMCTL_PINPOL;
278 port.TIMCFG[t_op] = FLEXIO_TIMCFG_TIMRST(6) | FLEXIO_TIMCFG_TIMDIS(0b110) | FLEXIO_TIMCFG_TIMENA(6);
279 port.TIMCMP[t_op] = op_a - 1;
282 port.TIMCTL[t_op_second] = FLEXIO_TIMCTL_TRGSEL(4 * t_op + 3) | FLEXIO_TIMCTL_TRGSRC |
283 FLEXIO_TIMCTL_TIMOD(3);
284 port.TIMCFG[t_op_second] = FLEXIO_TIMCFG_TIMDEC(1) | FLEXIO_TIMCFG_TIMRST(0) |
285 FLEXIO_TIMCFG_TIMDIS(1) | FLEXIO_TIMCFG_TIMENA(1);
286 port.TIMCMP[t_op_second] = op_b;
289 port.TIMCTL[t_op_third] = FLEXIO_TIMCTL_TRGSEL(4 * t_op_second + 3) | FLEXIO_TIMCTL_TRGSRC |
290 FLEXIO_TIMCTL_TIMOD(3) | FLEXIO_TIMCTL_PINCFG(3) |
291 FLEXIO_TIMCTL_PINSEL(12);
292 port.TIMCFG[t_op_third] = FLEXIO_TIMCFG_TIMDEC(1) | FLEXIO_TIMCFG_TIMRST(0) |
293 FLEXIO_TIMCFG_TIMDIS(1) | FLEXIO_TIMCFG_TIMENA(1) |
294 FLEXIO_TIMCFG_TIMOUT(1);
295 port.TIMCMP[t_op_third] = op_c;
299 port.SHIFTCTL[s_op] = FLEXIO_SHIFTCTL_TIMSEL(t_state_check) | FLEXIO_SHIFTCTL_PINCFG(3) |
300 FLEXIO_SHIFTCTL_PINSEL(10) | FLEXIO_SHIFTCTL_SMOD_STATE;
301 port.SHIFTCFG[s_op] = 0;
305 uint8_t next_if_overload_and_exthalt = s_op, next_if_overload = s_op, next_if_exthalt = s_op;
306 switch (on_ext_halt) {
307 case OnExtHalt::IGNORE:
308 next_if_exthalt = s_op;
310 case OnExtHalt::PAUSE_THEN_RESTART:
311 next_if_exthalt = s_exthalt;
314 switch (on_overload) {
315 case OnOverload::IGNORE:
316 next_if_overload = s_op;
317 next_if_overload_and_exthalt = next_if_exthalt;
319 case OnOverload::HALT:
320 next_if_overload = s_overload;
321 next_if_overload_and_exthalt = s_overload;
324 port.SHIFTBUF[s_op] = FLEXIO_STATE_SHIFTBUF(0b11011111,
325 next_if_overload_and_exthalt,
339 port.SHIFTCTL[s_end] = FLEXIO_SHIFTCTL_PINCFG(3) | FLEXIO_SHIFTCTL_SMOD_STATE;
340 port.SHIFTCFG[s_end] = 0;
341 port.SHIFTBUF[s_end] = FLEXIO_STATE_SHIFTBUF(0b11111111, s_end);
347 port.SHIFTCTL[s_overload] = FLEXIO_SHIFTCTL_PINCFG(3) | FLEXIO_SHIFTCTL_SMOD_STATE;
348 port.SHIFTCFG[s_overload] = 0;
349 port.SHIFTBUF[s_overload] = FLEXIO_STATE_SHIFTBUF(0b11111111, s_overload);
361 port.SHIFTCTL[s_exthalt] = FLEXIO_SHIFTCTL_TIMSEL(t_state_check) | FLEXIO_SHIFTCTL_PINCFG(3) |
362 FLEXIO_SHIFTCTL_PINSEL(10) | FLEXIO_SHIFTCTL_SMOD_STATE;
363 port.SHIFTCFG[s_exthalt] = 0;
365 port.SHIFTBUF[s_exthalt] =
366 FLEXIO_STATE_SHIFTBUF(0b11111111, s_exthalt, s_exthalt, s_op, s_op, s_exthalt, s_exthalt, s_op, s_op);
374 if (flexio->mapIOPinToFlexPin(pin) == 0xff) {
378 flexio->setIOPinToFlexMode(pin);
382 _is_initialized =
true;