mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
mbed_official
Date:
Fri Sep 25 14:15:10 2015 +0100
Revision:
627:4fa1328d9c60
Parent:
593:78ee8643776a
Synchronized with git revision fe238a91ab7a4d1d72c4cab9da04967c619d54ad

Full URL: https://github.com/mbedmicro/mbed/commit/fe238a91ab7a4d1d72c4cab9da04967c619d54ad/

Silicon Labs - Add support for low-power async Serial

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 627:4fa1328d9c60 1 /***************************************************************************//**
mbed_official 627:4fa1328d9c60 2 * @file gpio_irq_api.h
mbed_official 627:4fa1328d9c60 3 *******************************************************************************
mbed_official 627:4fa1328d9c60 4 * @section License
mbed_official 627:4fa1328d9c60 5 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
mbed_official 627:4fa1328d9c60 6 *******************************************************************************
mbed_official 525:c320967f86b9 7 *
mbed_official 627:4fa1328d9c60 8 * Permission is granted to anyone to use this software for any purpose,
mbed_official 627:4fa1328d9c60 9 * including commercial applications, and to alter it and redistribute it
mbed_official 627:4fa1328d9c60 10 * freely, subject to the following restrictions:
mbed_official 525:c320967f86b9 11 *
mbed_official 627:4fa1328d9c60 12 * 1. The origin of this software must not be misrepresented; you must not
mbed_official 627:4fa1328d9c60 13 * claim that you wrote the original software.
mbed_official 627:4fa1328d9c60 14 * 2. Altered source versions must be plainly marked as such, and must not be
mbed_official 627:4fa1328d9c60 15 * misrepresented as being the original software.
mbed_official 627:4fa1328d9c60 16 * 3. This notice may not be removed or altered from any source distribution.
mbed_official 525:c320967f86b9 17 *
mbed_official 627:4fa1328d9c60 18 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
mbed_official 627:4fa1328d9c60 19 * obligation to support this Software. Silicon Labs is providing the
mbed_official 627:4fa1328d9c60 20 * Software "AS IS", with no express or implied warranties of any kind,
mbed_official 627:4fa1328d9c60 21 * including, but not limited to, any implied warranties of merchantability
mbed_official 627:4fa1328d9c60 22 * or fitness for any particular purpose or warranties against infringement
mbed_official 627:4fa1328d9c60 23 * of any proprietary rights of a third party.
mbed_official 627:4fa1328d9c60 24 *
mbed_official 627:4fa1328d9c60 25 * Silicon Labs will not be liable for any consequential, incidental, or
mbed_official 627:4fa1328d9c60 26 * special damages, or any other relief, or for any claim by any third party,
mbed_official 627:4fa1328d9c60 27 * arising from your use of this Software.
mbed_official 627:4fa1328d9c60 28 *
mbed_official 627:4fa1328d9c60 29 ******************************************************************************/
mbed_official 525:c320967f86b9 30
mbed_official 525:c320967f86b9 31 #include "device.h"
mbed_official 525:c320967f86b9 32 #if DEVICE_INTERRUPTIN
mbed_official 525:c320967f86b9 33
mbed_official 525:c320967f86b9 34 #include "gpio_irq_api.h"
mbed_official 525:c320967f86b9 35 #include "mbed_assert.h"
mbed_official 525:c320967f86b9 36 #include "pinmap.h"
mbed_official 525:c320967f86b9 37
mbed_official 525:c320967f86b9 38 #include "em_gpio.h"
mbed_official 525:c320967f86b9 39 #include "em_int.h"
mbed_official 525:c320967f86b9 40 #include "em_cmu.h"
mbed_official 525:c320967f86b9 41 #include "sleep_api.h"
mbed_official 526:7c4bdfe6a168 42 #include "sleepmodes.h"
mbed_official 525:c320967f86b9 43
mbed_official 525:c320967f86b9 44 #define NUM_GPIO_CHANNELS (16)
mbed_official 525:c320967f86b9 45 #define GPIO_LEAST_ACTIVE_SLEEPMODE EM3
mbed_official 525:c320967f86b9 46
mbed_official 525:c320967f86b9 47 /* Macro return index of the LSB flag which is set. */
mbed_official 525:c320967f86b9 48 #if ((__CORTEX_M == 3) || (__CORTEX_M == 4))
mbed_official 525:c320967f86b9 49 #define GPIOINT_MASK2IDX(mask) (__CLZ(__RBIT(mask)))
mbed_official 525:c320967f86b9 50 #elif __CORTEX_M == 0
mbed_official 525:c320967f86b9 51 #define GPIOINT_MASK2IDX(mask) (countTrailingZeros(mask))
mbed_official 525:c320967f86b9 52 __STATIC_INLINE uint32_t countTrailingZeros(uint32_t mask)
mbed_official 525:c320967f86b9 53 {
mbed_official 548:1abac31e188e 54 uint32_t zeros;
mbed_official 548:1abac31e188e 55 for(zeros=0; (zeros<32) && (0 == (mask&0x1)); zeros++, mask>>=1);
mbed_official 548:1abac31e188e 56 return zeros;
mbed_official 525:c320967f86b9 57 }
mbed_official 525:c320967f86b9 58 #else
mbed_official 525:c320967f86b9 59 #error Unsupported architecture.
mbed_official 525:c320967f86b9 60 #endif
mbed_official 525:c320967f86b9 61
mbed_official 525:c320967f86b9 62 static uint32_t channel_ids[NUM_GPIO_CHANNELS] = { 0 }; // Relates pin number with interrupt action id
mbed_official 593:78ee8643776a 63 static uint8_t channel_ports[NUM_GPIO_CHANNELS/2] = { 0 }; // Storing 2 ports in each uint8
mbed_official 525:c320967f86b9 64 static gpio_irq_handler irq_handler;
mbed_official 525:c320967f86b9 65 static void GPIOINT_IRQDispatcher(uint32_t iflags);
mbed_official 525:c320967f86b9 66
mbed_official 525:c320967f86b9 67 static void handle_interrupt_in(uint8_t pin)
mbed_official 525:c320967f86b9 68 {
mbed_official 525:c320967f86b9 69 // Return if pin not linked with an interrupt function
mbed_official 525:c320967f86b9 70 if (channel_ids[pin] == 0) {
mbed_official 525:c320967f86b9 71 return;
mbed_official 525:c320967f86b9 72 }
mbed_official 525:c320967f86b9 73
mbed_official 593:78ee8643776a 74 //we are storing two ports in each uint8, so we must aquire the one we want.
mbed_official 593:78ee8643776a 75 // If pin is odd, the port is encoded in the 4 most significant bits. If pin is even, the port is encoded in the 4 least significant bits
mbed_official 593:78ee8643776a 76 uint8_t isRise = GPIO_PinInGet((pin & 0x1) ? channel_ports[(pin>>1) & 0x7] >> 4 & 0xF : channel_ports[(pin>>1) & 0x7] & 0xF, pin);
mbed_official 525:c320967f86b9 77
mbed_official 525:c320967f86b9 78 // Get trigger event
mbed_official 525:c320967f86b9 79 gpio_irq_event event = IRQ_NONE;
mbed_official 525:c320967f86b9 80 if ((GPIO->EXTIFALL & (1 << pin)) && !isRise) {
mbed_official 525:c320967f86b9 81 event = IRQ_FALL;
mbed_official 525:c320967f86b9 82 } else if ((GPIO->EXTIRISE & (1 << pin)) && isRise) {
mbed_official 525:c320967f86b9 83 event = IRQ_RISE;
mbed_official 525:c320967f86b9 84 }
mbed_official 525:c320967f86b9 85 GPIO_IntClear(pin);
mbed_official 525:c320967f86b9 86 irq_handler(channel_ids[pin], event);
mbed_official 525:c320967f86b9 87 }
mbed_official 525:c320967f86b9 88
mbed_official 525:c320967f86b9 89 void gpio_irq_preinit(gpio_irq_t *obj, PinName pin)
mbed_official 525:c320967f86b9 90 {
mbed_official 525:c320967f86b9 91 MBED_ASSERT(pin != NC);
mbed_official 525:c320967f86b9 92
mbed_official 525:c320967f86b9 93 /* Pin and port index encoded in one uint32.
mbed_official 525:c320967f86b9 94 * The four least significant bits represent the pin number
mbed_official 525:c320967f86b9 95 * The remaining bits represent the port number */
mbed_official 593:78ee8643776a 96 obj->pin = pin;
mbed_official 525:c320967f86b9 97 obj->risingEdge = 0;
mbed_official 525:c320967f86b9 98 obj->fallingEdge = 0;
mbed_official 525:c320967f86b9 99 }
mbed_official 525:c320967f86b9 100
mbed_official 525:c320967f86b9 101 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
mbed_official 525:c320967f86b9 102 {
mbed_official 593:78ee8643776a 103 // Init pins
mbed_official 548:1abac31e188e 104 gpio_irq_preinit(obj, pin);
mbed_official 593:78ee8643776a 105 // Initialize GPIO interrupt dispatcher
mbed_official 525:c320967f86b9 106 NVIC_ClearPendingIRQ(GPIO_ODD_IRQn);
mbed_official 525:c320967f86b9 107 NVIC_EnableIRQ(GPIO_ODD_IRQn);
mbed_official 525:c320967f86b9 108 NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn);
mbed_official 525:c320967f86b9 109 NVIC_EnableIRQ(GPIO_EVEN_IRQn);
mbed_official 525:c320967f86b9 110
mbed_official 525:c320967f86b9 111 /* Relate pin to interrupt action id */
mbed_official 593:78ee8643776a 112 channel_ids[obj->pin & 0xF] = id;
mbed_official 593:78ee8643776a 113
mbed_official 593:78ee8643776a 114 // Relate the pin number to a port. If pin in is odd store in the 4 most significant bits, if pin is even store in the 4 least significant bits
mbed_official 593:78ee8643776a 115 channel_ports[(obj->pin >> 1) & 0x7] = (obj->pin & 0x1) ? (channel_ports[(obj->pin >> 1) & 0x7] & 0x0F) | (obj->pin & 0xF0) : (channel_ports[(obj->pin >> 1) & 0x7] & 0xF0) | ((obj->pin >> 4) & 0xF);
mbed_official 525:c320967f86b9 116 /* Save pointer to handler */
mbed_official 525:c320967f86b9 117 irq_handler = handler;
mbed_official 525:c320967f86b9 118
mbed_official 593:78ee8643776a 119 pin_mode(obj->pin, Input);
mbed_official 525:c320967f86b9 120 return 0;
mbed_official 525:c320967f86b9 121 }
mbed_official 525:c320967f86b9 122
mbed_official 525:c320967f86b9 123 void gpio_irq_free(gpio_irq_t *obj)
mbed_official 525:c320967f86b9 124 {
mbed_official 525:c320967f86b9 125 // Destructor
mbed_official 593:78ee8643776a 126 channel_ids[obj->pin & 0xF] = 0;
mbed_official 525:c320967f86b9 127 gpio_irq_disable(obj); // Disable interrupt channel
mbed_official 593:78ee8643776a 128 pin_mode(obj->pin, Disabled); // Disable input pin
mbed_official 525:c320967f86b9 129 }
mbed_official 525:c320967f86b9 130
mbed_official 525:c320967f86b9 131 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
mbed_official 525:c320967f86b9 132 {
mbed_official 525:c320967f86b9 133 switch (event) {
mbed_official 525:c320967f86b9 134 case (IRQ_RISE):
mbed_official 525:c320967f86b9 135 obj->risingEdge = enable;
mbed_official 525:c320967f86b9 136 break;
mbed_official 525:c320967f86b9 137 case (IRQ_FALL):
mbed_official 525:c320967f86b9 138 obj->fallingEdge = enable;
mbed_official 525:c320967f86b9 139 break;
mbed_official 525:c320967f86b9 140 case (IRQ_NONE):
mbed_official 525:c320967f86b9 141 break;
mbed_official 525:c320967f86b9 142 }
mbed_official 525:c320967f86b9 143
mbed_official 525:c320967f86b9 144 /* Disable, set config and enable */
mbed_official 525:c320967f86b9 145 gpio_irq_disable(obj);
mbed_official 548:1abac31e188e 146
mbed_official 525:c320967f86b9 147 bool was_disabled = false;
mbed_official 525:c320967f86b9 148 if(GPIO->IEN == 0) was_disabled = true;
mbed_official 548:1abac31e188e 149
mbed_official 593:78ee8643776a 150 GPIO_IntConfig((GPIO_Port_TypeDef)(obj->pin >> 4 & 0xF), obj->pin &0xF, obj->risingEdge, obj->fallingEdge, obj->risingEdge || obj->fallingEdge);
mbed_official 525:c320967f86b9 151 if ((GPIO->IEN != 0) && (obj->risingEdge || obj->fallingEdge) && was_disabled) {
mbed_official 548:1abac31e188e 152 blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE);
mbed_official 525:c320967f86b9 153 }
mbed_official 525:c320967f86b9 154 }
mbed_official 525:c320967f86b9 155
mbed_official 525:c320967f86b9 156 inline void gpio_irq_enable(gpio_irq_t *obj)
mbed_official 525:c320967f86b9 157 {
mbed_official 548:1abac31e188e 158 if(GPIO->IEN == 0) blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE);
mbed_official 593:78ee8643776a 159 GPIO_IntEnable(1 << obj->pin & 0xF); // pin mask for pins to enable
mbed_official 525:c320967f86b9 160 }
mbed_official 525:c320967f86b9 161
mbed_official 525:c320967f86b9 162 inline void gpio_irq_disable(gpio_irq_t *obj)
mbed_official 525:c320967f86b9 163 {
mbed_official 593:78ee8643776a 164 GPIO_IntDisable(1 << obj->pin & 0xF); // pin mask for pins to disable
mbed_official 525:c320967f86b9 165 if(GPIO->IEN == 0) unblockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE);
mbed_official 525:c320967f86b9 166 }
mbed_official 525:c320967f86b9 167
mbed_official 525:c320967f86b9 168 /***************************************************************************//**
mbed_official 525:c320967f86b9 169 * @brief
mbed_official 525:c320967f86b9 170 * Function calls users callback for registered pin interrupts.
mbed_official 525:c320967f86b9 171 *
mbed_official 525:c320967f86b9 172 * @details
mbed_official 525:c320967f86b9 173 * This function is called when GPIO interrupts are handled by the dispatcher.
mbed_official 525:c320967f86b9 174 * Function gets even or odd interrupt flags and calls user callback
mbed_official 525:c320967f86b9 175 * registered for that pin. Function iterates on flags starting from MSB.
mbed_official 525:c320967f86b9 176 *
mbed_official 525:c320967f86b9 177 * @param iflags
mbed_official 525:c320967f86b9 178 * Interrupt flags which shall be handled by the dispatcher.
mbed_official 525:c320967f86b9 179 *
mbed_official 525:c320967f86b9 180 ******************************************************************************/
mbed_official 525:c320967f86b9 181 static void GPIOINT_IRQDispatcher(uint32_t iflags)
mbed_official 525:c320967f86b9 182 {
mbed_official 548:1abac31e188e 183 uint32_t irqIdx;
mbed_official 525:c320967f86b9 184
mbed_official 548:1abac31e188e 185 /* check for all flags set in IF register */
mbed_official 548:1abac31e188e 186 while(iflags) {
mbed_official 548:1abac31e188e 187 irqIdx = GPIOINT_MASK2IDX(iflags);
mbed_official 525:c320967f86b9 188
mbed_official 593:78ee8643776a 189 /* clear flag */
mbed_official 548:1abac31e188e 190 iflags &= ~(1 << irqIdx);
mbed_official 525:c320967f86b9 191
mbed_official 548:1abac31e188e 192 /* call user callback */
mbed_official 548:1abac31e188e 193 handle_interrupt_in(irqIdx);
mbed_official 548:1abac31e188e 194 }
mbed_official 525:c320967f86b9 195 }
mbed_official 525:c320967f86b9 196
mbed_official 525:c320967f86b9 197 /***************************************************************************//**
mbed_official 525:c320967f86b9 198 * @brief
mbed_official 525:c320967f86b9 199 * GPIO EVEN interrupt handler. Interrupt handler clears all IF even flags and
mbed_official 525:c320967f86b9 200 * call the dispatcher passing the flags which triggered the interrupt.
mbed_official 525:c320967f86b9 201 *
mbed_official 525:c320967f86b9 202 ******************************************************************************/
mbed_official 525:c320967f86b9 203 void GPIO_EVEN_IRQHandler(void)
mbed_official 525:c320967f86b9 204 {
mbed_official 548:1abac31e188e 205 uint32_t iflags;
mbed_official 593:78ee8643776a 206 /* Get all even interrupts */
mbed_official 548:1abac31e188e 207 iflags = GPIO_IntGetEnabled() & 0x00005555;
mbed_official 525:c320967f86b9 208
mbed_official 593:78ee8643776a 209 /* Clean only even interrupts*/
mbed_official 593:78ee8643776a 210
mbed_official 548:1abac31e188e 211 GPIO_IntClear(iflags);
mbed_official 548:1abac31e188e 212 GPIOINT_IRQDispatcher(iflags);
mbed_official 525:c320967f86b9 213 }
mbed_official 525:c320967f86b9 214
mbed_official 525:c320967f86b9 215
mbed_official 525:c320967f86b9 216 /***************************************************************************//**
mbed_official 525:c320967f86b9 217 * @brief
mbed_official 525:c320967f86b9 218 * GPIO ODD interrupt handler. Interrupt handler clears all IF odd flags and
mbed_official 525:c320967f86b9 219 * call the dispatcher passing the flags which triggered the interrupt.
mbed_official 525:c320967f86b9 220 *
mbed_official 525:c320967f86b9 221 ******************************************************************************/
mbed_official 525:c320967f86b9 222 void GPIO_ODD_IRQHandler(void)
mbed_official 525:c320967f86b9 223 {
mbed_official 548:1abac31e188e 224 uint32_t iflags;
mbed_official 525:c320967f86b9 225
mbed_official 593:78ee8643776a 226 /* Get all odd interrupts */
mbed_official 548:1abac31e188e 227 iflags = GPIO_IntGetEnabled() & 0x0000AAAA;
mbed_official 525:c320967f86b9 228
mbed_official 593:78ee8643776a 229 /* Clean only even interrupts */
mbed_official 548:1abac31e188e 230 GPIO_IntClear(iflags);
mbed_official 548:1abac31e188e 231 GPIOINT_IRQDispatcher(iflags);
mbed_official 525:c320967f86b9 232 }
mbed_official 525:c320967f86b9 233
mbed_official 525:c320967f86b9 234 #endif