@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_HARDWARE_PIO, Enable/disable assertions in the hardware_pio module, type=bool, default=0, group=hardware_pio
18#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_PIO
19#ifdef PARAM_ASSERTIONS_ENABLED_PIO // backwards compatibility with SDK < 2.0.0
20#define PARAM_ASSERTIONS_ENABLED_HARDWARE_PIO PARAM_ASSERTIONS_ENABLED_PIO
21#else
22#define PARAM_ASSERTIONS_ENABLED_HARDWARE_PIO 0
23#endif
24#endif
25
26// PICO_CONFIG: PICO_PIO_VERSION, PIO hardware version, type=int, default=0 on RP2040 and 1 on RP2350, group=hardware_pio
27#ifndef PICO_PIO_VERSION
28#if PIO_GPIOBASE_BITS
29#define PICO_PIO_VERSION 1
30#else
31#define PICO_PIO_VERSION 0
32#endif
33#endif
34
35// PICO_CONFIG: PICO_PIO_CLKDIV_ROUND_NEAREST, True if floating point PIO clock divisors should be rounded to the nearest possible clock divisor rather than rounding down, type=bool, default=PICO_CLKDIV_ROUND_NEAREST, group=hardware_pio
36#ifndef PICO_PIO_CLKDIV_ROUND_NEAREST
37#define PICO_PIO_CLKDIV_ROUND_NEAREST PICO_CLKDIV_ROUND_NEAREST
38#endif
39
98
99#ifdef __cplusplus
100extern "C" {
101#endif
102
103static_assert(PIO_SM0_SHIFTCTRL_FJOIN_RX_LSB == PIO_SM0_SHIFTCTRL_FJOIN_TX_LSB + 1, "");
104
112#if PICO_PIO_VERSION > 0
113 PIO_FIFO_JOIN_TXGET = 4,
114 PIO_FIFO_JOIN_TXPUT = 8,
115 PIO_FIFO_JOIN_PUTGET = 12,
116#endif
117};
118
123 STATUS_TX_LESSTHAN = 0,
124 STATUS_RX_LESSTHAN = 1,
125#if PICO_PIO_VERSION > 0
126 STATUS_IRQ_SET = 2
127#endif
128};
129
130typedef pio_hw_t *PIO;
131
138#define pio0 pio0_hw
139
146#define pio1 pio1_hw
147
148#if NUM_PIOS > 2
155#define pio2 pio2_hw
156#endif
157
158#if PICO_PIO_VERSION > 0
159#ifndef PICO_PIO_USE_GPIO_BASE
160// PICO_CONFIG: PICO_PIO_USE_GPIO_BASE, Enable code for handling more than 32 PIO pins, type=bool, default=true when supported and when the device has more than 32 pins, group=hardware_pio
161#define PICO_PIO_USE_GPIO_BASE ((NUM_BANK0_GPIOS) > 32)
162#endif
163#endif
164
173#ifndef PIO_NUM
174static_assert(PIO1_BASE - PIO0_BASE == (1u << 20), "hardware layout mismatch");
175#if NUM_PIOS > 2
176static_assert(PIO2_BASE - PIO0_BASE == (2u << 20), "hardware layout mismatch");
177#endif
178#define PIO_NUM(pio) (((uintptr_t)(pio) - PIO0_BASE) >> 20)
179#endif
180
189#ifndef PIO_INSTANCE
190static_assert(PIO1_BASE - PIO0_BASE == (1u << 20), "hardware layout mismatch");
191#if NUM_PIOS > 2
192static_assert(PIO2_BASE - PIO0_BASE == (2u << 20), "hardware layout mismatch");
193#endif
194#define PIO_INSTANCE(instance) ((pio_hw_t *)(PIO0_BASE + (instance) * (1u << 20)))
195#endif
196
205#ifndef PIO_FUNCSEL_NUM
206#define PIO_FUNCSEL_NUM(pio, gpio) ((gpio_function_t) (GPIO_FUNC_PIO0 + PIO_NUM(pio)))
207#endif
208
218#ifndef PIO_DREQ_NUM
219static_assert(DREQ_PIO0_TX1 == DREQ_PIO0_TX0 + 1, "");
220static_assert(DREQ_PIO0_TX2 == DREQ_PIO0_TX0 + 2, "");
221static_assert(DREQ_PIO0_TX3 == DREQ_PIO0_TX0 + 3, "");
222static_assert(DREQ_PIO0_RX0 == DREQ_PIO0_TX0 + NUM_PIO_STATE_MACHINES, "");
223static_assert(DREQ_PIO1_TX0 == DREQ_PIO0_RX0 + NUM_PIO_STATE_MACHINES, "");
224static_assert(DREQ_PIO1_RX0 == DREQ_PIO1_TX0 + NUM_PIO_STATE_MACHINES, "");
225#if NUM_PIOS > 2
226static_assert(DREQ_PIO2_TX0 == DREQ_PIO1_RX0 + NUM_PIO_STATE_MACHINES, "");
227static_assert(DREQ_PIO2_RX0 == DREQ_PIO2_TX0 + NUM_PIO_STATE_MACHINES, "");
228#endif
229#define PIO_DREQ_NUM(pio, sm, is_tx) (DREQ_PIO0_TX0 + (sm) + (((is_tx) ? 0 : NUM_PIO_STATE_MACHINES) + PIO_NUM(pio) * (DREQ_PIO1_TX0 - DREQ_PIO0_TX0)))
230#endif
231
240#ifndef PIO_IRQ_NUM
241#define PIO_IRQ_NUM(pio, irqn) (PIO0_IRQ_0 + NUM_PIO_IRQS * PIO_NUM(pio) + (irqn))
242#endif
243
283
290typedef struct {
291 uint32_t clkdiv;
292 uint32_t execctrl;
293 uint32_t shiftctrl;
294 uint32_t pinctrl;
295#if PICO_PIO_USE_GPIO_BASE
296#define PINHI_ALL_PINCTRL_LSBS ((1u << PIO_SM0_PINCTRL_IN_BASE_LSB) | (1u << PIO_SM0_PINCTRL_OUT_BASE_LSB) | \
297 (1u << PIO_SM0_PINCTRL_SET_BASE_LSB) | (1u << PIO_SM0_PINCTRL_SIDESET_BASE_LSB))
298// note we put the out_special pin starting at bit 20
299#define PINHI_EXECCTRL_LSB 20
300static_assert( (1u << PINHI_EXECCTRL_LSB) > (PINHI_ALL_PINCTRL_LSBS * 0x1f), "");
301#define PINHI_ALL_PIN_LSBS ((1u << PINHI_EXECCTRL_LSB) |(1u << PIO_SM0_PINCTRL_IN_BASE_LSB) | (1u << PIO_SM0_PINCTRL_OUT_BASE_LSB) | \
302 (1u << PIO_SM0_PINCTRL_SET_BASE_LSB) | (1u << PIO_SM0_PINCTRL_SIDESET_BASE_LSB))
303 // each 5-bit field which would usually be used for the pin_base in pin_ctrl, is used for:
304 // 0b11111 - corresponding field not specified
305 // 0b00000 - pin is in range 0-15
306 // 0b00001 - pin is in range 16-31
307 // 0b00010 - pin is in range 32-47
308 uint32_t pinhi;
309#endif
311
312static inline void check_sm_param(__unused uint sm) {
313 valid_params_if(HARDWARE_PIO, sm < NUM_PIO_STATE_MACHINES);
314}
315
316static inline void check_sm_mask(__unused uint mask) {
317 valid_params_if(HARDWARE_PIO, mask < (1u << NUM_PIO_STATE_MACHINES));
318}
319
320static inline void check_pio_param(__unused PIO pio) {
321#if NUM_PIOS == 2
322 valid_params_if(HARDWARE_PIO, pio == pio0 || pio == pio1);
323#elif NUM_PIOS == 3
324 valid_params_if(HARDWARE_PIO, pio == pio0 || pio == pio1 || pio == pio2);
325#endif
326}
327
328static inline void check_pio_pin_param(__unused uint pin) {
329#if !PICO_PIO_USE_GPIO_BASE
330 invalid_params_if(HARDWARE_PIO, pin >= 32);
331#else
332 // pin base allows us to move up 16 pins at a time
333 invalid_params_if(HARDWARE_PIO, pin >= ((NUM_BANK0_GPIOS + 15u)&~15u));
334#endif
335}
336
345static inline void sm_config_set_out_pin_base(pio_sm_config *c, uint out_base) {
346 check_pio_pin_param(out_base);
347 c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_OUT_BASE_BITS) |
348 ((out_base & 31) << PIO_SM0_PINCTRL_OUT_BASE_LSB);
349#if PICO_PIO_USE_GPIO_BASE
350 c->pinhi = (c->pinhi & ~(31u << PIO_SM0_PINCTRL_OUT_BASE_LSB)) |
351 ((out_base >> 4) << PIO_SM0_PINCTRL_OUT_BASE_LSB);
352#endif
353}
354
363static inline void sm_config_set_out_pin_count(pio_sm_config *c, uint out_count) {
364 valid_params_if(HARDWARE_PIO, out_count <= 32);
365 c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_OUT_COUNT_BITS) |
366 (out_count << PIO_SM0_PINCTRL_OUT_COUNT_LSB);
367}
368
378static inline void sm_config_set_out_pins(pio_sm_config *c, uint out_base, uint out_count) {
379 sm_config_set_out_pin_base(c, out_base);
380 sm_config_set_out_pin_count(c, out_count);
381}
382
391static inline void sm_config_set_set_pin_base(pio_sm_config *c, uint set_base) {
392 check_pio_pin_param(set_base);
393 c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_SET_BASE_BITS) |
394 ((set_base & 31) << PIO_SM0_PINCTRL_SET_BASE_LSB);
395#if PICO_PIO_USE_GPIO_BASE
396 c->pinhi = (c->pinhi & ~(31u << PIO_SM0_PINCTRL_SET_BASE_LSB)) |
397 ((set_base >> 4) << PIO_SM0_PINCTRL_SET_BASE_LSB);
398#endif
399}
400
409static inline void sm_config_set_set_pin_count(pio_sm_config *c, uint set_count) {
410 valid_params_if(HARDWARE_PIO, set_count <= 5);
411 c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_SET_COUNT_BITS) |
412 (set_count << PIO_SM0_PINCTRL_SET_COUNT_LSB);
413}
414
424static inline void sm_config_set_set_pins(pio_sm_config *c, uint set_base, uint set_count) {
425 sm_config_set_set_pin_base(c, set_base);
426 sm_config_set_set_pin_count(c, set_count);
427}
428
437static inline void sm_config_set_in_pin_base(pio_sm_config *c, uint in_base) {
438 check_pio_pin_param(in_base);
439 c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_IN_BASE_BITS) |
440 ((in_base & 31) << PIO_SM0_PINCTRL_IN_BASE_LSB);
441#if PICO_PIO_USE_GPIO_BASE
442 c->pinhi = (c->pinhi & ~(31u << PIO_SM0_PINCTRL_IN_BASE_LSB)) |
443 ((in_base >> 4) << PIO_SM0_PINCTRL_IN_BASE_LSB);
444#endif
445}
446
455static inline void sm_config_set_in_pins(pio_sm_config *c, uint in_base) {
456 sm_config_set_in_pin_base(c, in_base);
457}
458
472static inline void sm_config_set_in_pin_count(pio_sm_config *c, uint in_count) {
473#if PICO_PIO_VERSION == 0
474 // can't be changed from 32 on PIO v0
475 ((void)c);
476 valid_params_if(HARDWARE_PIO, in_count == 32);
477#else
478 valid_params_if(HARDWARE_PIO, in_count && in_count <= 32);
479 c->shiftctrl = (c->shiftctrl & ~PIO_SM0_SHIFTCTRL_IN_COUNT_BITS) |
480 ((in_count & 0x1fu) << PIO_SM0_SHIFTCTRL_IN_COUNT_LSB);
481#endif
482}
483
492static inline void sm_config_set_sideset_pin_base(pio_sm_config *c, uint sideset_base) {
493 check_pio_pin_param(sideset_base);
494 c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_SIDESET_BASE_BITS) |
495 ((sideset_base & 31) << PIO_SM0_PINCTRL_SIDESET_BASE_LSB);
496#if PICO_PIO_USE_GPIO_BASE
497 c->pinhi = (c->pinhi & ~(31u << PIO_SM0_PINCTRL_SIDESET_BASE_LSB)) |
498 ((sideset_base >> 4) << PIO_SM0_PINCTRL_SIDESET_BASE_LSB);
499#endif
500}
501
513static inline void sm_config_set_sideset_pins(pio_sm_config *c, uint sideset_base) {
514 sm_config_set_sideset_pin_base(c, sideset_base);
515}
516
525static inline void sm_config_set_sideset(pio_sm_config *c, uint bit_count, bool optional, bool pindirs) {
526 valid_params_if(HARDWARE_PIO, bit_count <= 5);
527 valid_params_if(HARDWARE_PIO, !optional || bit_count >= 1);
528 c->pinctrl = (c->pinctrl & ~PIO_SM0_PINCTRL_SIDESET_COUNT_BITS) |
529 (bit_count << PIO_SM0_PINCTRL_SIDESET_COUNT_LSB);
530 c->execctrl = (c->execctrl & ~(PIO_SM0_EXECCTRL_SIDE_EN_BITS | PIO_SM0_EXECCTRL_SIDE_PINDIR_BITS)) |
531 (bool_to_bit(optional) << PIO_SM0_EXECCTRL_SIDE_EN_LSB) |
532 (bool_to_bit(pindirs) << PIO_SM0_EXECCTRL_SIDE_PINDIR_LSB);
533}
534
548static inline void sm_config_set_clkdiv_int_frac8(pio_sm_config *c, uint32_t div_int, uint8_t div_frac8) {
549 static_assert(REG_FIELD_WIDTH(PIO_SM0_CLKDIV_INT) == 16, "");
550 invalid_params_if(HARDWARE_PIO, div_int >> 16);
551 invalid_params_if(HARDWARE_PIO, div_int == 0 && div_frac8 != 0);
552 static_assert(REG_FIELD_WIDTH(PIO_SM0_CLKDIV_FRAC) == 8, "");
553 c->clkdiv =
554 (((uint)div_frac8) << PIO_SM0_CLKDIV_FRAC_LSB) |
555 (((uint)div_int) << PIO_SM0_CLKDIV_INT_LSB);
556}
557
558// backwards compatibility
559static inline void sm_config_set_clkdiv_int_frac(pio_sm_config *c, uint16_t div_int, uint8_t div_frac8) {
560 sm_config_set_clkdiv_int_frac8(c, div_int, div_frac8);
561}
562
563static inline void pio_calculate_clkdiv8_from_float(float div, uint32_t *div_int, uint8_t *div_frac8) {
564 valid_params_if(HARDWARE_PIO, div >= 1 && div <= 65536);
565 const int frac_bit_count = REG_FIELD_WIDTH(PIO_SM0_CLKDIV_FRAC);
566#if PICO_PIO_CLKDIV_ROUND_NEAREST
567 div += 0.5f / (1 << frac_bit_count); // round to the nearest 1/256
568#endif
569 *div_int = (uint16_t)div;
570 // not a strictly necessary check, but if this changes, then this method should
571 // probably no longer be used in favor of one with a larger fraction
572 static_assert(REG_FIELD_WIDTH(PIO_SM0_CLKDIV_FRAC) == 8, "");
573 if (*div_int == 0) {
574 *div_frac8 = 0;
575 } else {
576 *div_frac8 = (uint8_t)((div - (float)*div_int) * (1u << frac_bit_count));
577 }
578}
579
580// backwards compatibility
581static inline void pio_calculate_clkdiv_from_float(float div, uint16_t *div_int16, uint8_t *div_frac8) {
582 uint32_t div_int;
583 pio_calculate_clkdiv8_from_float(div, &div_int, div_frac8);
584 *div_int16 = (uint16_t) div_int;
585}
586
602static inline void sm_config_set_clkdiv(pio_sm_config *c, float div) {
603 uint32_t div_int;
604 uint8_t div_frac8;
605 pio_calculate_clkdiv8_from_float(div, &div_int, &div_frac8);
606 sm_config_set_clkdiv_int_frac8(c, div_int, div_frac8);
607}
608
617static inline void sm_config_set_wrap(pio_sm_config *c, uint wrap_target, uint wrap) {
618 valid_params_if(HARDWARE_PIO, wrap < PIO_INSTRUCTION_COUNT);
619 valid_params_if(HARDWARE_PIO, wrap_target < PIO_INSTRUCTION_COUNT);
620 c->execctrl = (c->execctrl & ~(PIO_SM0_EXECCTRL_WRAP_TOP_BITS | PIO_SM0_EXECCTRL_WRAP_BOTTOM_BITS)) |
621 (wrap_target << PIO_SM0_EXECCTRL_WRAP_BOTTOM_LSB) |
622 (wrap << PIO_SM0_EXECCTRL_WRAP_TOP_LSB);
623}
624
631static inline void sm_config_set_jmp_pin(pio_sm_config *c, uint pin) {
632 check_pio_pin_param(pin);
633 c->execctrl = (c->execctrl & ~PIO_SM0_EXECCTRL_JMP_PIN_BITS) |
634 ((pin & 31) << PIO_SM0_EXECCTRL_JMP_PIN_LSB);
635#if PICO_PIO_USE_GPIO_BASE
636 c->pinhi = (c->pinhi & ~(31u << 20)) |
637 ((pin >> 4) << 20);
638#endif
639}
640
649static inline void sm_config_set_in_shift(pio_sm_config *c, bool shift_right, bool autopush, uint push_threshold) {
650 valid_params_if(HARDWARE_PIO, push_threshold <= 32);
651 c->shiftctrl = (c->shiftctrl &
652 ~(PIO_SM0_SHIFTCTRL_IN_SHIFTDIR_BITS |
653 PIO_SM0_SHIFTCTRL_AUTOPUSH_BITS |
654 PIO_SM0_SHIFTCTRL_PUSH_THRESH_BITS)) |
655 (bool_to_bit(shift_right) << PIO_SM0_SHIFTCTRL_IN_SHIFTDIR_LSB) |
656 (bool_to_bit(autopush) << PIO_SM0_SHIFTCTRL_AUTOPUSH_LSB) |
657 ((push_threshold & 0x1fu) << PIO_SM0_SHIFTCTRL_PUSH_THRESH_LSB);
658}
659
668static inline void sm_config_set_out_shift(pio_sm_config *c, bool shift_right, bool autopull, uint pull_threshold) {
669 valid_params_if(HARDWARE_PIO, pull_threshold <= 32);
670 c->shiftctrl = (c->shiftctrl &
671 ~(PIO_SM0_SHIFTCTRL_OUT_SHIFTDIR_BITS |
672 PIO_SM0_SHIFTCTRL_AUTOPULL_BITS |
673 PIO_SM0_SHIFTCTRL_PULL_THRESH_BITS)) |
674 (bool_to_bit(shift_right) << PIO_SM0_SHIFTCTRL_OUT_SHIFTDIR_LSB) |
675 (bool_to_bit(autopull) << PIO_SM0_SHIFTCTRL_AUTOPULL_LSB) |
676 ((pull_threshold & 0x1fu) << PIO_SM0_SHIFTCTRL_PULL_THRESH_LSB);
677}
678
685static inline void sm_config_set_fifo_join(pio_sm_config *c, enum pio_fifo_join join) {
686 valid_params_if(HARDWARE_PIO, join == PIO_FIFO_JOIN_NONE || join == PIO_FIFO_JOIN_TX || join == PIO_FIFO_JOIN_RX
687#if PICO_PIO_VERSION > 0
688 || join == PIO_FIFO_JOIN_TXPUT || join == PIO_FIFO_JOIN_TXGET || join == PIO_FIFO_JOIN_PUTGET
689#endif
690 );
691#if PICO_PIO_VERSION == 0
692 c->shiftctrl = (c->shiftctrl & (uint)~(PIO_SM0_SHIFTCTRL_FJOIN_TX_BITS | PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS)) |
693 (((uint)join) << PIO_SM0_SHIFTCTRL_FJOIN_TX_LSB);
694#else
695 c->shiftctrl = (c->shiftctrl & (uint)~(PIO_SM0_SHIFTCTRL_FJOIN_TX_BITS | PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS |
696 PIO_SM0_SHIFTCTRL_FJOIN_RX_PUT_BITS | PIO_SM0_SHIFTCTRL_FJOIN_RX_GET_BITS)) |
697 (((uint)(join & 3)) << PIO_SM0_SHIFTCTRL_FJOIN_TX_LSB) |
698 (((uint)(join >> 2)) << PIO_SM0_SHIFTCTRL_FJOIN_RX_GET_LSB);
699#endif
700}
701
710static inline void sm_config_set_out_special(pio_sm_config *c, bool sticky, bool has_enable_pin, uint enable_bit_index) {
711 c->execctrl = (c->execctrl &
712 (uint)~(PIO_SM0_EXECCTRL_OUT_STICKY_BITS | PIO_SM0_EXECCTRL_INLINE_OUT_EN_BITS |
713 PIO_SM0_EXECCTRL_OUT_EN_SEL_BITS)) |
714 (bool_to_bit(sticky) << PIO_SM0_EXECCTRL_OUT_STICKY_LSB) |
715 (bool_to_bit(has_enable_pin) << PIO_SM0_EXECCTRL_INLINE_OUT_EN_LSB) |
716 ((enable_bit_index << PIO_SM0_EXECCTRL_OUT_EN_SEL_LSB) & PIO_SM0_EXECCTRL_OUT_EN_SEL_BITS);
717}
718
726static inline void sm_config_set_mov_status(pio_sm_config *c, enum pio_mov_status_type status_sel, uint status_n) {
727 valid_params_if(HARDWARE_PIO,
728 status_sel == STATUS_TX_LESSTHAN || status_sel == STATUS_RX_LESSTHAN
729#if PICO_PIO_VERSION > 0
730 || status_sel == STATUS_IRQ_SET
731#endif
732 );
733 c->execctrl = (c->execctrl
734 & ~(PIO_SM0_EXECCTRL_STATUS_SEL_BITS | PIO_SM0_EXECCTRL_STATUS_N_BITS))
735 | ((((uint)status_sel) << PIO_SM0_EXECCTRL_STATUS_SEL_LSB) & PIO_SM0_EXECCTRL_STATUS_SEL_BITS)
736 | ((status_n << PIO_SM0_EXECCTRL_STATUS_N_LSB) & PIO_SM0_EXECCTRL_STATUS_N_BITS);
737}
738
759 pio_sm_config c = {};
760#if PICO_PIO_USE_GPIO_BASE
761 c.pinhi = -1;
762#endif
764 sm_config_set_wrap(&c, 0, 31);
765 sm_config_set_in_shift(&c, true, false, 32);
766 sm_config_set_out_shift(&c, true, false, 32);
767 return c;
768}
769
780static inline uint pio_get_gpio_base(PIO pio) {
781#if PICO_PIO_VERSION > 0
782 return pio->gpiobase;
783#else
784 ((void)pio);
785 return 0;
786#endif
787}
788
789static inline void check_pio_pin_mask64(__unused PIO pio, __unused uint sm, __unused uint64_t pinmask) {
790 // check no pins are set in the mask which are incompatible with the pio
791#if PICO_PIO_USE_GPIO_BASE
792 valid_params_if(HARDWARE_PIO, (pinmask & ~(0xffffffffull << pio_get_gpio_base(pio))) == 0);
793#else
794 valid_params_if(HARDWARE_PIO, (pinmask & ~0xffffffffull) == 0);
795#endif
796}
797
809static inline int pio_sm_set_config(PIO pio, uint sm, const pio_sm_config *config) {
810 check_pio_param(pio);
811 check_sm_param(sm);
812 pio->sm[sm].clkdiv = config->clkdiv;
813 pio->sm[sm].shiftctrl = config->shiftctrl;
814#if PICO_PIO_USE_GPIO_BASE
815 uint used = (~config->pinhi >> 4) & PINHI_ALL_PIN_LSBS;
816 // configs that use pins 0-15
817 uint gpio_under_16 = (~config->pinhi) & (~config->pinhi >> 1) & used;
818 // configs that use pins 32-47
819 uint gpio_over_32 = (config->pinhi >> 1) & used;
820 uint gpio_base = pio_get_gpio_base(pio);
821 invalid_params_if_and_return(PIO, gpio_under_16 && gpio_base, PICO_ERROR_BAD_ALIGNMENT);
822 invalid_params_if_and_return(PIO, gpio_over_32 && !gpio_base, PICO_ERROR_BAD_ALIGNMENT);
823 // flip the top bit of any used (execctrl/pinctrl) values to turn:
824 // bit6(32) + 0-15 -> base(16) + 16-31
825 // bit6(0) + 16-31 -> base(16) + 0-15
826 static_assert(PINHI_EXECCTRL_LSB == 20, ""); // we use shifts to mask off bits below
827 pio->sm[sm].execctrl = config->execctrl ^ (gpio_base ? ((used >> 20) << (PIO_SM0_EXECCTRL_JMP_PIN_LSB + 4)) : 0);
828 pio->sm[sm].pinctrl = config->pinctrl ^ (gpio_base ? ((used << 12) >> 8) : 0);
829#else
830 pio->sm[sm].execctrl = config->execctrl;
831 pio->sm[sm].pinctrl = config->pinctrl;
832#endif
833 return PICO_OK;
834}
835
842static inline uint pio_get_index(PIO pio) {
843 check_pio_param(pio);
844 return PIO_NUM(pio);
845}
846
854static inline uint pio_get_funcsel(PIO pio) {
855 check_pio_param(pio);
856 return PIO_FUNCSEL_NUM(pio, 0); // note GPIO currently unused, so won't bother updating API
857}
858
865static inline PIO pio_get_instance(uint instance) {
866 invalid_params_if(HARDWARE_PIO, instance >= NUM_PIOS);
867 return PIO_INSTANCE(instance);
868}
869
898static inline void pio_gpio_init(PIO pio, uint pin) {
899 check_pio_param(pio);
900 valid_params_if(HARDWARE_PIO, pin < NUM_BANK0_GPIOS);
901 gpio_set_function(pin, PIO_FUNCSEL_NUM(pio, pin));
902}
903
911static inline uint pio_get_dreq(PIO pio, uint sm, bool is_tx) {
912 check_pio_param(pio);
913 check_sm_param(sm);
914 return PIO_DREQ_NUM(pio, sm, is_tx);
915}
916
917typedef struct pio_program {
918 const uint16_t *instructions;
919 uint8_t length;
920 int8_t origin; // required instruction memory origin or -1
921 uint8_t pio_version;
922#if PICO_PIO_VERSION > 0
923 uint8_t used_gpio_ranges; // bitmap with one bit per 16 pins
924#endif
925} pio_program_t;
926
941int pio_set_gpio_base(PIO pio, uint gpio_base);
942
951bool pio_can_add_program(PIO pio, const pio_program_t *program);
952
962bool pio_can_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset);
963
974int pio_add_program(PIO pio, const pio_program_t *program);
975
987int pio_add_program_at_offset(PIO pio, const pio_program_t *program, uint offset);
988
996void pio_remove_program(PIO pio, const pio_program_t *program, uint loaded_offset);
997
1003void pio_clear_instruction_memory(PIO pio);
1004
1027int pio_sm_init(PIO pio, uint sm, uint initial_pc, const pio_sm_config *config);
1028
1036static inline void pio_sm_set_enabled(PIO pio, uint sm, bool enabled) {
1037 check_pio_param(pio);
1038 check_sm_param(sm);
1039 pio->ctrl = (pio->ctrl & ~(1u << sm)) | (bool_to_bit(enabled) << sm);
1040}
1041
1055static inline void pio_set_sm_mask_enabled(PIO pio, uint32_t mask, bool enabled) {
1056 check_pio_param(pio);
1057 check_sm_mask(mask);
1058 pio->ctrl = (pio->ctrl & ~mask) | (enabled ? mask : 0u);
1059}
1060
1061#if PICO_PIO_VERSION > 0
1077static inline void pio_set_sm_multi_mask_enabled(PIO pio, uint32_t mask_prev, uint32_t mask, uint32_t mask_next, bool enabled) {
1078 check_pio_param(pio);
1079 check_sm_mask(mask);
1080 pio->ctrl = (pio->ctrl & ~(mask << PIO_CTRL_SM_ENABLE_LSB)) |
1081 (enabled ? ((mask << PIO_CTRL_SM_ENABLE_LSB) & PIO_CTRL_SM_ENABLE_BITS) : 0) |
1082 (enabled ? PIO_CTRL_NEXTPREV_SM_ENABLE_BITS : PIO_CTRL_NEXTPREV_SM_DISABLE_BITS) |
1083 ((mask_prev << PIO_CTRL_PREV_PIO_MASK_LSB) & PIO_CTRL_PREV_PIO_MASK_BITS) |
1084 ((mask_next << PIO_CTRL_NEXT_PIO_MASK_LSB) & PIO_CTRL_NEXT_PIO_MASK_BITS);
1085
1086}
1087#endif
1088
1098static inline void pio_sm_restart(PIO pio, uint sm) {
1099 check_pio_param(pio);
1100 check_sm_param(sm);
1101 hw_set_bits(&pio->ctrl, 1u << (PIO_CTRL_SM_RESTART_LSB + sm));
1102}
1103
1113static inline void pio_restart_sm_mask(PIO pio, uint32_t mask) {
1114 check_pio_param(pio);
1115 check_sm_mask(mask);
1116 hw_set_bits(&pio->ctrl, (mask << PIO_CTRL_SM_RESTART_LSB) & PIO_CTRL_SM_RESTART_BITS);
1117}
1118
1140static inline void pio_sm_clkdiv_restart(PIO pio, uint sm) {
1141 check_pio_param(pio);
1142 check_sm_param(sm);
1143 hw_set_bits(&pio->ctrl, 1u << (PIO_CTRL_CLKDIV_RESTART_LSB + sm));
1144}
1145
1175static inline void pio_clkdiv_restart_sm_mask(PIO pio, uint32_t mask) {
1176 check_pio_param(pio);
1177 check_sm_mask(mask);
1178 hw_set_bits(&pio->ctrl, (mask << PIO_CTRL_CLKDIV_RESTART_LSB) & PIO_CTRL_CLKDIV_RESTART_BITS);
1179}
1180
1181#if PICO_PIO_VERSION > 0
1213static inline void pio_clkdiv_restart_sm_multi_mask(PIO pio, uint32_t mask_prev, uint32_t mask, uint32_t mask_next) {
1214 check_pio_param(pio);
1215 check_sm_mask(mask);
1216 hw_set_bits(&pio->ctrl, ((mask << PIO_CTRL_CLKDIV_RESTART_LSB) & PIO_CTRL_CLKDIV_RESTART_BITS) |
1217 PIO_CTRL_NEXTPREV_CLKDIV_RESTART_BITS |
1218 ((mask_prev << PIO_CTRL_PREV_PIO_MASK_LSB) & PIO_CTRL_PREV_PIO_MASK_BITS) |
1219 ((mask_next << PIO_CTRL_NEXT_PIO_MASK_LSB) & PIO_CTRL_NEXT_PIO_MASK_BITS));
1220}
1221#endif
1222
1234static inline void pio_enable_sm_mask_in_sync(PIO pio, uint32_t mask) {
1235 check_pio_param(pio);
1236 check_sm_mask(mask);
1237 hw_set_bits(&pio->ctrl,
1238 ((mask << PIO_CTRL_CLKDIV_RESTART_LSB) & PIO_CTRL_CLKDIV_RESTART_BITS) |
1239 ((mask << PIO_CTRL_SM_ENABLE_LSB) & PIO_CTRL_SM_ENABLE_BITS));
1240}
1241
1242#if PICO_PIO_VERSION > 0
1256static inline void pio_enable_sm_multi_mask_in_sync(PIO pio, uint32_t mask_prev, uint32_t mask, uint32_t mask_next) {
1257 check_pio_param(pio);
1258 check_sm_mask(mask);
1259 check_pio_param(pio);
1260 check_sm_mask(mask);
1261 hw_set_bits(&pio->ctrl, ((mask << PIO_CTRL_CLKDIV_RESTART_LSB) & PIO_CTRL_CLKDIV_RESTART_BITS) |
1262 ((mask << PIO_CTRL_SM_ENABLE_LSB) & PIO_CTRL_SM_ENABLE_BITS) |
1263 PIO_CTRL_NEXTPREV_CLKDIV_RESTART_BITS | PIO_CTRL_NEXTPREV_SM_ENABLE_BITS |
1264 ((mask_prev << PIO_CTRL_PREV_PIO_MASK_LSB) & PIO_CTRL_PREV_PIO_MASK_BITS) |
1265 ((mask_next << PIO_CTRL_NEXT_PIO_MASK_LSB) & PIO_CTRL_NEXT_PIO_MASK_BITS));
1266}
1267#endif
1268
1273 pis_interrupt0 = PIO_INTR_SM0_LSB,
1274 pis_interrupt1 = PIO_INTR_SM1_LSB,
1275 pis_interrupt2 = PIO_INTR_SM2_LSB,
1276 pis_interrupt3 = PIO_INTR_SM3_LSB,
1277#if PICO_PIO_VERSION > 0
1278 pis_interrupt4 = PIO_INTR_SM4_LSB,
1279 pis_interrupt5 = PIO_INTR_SM5_LSB,
1280 pis_interrupt6 = PIO_INTR_SM6_LSB,
1281 pis_interrupt7 = PIO_INTR_SM7_LSB,
1282#endif
1283 pis_sm0_tx_fifo_not_full = PIO_INTR_SM0_TXNFULL_LSB,
1284 pis_sm1_tx_fifo_not_full = PIO_INTR_SM1_TXNFULL_LSB,
1285 pis_sm2_tx_fifo_not_full = PIO_INTR_SM2_TXNFULL_LSB,
1286 pis_sm3_tx_fifo_not_full = PIO_INTR_SM3_TXNFULL_LSB,
1287 pis_sm0_rx_fifo_not_empty = PIO_INTR_SM0_RXNEMPTY_LSB,
1288 pis_sm1_rx_fifo_not_empty = PIO_INTR_SM1_RXNEMPTY_LSB,
1289 pis_sm2_rx_fifo_not_empty = PIO_INTR_SM2_RXNEMPTY_LSB,
1290 pis_sm3_rx_fifo_not_empty = PIO_INTR_SM3_RXNEMPTY_LSB,
1292
1300static inline void pio_set_irq0_source_enabled(PIO pio, pio_interrupt_source_t source, bool enabled) {
1301 check_pio_param(pio);
1302 invalid_params_if(HARDWARE_PIO, source >= 32u || (1u << source) > PIO_INTR_BITS);
1303 if (enabled)
1304 hw_set_bits(&pio->inte0, 1u << source);
1305 else
1306 hw_clear_bits(&pio->inte0, 1u << source);
1307}
1308
1316static inline void pio_set_irq1_source_enabled(PIO pio, pio_interrupt_source_t source, bool enabled) {
1317 check_pio_param(pio);
1318 invalid_params_if(HARDWARE_PIO, source >= 32 || (1u << source) > PIO_INTR_BITS);
1319 if (enabled)
1320 hw_set_bits(&pio->inte1, 1u << source);
1321 else
1322 hw_clear_bits(&pio->inte1, 1u << source);
1323}
1324
1332static inline void pio_set_irq0_source_mask_enabled(PIO pio, uint32_t source_mask, bool enabled) {
1333 check_pio_param(pio);
1334 invalid_params_if(HARDWARE_PIO, source_mask > PIO_INTR_BITS);
1335 if (enabled) {
1336 hw_set_bits(&pio->inte0, source_mask);
1337 } else {
1338 hw_clear_bits(&pio->inte0, source_mask);
1339 }
1340}
1341
1349static inline void pio_set_irq1_source_mask_enabled(PIO pio, uint32_t source_mask, bool enabled) {
1350 check_pio_param(pio);
1351 invalid_params_if(HARDWARE_PIO, source_mask > PIO_INTR_BITS);
1352 if (enabled) {
1353 hw_set_bits(&pio->inte1, source_mask);
1354 } else {
1355 hw_clear_bits(&pio->inte1, source_mask);
1356 }
1357}
1358
1367static inline void pio_set_irqn_source_enabled(PIO pio, uint irq_index, pio_interrupt_source_t source, bool enabled) {
1368 invalid_params_if(HARDWARE_PIO, irq_index > NUM_PIO_IRQS);
1369 invalid_params_if(HARDWARE_PIO, source >= 32 || (1u << source) > PIO_INTR_BITS);
1370 if (enabled)
1371 hw_set_bits(&pio->irq_ctrl[irq_index].inte, 1u << source);
1372 else
1373 hw_clear_bits(&pio->irq_ctrl[irq_index].inte, 1u << source);
1374}
1375
1384static inline void pio_set_irqn_source_mask_enabled(PIO pio, uint irq_index, uint32_t source_mask, bool enabled) {
1385 invalid_params_if(HARDWARE_PIO, irq_index > NUM_PIO_IRQS);
1386 static_assert(NUM_PIO_IRQS == 2, "");
1387 invalid_params_if(HARDWARE_PIO, source_mask > PIO_INTR_BITS);
1388 if (enabled) {
1389 hw_set_bits(&pio->irq_ctrl[irq_index].inte, source_mask);
1390 } else {
1391 hw_clear_bits(&pio->irq_ctrl[irq_index].inte, source_mask);
1392 }
1393}
1394
1402static inline bool pio_interrupt_get(PIO pio, uint pio_interrupt_num) {
1403 check_pio_param(pio);
1404 invalid_params_if(HARDWARE_PIO, pio_interrupt_num >= 8);
1405 return pio->irq & (1u << pio_interrupt_num);
1406}
1407
1414static inline void pio_interrupt_clear(PIO pio, uint pio_interrupt_num) {
1415 check_pio_param(pio);
1416 invalid_params_if(HARDWARE_PIO, pio_interrupt_num >= 8);
1417 pio->irq = (1u << pio_interrupt_num);
1418}
1419
1427static inline uint8_t pio_sm_get_pc(PIO pio, uint sm) {
1428 check_pio_param(pio);
1429 check_sm_param(sm);
1430 return (uint8_t) pio->sm[sm].addr;
1431}
1432
1445inline static void pio_sm_exec(PIO pio, uint sm, uint instr) {
1446 check_pio_param(pio);
1447 check_sm_param(sm);
1448 pio->sm[sm].instr = instr;
1449}
1450
1458static inline bool pio_sm_is_exec_stalled(PIO pio, uint sm) {
1459 check_pio_param(pio);
1460 check_sm_param(sm);
1461 return pio->sm[sm].execctrl & PIO_SM0_EXECCTRL_EXEC_STALLED_BITS;
1462}
1463
1476static inline void pio_sm_exec_wait_blocking(PIO pio, uint sm, uint instr) {
1477 check_pio_param(pio);
1478 check_sm_param(sm);
1479 pio_sm_exec(pio, sm, instr);
1481}
1482
1492static inline void pio_sm_set_wrap(PIO pio, uint sm, uint wrap_target, uint wrap) {
1493 check_pio_param(pio);
1494 check_sm_param(sm);
1495 valid_params_if(HARDWARE_PIO, wrap < PIO_INSTRUCTION_COUNT);
1496 valid_params_if(HARDWARE_PIO, wrap_target < PIO_INSTRUCTION_COUNT);
1497 pio->sm[sm].execctrl =
1498 (pio->sm[sm].execctrl & ~(PIO_SM0_EXECCTRL_WRAP_TOP_BITS | PIO_SM0_EXECCTRL_WRAP_BOTTOM_BITS)) |
1499 (wrap_target << PIO_SM0_EXECCTRL_WRAP_BOTTOM_LSB) |
1500 (wrap << PIO_SM0_EXECCTRL_WRAP_TOP_LSB);
1501}
1502
1513static inline void pio_sm_set_out_pins(PIO pio, uint sm, uint out_base, uint out_count) {
1514 check_pio_param(pio);
1515 check_sm_param(sm);
1516#if PICO_PIO_USE_GPIO_BASE
1517 out_base -= pio_get_gpio_base(pio);
1518#endif
1519 valid_params_if(HARDWARE_PIO, out_base < 32);
1520 valid_params_if(HARDWARE_PIO, out_count <= 32);
1521 pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~(PIO_SM0_PINCTRL_OUT_BASE_BITS | PIO_SM0_PINCTRL_OUT_COUNT_BITS)) |
1522 (out_base << PIO_SM0_PINCTRL_OUT_BASE_LSB) |
1523 (out_count << PIO_SM0_PINCTRL_OUT_COUNT_LSB);
1524}
1525
1526
1537static inline void pio_sm_set_set_pins(PIO pio, uint sm, uint set_base, uint set_count) {
1538 check_pio_param(pio);
1539 check_sm_param(sm);
1540#if PICO_PIO_USE_GPIO_BASE
1541 set_base -= pio_get_gpio_base(pio);
1542#endif
1543 valid_params_if(HARDWARE_PIO, set_base < 32);
1544 valid_params_if(HARDWARE_PIO, set_count <= 5);
1545 pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~(PIO_SM0_PINCTRL_SET_BASE_BITS | PIO_SM0_PINCTRL_SET_COUNT_BITS)) |
1546 (set_base << PIO_SM0_PINCTRL_SET_BASE_LSB) |
1547 (set_count << PIO_SM0_PINCTRL_SET_COUNT_LSB);
1548}
1549
1559static inline void pio_sm_set_in_pins(PIO pio, uint sm, uint in_base) {
1560 check_pio_param(pio);
1561 check_sm_param(sm);
1562#if PICO_PIO_USE_GPIO_BASE
1563 in_base -= pio_get_gpio_base(pio);
1564#endif
1565 valid_params_if(HARDWARE_PIO, in_base < 32);
1566 pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~PIO_SM0_PINCTRL_IN_BASE_BITS) |
1567 (in_base << PIO_SM0_PINCTRL_IN_BASE_LSB);
1568}
1569
1579static inline void pio_sm_set_sideset_pins(PIO pio, uint sm, uint sideset_base) {
1580 check_pio_param(pio);
1581 check_sm_param(sm);
1582#if PICO_PIO_USE_GPIO_BASE
1583 sideset_base -= pio_get_gpio_base(pio);
1584#endif
1585 valid_params_if(HARDWARE_PIO, sideset_base < 32);
1586 pio->sm[sm].pinctrl = (pio->sm[sm].pinctrl & ~PIO_SM0_PINCTRL_SIDESET_BASE_BITS) |
1587 (sideset_base << PIO_SM0_PINCTRL_SIDESET_BASE_LSB);
1588}
1589
1597
1598static inline void pio_sm_set_jmp_pin(PIO pio, uint sm, uint pin) {
1599 check_pio_param(pio);
1600 check_sm_param(sm);
1601#if PICO_PIO_USE_GPIO_BASE
1602 pin -= pio_get_gpio_base(pio);
1603#endif
1604 valid_params_if(HARDWARE_PIO, pin < 32);
1605 pio->sm[sm].execctrl =
1606 (pio->sm[sm].execctrl & ~PIO_SM0_EXECCTRL_JMP_PIN_BITS)
1607 | (pin << PIO_SM0_EXECCTRL_JMP_PIN_LSB);
1608}
1609
1624static inline void pio_sm_put(PIO pio, uint sm, uint32_t data) {
1625 check_pio_param(pio);
1626 check_sm_param(sm);
1627 pio->txf[sm] = data;
1628}
1629
1645static inline uint32_t pio_sm_get(PIO pio, uint sm) {
1646 check_pio_param(pio);
1647 check_sm_param(sm);
1648 return pio->rxf[sm];
1649}
1650
1658static inline bool pio_sm_is_rx_fifo_full(PIO pio, uint sm) {
1659 check_pio_param(pio);
1660 check_sm_param(sm);
1661 return (pio->fstat & (1u << (PIO_FSTAT_RXFULL_LSB + sm))) != 0;
1662}
1663
1671static inline bool pio_sm_is_rx_fifo_empty(PIO pio, uint sm) {
1672 check_pio_param(pio);
1673 check_sm_param(sm);
1674 return (pio->fstat & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) != 0;
1675}
1676
1684static inline uint pio_sm_get_rx_fifo_level(PIO pio, uint sm) {
1685 check_pio_param(pio);
1686 check_sm_param(sm);
1687 uint bitoffs = PIO_FLEVEL_RX0_LSB + sm * (PIO_FLEVEL_RX1_LSB - PIO_FLEVEL_RX0_LSB);
1688 const uint32_t mask = PIO_FLEVEL_RX0_BITS >> PIO_FLEVEL_RX0_LSB;
1689 return (pio->flevel >> bitoffs) & mask;
1690}
1691
1699static inline bool pio_sm_is_tx_fifo_full(PIO pio, uint sm) {
1700 check_pio_param(pio);
1701 check_sm_param(sm);
1702 return (pio->fstat & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) != 0;
1703}
1704
1712static inline bool pio_sm_is_tx_fifo_empty(PIO pio, uint sm) {
1713 check_pio_param(pio);
1714 check_sm_param(sm);
1715 return (pio->fstat & (1u << (PIO_FSTAT_TXEMPTY_LSB + sm))) != 0;
1716}
1717
1725static inline uint pio_sm_get_tx_fifo_level(PIO pio, uint sm) {
1726 check_pio_param(pio);
1727 check_sm_param(sm);
1728 unsigned int bitoffs = PIO_FLEVEL_TX0_LSB + sm * (PIO_FLEVEL_TX1_LSB - PIO_FLEVEL_TX0_LSB);
1729 const uint32_t mask = PIO_FLEVEL_TX0_BITS >> PIO_FLEVEL_TX0_LSB;
1730 return (pio->flevel >> bitoffs) & mask;
1731}
1732
1740static inline void pio_sm_put_blocking(PIO pio, uint sm, uint32_t data) {
1741 check_pio_param(pio);
1742 check_sm_param(sm);
1744 pio_sm_put(pio, sm, data);
1745}
1746
1753static inline uint32_t pio_sm_get_blocking(PIO pio, uint sm) {
1754 check_pio_param(pio);
1755 check_sm_param(sm);
1757 return pio_sm_get(pio, sm);
1758}
1759
1773void pio_sm_drain_tx_fifo(PIO pio, uint sm);
1774
1783static inline void pio_sm_set_clkdiv_int_frac8(PIO pio, uint sm, uint32_t div_int, uint8_t div_frac8) {
1784 check_pio_param(pio);
1785 check_sm_param(sm);
1786 static_assert(REG_FIELD_WIDTH(PIO_SM0_CLKDIV_INT) == 16, "");
1787 invalid_params_if(HARDWARE_PIO, div_int >> 16);
1788 invalid_params_if(HARDWARE_PIO, div_int == 0 && div_frac8 != 0);
1789 static_assert(REG_FIELD_WIDTH(PIO_SM0_CLKDIV_FRAC) == 8, "");
1790 pio->sm[sm].clkdiv =
1791 (((uint)div_frac8) << PIO_SM0_CLKDIV_FRAC_LSB) |
1792 (((uint)div_int) << PIO_SM0_CLKDIV_INT_LSB);
1793}
1794
1795// backwards compatibility
1796static inline void pio_sm_set_clkdiv_int_frac(PIO pio, uint sm, uint16_t div_int, uint8_t div_frac8) {
1797 pio_sm_set_clkdiv_int_frac8(pio, sm, div_int, div_frac8);
1798}
1799
1807static inline void pio_sm_set_clkdiv(PIO pio, uint sm, float div) {
1808 check_pio_param(pio);
1809 check_sm_param(sm);
1810 uint32_t div_int;
1811 uint8_t div_frac8;
1812 pio_calculate_clkdiv8_from_float(div, &div_int, &div_frac8);
1813 pio_sm_set_clkdiv_int_frac8(pio, sm, div_int, div_frac8);
1814}
1815
1822static inline void pio_sm_clear_fifos(PIO pio, uint sm) {
1823 // changing the FIFO join state clears the fifo
1824 check_pio_param(pio);
1825 check_sm_param(sm);
1826 hw_xor_bits(&pio->sm[sm].shiftctrl, PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS);
1827 hw_xor_bits(&pio->sm[sm].shiftctrl, PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS);
1828}
1829
1843void pio_sm_set_pins(PIO pio, uint sm, uint32_t pin_values);
1844
1857void pio_sm_set_pins64(PIO pio, uint sm, uint64_t pin_values);
1858
1873void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pin_values, uint32_t pin_mask);
1874
1888void pio_sm_set_pins_with_mask64(PIO pio, uint sm, uint64_t pin_values, uint64_t pin_mask);
1889
1904void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pin_dirs, uint32_t pin_mask);
1905
1919void pio_sm_set_pindirs_with_mask64(PIO pio, uint sm, uint64_t pin_dirs, uint64_t pin_mask);
1920
1936int pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pins_base, uint pin_count, bool is_out);
1937
1948void pio_sm_claim(PIO pio, uint sm);
1949
1960void pio_claim_sm_mask(PIO pio, uint sm_mask);
1961
1970void pio_sm_unclaim(PIO pio, uint sm);
1971
1980int pio_claim_unused_sm(PIO pio, bool required);
1981
1991bool pio_sm_is_claimed(PIO pio, uint sm);
1992
2003bool pio_claim_free_sm_and_add_program(const pio_program_t *program, PIO *pio, uint *sm, uint *offset);
2004
2027bool pio_claim_free_sm_and_add_program_for_gpio_range(const pio_program_t *program, PIO *pio, uint *sm, uint *offset, uint gpio_base, uint gpio_count, bool set_gpio_base);
2028
2038void pio_remove_program_and_unclaim_sm(const pio_program_t *program, PIO pio, uint sm, uint offset);
2039
2047static inline int pio_get_irq_num(PIO pio, uint irqn) {
2048 check_pio_param(pio);
2049 valid_params_if(HARDWARE_PIO, irqn < NUM_PIO_IRQS);
2050 return PIO_IRQ_NUM(pio, irqn);
2051}
2052
2060 check_sm_param(sm);
2062}
2063
2071 check_sm_param(sm);
2073}
2074
2075#ifdef __cplusplus
2076}
2077#endif
2078
2079#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:135
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:155
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:145
@ DREQ_PIO0_TX3
Select PIO0's TX FIFO 3 as DREQ.
Definition dreq.h:70
@ DREQ_PIO1_TX0
Select PIO1's TX FIFO 0 as DREQ.
Definition dreq.h:75
@ DREQ_PIO1_RX0
Select PIO1's RX FIFO 0 as DREQ.
Definition dreq.h:79
@ DREQ_PIO0_TX2
Select PIO0's TX FIFO 2 as DREQ.
Definition dreq.h:69
@ DREQ_PIO0_RX0
Select PIO0's RX FIFO 0 as DREQ.
Definition dreq.h:71
@ DREQ_PIO0_TX1
Select PIO0's TX FIFO 1 as DREQ.
Definition dreq.h:68
@ DREQ_PIO0_TX0
Select PIO0's TX FIFO 0 as DREQ.
Definition dreq.h:67
void gpio_set_function(uint gpio, gpio_function_t fn)
Select GPIO function.
Definition gpio.c:38
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:1725
bool pio_claim_free_sm_and_add_program(const pio_program_t *program, PIO *pio, uint *sm, uint *offset)
Finds a PIO and statemachine and adds a program into PIO memory.
Definition pio.c:404
#define PIO_INSTANCE(instance)
Returns the PIO instance with the given PIO number.
Definition pio.h:194
static void pio_set_irqn_source_enabled(PIO pio, uint irq_index, pio_interrupt_source_t source, bool enabled)
Enable/Disable a single source on a PIO's specified (0/1) IRQ index.
Definition pio.h:1367
void pio_sm_set_pins_with_mask64(PIO pio, uint sm, uint64_t pin_values, uint64_t pin_mask)
Use a state machine to set a value on multiple pins for the PIO instance.
Definition pio.c:298
pio_interrupt_source
PIO interrupt source numbers for pio related IRQs.
Definition pio.h:1272
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:1753
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:230
int 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.
Definition pio.c:192
static void pio_sm_set_clkdiv_int_frac8(PIO pio, uint sm, uint32_t div_int, uint8_t div_frac8)
set the current clock divider for a state machine using a 16:8 fraction
Definition pio.h:1783
static PIO pio_get_instance(uint instance)
Convert PIO instance to hardware instance.
Definition pio.h:865
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:1476
static int 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:809
static int pio_get_irq_num(PIO pio, uint irqn)
Return an IRQ for a PIO hardware instance.
Definition pio.h:2047
int pio_set_gpio_base(PIO pio, uint gpio_base)
Set the base GPIO base for the PIO instance.
Definition pio.c:97
pio_mov_status_type
MOV status types.
Definition pio.h:122
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:1699
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:911
static void pio_set_irq1_source_enabled(PIO pio, pio_interrupt_source_t source, bool enabled)
Enable/Disable a single source on a PIO's IRQ 1.
Definition pio.h:1316
void pio_sm_set_pindirs_with_mask64(PIO pio, uint sm, uint64_t pin_dirs, uint64_t pin_mask)
Use a state machine to set the pin directions for multiple pins for the PIO instance.
Definition pio.c:335
void pio_sm_drain_tx_fifo(PIO pio, uint sm)
Empty out a state machine's TX FIFO.
Definition pio.c:396
void pio_claim_sm_mask(PIO pio, uint sm_mask)
Mark multiple state machines as used.
Definition pio.c:36
bool pio_claim_free_sm_and_add_program_for_gpio_range(const pio_program_t *program, PIO *pio, uint *sm, uint *offset, uint gpio_base, uint gpio_count, bool set_gpio_base)
Finds a PIO and statemachine and adds a program into PIO memory.
Definition pio.c:408
void pio_sm_set_pins64(PIO pio, uint sm, uint64_t pin_values)
Use a state machine to set a value on all pins for the PIO instance.
Definition pio.c:261
int pio_claim_unused_sm(PIO pio, bool required)
Claim a free state machine on a PIO instance.
Definition pio.c:48
void pio_sm_unclaim(PIO pio, uint sm)
Mark a state machine as no longer used.
Definition pio.c:42
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:1175
bool pio_sm_is_claimed(PIO pio, uint sm)
Determine if a PIO state machine is claimed.
Definition pio.c:57
static void pio_interrupt_clear(PIO pio, uint pio_interrupt_num)
Clear a particular PIO interrupt.
Definition pio.h:1414
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:1645
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:1658
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:1492
#define PIO_NUM(pio)
Returns the PIO number for a PIO instance.
Definition pio.h:178
static void pio_sm_restart(PIO pio, uint sm)
Restart a state machine with a known state.
Definition pio.h:1098
pio_fifo_join
FIFO join states.
Definition pio.h:108
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:1513
static void pio_sm_exec(PIO pio, uint sm, uint instr)
Immediately execute an instruction on a state machine.
Definition pio.h:1445
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:1332
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:199
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:307
void pio_clear_instruction_memory(PIO pio)
Clears all of a PIO instance's instruction memory.
Definition pio.c:208
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:1579
static void pio_sm_set_clkdiv(PIO pio, uint sm, float div)
set the current clock divider for a state machine
Definition pio.h:1807
static uint pio_get_gpio_base(PIO pio)
Return the base GPIO base for the PIO instance.
Definition pio.h:780
static pio_interrupt_source_t pio_get_tx_fifo_not_full_interrupt_source(uint sm)
Return the interrupt source for a state machines TX FIFO not full interrupt.
Definition pio.h:2059
int 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:365
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:1684
#define pio0
Definition pio.h:138
#define pio1
Definition pio.h:146
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:270
static void pio_sm_set_jmp_pin(PIO pio, uint sm, uint pin)
Set the 'jmp' pin for a state machine.
Definition pio.h:1598
static uint8_t pio_sm_get_pc(PIO pio, uint sm)
Return the current program counter for a state machine.
Definition pio.h:1427
static uint pio_get_funcsel(PIO pio)
Return the funcsel number of a PIO instance.
Definition pio.h:854
#define PIO_FUNCSEL_NUM(pio, gpio)
Returns gpio_function_t needed to select the PIO function for the given PIO instance on the given GPI...
Definition pio.h:206
static void pio_sm_set_enabled(PIO pio, uint sm, bool enabled)
Enable or disable a PIO state machine.
Definition pio.h:1036
void pio_sm_claim(PIO pio, uint sm)
Mark a state machine as used.
Definition pio.c:24
void pio_remove_program_and_unclaim_sm(const pio_program_t *program, PIO pio, uint sm, uint offset)
Removes a program from PIO memory and unclaims the state machine.
Definition pio.c:464
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:145
static bool pio_interrupt_get(PIO pio, uint pio_interrupt_num)
Determine if a particular PIO interrupt is set.
Definition pio.h:1402
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:1458
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:153
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:1624
static void pio_sm_clear_fifos(PIO pio, uint sm)
Clear a state machine's TX and RX FIFOs.
Definition pio.h:1822
enum pio_interrupt_source pio_interrupt_source_t
PIO interrupt source numbers for pio related IRQs.
#define PIO_DREQ_NUM(pio, sm, is_tx)
Returns the dreq_num_t used for pacing DMA transfers to or from a given state machine's FIFOs on this...
Definition pio.h:229
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:1234
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:1537
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:1140
static pio_interrupt_source_t pio_get_rx_fifo_not_empty_interrupt_source(uint sm)
Return the interrupt source for a state machines RX FIFO not empty interrupt.
Definition pio.h:2070
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:1671
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:1712
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:1349
static void pio_restart_sm_mask(PIO pio, uint32_t mask)
Restart multiple state machine with a known state.
Definition pio.h:1113
static uint pio_get_index(PIO pio)
Return the instance number of a PIO instance.
Definition pio.h:842
#define PIO_IRQ_NUM(pio, irqn)
Returns the irq_num_t for processor interrupts from the given PIO instance.
Definition pio.h:241
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:1740
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:1559
int pio_add_program(PIO pio, const pio_program_t *program)
Attempt to load the program.
Definition pio.c:182
int pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pins_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:343
static void pio_set_sm_mask_enabled(PIO pio, uint32_t mask, bool enabled)
Enable or disable multiple PIO state machines.
Definition pio.h:1055
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:898
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:1384
static void pio_set_irq0_source_enabled(PIO pio, pio_interrupt_source_t source, bool enabled)
Enable/Disable a single source on a PIO's IRQ 0.
Definition pio.h:1300
@ pis_interrupt2
PIO interrupt 2 is raised.
Definition pio.h:1275
@ pis_sm2_tx_fifo_not_full
State machine 2 TX FIFO is not full.
Definition pio.h:1285
@ pis_interrupt0
PIO interrupt 0 is raised.
Definition pio.h:1273
@ pis_sm1_tx_fifo_not_full
State machine 1 TX FIFO is not full.
Definition pio.h:1284
@ pis_sm3_tx_fifo_not_full
State machine 3 TX FIFO is not full.
Definition pio.h:1286
@ pis_interrupt1
PIO interrupt 1 is raised.
Definition pio.h:1274
@ pis_sm2_rx_fifo_not_empty
State machine 2 RX FIFO is not empty.
Definition pio.h:1289
@ pis_sm1_rx_fifo_not_empty
State machine 1 RX FIFO is not empty.
Definition pio.h:1288
@ pis_sm0_tx_fifo_not_full
State machine 0 TX FIFO is not full.
Definition pio.h:1283
@ pis_interrupt3
PIO interrupt 3 is raised.
Definition pio.h:1276
@ pis_sm0_rx_fifo_not_empty
State machine 0 RX FIFO is not empty.
Definition pio.h:1287
@ pis_sm3_rx_fifo_not_empty
State machine 3 RX FIFO is not empty.
Definition pio.h:1290
@ PIO_FIFO_JOIN_NONE
TX FIFO length=4 is used for transmit, RX FIFO length=4 is used for receive.
Definition pio.h:109
@ PIO_FIFO_JOIN_TX
TX FIFO length=8 is used for transmit, RX FIFO is disabled.
Definition pio.h:110
@ PIO_FIFO_JOIN_RX
RX FIFO length=8 is used for receive, TX FIFO is disabled.
Definition pio.h:111
@ PICO_OK
No error; the operation succeeded.
Definition error.h:23
@ PICO_ERROR_BAD_ALIGNMENT
Address was mis-aligned (usually not on word boundary).
Definition error.h:35
static __force_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition common.h:74
static void sm_config_set_out_pin_base(pio_sm_config *c, uint out_base)
Set the base of the 'out' pins in a state machine configuration.
Definition pio.h:345
static void sm_config_set_out_special(pio_sm_config *c, bool sticky, bool has_enable_pin, uint enable_bit_index)
Set special 'out' operations in a state machine configuration.
Definition pio.h:710
static void sm_config_set_set_pin_base(pio_sm_config *c, uint set_base)
Set the base of the 'set' pins in a state machine configuration.
Definition pio.h:391
static void sm_config_set_in_pin_count(pio_sm_config *c, uint in_count)
Set the count of 'in' pins in a state machine configuration.
Definition pio.h:472
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:668
static void sm_config_set_set_pin_count(pio_sm_config *c, uint set_count)
Set the count of 'set' pins in a state machine configuration.
Definition pio.h:409
static void sm_config_set_sideset_pin_base(pio_sm_config *c, uint sideset_base)
Set the base of the 'sideset' pins in a state machine configuration.
Definition pio.h:492
static void sm_config_set_clkdiv_int_frac8(pio_sm_config *c, uint32_t div_int, uint8_t div_frac8)
Set the state machine clock divider (from integer and fractional parts - 16:8) in a state machine con...
Definition pio.h:548
static void sm_config_set_in_pin_base(pio_sm_config *c, uint in_base)
Set the base of the 'in' pins in a state machine configuration.
Definition pio.h:437
static void sm_config_set_in_pins(pio_sm_config *c, uint in_base)
Set the base for the 'in' pins in a state machine configuration.
Definition pio.h:455
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:726
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:513
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:424
static void sm_config_set_out_pin_count(pio_sm_config *c, uint out_count)
Set the number of 'out' pins in a state machine configuration.
Definition pio.h:363
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:602
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:649
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:631
static pio_sm_config pio_get_default_sm_config(void)
Get the default state machine configuration.
Definition pio.h:758
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:378
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:525
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:617
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:685
Definition pio.h:132
Definition pio.h:917
PIO Configuration structure.
Definition pio.h:290