Nordic nRF GPIO: Fixup race condition in GPIO pin Toggle

This PR fixes up a race condition which could cause GPIO writes to be
dropped when one thread was toggling a gpio on a port, and a different
thread was also modifying a (different) gpio on the same port.

Signed-off-by: Nickolas Lapp <nickolaslapp@gmail.com>
This commit is contained in:
Nickolas Lapp 2022-08-02 14:56:59 -04:00 committed by Carles Cufí
parent e9ea1b0e68
commit 3feebd6571

View file

@ -173,10 +173,12 @@ static int gpio_nrfx_port_set_masked_raw(const struct device *port,
gpio_port_value_t value)
{
NRF_GPIO_Type *reg = get_port_cfg(port)->port;
uint32_t value_tmp;
value_tmp = nrf_gpio_port_out_read(reg) & ~mask;
nrf_gpio_port_out_write(reg, value_tmp | (mask & value));
const uint32_t set_mask = value & mask;
const uint32_t clear_mask = (~set_mask) & mask;
nrf_gpio_port_out_set(reg, set_mask);
nrf_gpio_port_out_clear(reg, clear_mask);
return 0;
}
@ -205,10 +207,12 @@ static int gpio_nrfx_port_toggle_bits(const struct device *port,
gpio_port_pins_t mask)
{
NRF_GPIO_Type *reg = get_port_cfg(port)->port;
uint32_t value;
const uint32_t value = nrf_gpio_port_out_read(reg) ^ mask;
const uint32_t set_mask = value & mask;
const uint32_t clear_mask = (~value) & mask;
value = nrf_gpio_port_out_read(reg);
nrf_gpio_port_out_write(reg, value ^ mask);
nrf_gpio_port_out_set(reg, set_mask);
nrf_gpio_port_out_clear(reg, clear_mask);
return 0;
}