Merge pull request #14888 from bergzand/pr/fe310/gpio_atomics
fe310: Use read-modify-store instruction for GPIO bitwise operations
This commit is contained in:
commit
f264b049aa
@ -37,6 +37,20 @@ static gpio_flank_t isr_flank[GPIO_NUMOF];
|
|||||||
static gpio_isr_ctx_t isr_ctx[GPIO_NUMOF];
|
static gpio_isr_ctx_t isr_ctx[GPIO_NUMOF];
|
||||||
#endif /* MODULE_PERIPH_GPIO_IRQ */
|
#endif /* MODULE_PERIPH_GPIO_IRQ */
|
||||||
|
|
||||||
|
/* Really always inline these functions These two should be only a few
|
||||||
|
* instructions as the atomic_fetch_or is a single instruction on rv32imac */
|
||||||
|
static __attribute((always_inline)) inline
|
||||||
|
void _set_pin_reg(uint32_t offset, gpio_t pin)
|
||||||
|
{
|
||||||
|
__atomic_fetch_or(&GPIO_REG(offset), 1 << pin, __ATOMIC_RELAXED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __attribute((always_inline)) inline
|
||||||
|
void _clr_pin_reg(uint32_t offset, gpio_t pin)
|
||||||
|
{
|
||||||
|
__atomic_fetch_and(&GPIO_REG(offset), ~(1 << pin), __ATOMIC_RELAXED);
|
||||||
|
}
|
||||||
|
|
||||||
int gpio_init(gpio_t pin, gpio_mode_t mode)
|
int gpio_init(gpio_t pin, gpio_mode_t mode)
|
||||||
{
|
{
|
||||||
/* Check for valid pin */
|
/* Check for valid pin */
|
||||||
@ -45,23 +59,24 @@ int gpio_init(gpio_t pin, gpio_mode_t mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Configure the mode */
|
/* Configure the mode */
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case GPIO_IN:
|
case GPIO_IN:
|
||||||
GPIO_REG(GPIO_INPUT_EN) |= (1 << pin);
|
_set_pin_reg(GPIO_INPUT_EN, pin);
|
||||||
GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << pin);
|
_clr_pin_reg(GPIO_OUTPUT_EN, pin);
|
||||||
GPIO_REG(GPIO_PULLUP_EN) &= ~(1 << pin);
|
_clr_pin_reg(GPIO_PULLUP_EN, pin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPIO_IN_PU:
|
case GPIO_IN_PU:
|
||||||
GPIO_REG(GPIO_INPUT_EN) |= (1 << pin);
|
_clr_pin_reg(GPIO_OUTPUT_EN, pin);
|
||||||
GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << pin);
|
_set_pin_reg(GPIO_INPUT_EN, pin);
|
||||||
GPIO_REG(GPIO_PULLUP_EN) |= (1 << pin);
|
_set_pin_reg(GPIO_PULLUP_EN, pin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPIO_OUT:
|
case GPIO_OUT:
|
||||||
GPIO_REG(GPIO_INPUT_EN) &= ~(1 << pin);
|
_set_pin_reg(GPIO_OUTPUT_EN, pin);
|
||||||
GPIO_REG(GPIO_OUTPUT_EN) |= (1 << pin);
|
_clr_pin_reg(GPIO_INPUT_EN, pin);
|
||||||
GPIO_REG(GPIO_PULLUP_EN) &= ~(1 << pin);
|
_clr_pin_reg(GPIO_PULLUP_EN, pin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -69,8 +84,8 @@ int gpio_init(gpio_t pin, gpio_mode_t mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Configure the pin muxing for the GPIO */
|
/* Configure the pin muxing for the GPIO */
|
||||||
GPIO_REG(GPIO_IOF_EN) &= ~(1 << pin);
|
_clr_pin_reg(GPIO_IOF_EN, pin);
|
||||||
GPIO_REG(GPIO_IOF_SEL) &= ~(1 << pin);
|
_clr_pin_reg(GPIO_IOF_SEL, pin);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -82,26 +97,26 @@ int gpio_read(gpio_t pin)
|
|||||||
|
|
||||||
void gpio_set(gpio_t pin)
|
void gpio_set(gpio_t pin)
|
||||||
{
|
{
|
||||||
GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << pin);
|
_set_pin_reg(GPIO_OUTPUT_VAL, pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_clear(gpio_t pin)
|
void gpio_clear(gpio_t pin)
|
||||||
{
|
{
|
||||||
GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << pin);
|
_clr_pin_reg(GPIO_OUTPUT_VAL, pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_toggle(gpio_t pin)
|
void gpio_toggle(gpio_t pin)
|
||||||
{
|
{
|
||||||
GPIO_REG(GPIO_OUTPUT_VAL) ^= (1 << pin);
|
__atomic_fetch_xor(&GPIO_REG(GPIO_OUTPUT_VAL), (1 << pin), __ATOMIC_RELAXED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_write(gpio_t pin, int value)
|
void gpio_write(gpio_t pin, int value)
|
||||||
{
|
{
|
||||||
if (value) {
|
if (value) {
|
||||||
GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << pin);
|
_set_pin_reg(GPIO_OUTPUT_VAL, pin);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << pin);
|
_clr_pin_reg(GPIO_OUTPUT_VAL, pin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,16 +133,16 @@ void gpio_isr(int num)
|
|||||||
/* Clear interrupt */
|
/* Clear interrupt */
|
||||||
switch (isr_flank[pin]) {
|
switch (isr_flank[pin]) {
|
||||||
case GPIO_FALLING:
|
case GPIO_FALLING:
|
||||||
GPIO_REG(GPIO_FALL_IP) |= (1 << pin);
|
_set_pin_reg(GPIO_FALL_IP, pin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPIO_RISING:
|
case GPIO_RISING:
|
||||||
GPIO_REG(GPIO_RISE_IP) |= (1 << pin);
|
_set_pin_reg(GPIO_RISE_IP, pin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPIO_BOTH:
|
case GPIO_BOTH:
|
||||||
GPIO_REG(GPIO_FALL_IP) |= (1 << pin);
|
_set_pin_reg(GPIO_FALL_IP, pin);
|
||||||
GPIO_REG(GPIO_RISE_IP) |= (1 << pin);
|
_set_pin_reg(GPIO_RISE_IP, pin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,16 +187,16 @@ void gpio_irq_enable(gpio_t pin)
|
|||||||
/* Enable interrupt for pin */
|
/* Enable interrupt for pin */
|
||||||
switch (isr_flank[pin]) {
|
switch (isr_flank[pin]) {
|
||||||
case GPIO_FALLING:
|
case GPIO_FALLING:
|
||||||
GPIO_REG(GPIO_FALL_IE) |= (1 << pin);
|
_set_pin_reg(GPIO_FALL_IE, pin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPIO_RISING:
|
case GPIO_RISING:
|
||||||
GPIO_REG(GPIO_RISE_IE) |= (1 << pin);
|
_set_pin_reg(GPIO_RISE_IE, pin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPIO_BOTH:
|
case GPIO_BOTH:
|
||||||
GPIO_REG(GPIO_FALL_IE) |= (1 << pin);
|
_set_pin_reg(GPIO_FALL_IE, pin);
|
||||||
GPIO_REG(GPIO_RISE_IE) |= (1 << pin);
|
_set_pin_reg(GPIO_RISE_IE, pin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -199,16 +214,16 @@ void gpio_irq_disable(gpio_t pin)
|
|||||||
/* Disable interrupt for pin */
|
/* Disable interrupt for pin */
|
||||||
switch (isr_flank[pin]) {
|
switch (isr_flank[pin]) {
|
||||||
case GPIO_FALLING:
|
case GPIO_FALLING:
|
||||||
GPIO_REG(GPIO_FALL_IE) &= ~(1 << pin);
|
_clr_pin_reg(GPIO_FALL_IE, pin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPIO_RISING:
|
case GPIO_RISING:
|
||||||
GPIO_REG(GPIO_RISE_IE) &= ~(1 << pin);
|
_clr_pin_reg(GPIO_RISE_IE, pin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPIO_BOTH:
|
case GPIO_BOTH:
|
||||||
GPIO_REG(GPIO_FALL_IE) &= ~(1 << pin);
|
_clr_pin_reg(GPIO_FALL_IE, pin);
|
||||||
GPIO_REG(GPIO_RISE_IE) &= ~(1 << pin);
|
_clr_pin_reg(GPIO_RISE_IE, pin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user