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
47 extern "C" {
48 #endif
49 
50 static_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 
69 typedef pio_hw_t *PIO;
70 
77 #define pio0 pio0_hw
78 
85 #define pio1 pio1_hw
86 
102 typedef struct {
103  uint32_t clkdiv;
104  uint32_t execctrl;
105  uint32_t shiftctrl;
106  uint32_t pinctrl;
107 } pio_sm_config;
108 
109 static inline void check_sm_param(__unused uint sm) {
110  valid_params_if(PIO, sm < NUM_PIO_STATE_MACHINES);
111 }
112 
113 static inline void check_sm_mask(__unused uint mask) {
114  valid_params_if(PIO, mask < (1u << NUM_PIO_STATE_MACHINES));
115 }
116 
117 
118 static inline void check_pio_param(__unused PIO pio) {
119  valid_params_if(PIO, pio == pio0 || pio == pio1);
120 }
121 
131 static 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 
148 static 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 
164 static 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 
178 static 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 
192 static 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 
216 static 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 
223 static 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 
248 static 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 
263 static 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 
277 static 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 
291 static 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 
310 static 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 
327 static 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 
341 static 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 
357 static 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 
401 static 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 
416 static inline uint pio_get_index(PIO pio) {
417  check_pio_param(pio);
418  return pio == pio1 ? 1 : 0;
419 }
420 
433 static 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 
446 static 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 
457 typedef 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 
470 bool pio_can_add_program(PIO pio, const pio_program_t *program);
471 
480 bool pio_can_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset);
481 
491 uint pio_add_program(PIO pio, const pio_program_t *program);
492 
502 void pio_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset);
503 
511 void pio_remove_program(PIO pio, const pio_program_t *program, uint loaded_offset);
512 
519 
537 void pio_sm_init(PIO pio, uint sm, uint initial_pc, const pio_sm_config *config);
538 
546 static 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 
565 static 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 
580 static 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 
595 static 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 
622 static 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 
657 static 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 
674 static 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 
707 static 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 
723 static 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 
739 static 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 
756 static 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 
774 static 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 
791 static 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 
807 static 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 
819 static 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 
832 static 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 
850 inline 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 
863 static 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 
881 static 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);
885  while (pio_sm_is_exec_stalled(pio, sm)) tight_loop_contents();
886 }
887 
897 static 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 
918 static 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 
939 static 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 
958 static 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 
975 static 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 
997 static 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 
1018 static 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 
1031 static 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 
1044 static 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 
1057 static 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 
1072 static 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 
1085 static 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 
1098 static 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 
1113 static inline void pio_sm_put_blocking(PIO pio, uint sm, uint32_t data) {
1114  check_pio_param(pio);
1115  check_sm_param(sm);
1116  while (pio_sm_is_tx_fifo_full(pio, sm)) tight_loop_contents();
1117  pio_sm_put(pio, sm, data);
1118 }
1119 
1126 static inline uint32_t pio_sm_get_blocking(PIO pio, uint sm) {
1127  check_pio_param(pio);
1128  check_sm_param(sm);
1129  while (pio_sm_is_rx_fifo_empty(pio, sm)) tight_loop_contents();
1130  return pio_sm_get(pio, sm);
1131 }
1132 
1146 void pio_sm_drain_tx_fifo(PIO pio, uint sm);
1147 
1156 static 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 
1172 static 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 
1187 static 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 
1207 void pio_sm_set_pins(PIO pio, uint sm, uint32_t pin_values);
1208 
1222 void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pin_values, uint32_t pin_mask);
1223 
1237 void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pin_dirs, uint32_t pin_mask);
1238 
1253 void pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pin_base, uint pin_count, bool is_out);
1254 
1265 void pio_sm_claim(PIO pio, uint sm);
1266 
1277 void pio_claim_sm_mask(PIO pio, uint sm_mask);
1278 
1287 void pio_sm_unclaim(PIO pio, uint sm);
1288 
1296 int pio_claim_unused_sm(PIO pio, bool required);
1297 
1307 bool pio_sm_is_claimed(PIO pio, uint sm);
1308 
1309 #ifdef __cplusplus
1310 }
1311 #endif
1312 
1313 #endif // _PIO_H_
pio_sm_set_in_pins
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
hw_clear_bits
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
pio_sm_set_clkdiv_int_frac
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
pio_get_index
static uint pio_get_index(PIO pio)
Return the instance number of a PIO instance.
Definition: pio.h:416
address_mapped.h
pio_remove_program
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
sm_config_set_clkdiv_int_frac
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
pio_clkdiv_restart_sm_mask
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
pio_sm_set_out_pins
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
sm_config_set_wrap
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
pio_sm_init
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
pio_sm_put
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
pio_sm_get
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
pio_sm_is_rx_fifo_full
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
pio0
#define pio0
Definition: pio.h:77
pio_clear_instruction_memory
void pio_clear_instruction_memory(PIO pio)
Clears all of a PIO instance's instruction memory.
Definition: pio.c:143
pio_interrupt_clear
static void pio_interrupt_clear(PIO pio, uint pio_interrupt_num)
Clear a particular PIO interrupt.
Definition: pio.h:819
sm_config_set_mov_status
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
pio_sm_set_enabled
static void pio_sm_set_enabled(PIO pio, uint sm, bool enabled)
Enable or disable a PIO state machine.
Definition: pio.h:546
pio_sm_get_blocking
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
pio_set_irq0_source_mask_enabled
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
pio_sm_restart
static void pio_sm_restart(PIO pio, uint sm)
Restart a state machine with a known state.
Definition: pio.h:580
pio_sm_is_claimed
bool pio_sm_is_claimed(PIO pio, uint sm)
Determine if a PIO state machine is claimed.
Definition: pio.c:54
pio_sm_is_rx_fifo_empty
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
pio_sm_set_sideset_pins
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
pio_restart_sm_mask
static void pio_restart_sm_mask(PIO pio, uint32_t mask)
Restart multiple state machine with a known state.
Definition: pio.h:595
pio_interrupt_get
static bool pio_interrupt_get(PIO pio, uint pio_interrupt_num)
Determine if a particular PIO interrupt is set.
Definition: pio.h:807
pio_sm_set_clkdiv
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
pio_sm_put_blocking
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
pio_sm_set_pindirs_with_mask
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
pio_sm_exec
static void pio_sm_exec(PIO pio, uint sm, uint instr)
Immediately execute an instruction on a state machine.
Definition: pio.h:850
pio_mov_status_type
pio_mov_status_type
MOV status types.
Definition: pio.h:64
sm_config_set_sideset
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
pio_add_program_at_offset
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
pio_set_irq0_source_enabled
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
sm_config_set_out_pins
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
pio_can_add_program
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
hw_set_bits
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
sm_config_set_out_shift
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
sm_config_set_clkdiv
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
pio_get_dreq
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
pio_sm_set_consecutive_pindirs
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
pio_sm_claim
void pio_sm_claim(PIO pio, uint sm)
Mark a state machine as used.
Definition: pio.c:23
pio_sm_is_tx_fifo_full
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
sm_config_set_sideset_pins
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
pio_set_sm_mask_enabled
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
gpio_set_function
void gpio_set_function(uint gpio, enum gpio_function fn)
Select GPIO function.
Definition: gpio.c:32
sm_config_set_in_shift
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
pio_sm_config
PIO Configuration structure.
Definition: pio.h:102
sm_config_set_set_pins
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
pio_get_default_sm_config
static pio_sm_config pio_get_default_sm_config(void)
Get the default state machine configuration.
Definition: pio.h:385
tight_loop_contents
static __always_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition: platform.h:358
hw_xor_bits
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
pio_add_program
uint pio_add_program(PIO pio, const pio_program_t *program)
Attempt to load the program, panicking if not possible.
Definition: pio.c:117
pio_program
Definition: pio.h:457
pio_sm_unclaim
void pio_sm_unclaim(PIO pio, uint sm)
Mark a state machine as no longer used.
Definition: pio.c:39
sm_config_set_in_pins
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
pico.h
pio_sm_set_set_pins
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
pio_sm_exec_wait_blocking
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
pio1
#define pio1
Definition: pio.h:85
pio_sm_get_tx_fifo_level
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
pio_sm_clear_fifos
static void pio_sm_clear_fifos(PIO pio, uint sm)
Clear a state machine's TX and RX FIFOs.
Definition: pio.h:1187
gpio.h
pio_sm_get_pc
static uint8_t pio_sm_get_pc(PIO pio, uint sm)
Return the current program counter for a state machine.
Definition: pio.h:832
sm_config_set_out_special
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
pio_sm_is_tx_fifo_empty
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
pio_sm_is_exec_stalled
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
pio_can_add_program_at_offset
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
pio_set_irqn_source_mask_enabled
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
sm_config_set_jmp_pin
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
pio_sm_set_config
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_sm_set_pins
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
sm_config_set_fifo_join
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
pio_interrupt_source
pio_interrupt_source
PIO interrupt source numbers for pio related IRQs.
Definition: pio.h:685
pio_sm_clkdiv_restart
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
pio_set_irq1_source_enabled
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
pio_set_irqn_source_enabled
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
pio_hw_t
Definition: pio.h:79
pio_enable_sm_mask_in_sync
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
pio_sm_drain_tx_fifo
void pio_sm_drain_tx_fifo(PIO pio, uint sm)
Empty out a state machine's TX FIFO.
Definition: pio.c:262
pio_gpio_init
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
pio_sm_set_wrap
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
pio_fifo_join
pio_fifo_join
FIFO join states.
Definition: pio.h:55
pio_sm_set_pins_with_mask
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
pio_set_irq1_source_mask_enabled
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
pio_claim_sm_mask
void pio_claim_sm_mask(PIO pio, uint sm_mask)
Mark multiple state machines as used.
Definition: pio.c:33
pio_claim_unused_sm
int pio_claim_unused_sm(PIO pio, bool required)
Claim a free state machine on a PIO instance.
Definition: pio.c:45
pio_sm_get_rx_fifo_level
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