From fc907f9251219412ced2290f245012997a38423b Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 20 May 2024 10:06:03 +0200 Subject: [PATCH] cpu/msp430/periph_gpio: resolve conflict with GPIO LL In case both periph_gpio_irq and periph_gpio_ll_irq are used, the periph_gpio_irq implementation now uses periph_gpio_ll_irq, so that they can coexist. --- cpu/msp430/periph/gpio.c | 75 +++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/cpu/msp430/periph/gpio.c b/cpu/msp430/periph/gpio.c index 484606310a..2629e906d5 100644 --- a/cpu/msp430/periph/gpio.c +++ b/cpu/msp430/periph/gpio.c @@ -20,11 +20,16 @@ */ #include "bitarithm.h" +#include "compiler_hints.h" #include "container.h" -#include "cpu.h" #include "periph/gpio.h" #include "periph/gpio_ll.h" +#ifdef MODULE_PERIPH_GPIO_IRQ +#include "modules.h" +#include "periph/gpio_ll_irq.h" +#endif + /** * @brief Number of possible interrupt lines: 2 ports * 8 pins */ @@ -40,11 +45,17 @@ static msp430_port_t *_port(gpio_t pin) return (msp430_port_t *)gpio_port(pin >> 8); } -static inline uint8_t _pin(gpio_t pin) +static inline uint8_t _pin_mask(gpio_t pin) { return (uint8_t)(pin & 0xff); } +MAYBE_UNUSED +static uint8_t _pin_num(gpio_t pin) +{ + return bitarithm_lsb(_pin_mask(pin)); +} + static inline msp430_port_p1_p2_t *_isr_port(gpio_t pin) { /* checking for (pin >> 8) <= 2 requires 6 byte of .text more than @@ -68,10 +79,10 @@ int gpio_init(gpio_t pin, gpio_mode_t mode) /* set pin direction */ if (mode == GPIO_OUT) { - port->DIR |= _pin(pin); + port->DIR |= _pin_mask(pin); } else { - port->DIR &= ~(_pin(pin)); + port->DIR &= ~(_pin_mask(pin)); } return 0; @@ -94,46 +105,46 @@ void gpio_periph_mode(gpio_t pin, bool enable) } } if (enable) { - *sel |= _pin(pin); + *sel |= _pin_mask(pin); } else { - *sel &= ~(_pin(pin)); + *sel &= ~(_pin_mask(pin)); } } int gpio_read(gpio_t pin) { msp430_port_t *port = _port(pin); - if (port->DIR & _pin(pin)) { - return (int)(port->OD & _pin(pin)); + if (port->DIR & _pin_mask(pin)) { + return (int)(port->OD & _pin_mask(pin)); } else { - return (int)(port->IN & _pin(pin)); + return (int)(port->IN & _pin_mask(pin)); } } void gpio_set(gpio_t pin) { - _port(pin)->OD |= _pin(pin); + _port(pin)->OD |= _pin_mask(pin); } void gpio_clear(gpio_t pin) { - _port(pin)->OD &= ~(_pin(pin)); + _port(pin)->OD &= ~(_pin_mask(pin)); } void gpio_toggle(gpio_t pin) { - _port(pin)->OD ^= _pin(pin); + _port(pin)->OD ^= _pin_mask(pin); } void gpio_write(gpio_t pin, int value) { if (value) { - _port(pin)->OD |= _pin(pin); + _port(pin)->OD |= _pin_mask(pin); } else { - _port(pin)->OD &= ~(_pin(pin)); + _port(pin)->OD &= ~(_pin_mask(pin)); } } @@ -145,7 +156,7 @@ static gpio_isr_ctx_t isr_ctx[ISR_NUMOF]; static int _ctx(gpio_t pin) { - int i = bitarithm_lsb(_pin(pin)); + int i = _pin_num(pin); return (_port(pin) == &PORT_1.base) ? i : (i + 8); } @@ -160,20 +171,28 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, } /* disable any activated interrupt */ - port->IE &= ~(_pin(pin)); + port->IE &= ~(_pin_mask(pin)); /* configure as input */ if (gpio_init(pin, mode) < 0) { return -1; } - /* save ISR context */ - isr_ctx[_ctx(pin)].cb = cb; - isr_ctx[_ctx(pin)].arg = arg; - /* configure flank */ - port->IES &= ~(_pin(pin)); - port->IES |= (flank & _pin(pin)); - /* clear pending interrupts and enable the IRQ */ - port->IFG &= ~(_pin(pin)); - gpio_irq_enable(pin); + + if (IS_USED(MODULE_GPIO_LL_IRQ)) { + gpio_irq_trig_t trig = (flank == GPIO_RISING) ? GPIO_TRIGGER_EDGE_RISING + : GPIO_TRIGGER_EDGE_FALLING; + return gpio_ll_irq((gpio_port_t)&port->base, _pin_num(pin), trig, cb, arg); + } + else { + /* save ISR context */ + isr_ctx[_ctx(pin)].cb = cb; + isr_ctx[_ctx(pin)].arg = arg; + /* configure flank */ + port->IES &= ~(_pin_mask(pin)); + port->IES |= (flank & _pin_mask(pin)); + /* clear pending interrupts and enable the IRQ */ + port->IFG &= ~(_pin_mask(pin)); + gpio_irq_enable(pin); + } return 0; } @@ -181,7 +200,7 @@ void gpio_irq_enable(gpio_t pin) { msp430_port_p1_p2_t *port = _isr_port(pin); if (port) { - port->IE |= _pin(pin); + port->IE |= _pin_mask(pin); } } @@ -189,10 +208,11 @@ void gpio_irq_disable(gpio_t pin) { msp430_port_p1_p2_t *port = _isr_port(pin); if (port) { - port->IE &= ~(_pin(pin)); + port->IE &= ~(_pin_mask(pin)); } } +# ifndef MODULE_GPIO_LL_IRQ static inline void isr_handler(msp430_port_p1_p2_t *port, int ctx) { for (unsigned i = 0; i < PINS_PER_PORT; i++) { @@ -216,4 +236,5 @@ ISR(PORT2_VECTOR, isr_port2) isr_handler(&PORT_2, 8); __exit_isr(); } +# endif #endif /* MODULE_PERIPH_GPIO_IRQ */