From 44a5c76884d0190675373b16ee42c9a254650262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Tue, 26 Nov 2013 22:10:47 +0100 Subject: [PATCH 1/2] cc2538: gpio: Add macros to use GPIO power-up interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GPIO power-up interrupts have to be configured and enabled in order to be able to wake-up the SoC from PM1+ upon a signal edge occurring on a GPIO input pin. This set of macros allows to: - configure the signal edge triggering a power-up interrupt, - enable and disable a power-up interrupt, - clear a power-up interrupt flag. Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/dev/gpio.h | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/cpu/cc2538/dev/gpio.h b/cpu/cc2538/dev/gpio.h index c81482c9e..8a61f668b 100644 --- a/cpu/cc2538/dev/gpio.h +++ b/cpu/cc2538/dev/gpio.h @@ -214,6 +214,51 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin); #define GPIO_SOFTWARE_CONTROL(PORT_BASE, PIN_MASK) \ do { REG((PORT_BASE) | GPIO_AFSEL) &= ~(PIN_MASK); } while(0) +/** \brief Set pins with PIN_MASK of port PORT to trigger a power-up interrupt + * on rising edge. + * \param PORT GPIO Port (not port base address) + * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 + */ +#define GPIO_POWER_UP_ON_RISING(PORT, PIN_MASK) \ + do { REG(GPIO_PORT_TO_BASE(PORT) | GPIO_P_EDGE_CTRL) &= \ + ~((PIN_MASK) << ((PORT) << 3)); } while(0) + +/** \brief Set pins with PIN_MASK of port PORT to trigger a power-up interrupt + * on falling edge. + * \param PORT GPIO Port (not port base address) + * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 + */ +#define GPIO_POWER_UP_ON_FALLING(PORT, PIN_MASK) \ + do { REG(GPIO_PORT_TO_BASE(PORT) | GPIO_P_EDGE_CTRL) |= \ + (PIN_MASK) << ((PORT) << 3); } while(0) + +/** \brief Enable power-up interrupt triggering for pins with PIN_MASK of port + * PORT. + * \param PORT GPIO Port (not port base address) + * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 + */ +#define GPIO_ENABLE_POWER_UP_INTERRUPT(PORT, PIN_MASK) \ + do { REG(GPIO_PORT_TO_BASE(PORT) | GPIO_PI_IEN) |= \ + (PIN_MASK) << ((PORT) << 3); } while(0) + +/** \brief Disable power-up interrupt triggering for pins with PIN_MASK of port + * PORT. + * \param PORT GPIO Port (not port base address) + * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 + */ +#define GPIO_DISABLE_POWER_UP_INTERRUPT(PORT, PIN_MASK) \ + do { REG(GPIO_PORT_TO_BASE(PORT) | GPIO_PI_IEN) &= \ + ~((PIN_MASK) << ((PORT) << 3)); } while(0) + +/** \brief Clear power-up interrupt triggering for pins with PIN_MASK of port + * PORT. + * \param PORT GPIO Port (not port base address) + * \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80 + */ +#define GPIO_CLEAR_POWER_UP_INTERRUPT(PORT, PIN_MASK) \ + do { REG(GPIO_PORT_TO_BASE(PORT) | GPIO_IRQ_DETECT_ACK) = \ + (PIN_MASK) << ((PORT) << 3); } while(0) + /** * \brief Converts a pin number to a pin mask * \param The pin number in the range [0..7] From 1a696eb123613835a6c8ae663ed79f87395c4874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Tue, 26 Nov 2013 22:20:05 +0100 Subject: [PATCH 2/2] cc2538: gpio: Clear the power-up interrupts in the port ISRs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pending GPIO power-up interrupts have to be cleared in the ISRs in order not to re-trigger the interrupts and the wake-up events. The power-up interrupts of all pins are cleared for each port in the corresponding port ISR. This is done after calling the registered callbacks so that the callbacks can know which pin woke up the SoC. This is done after clearing the regular interrupt in order to avoid getting a new wake-up interrupt without the regular interrupt in the case of a new wake-up edge occurring between the two clears. Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/dev/gpio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cpu/cc2538/dev/gpio.c b/cpu/cc2538/dev/gpio.c index 80a1b7d8d..111946001 100644 --- a/cpu/cc2538/dev/gpio.c +++ b/cpu/cc2538/dev/gpio.c @@ -90,6 +90,7 @@ gpio_port_a_isr() notify(REG(GPIO_A_BASE | GPIO_MIS), GPIO_A_NUM); GPIO_CLEAR_INTERRUPT(GPIO_A_BASE, 0xFF); + GPIO_CLEAR_POWER_UP_INTERRUPT(GPIO_A_NUM, 0xFF); ENERGEST_OFF(ENERGEST_TYPE_IRQ); } @@ -105,6 +106,7 @@ gpio_port_b_isr() notify(REG(GPIO_B_BASE | GPIO_MIS), GPIO_B_NUM); GPIO_CLEAR_INTERRUPT(GPIO_B_BASE, 0xFF); + GPIO_CLEAR_POWER_UP_INTERRUPT(GPIO_B_NUM, 0xFF); ENERGEST_OFF(ENERGEST_TYPE_IRQ); } @@ -120,6 +122,7 @@ gpio_port_c_isr() notify(REG(GPIO_C_BASE | GPIO_MIS), GPIO_C_NUM); GPIO_CLEAR_INTERRUPT(GPIO_C_BASE, 0xFF); + GPIO_CLEAR_POWER_UP_INTERRUPT(GPIO_C_NUM, 0xFF); ENERGEST_OFF(ENERGEST_TYPE_IRQ); } @@ -135,6 +138,7 @@ gpio_port_d_isr() notify(REG(GPIO_D_BASE | GPIO_MIS), GPIO_D_NUM); GPIO_CLEAR_INTERRUPT(GPIO_D_BASE, 0xFF); + GPIO_CLEAR_POWER_UP_INTERRUPT(GPIO_D_NUM, 0xFF); ENERGEST_OFF(ENERGEST_TYPE_IRQ); }