diff --git a/src/rp2_common/hardware_pio/include/hardware/pio.h b/src/rp2_common/hardware_pio/include/hardware/pio.h index 4363608fc..39b8ef5bd 100644 --- a/src/rp2_common/hardware_pio/include/hardware/pio.h +++ b/src/rp2_common/hardware_pio/include/hardware/pio.h @@ -786,6 +786,15 @@ static inline uint pio_get_gpio_base(PIO pio) { #endif } +static inline void check_pio_pin_mask(__unused PIO pio, __unused uint sm, __unused uint32_t pinmask) { + // check no pins are set in the mask which are incompatible with the pio +#if PICO_PIO_USE_GPIO_BASE + valid_params_if(HARDWARE_PIO, (pinmask & ~(0xfffffffful << pio_get_gpio_base(pio))) == 0); +#else + valid_params_if(HARDWARE_PIO, (pinmask & ~0xfffffffful) == 0); +#endif +} + static inline void check_pio_pin_mask64(__unused PIO pio, __unused uint sm, __unused uint64_t pinmask) { // check no pins are set in the mask which are incompatible with the pio #if PICO_PIO_USE_GPIO_BASE @@ -1514,6 +1523,7 @@ static inline void pio_sm_set_out_pins(PIO pio, uint sm, uint out_base, uint out check_pio_param(pio); check_sm_param(sm); #if PICO_PIO_USE_GPIO_BASE + invalid_params_if(HARDWARE_PIO, out_base < pio_get_gpio_base(pio)); out_base -= pio_get_gpio_base(pio); #endif valid_params_if(HARDWARE_PIO, out_base < 32); @@ -1538,6 +1548,7 @@ static inline void pio_sm_set_set_pins(PIO pio, uint sm, uint set_base, uint set check_pio_param(pio); check_sm_param(sm); #if PICO_PIO_USE_GPIO_BASE + invalid_params_if(HARDWARE_PIO, set_base < pio_get_gpio_base(pio)); set_base -= pio_get_gpio_base(pio); #endif valid_params_if(HARDWARE_PIO, set_base < 32); @@ -1560,6 +1571,7 @@ static inline void pio_sm_set_in_pins(PIO pio, uint sm, uint in_base) { check_pio_param(pio); check_sm_param(sm); #if PICO_PIO_USE_GPIO_BASE + invalid_params_if(HARDWARE_PIO, in_base < pio_get_gpio_base(pio)); in_base -= pio_get_gpio_base(pio); #endif valid_params_if(HARDWARE_PIO, in_base < 32); @@ -1580,6 +1592,7 @@ static inline void pio_sm_set_sideset_pins(PIO pio, uint sm, uint sideset_base) check_pio_param(pio); check_sm_param(sm); #if PICO_PIO_USE_GPIO_BASE + invalid_params_if(HARDWARE_PIO, sideset_base < pio_get_gpio_base(pio)); sideset_base -= pio_get_gpio_base(pio); #endif valid_params_if(HARDWARE_PIO, sideset_base < 32); @@ -1599,6 +1612,7 @@ static inline void pio_sm_set_jmp_pin(PIO pio, uint sm, uint pin) { check_pio_param(pio); check_sm_param(sm); #if PICO_PIO_USE_GPIO_BASE + invalid_params_if(HARDWARE_PIO, pin < pio_get_gpio_base(pio)); pin -= pio_get_gpio_base(pio); #endif valid_params_if(HARDWARE_PIO, pin < 32); diff --git a/src/rp2_common/hardware_pio/pio.c b/src/rp2_common/hardware_pio/pio.c index 7182cfff5..7550e619e 100644 --- a/src/rp2_common/hardware_pio/pio.c +++ b/src/rp2_common/hardware_pio/pio.c @@ -82,10 +82,10 @@ static int find_offset_for_program(PIO pio, const pio_program_t *program) { } static int pio_set_gpio_base_unsafe(PIO pio, uint gpio_base) { - invalid_params_if_and_return(PIO, gpio_base != 0 && (!PICO_PIO_VERSION || gpio_base != 16), PICO_ERROR_BAD_ALIGNMENT); + invalid_params_if_and_return(HARDWARE_PIO, gpio_base != 0 && (!PICO_PIO_VERSION || gpio_base != 16), PICO_ERROR_BAD_ALIGNMENT); #if PICO_PIO_VERSION > 0 uint32_t used_mask = _used_instruction_space[pio_get_index(pio)]; - invalid_params_if_and_return(PIO, used_mask, PICO_ERROR_INVALID_STATE); + invalid_params_if_and_return(HARDWARE_PIO, used_mask, PICO_ERROR_INVALID_STATE); pio->gpiobase = gpio_base; #else ((void)pio); @@ -251,6 +251,7 @@ void pio_sm_set_pins_internal(PIO pio, uint sm, uint32_t pins) { #ifndef pio_sm_set_pins_internal void pio_sm_set_pins(PIO pio, uint sm, uint32_t pins) { + check_pio_pin_mask(pio, sm, pins); #if PICO_PIO_USE_GPIO_BASE pins >>= pio_get_gpio_base(pio); #endif @@ -287,6 +288,7 @@ void pio_sm_set_pins_with_mask_internal(PIO pio, uint sm, uint32_t pin_values, u #ifndef pio_sm_set_pins_with_mask_internal void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pin_values, uint32_t pin_mask) { + check_pio_pin_mask(pio, sm, pin_mask); #if PICO_PIO_USE_GPIO_BASE pin_values >>= pio_get_gpio_base(pio); pin_mask >>= pio_get_gpio_base(pio); @@ -324,6 +326,7 @@ void pio_sm_set_pindirs_with_mask_internal(PIO pio, uint sm, uint32_t pindirs, u #ifndef pio_sm_set_pindirs_with_mask_internal void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pindirs, uint32_t pin_mask) { + check_pio_pin_mask(pio, sm, pin_mask); #if PICO_PIO_USE_GPIO_BASE pindirs >>= pio_get_gpio_base(pio); pin_mask >>= pio_get_gpio_base(pio); @@ -333,6 +336,7 @@ void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pindirs, uint32_t p #endif void pio_sm_set_pindirs_with_mask64(PIO pio, uint sm, uint64_t pindirs, uint64_t pin_mask) { + check_pio_pin_mask64(pio, sm, pin_mask); #if PICO_PIO_USE_GPIO_BASE pindirs >>= pio_get_gpio_base(pio); pin_mask >>= pio_get_gpio_base(pio); @@ -343,8 +347,11 @@ void pio_sm_set_pindirs_with_mask64(PIO pio, uint sm, uint64_t pindirs, uint64_t int pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pin, uint count, bool is_out) { check_pio_param(pio); check_sm_param(sm); +#if PICO_PIO_USE_GPIO_BASE + invalid_params_if_and_return(HARDWARE_PIO, pin < pio_get_gpio_base(pio), PICO_ERROR_INVALID_ARG); pin -= pio_get_gpio_base(pio); - invalid_params_if_and_return(PIO, pin >= 32u, PICO_ERROR_INVALID_ARG); +#endif + invalid_params_if_and_return(HARDWARE_PIO, pin >= 32u, PICO_ERROR_INVALID_ARG); uint32_t pinctrl_saved = pio->sm[sm].pinctrl; uint32_t execctrl_saved = pio->sm[sm].execctrl; hw_clear_bits(&pio->sm[sm].execctrl, 1u << PIO_SM0_EXECCTRL_OUT_STICKY_LSB); @@ -409,12 +416,12 @@ bool pio_claim_free_sm_and_add_program_for_gpio_range(const pio_program_t *progr invalid_params_if(HARDWARE_PIO, (gpio_base + gpio_count) > NUM_BANK0_GPIOS); #if !PICO_PIO_USE_GPIO_BASE - // short-circuit some logic when not using GIO_BASE + // short-circuit some logic when not using GPIO_BASE set_gpio_base = 0; gpio_count = 0; #endif - // note if we gpio_count == 0, we don't care about GPIOs so use a zero mask for what we require + // note if gpio_count == 0, we don't care about GPIOs so use a zero mask for what we require // if gpio_count > 0, then we just set used mask for the ends, since that is all that is checked at the moment uint32_t required_gpio_ranges; if (gpio_count) required_gpio_ranges = (1u << (gpio_base >> 4)) | (1u << ((gpio_base + gpio_count - 1) >> 4));