@web-font-path: "roboto-debian.css";
Loading...
Searching...
No Matches
pio.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _HARDWARE_PIO_H
8#define _HARDWARE_PIO_H
9
10#include "pico.h"
12#include "hardware/structs/pio.h"
13#include "hardware/gpio.h"
14#include "hardware/regs/dreq.h"
15#include "hardware/pio_instructions.h"
16
17// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_PIO, Enable/disable assertions in the PIO module, type=bool, default=0, group=hardware_pio
18#ifndef PARAM_ASSERTIONS_ENABLED_PIO
19#define PARAM_ASSERTIONS_ENABLED_PIO 0
20#endif
21
46#ifdef __cplusplus
47extern "C" {
48#endif
49
50static_assert(PIO_SM0_SHIFTCTRL_FJOIN_RX_LSB == PIO_SM0_SHIFTCTRL_FJOIN_TX_LSB + 1, "");
51
56 PIO_FIFO_JOIN_NONE = 0,
57 PIO_FIFO_JOIN_TX = 1,
58 PIO_FIFO_JOIN_RX = 2,
59};
60
65 STATUS_TX_LESSTHAN = 0,
66 STATUS_RX_LESSTHAN = 1
67};
68
69typedef pio_hw_t *PIO;
70
77#define pio0 pio0_hw
78
85#define pio1 pio1_hw
86
102typedef struct {
103 uint32_t clkdiv;
104 uint32_t execctrl;
105 uint32_t shiftctrl;
106 uint32_t pinctrl;
108
109static inline void check_sm_param(__unused uint sm) {
110 valid_params_if(PIO, sm < NUM_PIO_STATE_MACHINES);
111}
112
113static inline void check_sm_mask(__unused uint mask) {
114 valid_params_if(PIO, mask < (1u << NUM_PIO_STATE_MACHINES));
115}
116
117
118static inline void check_pio_param(__unused PIO pio) {
119 valid_params_if(PIO, pio == pio0 || pio == pio1);
120}
121
131static inline void sm_config_set_out_pins(pio_sm_config *c, uint out_base, uint out_count) {
132 valid_params_if(PIO, out_base < 32);
133 valid_params_if(PIO, out_count <= 32);
134 c->pinctrl = (c->pinctrl & ~(PIO_SM0_PINCTRL_OUT_BASE_BITS | PIO_SM0_PINCTRL_OUT_COUNT_BITS)) |
135 (out_base << PIO_SM0_PINCTRL_OUT_BASE_LSB) |
136 (out_count << PIO_SM0_PINCTRL_OUT_COUNT_LSB);
137}
138
148static inline void sm_config_set_set_pins(pio_sm_config *c, uint set_base, uint set_count) {
149 valid_params_if(PIO, set_base < 32);
150 valid_params_if(PIO, set_count <= 5);
151 c->pinctrl = (c->pinctrl & ~(PIO_SM0_PINCTRL_SET_BASE_BITS | PIO_SM0_PINCTRL_SET_COUNT_BITS)) |
152 (set_base << PIO_SM0_PINCTRL_SET_BASE_LSB) |
153 (set_count << PIO_SM0_PINCTRL_SET_COUNT_LSB);
154}
155
164static inline void sm_config_set_in_pins(pio_sm_config *c, uint in_base) {
165 valid_params_if(PIO, in_base < 32);
166 c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_IN_BASE_BITS) |
167 (in_base << PIO_SM0_PINCTRL_IN_BASE_LSB);
168}
169
178static inline void sm_config_set_sideset_pins(pio_sm_config *c, uint sideset_base) {
179 valid_params_if(PIO, sideset_base < 32);
180 c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_SIDESET_BASE_BITS) |
181 (sideset_base << PIO_SM0_PINCTRL_SIDESET_BASE_LSB);
182}
183
192static inline void sm_config_set_sideset(pio_sm_config *c, uint bit_count, bool optional, bool pindirs) {
193 valid_params_if(PIO, bit_count <= 5);
194 valid_params_if(PIO, !optional || bit_count >= 1);
195 c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_SIDESET_COUNT_BITS) |
196 (bit_count << PIO_SM0_PINCTRL_SIDESET_COUNT_LSB);
197
198 c->execctrl = (c->execctrl & ~(PIO_SM0_EXECCTRL_SIDE_EN_BITS | PIO_SM0_EXECCTRL_SIDE_PINDIR_BITS)) |
199 (bool_to_bit(optional) << PIO_SM0_EXECCTRL_SIDE_EN_LSB) |
200 (bool_to_bit(pindirs) << PIO_SM0_EXECCTRL_SIDE_PINDIR_LSB);
201}
202
216static inline void sm_config_set_clkdiv_int_frac(pio_sm_config *c, uint16_t div_int, uint8_t div_frac) {
217 invalid_params_if(PIO, div_int == 0 && div_frac != 0);
218 c->clkdiv =
219 (((uint)div_frac) << PIO_SM0_CLKDIV_FRAC_LSB) |
220 (((uint)div_int) << PIO_SM0_CLKDIV_INT_LSB);
221}
222
223static inline void pio_calculate_clkdiv_from_float(float div, uint16_t *div_int, uint8_t *div_frac) {
224 valid_params_if(PIO, div >= 1 && div <= 65536);
225 *div_int = (uint16_t)div;
226 if (*div_int == 0) {
227 *div_frac = 0;
228 } else {
229 *div_frac = (uint8_t)((div - (float)*div_int) * (1u << 8u));
230 }
231}
232
248static inline void sm_config_set_clkdiv(pio_sm_config *c, float div) {
249 uint16_t div_int;
250 uint8_t div_frac;
251 pio_calculate_clkdiv_from_float(div, &div_int, &div_frac);
252 sm_config_set_clkdiv_int_frac(c, div_int, div_frac);
253}
254
263static inline void sm_config_set_wrap(pio_sm_config *c, uint wrap_target, uint wrap) {
264 valid_params_if(PIO, wrap < PIO_INSTRUCTION_COUNT);
265 valid_params_if(PIO, wrap_target < PIO_INSTRUCTION_COUNT);
266 c->execctrl = (c->execctrl & ~(PIO_SM0_EXECCTRL_WRAP_TOP_BITS | PIO_SM0_EXECCTRL_WRAP_BOTTOM_BITS)) |
267 (wrap_target << PIO_SM0_EXECCTRL_WRAP_BOTTOM_LSB) |
268 (wrap << PIO_SM0_EXECCTRL_WRAP_TOP_LSB);
269}
270
277static inline void sm_config_set_jmp_pin(pio_sm_config *c, uint pin) {
278 valid_params_if(PIO, pin < 32);
279 c->execctrl = (c->execctrl & ~PIO_SM0_EXECCTRL_JMP_PIN_BITS) |
280 (pin << PIO_SM0_EXECCTRL_JMP_PIN_LSB);
281}
282
291static inline void sm_config_set_in_shift(pio_sm_config *c, bool shift_right, bool autopush, uint push_threshold) {
292 valid_params_if(PIO, push_threshold <= 32);
293 c->shiftctrl = (c->shiftctrl &
294 ~(PIO_SM0_SHIFTCTRL_IN_SHIFTDIR_BITS |
295 PIO_SM0_SHIFTCTRL_AUTOPUSH_BITS |
296 PIO_SM0_SHIFTCTRL_PUSH_THRESH_BITS)) |
297 (bool_to_bit(shift_right) << PIO_SM0_SHIFTCTRL_IN_SHIFTDIR_LSB) |
298 (bool_to_bit(autopush) << PIO_SM0_SHIFTCTRL_AUTOPUSH_LSB) |
299 ((push_threshold & 0x1fu) << PIO_SM0_SHIFTCTRL_PUSH_THRESH_LSB);
300}
301
310static inline void sm_config_set_out_shift(pio_sm_config *c, bool shift_right, bool autopull, uint pull_threshold) {
311 valid_params_if(PIO, pull_threshold <= 32);
312 c->shiftctrl = (c->shiftctrl &
313 ~(PIO_SM0_SHIFTCTRL_OUT_SHIFTDIR_BITS |
314 PIO_SM0_SHIFTCTRL_AUTOPULL_BITS |
315 PIO_SM0_SHIFTCTRL_PULL_THRESH_BITS)) |
316 (bool_to_bit(shift_right) << PIO_SM0_SHIFTCTRL_OUT_SHIFTDIR_LSB) |
317 (bool_to_bit(autopull) << PIO_SM0_SHIFTCTRL_AUTOPULL_LSB) |
318 ((pull_threshold & 0x1fu) << PIO_SM0_SHIFTCTRL_PULL_THRESH_LSB);
319}
320
327static inline void sm_config_set_fifo_join(pio_sm_config *c, enum pio_fifo_join join) {
328 valid_params_if(PIO, join == PIO_FIFO_JOIN_NONE || join == PIO_FIFO_JOIN_TX || join == PIO_FIFO_JOIN_RX);
329 c->shiftctrl = (c->shiftctrl & (uint)~(PIO_SM0_SHIFTCTRL_FJOIN_TX_BITS | PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS)) |
330 (((uint)join) << PIO_SM0_SHIFTCTRL_FJOIN_TX_LSB);
331}
332
341static inline void sm_config_set_out_special(pio_sm_config *c, bool sticky, bool has_enable_pin, uint enable_pin_index) {
342 c->execctrl = (c->execctrl &
343 (uint)~(PIO_SM0_EXECCTRL_OUT_STICKY_BITS | PIO_SM0_EXECCTRL_INLINE_OUT_EN_BITS |
344 PIO_SM0_EXECCTRL_OUT_EN_SEL_BITS)) |
345 (bool_to_bit(sticky) << PIO_SM0_EXECCTRL_OUT_STICKY_LSB) |
346 (bool_to_bit(has_enable_pin) << PIO_SM0_EXECCTRL_INLINE_OUT_EN_LSB) |
347 ((enable_pin_index << PIO_SM0_EXECCTRL_OUT_EN_SEL_LSB) & PIO_SM0_EXECCTRL_OUT_EN_SEL_BITS);
348}
349
357static inline void sm_config_set_mov_status(pio_sm_config *c, enum pio_mov_status_type status_sel, uint status_n) {
358 valid_params_if(PIO, status_sel == STATUS_TX_LESSTHAN || status_sel == STATUS_RX_LESSTHAN);
359 c->execctrl = (c->execctrl
360 & ~(PIO_SM0_EXECCTRL_STATUS_SEL_BITS | PIO_SM0_EXECCTRL_STATUS_N_BITS))
361 | ((((uint)status_sel) << PIO_SM0_EXECCTRL_STATUS_SEL_LSB) & PIO_SM0_EXECCTRL_STATUS_SEL_BITS)
362 | ((status_n << PIO_SM0_EXECCTRL_STATUS_N_LSB) & PIO_SM0_EXECCTRL_STATUS_N_BITS);
363}
364
365
386 pio_sm_config c = {0, 0, 0, 0};
388 sm_config_set_wrap(&c, 0, 31);
389 sm_config_set_in_shift(&c, true, false, 32);
390 sm_config_set_out_shift(&c, true, false, 32);
391 return c;
392}
393
401static inline void pio_sm_set_config(PIO pio, uint sm, const pio_sm_config *config) {
402 check_pio_param(pio);
403 check_sm_param(sm);
404 pio->sm[sm].clkdiv = config->clkdiv;
405 pio->sm[sm].execctrl = config->execctrl;
406 pio->sm[sm].shiftctrl = config->shiftctrl;
407 pio->sm[sm].pinctrl = config->pinctrl;
408}
409
416static inline uint pio_get_index(PIO pio) {
417 check_pio_param(pio);
418 return pio == pio1 ? 1 : 0;
419}
420
433static inline void pio_gpio_init(PIO pio, uint pin) {
434 check_pio_param(pio);
435 valid_params_if(PIO, pin < 32);
436 gpio_set_function(pin, pio == pio0 ? GPIO_FUNC_PIO0 : GPIO_FUNC_PIO1);
437}
438
446static inline uint pio_get_dreq(PIO pio, uint sm, bool is_tx) {
447 static_assert(DREQ_PIO0_TX1 == DREQ_PIO0_TX0 + 1, "");
448 static_assert(DREQ_PIO0_TX2 == DREQ_PIO0_TX0 + 2, "");
449 static_assert(DREQ_PIO0_TX3 == DREQ_PIO0_TX0 + 3, "");
450 static_assert(DREQ_PIO0_RX0 == DREQ_PIO0_TX0 + NUM_PIO_STATE_MACHINES, "");
451 static_assert(DREQ_PIO1_RX0 == DREQ_PIO1_TX0 + NUM_PIO_STATE_MACHINES, "");
452 check_pio_param(pio);
453 check_sm_param(sm);
454 return sm + (is_tx ? 0 : NUM_PIO_STATE_MACHINES) + (pio == pio0 ? DREQ_PIO0_TX0 : DREQ_PIO1_TX0);
455}
456
457typedef struct pio_program {
458 const uint16_t *instructions;
459 uint8_t length;
460 int8_t origin; // required instruction memory origin or -1
461} __packed pio_program_t;
462
470bool pio_can_add_program(PIO pio, const pio_program_t *program);
471
480bool pio_can_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset);
481
491uint pio_add_program(PIO pio, const pio_program_t *program);
492
502void pio_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset);
503
511void pio_remove_program(PIO pio, const pio_program_t *program, uint loaded_offset);
512
519
537void pio_sm_init(PIO pio, uint sm, uint initial_pc, const pio_sm_config *config);
538
546static inline void pio_sm_set_enabled(PIO pio, uint sm, bool enabled) {
547 check_pio_param(pio);
548 check_sm_param(sm);
549 pio->ctrl = (pio->ctrl & ~(1u << sm)) | (bool_to_bit(enabled) << sm);
550}
551
565static inline void pio_set_sm_mask_enabled(PIO pio, uint32_t mask, bool enabled) {
566 check_pio_param(pio);
567 check_sm_mask(mask);
568 pio->ctrl = (pio->ctrl & ~mask) | (enabled ? mask : 0u);
569}
570
580static inline void pio_sm_restart(PIO pio, uint sm) {
581 check_pio_param(pio);
582 check_sm_param(sm);
583 hw_set_bits(&pio->ctrl, 1u << (PIO_CTRL_SM_RESTART_LSB + sm));
584}
585
595static inline void pio_restart_sm_mask(PIO pio, uint32_t mask) {
596 check_pio_param(pio);
597 check_sm_mask(mask);
598 hw_set_bits(&pio->ctrl, (mask << PIO_CTRL_SM_RESTART_LSB) & PIO_CTRL_SM_RESTART_BITS);
599}
600
622static inline void pio_sm_clkdiv_restart(PIO pio, uint sm) {
623 check_pio_param(pio);
624 check_sm_param(sm);
625 hw_set_bits(&pio->ctrl, 1u << (PIO_CTRL_CLKDIV_RESTART_LSB + sm));
626}
627
657static inline void pio_clkdiv_restart_sm_mask(PIO pio, uint32_t mask) {
658 check_pio_param(pio);
659 check_sm_mask(mask);
660 hw_set_bits(&pio->ctrl, (mask << PIO_CTRL_CLKDIV_RESTART_LSB) & PIO_CTRL_CLKDIV_RESTART_BITS);
661}
662
674static inline void pio_enable_sm_mask_in_sync(PIO pio, uint32_t mask) {
675 check_pio_param(pio);
676 check_sm_mask(mask);
677 hw_set_bits(&pio->ctrl,
678 ((mask << PIO_CTRL_CLKDIV_RESTART_LSB) & PIO_CTRL_CLKDIV_RESTART_BITS) |
679 ((mask << PIO_CTRL_SM_ENABLE_LSB) & PIO_CTRL_SM_ENABLE_BITS));
680}
681
686 pis_interrupt0 = PIO_INTR_SM0_LSB,
687 pis_interrupt1 = PIO_INTR_SM1_LSB,
688 pis_interrupt2 = PIO_INTR_SM2_LSB,
689 pis_interrupt3 = PIO_INTR_SM3_LSB,
690 pis_sm0_tx_fifo_not_full = PIO_INTR_SM0_TXNFULL_LSB,
691 pis_sm1_tx_fifo_not_full = PIO_INTR_SM1_TXNFULL_LSB,
692 pis_sm2_tx_fifo_not_full = PIO_INTR_SM2_TXNFULL_LSB,
693 pis_sm3_tx_fifo_not_full = PIO_INTR_SM3_TXNFULL_LSB,
694 pis_sm0_rx_fifo_not_empty = PIO_INTR_SM0_RXNEMPTY_LSB,
695 pis_sm1_rx_fifo_not_empty = PIO_INTR_SM1_RXNEMPTY_LSB,
696 pis_sm2_rx_fifo_not_empty = PIO_INTR_SM2_RXNEMPTY_LSB,
697 pis_sm3_rx_fifo_not_empty = PIO_INTR_SM3_RXNEMPTY_LSB,
698};
699
707static inline void pio_set_irq0_source_enabled(PIO pio, enum pio_interrupt_source source, bool enabled) {
708 check_pio_param(pio);
709 invalid_params_if(PIO, source >= 12);
710 if (enabled)
711 hw_set_bits(&pio->inte0, 1u << source);
712 else
713 hw_clear_bits(&pio->inte0, 1u << source);
714}
715
723static inline void pio_set_irq1_source_enabled(PIO pio, enum pio_interrupt_source source, bool enabled) {
724 check_pio_param(pio);
725 invalid_params_if(PIO, source >= 12);
726 if (enabled)
727 hw_set_bits(&pio->inte1, 1u << source);
728 else
729 hw_clear_bits(&pio->inte1, 1u << source);
730}
731
739static inline void pio_set_irq0_source_mask_enabled(PIO pio, uint32_t source_mask, bool enabled) {
740 check_pio_param(pio);
741 invalid_params_if(PIO, source_mask > PIO_INTR_BITS);
742 if (enabled) {
743 hw_set_bits(&pio->inte0, source_mask);
744 } else {
745 hw_clear_bits(&pio->inte0, source_mask);
746 }
747}
748
756static inline void pio_set_irq1_source_mask_enabled(PIO pio, uint32_t source_mask, bool enabled) {
757 check_pio_param(pio);
758 invalid_params_if(PIO, source_mask > PIO_INTR_BITS);
759 if (enabled) {
760 hw_set_bits(&pio->inte1, source_mask);
761 } else {
762 hw_clear_bits(&pio->inte1, source_mask);
763 }
764}
765
774static inline void pio_set_irqn_source_enabled(PIO pio, uint irq_index, enum pio_interrupt_source source, bool enabled) {
775 invalid_params_if(PIO, irq_index > 1);
776 if (irq_index) {
777 pio_set_irq1_source_enabled(pio, source, enabled);
778 } else {
779 pio_set_irq0_source_enabled(pio, source, enabled);
780 }
781}
782
791static inline void pio_set_irqn_source_mask_enabled(PIO pio, uint irq_index, uint32_t source_mask, bool enabled) {
792 invalid_params_if(PIO, irq_index > 1);
793 if (irq_index) {
794 pio_set_irq1_source_mask_enabled(pio, source_mask, enabled);
795 } else {
796 pio_set_irq0_source_mask_enabled(pio, source_mask, enabled);
797 }
798}
799
807static inline bool pio_interrupt_get(PIO pio, uint pio_interrupt_num) {
808 check_pio_param(pio);
809 invalid_params_if(PIO, pio_interrupt_num >= 8);
810 return pio->irq & (1u << pio_interrupt_num);
811}
812
819static inline void pio_interrupt_clear(PIO pio, uint pio_interrupt_num) {
820 check_pio_param(pio);
821 invalid_params_if(PIO, pio_interrupt_num >= 8);
822 pio->irq = (1u << pio_interrupt_num);
823}
824
832static inline uint8_t pio_sm_get_pc(PIO pio, uint sm) {
833 check_pio_param(pio);
834 check_sm_param(sm);
835 return (uint8_t) pio->sm[sm].addr;
836}
837
850inline static void pio_sm_exec(PIO pio, uint sm, uint instr) {
851 check_pio_param(pio);
852 check_sm_param(sm);
853 pio->sm[sm].instr = instr;
854}
855
863static inline bool pio_sm_is_exec_stalled(PIO pio, uint sm) {
864 check_pio_param(pio);
865 check_sm_param(sm);
866 return !!(pio->sm[sm].execctrl & PIO_SM0_EXECCTRL_EXEC_STALLED_BITS);
867}
868
881static inline void pio_sm_exec_wait_blocking(PIO pio, uint sm, uint instr) {
882 check_pio_param(pio);
883 check_sm_param(sm);
884 pio_sm_exec(pio, sm, instr);
886}
887
897static inline void pio_sm_set_wrap(PIO pio, uint sm, uint wrap_target, uint wrap) {
898 check_pio_param(pio);
899 check_sm_param(sm);
900 valid_params_if(PIO, wrap < PIO_INSTRUCTION_COUNT);
901 valid_params_if(PIO, wrap_target < PIO_INSTRUCTION_COUNT);
902 pio->sm[sm].execctrl =
903 (pio->sm[sm].execctrl & ~(PIO_SM0_EXECCTRL_WRAP_TOP_BITS | PIO_SM0_EXECCTRL_WRAP_BOTTOM_BITS)) |
904 (wrap_target << PIO_SM0_EXECCTRL_WRAP_BOTTOM_LSB) |
905 (wrap << PIO_SM0_EXECCTRL_WRAP_TOP_LSB);
906}
907
918static inline void pio_sm_set_out_pins(PIO pio, uint sm, uint out_base, uint out_count) {
919 check_pio_param(pio);
920 check_sm_param(sm);
921 valid_params_if(PIO, out_base < 32);
922 valid_params_if(PIO, out_count <= 32);
923 pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~(PIO_SM0_PINCTRL_OUT_BASE_BITS | PIO_SM0_PINCTRL_OUT_COUNT_BITS)) |
924 (out_base << PIO_SM0_PINCTRL_OUT_BASE_LSB) |
925 (out_count << PIO_SM0_PINCTRL_OUT_COUNT_LSB);
926}
927
928
939static inline void pio_sm_set_set_pins(PIO pio, uint sm, uint set_base, uint set_count) {
940 check_pio_param(pio);
941 check_sm_param(sm);
942 valid_params_if(PIO, set_base < 32);
943 valid_params_if(PIO, set_count <= 5);
944 pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~(PIO_SM0_PINCTRL_SET_BASE_BITS | PIO_SM0_PINCTRL_SET_COUNT_BITS)) |
945 (set_base << PIO_SM0_PINCTRL_SET_BASE_LSB) |
946 (set_count << PIO_SM0_PINCTRL_SET_COUNT_LSB);
947}
948
958static inline void pio_sm_set_in_pins(PIO pio, uint sm, uint in_base) {
959 check_pio_param(pio);
960 check_sm_param(sm);
961 valid_params_if(PIO, in_base < 32);
962 pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~PIO_SM0_PINCTRL_IN_BASE_BITS) |
963 (in_base << PIO_SM0_PINCTRL_IN_BASE_LSB);
964}
965
975static inline void pio_sm_set_sideset_pins(PIO pio, uint sm, uint sideset_base) {
976 check_pio_param(pio);
977 check_sm_param(sm);
978 valid_params_if(PIO, sideset_base < 32);
979 pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~PIO_SM0_PINCTRL_SIDESET_BASE_BITS) |
980 (sideset_base << PIO_SM0_PINCTRL_SIDESET_BASE_LSB);
981}
982
997static inline void pio_sm_put(PIO pio, uint sm, uint32_t data) {
998 check_pio_param(pio);
999 check_sm_param(sm);
1000 pio->txf[sm] = data;
1001}
1002
1018static inline uint32_t pio_sm_get(PIO pio, uint sm) {
1019 check_pio_param(pio);
1020 check_sm_param(sm);
1021 return pio->rxf[sm];
1022}
1023
1031static inline bool pio_sm_is_rx_fifo_full(PIO pio, uint sm) {
1032 check_pio_param(pio);
1033 check_sm_param(sm);
1034 return (pio->fstat & (1u << (PIO_FSTAT_RXFULL_LSB + sm))) != 0;
1035}
1036
1044static inline bool pio_sm_is_rx_fifo_empty(PIO pio, uint sm) {
1045 check_pio_param(pio);
1046 check_sm_param(sm);
1047 return (pio->fstat & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) != 0;
1048}
1049
1057static inline uint pio_sm_get_rx_fifo_level(PIO pio, uint sm) {
1058 check_pio_param(pio);
1059 check_sm_param(sm);
1060 uint bitoffs = PIO_FLEVEL_RX0_LSB + sm * (PIO_FLEVEL_RX1_LSB - PIO_FLEVEL_RX0_LSB);
1061 const uint32_t mask = PIO_FLEVEL_RX0_BITS >> PIO_FLEVEL_RX0_LSB;
1062 return (pio->flevel >> bitoffs) & mask;
1063}
1064
1072static inline bool pio_sm_is_tx_fifo_full(PIO pio, uint sm) {
1073 check_pio_param(pio);
1074 check_sm_param(sm);
1075 return (pio->fstat & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) != 0;
1076}
1077
1085static inline bool pio_sm_is_tx_fifo_empty(PIO pio, uint sm) {
1086 check_pio_param(pio);
1087 check_sm_param(sm);
1088 return (pio->fstat & (1u << (PIO_FSTAT_TXEMPTY_LSB + sm))) != 0;
1089}
1090
1098static inline uint pio_sm_get_tx_fifo_level(PIO pio, uint sm) {
1099 check_pio_param(pio);
1100 check_sm_param(sm);
1101 unsigned int bitoffs = PIO_FLEVEL_TX0_LSB + sm * (PIO_FLEVEL_TX1_LSB - PIO_FLEVEL_TX0_LSB);
1102 const uint32_t mask = PIO_FLEVEL_TX0_BITS >> PIO_FLEVEL_TX0_LSB;
1103 return (pio->flevel >> bitoffs) & mask;
1104}
1105
1113static inline void pio_sm_put_blocking(PIO pio, uint sm, uint32_t data) {
1114 check_pio_param(pio);
1115 check_sm_param(sm);
1117 pio_sm_put(pio, sm, data);
1118}
1119
1126static inline uint32_t pio_sm_get_blocking(PIO pio, uint sm) {
1127 check_pio_param(pio);
1128 check_sm_param(sm);
1130 return pio_sm_get(pio, sm);
1131}
1132
1146void pio_sm_drain_tx_fifo(PIO pio, uint sm);
1147
1156static inline void pio_sm_set_clkdiv_int_frac(PIO pio, uint sm, uint16_t div_int, uint8_t div_frac) {
1157 check_pio_param(pio);
1158 check_sm_param(sm);
1159 invalid_params_if(PIO, div_int == 0 && div_frac != 0);
1160 pio->sm[sm].clkdiv =
1161 (((uint)div_frac) << PIO_SM0_CLKDIV_FRAC_LSB) |
1162 (((uint)div_int) << PIO_SM0_CLKDIV_INT_LSB);
1163}
1164
1172static inline void pio_sm_set_clkdiv(PIO pio, uint sm, float div) {
1173 check_pio_param(pio);
1174 check_sm_param(sm);
1175 uint16_t div_int;
1176 uint8_t div_frac;
1177 pio_calculate_clkdiv_from_float(div, &div_int, &div_frac);
1178 pio_sm_set_clkdiv_int_frac(pio, sm, div_int, div_frac);
1179}
1180
1187static inline void pio_sm_clear_fifos(PIO pio, uint sm) {
1188 // changing the FIFO join state clears the fifo
1189 check_pio_param(pio);
1190 check_sm_param(sm);
1191 hw_xor_bits(&pio->sm[sm].shiftctrl, PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS);
1192 hw_xor_bits(&pio->sm[sm].shiftctrl, PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS);
1193}
1194
1207void pio_sm_set_pins(PIO pio, uint sm, uint32_t pin_values);
1208
1222void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pin_values, uint32_t pin_mask);
1223
1237void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pin_dirs, uint32_t pin_mask);
1238
1253void pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pin_base, uint pin_count, bool is_out);
1254
1265void pio_sm_claim(PIO pio, uint sm);
1266
1277void pio_claim_sm_mask(PIO pio, uint sm_mask);
1278
1287void pio_sm_unclaim(PIO pio, uint sm);
1288
1296int pio_claim_unused_sm(PIO pio, bool required);
1297
1307bool pio_sm_is_claimed(PIO pio, uint sm);
1308
1309#ifdef __cplusplus
1310}
1311#endif
1312
1313#endif // _PIO_H_
static __force_inline void hw_set_bits(io_rw_32 *addr, uint32_t mask)
Atomically set the specified bits to 1 in a HW register.
Definition address_mapped.h:121
static __force_inline void hw_xor_bits(io_rw_32 *addr, uint32_t mask)
Atomically flip the specified bits in a HW register.
Definition address_mapped.h:141
static __force_inline void hw_clear_bits(io_rw_32 *addr, uint32_t mask)
Atomically clear the specified bits to 0 in a HW register.
Definition address_mapped.h:131
void gpio_set_function(uint gpio, enum gpio_function fn)
Select GPIO function.
Definition gpio.c:32
static uint pio_sm_get_tx_fifo_level(PIO pio, uint sm)
Return the number of elements currently in a state machine's TX FIFO.
Definition pio.h:1098
static void pio_sm_set_config(PIO pio, uint sm, const pio_sm_config *config)
Apply a state machine configuration to a state machine.
Definition pio.h:401
pio_interrupt_source
PIO interrupt source numbers for pio related IRQs.
Definition pio.h:685
static uint32_t pio_sm_get_blocking(PIO pio, uint sm)
Read a word of data from a state machine's RX FIFO, blocking if the FIFO is empty.
Definition pio.h:1126
void pio_sm_set_pins(PIO pio, uint sm, uint32_t pin_values)
Use a state machine to set a value on all pins for the PIO instance.
Definition pio.c:156
static void pio_sm_exec_wait_blocking(PIO pio, uint sm, uint instr)
Immediately execute an instruction on a state machine and wait for it to complete.
Definition pio.h:881
pio_mov_status_type
MOV status types.
Definition pio.h:64
uint pio_add_program(PIO pio, const pio_program_t *program)
Attempt to load the program, panicking if not possible.
Definition pio.c:117
static void pio_set_irqn_source_enabled(PIO pio, uint irq_index, enum pio_interrupt_source source, bool enabled)
Enable/Disable a single source on a PIO's specified (0/1) IRQ index.
Definition pio.h:774
static bool pio_sm_is_tx_fifo_full(PIO pio, uint sm)
Determine if a state machine's TX FIFO is full.
Definition pio.h:1072
static uint pio_get_dreq(PIO pio, uint sm, bool is_tx)
Return the DREQ to use for pacing transfers to/from a particular state machine FIFO.
Definition pio.h:446
void pio_sm_drain_tx_fifo(PIO pio, uint sm)
Empty out a state machine's TX FIFO.
Definition pio.c:262
void pio_claim_sm_mask(PIO pio, uint sm_mask)
Mark multiple state machines as used.
Definition pio.c:33
void pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pin_base, uint pin_count, bool is_out)
Use a state machine to set the same pin direction for multiple consecutive pins for the PIO instance.
Definition pio.c:214
void pio_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset)
Attempt to load the program at the specified instruction memory offset, panicking if not possible.
Definition pio.c:128
int pio_claim_unused_sm(PIO pio, bool required)
Claim a free state machine on a PIO instance.
Definition pio.c:45
void pio_sm_unclaim(PIO pio, uint sm)
Mark a state machine as no longer used.
Definition pio.c:39
static void pio_clkdiv_restart_sm_mask(PIO pio, uint32_t mask)
Restart multiple state machines' clock dividers from a phase of 0.
Definition pio.h:657
bool pio_sm_is_claimed(PIO pio, uint sm)
Determine if a PIO state machine is claimed.
Definition pio.c:54
static void pio_set_irq1_source_enabled(PIO pio, enum pio_interrupt_source source, bool enabled)
Enable/Disable a single source on a PIO's IRQ 1.
Definition pio.h:723
static void pio_interrupt_clear(PIO pio, uint pio_interrupt_num)
Clear a particular PIO interrupt.
Definition pio.h:819
static uint32_t pio_sm_get(PIO pio, uint sm)
Read a word of data from a state machine's RX FIFO.
Definition pio.h:1018
static bool pio_sm_is_rx_fifo_full(PIO pio, uint sm)
Determine if a state machine's RX FIFO is full.
Definition pio.h:1031
static void pio_sm_set_wrap(PIO pio, uint sm, uint wrap_target, uint wrap)
Set the current wrap configuration for a state machine.
Definition pio.h:897
static void pio_sm_restart(PIO pio, uint sm)
Restart a state machine with a known state.
Definition pio.h:580
pio_fifo_join
FIFO join states.
Definition pio.h:55
static void pio_sm_set_out_pins(PIO pio, uint sm, uint out_base, uint out_count)
Set the current 'out' pins for a state machine.
Definition pio.h:918
static void pio_sm_exec(PIO pio, uint sm, uint instr)
Immediately execute an instruction on a state machine.
Definition pio.h:850
static void pio_set_irq0_source_mask_enabled(PIO pio, uint32_t source_mask, bool enabled)
Enable/Disable multiple sources on a PIO's IRQ 0.
Definition pio.h:739
void pio_remove_program(PIO pio, const pio_program_t *program, uint loaded_offset)
Remove a program from a PIO instance's instruction memory.
Definition pio.c:134
void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pin_dirs, uint32_t pin_mask)
Use a state machine to set the pin directions for multiple pins for the PIO instance.
Definition pio.c:196
void pio_clear_instruction_memory(PIO pio)
Clears all of a PIO instance's instruction memory.
Definition pio.c:143
static void pio_sm_set_sideset_pins(PIO pio, uint sm, uint sideset_base)
Set the current 'sideset' pins for a state machine.
Definition pio.h:975
static void pio_sm_set_clkdiv(PIO pio, uint sm, float div)
set the current clock divider for a state machine
Definition pio.h:1172
static uint pio_sm_get_rx_fifo_level(PIO pio, uint sm)
Return the number of elements currently in a state machine's RX FIFO.
Definition pio.h:1057
#define pio0
Definition pio.h:77
#define pio1
Definition pio.h:85
void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pin_values, uint32_t pin_mask)
Use a state machine to set a value on multiple pins for the PIO instance.
Definition pio.c:178
static uint8_t pio_sm_get_pc(PIO pio, uint sm)
Return the current program counter for a state machine.
Definition pio.h:832
static void pio_sm_set_enabled(PIO pio, uint sm, bool enabled)
Enable or disable a PIO state machine.
Definition pio.h:546
void pio_sm_claim(PIO pio, uint sm)
Mark a state machine as used.
Definition pio.c:23
bool pio_can_add_program(PIO pio, const pio_program_t *program)
Determine whether the given program can (at the time of the call) be loaded onto the PIO instance.
Definition pio.c:81
static void pio_set_irq0_source_enabled(PIO pio, enum pio_interrupt_source source, bool enabled)
Enable/Disable a single source on a PIO's IRQ 0.
Definition pio.h:707
static bool pio_interrupt_get(PIO pio, uint pio_interrupt_num)
Determine if a particular PIO interrupt is set.
Definition pio.h:807
static void pio_sm_set_clkdiv_int_frac(PIO pio, uint sm, uint16_t div_int, uint8_t div_frac)
set the current clock divider for a state machine using a 16:8 fraction
Definition pio.h:1156
static bool pio_sm_is_exec_stalled(PIO pio, uint sm)
Determine if an instruction set by pio_sm_exec() is stalled executing.
Definition pio.h:863
bool pio_can_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset)
Determine whether the given program can (at the time of the call) be loaded onto the PIO instance sta...
Definition pio.c:97
void pio_sm_init(PIO pio, uint sm, uint initial_pc, const pio_sm_config *config)
Resets the state machine to a consistent state, and configures it.
Definition pio.c:234
static void pio_sm_put(PIO pio, uint sm, uint32_t data)
Write a word of data to a state machine's TX FIFO.
Definition pio.h:997
static void pio_sm_clear_fifos(PIO pio, uint sm)
Clear a state machine's TX and RX FIFOs.
Definition pio.h:1187
static void pio_enable_sm_mask_in_sync(PIO pio, uint32_t mask)
Enable multiple PIO state machines synchronizing their clock dividers.
Definition pio.h:674
static void pio_sm_set_set_pins(PIO pio, uint sm, uint set_base, uint set_count)
Set the current 'set' pins for a state machine.
Definition pio.h:939
static void pio_sm_clkdiv_restart(PIO pio, uint sm)
Restart a state machine's clock divider from a phase of 0.
Definition pio.h:622
static bool pio_sm_is_rx_fifo_empty(PIO pio, uint sm)
Determine if a state machine's RX FIFO is empty.
Definition pio.h:1044
static bool pio_sm_is_tx_fifo_empty(PIO pio, uint sm)
Determine if a state machine's TX FIFO is empty.
Definition pio.h:1085
static void pio_set_irq1_source_mask_enabled(PIO pio, uint32_t source_mask, bool enabled)
Enable/Disable multiple sources on a PIO's IRQ 1.
Definition pio.h:756
static void pio_restart_sm_mask(PIO pio, uint32_t mask)
Restart multiple state machine with a known state.
Definition pio.h:595
static uint pio_get_index(PIO pio)
Return the instance number of a PIO instance.
Definition pio.h:416
static void pio_sm_put_blocking(PIO pio, uint sm, uint32_t data)
Write a word of data to a state machine's TX FIFO, blocking if the FIFO is full.
Definition pio.h:1113
static void pio_sm_set_in_pins(PIO pio, uint sm, uint in_base)
Set the current 'in' pins for a state machine.
Definition pio.h:958
static void pio_set_sm_mask_enabled(PIO pio, uint32_t mask, bool enabled)
Enable or disable multiple PIO state machines.
Definition pio.h:565
static void pio_gpio_init(PIO pio, uint pin)
Setup the function select for a GPIO to use output from the given PIO instance.
Definition pio.h:433
static void pio_set_irqn_source_mask_enabled(PIO pio, uint irq_index, uint32_t source_mask, bool enabled)
Enable/Disable multiple sources on a PIO's specified (0/1) IRQ index.
Definition pio.h:791
static __always_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition platform.h:434
static void sm_config_set_clkdiv_int_frac(pio_sm_config *c, uint16_t div_int, uint8_t div_frac)
Set the state machine clock divider (from integer and fractional parts - 16:8) in a state machine con...
Definition pio.h:216
static void sm_config_set_out_shift(pio_sm_config *c, bool shift_right, bool autopull, uint pull_threshold)
Setup 'out' shifting parameters in a state machine configuration.
Definition pio.h:310
static void sm_config_set_out_special(pio_sm_config *c, bool sticky, bool has_enable_pin, uint enable_pin_index)
Set special 'out' operations in a state machine configuration.
Definition pio.h:341
static void sm_config_set_in_pins(pio_sm_config *c, uint in_base)
Set the 'in' pins in a state machine configuration.
Definition pio.h:164
static void sm_config_set_mov_status(pio_sm_config *c, enum pio_mov_status_type status_sel, uint status_n)
Set source for 'mov status' in a state machine configuration.
Definition pio.h:357
static void sm_config_set_sideset_pins(pio_sm_config *c, uint sideset_base)
Set the 'sideset' pins in a state machine configuration.
Definition pio.h:178
static void sm_config_set_set_pins(pio_sm_config *c, uint set_base, uint set_count)
Set the 'set' pins in a state machine configuration.
Definition pio.h:148
static void sm_config_set_clkdiv(pio_sm_config *c, float div)
Set the state machine clock divider (from a floating point value) in a state machine configuration.
Definition pio.h:248
static void sm_config_set_in_shift(pio_sm_config *c, bool shift_right, bool autopush, uint push_threshold)
Setup 'in' shifting parameters in a state machine configuration.
Definition pio.h:291
static void sm_config_set_jmp_pin(pio_sm_config *c, uint pin)
Set the 'jmp' pin in a state machine configuration.
Definition pio.h:277
static pio_sm_config pio_get_default_sm_config(void)
Get the default state machine configuration.
Definition pio.h:385
static void sm_config_set_out_pins(pio_sm_config *c, uint out_base, uint out_count)
Set the 'out' pins in a state machine configuration.
Definition pio.h:131
static void sm_config_set_sideset(pio_sm_config *c, uint bit_count, bool optional, bool pindirs)
Set the 'sideset' options in a state machine configuration.
Definition pio.h:192
static void sm_config_set_wrap(pio_sm_config *c, uint wrap_target, uint wrap)
Set the wrap addresses in a state machine configuration.
Definition pio.h:263
static void sm_config_set_fifo_join(pio_sm_config *c, enum pio_fifo_join join)
Setup the FIFO joining in a state machine configuration.
Definition pio.h:327
Definition pio.h:79
Definition pio.h:457
PIO Configuration structure.
Definition pio.h:102