From 8e014e6b5d2a89c5d45d0db618d4ed2ceafe8ec2 Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Sun, 16 Oct 2022 23:39:44 +0200 Subject: [PATCH] Make sure OUT_STICKY is not set when setting pins / pindirs (#989) --- src/rp2_common/hardware_pio/pio.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/rp2_common/hardware_pio/pio.c b/src/rp2_common/hardware_pio/pio.c index 0744110..6137566 100644 --- a/src/rp2_common/hardware_pio/pio.c +++ b/src/rp2_common/hardware_pio/pio.c @@ -157,6 +157,8 @@ void pio_sm_set_pins(PIO pio, uint sm, uint32_t pins) { check_pio_param(pio); check_sm_param(sm); 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); uint remaining = 32; uint base = 0; while (remaining) { @@ -170,12 +172,15 @@ void pio_sm_set_pins(PIO pio, uint sm, uint32_t pins) { pins >>= 5; } pio->sm[sm].pinctrl = pinctrl_saved; + pio->sm[sm].execctrl = execctrl_saved; } void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pinvals, uint32_t pin_mask) { check_pio_param(pio); check_sm_param(sm); 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); while (pin_mask) { uint base = (uint)__builtin_ctz(pin_mask); pio->sm[sm].pinctrl = @@ -185,12 +190,15 @@ void pio_sm_set_pins_with_mask(PIO pio, uint sm, uint32_t pinvals, uint32_t pin_ pin_mask &= pin_mask - 1; } pio->sm[sm].pinctrl = pinctrl_saved; + pio->sm[sm].execctrl = execctrl_saved; } void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pindirs, uint32_t pin_mask) { check_pio_param(pio); check_sm_param(sm); 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); while (pin_mask) { uint base = (uint)__builtin_ctz(pin_mask); pio->sm[sm].pinctrl = @@ -200,6 +208,7 @@ void pio_sm_set_pindirs_with_mask(PIO pio, uint sm, uint32_t pindirs, uint32_t p pin_mask &= pin_mask - 1; } pio->sm[sm].pinctrl = pinctrl_saved; + pio->sm[sm].execctrl = execctrl_saved; } void pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pin, uint count, bool is_out) { @@ -207,6 +216,8 @@ void pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pin, uint count, bool check_sm_param(sm); valid_params_if(PIO, pin < 32u); 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); uint pindir_val = is_out ? 0x1f : 0; while (count > 5) { pio->sm[sm].pinctrl = (5u << PIO_SM0_PINCTRL_SET_COUNT_LSB) | (pin << PIO_SM0_PINCTRL_SET_BASE_LSB); @@ -217,6 +228,7 @@ void pio_sm_set_consecutive_pindirs(PIO pio, uint sm, uint pin, uint count, bool pio->sm[sm].pinctrl = (count << PIO_SM0_PINCTRL_SET_COUNT_LSB) | (pin << PIO_SM0_PINCTRL_SET_BASE_LSB); pio_sm_exec(pio, sm, pio_encode_set(pio_pindirs, pindir_val)); pio->sm[sm].pinctrl = pinctrl_saved; + pio->sm[sm].execctrl = execctrl_saved; } void pio_sm_init(PIO pio, uint sm, uint initial_pc, const pio_sm_config *config) {