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:
Tue Apr 28 13:00:10 2015 +0100
Revision:
526:7c4bdfe6a168
Parent:
525:c320967f86b9
Child:
548:1abac31e188e
Synchronized with git revision cdff09e6b6c486eb58fb5e968f3191c8480b0567

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

Silabs - Fix unblock/block declaration, implement gpio_is_connected

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 525:c320967f86b9 1 /* mbed Microcontroller Library
mbed_official 525:c320967f86b9 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 525:c320967f86b9 3 *
mbed_official 525:c320967f86b9 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 525:c320967f86b9 5 * you may not use this file except in compliance with the License.
mbed_official 525:c320967f86b9 6 * You may obtain a copy of the License at
mbed_official 525:c320967f86b9 7 *
mbed_official 525:c320967f86b9 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 525:c320967f86b9 9 *
mbed_official 525:c320967f86b9 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 525:c320967f86b9 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 525:c320967f86b9 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 525:c320967f86b9 13 * See the License for the specific language governing permissions and
mbed_official 525:c320967f86b9 14 * limitations under the License.
mbed_official 525:c320967f86b9 15 */
mbed_official 525:c320967f86b9 16
mbed_official 525:c320967f86b9 17 #include "device.h"
mbed_official 525:c320967f86b9 18 #if DEVICE_INTERRUPTIN
mbed_official 525:c320967f86b9 19
mbed_official 525:c320967f86b9 20 #include "gpio_irq_api.h"
mbed_official 525:c320967f86b9 21 #include "mbed_assert.h"
mbed_official 525:c320967f86b9 22 #include "pinmap.h"
mbed_official 525:c320967f86b9 23
mbed_official 525:c320967f86b9 24 #include "em_gpio.h"
mbed_official 525:c320967f86b9 25 #include "em_int.h"
mbed_official 525:c320967f86b9 26 #include "em_cmu.h"
mbed_official 525:c320967f86b9 27 #include "sleep_api.h"
mbed_official 526:7c4bdfe6a168 28 #include "sleepmodes.h"
mbed_official 525:c320967f86b9 29
mbed_official 525:c320967f86b9 30 #define NUM_GPIO_CHANNELS (16)
mbed_official 525:c320967f86b9 31 #define GPIO_LEAST_ACTIVE_SLEEPMODE EM3
mbed_official 525:c320967f86b9 32
mbed_official 525:c320967f86b9 33 /* Macro return index of the LSB flag which is set. */
mbed_official 525:c320967f86b9 34 #if ((__CORTEX_M == 3) || (__CORTEX_M == 4))
mbed_official 525:c320967f86b9 35 #define GPIOINT_MASK2IDX(mask) (__CLZ(__RBIT(mask)))
mbed_official 525:c320967f86b9 36 #elif __CORTEX_M == 0
mbed_official 525:c320967f86b9 37 #define GPIOINT_MASK2IDX(mask) (countTrailingZeros(mask))
mbed_official 525:c320967f86b9 38 __STATIC_INLINE uint32_t countTrailingZeros(uint32_t mask)
mbed_official 525:c320967f86b9 39 {
mbed_official 525:c320967f86b9 40 uint32_t zeros;
mbed_official 525:c320967f86b9 41 for(zeros=0; (zeros<32) && (0 == (mask&0x1)); zeros++, mask>>=1);
mbed_official 525:c320967f86b9 42 return zeros;
mbed_official 525:c320967f86b9 43 }
mbed_official 525:c320967f86b9 44 #else
mbed_official 525:c320967f86b9 45 #error Unsupported architecture.
mbed_official 525:c320967f86b9 46 #endif
mbed_official 525:c320967f86b9 47
mbed_official 525:c320967f86b9 48 static uint32_t channel_ids[NUM_GPIO_CHANNELS] = { 0 }; // Relates pin number with interrupt action id
mbed_official 525:c320967f86b9 49 static uint32_t channel_ports[NUM_GPIO_CHANNELS] = { 0 };
mbed_official 525:c320967f86b9 50 static gpio_irq_handler irq_handler;
mbed_official 525:c320967f86b9 51 static void GPIOINT_IRQDispatcher(uint32_t iflags);
mbed_official 525:c320967f86b9 52
mbed_official 525:c320967f86b9 53 static void handle_interrupt_in(uint8_t pin)
mbed_official 525:c320967f86b9 54 {
mbed_official 525:c320967f86b9 55 // Return if pin not linked with an interrupt function
mbed_official 525:c320967f86b9 56 if (channel_ids[pin] == 0) {
mbed_official 525:c320967f86b9 57 return;
mbed_official 525:c320967f86b9 58 }
mbed_official 525:c320967f86b9 59
mbed_official 525:c320967f86b9 60 uint32_t isRise = GPIO_PinInGet(channel_ports[pin], pin);
mbed_official 525:c320967f86b9 61
mbed_official 525:c320967f86b9 62 // Get trigger event
mbed_official 525:c320967f86b9 63 gpio_irq_event event = IRQ_NONE;
mbed_official 525:c320967f86b9 64 if ((GPIO->EXTIFALL & (1 << pin)) && !isRise) {
mbed_official 525:c320967f86b9 65 event = IRQ_FALL;
mbed_official 525:c320967f86b9 66 } else if ((GPIO->EXTIRISE & (1 << pin)) && isRise) {
mbed_official 525:c320967f86b9 67 event = IRQ_RISE;
mbed_official 525:c320967f86b9 68 }
mbed_official 525:c320967f86b9 69 GPIO_IntClear(pin);
mbed_official 525:c320967f86b9 70 irq_handler(channel_ids[pin], event);
mbed_official 525:c320967f86b9 71 }
mbed_official 525:c320967f86b9 72
mbed_official 525:c320967f86b9 73 void gpio_irq_preinit(gpio_irq_t *obj, PinName pin)
mbed_official 525:c320967f86b9 74 {
mbed_official 525:c320967f86b9 75 MBED_ASSERT(pin != NC);
mbed_official 525:c320967f86b9 76
mbed_official 525:c320967f86b9 77 /* Pin and port index encoded in one uint32.
mbed_official 525:c320967f86b9 78 * The four least significant bits represent the pin number
mbed_official 525:c320967f86b9 79 * The remaining bits represent the port number */
mbed_official 525:c320967f86b9 80 obj->pin = pin & 0xF;
mbed_official 525:c320967f86b9 81 obj->port = pin >> 4;
mbed_official 525:c320967f86b9 82 obj->risingEdge = 0;
mbed_official 525:c320967f86b9 83 obj->fallingEdge = 0;
mbed_official 525:c320967f86b9 84 }
mbed_official 525:c320967f86b9 85
mbed_official 525:c320967f86b9 86 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
mbed_official 525:c320967f86b9 87 {
mbed_official 525:c320967f86b9 88 /* Init pins */
mbed_official 525:c320967f86b9 89 gpio_irq_preinit(obj, pin);
mbed_official 525:c320967f86b9 90 /* Initialize GPIO interrupt dispatcher */
mbed_official 525:c320967f86b9 91 NVIC_ClearPendingIRQ(GPIO_ODD_IRQn);
mbed_official 525:c320967f86b9 92 NVIC_EnableIRQ(GPIO_ODD_IRQn);
mbed_official 525:c320967f86b9 93 NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn);
mbed_official 525:c320967f86b9 94 NVIC_EnableIRQ(GPIO_EVEN_IRQn);
mbed_official 525:c320967f86b9 95
mbed_official 525:c320967f86b9 96 /* Relate pin to interrupt action id */
mbed_official 525:c320967f86b9 97 channel_ids[obj->pin] = id;
mbed_official 525:c320967f86b9 98 /* Relate the pin number to a port */
mbed_official 525:c320967f86b9 99 channel_ports[obj->pin] = obj->port;
mbed_official 525:c320967f86b9 100 /* Save pointer to handler */
mbed_official 525:c320967f86b9 101 irq_handler = handler;
mbed_official 525:c320967f86b9 102
mbed_official 525:c320967f86b9 103 pin_mode(obj->pin | (obj->port << 4), Input);
mbed_official 525:c320967f86b9 104
mbed_official 525:c320967f86b9 105 return 0;
mbed_official 525:c320967f86b9 106 }
mbed_official 525:c320967f86b9 107
mbed_official 525:c320967f86b9 108 void gpio_irq_free(gpio_irq_t *obj)
mbed_official 525:c320967f86b9 109 {
mbed_official 525:c320967f86b9 110 // Destructor
mbed_official 525:c320967f86b9 111 channel_ids[obj->pin] = 0;
mbed_official 525:c320967f86b9 112 gpio_irq_disable(obj); // Disable interrupt channel
mbed_official 525:c320967f86b9 113 pin_mode(obj->pin | (obj->port << 4), Disabled); // Disable input pin
mbed_official 525:c320967f86b9 114 }
mbed_official 525:c320967f86b9 115
mbed_official 525:c320967f86b9 116 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
mbed_official 525:c320967f86b9 117 {
mbed_official 525:c320967f86b9 118 switch (event) {
mbed_official 525:c320967f86b9 119 case (IRQ_RISE):
mbed_official 525:c320967f86b9 120 obj->risingEdge = enable;
mbed_official 525:c320967f86b9 121 break;
mbed_official 525:c320967f86b9 122 case (IRQ_FALL):
mbed_official 525:c320967f86b9 123 obj->fallingEdge = enable;
mbed_official 525:c320967f86b9 124 break;
mbed_official 525:c320967f86b9 125 case (IRQ_NONE):
mbed_official 525:c320967f86b9 126 break;
mbed_official 525:c320967f86b9 127 }
mbed_official 525:c320967f86b9 128
mbed_official 525:c320967f86b9 129 /* Disable, set config and enable */
mbed_official 525:c320967f86b9 130 gpio_irq_disable(obj);
mbed_official 525:c320967f86b9 131
mbed_official 525:c320967f86b9 132 bool was_disabled = false;
mbed_official 525:c320967f86b9 133 if(GPIO->IEN == 0) was_disabled = true;
mbed_official 525:c320967f86b9 134
mbed_official 525:c320967f86b9 135 GPIO_IntConfig(obj->port, obj->pin, obj->risingEdge, obj->fallingEdge, obj->risingEdge || obj->fallingEdge);
mbed_official 525:c320967f86b9 136 if ((GPIO->IEN != 0) && (obj->risingEdge || obj->fallingEdge) && was_disabled) {
mbed_official 525:c320967f86b9 137 blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE);
mbed_official 525:c320967f86b9 138 }
mbed_official 525:c320967f86b9 139 }
mbed_official 525:c320967f86b9 140
mbed_official 525:c320967f86b9 141 inline void gpio_irq_enable(gpio_irq_t *obj)
mbed_official 525:c320967f86b9 142 {
mbed_official 525:c320967f86b9 143 if(GPIO->IEN == 0) blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE);
mbed_official 525:c320967f86b9 144 GPIO_IntEnable(1 << obj->pin); // pin mask for pins to enable
mbed_official 525:c320967f86b9 145 }
mbed_official 525:c320967f86b9 146
mbed_official 525:c320967f86b9 147 inline void gpio_irq_disable(gpio_irq_t *obj)
mbed_official 525:c320967f86b9 148 {
mbed_official 525:c320967f86b9 149 GPIO_IntDisable(1 << obj->pin); // pin mask for pins to disable
mbed_official 525:c320967f86b9 150 if(GPIO->IEN == 0) unblockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE);
mbed_official 525:c320967f86b9 151 }
mbed_official 525:c320967f86b9 152
mbed_official 525:c320967f86b9 153 /***************************************************************************//**
mbed_official 525:c320967f86b9 154 * @brief
mbed_official 525:c320967f86b9 155 * Function calls users callback for registered pin interrupts.
mbed_official 525:c320967f86b9 156 *
mbed_official 525:c320967f86b9 157 * @details
mbed_official 525:c320967f86b9 158 * This function is called when GPIO interrupts are handled by the dispatcher.
mbed_official 525:c320967f86b9 159 * Function gets even or odd interrupt flags and calls user callback
mbed_official 525:c320967f86b9 160 * registered for that pin. Function iterates on flags starting from MSB.
mbed_official 525:c320967f86b9 161 *
mbed_official 525:c320967f86b9 162 * @param iflags
mbed_official 525:c320967f86b9 163 * Interrupt flags which shall be handled by the dispatcher.
mbed_official 525:c320967f86b9 164 *
mbed_official 525:c320967f86b9 165 ******************************************************************************/
mbed_official 525:c320967f86b9 166 static void GPIOINT_IRQDispatcher(uint32_t iflags)
mbed_official 525:c320967f86b9 167 {
mbed_official 525:c320967f86b9 168 uint32_t irqIdx;
mbed_official 525:c320967f86b9 169
mbed_official 525:c320967f86b9 170 /* check for all flags set in IF register */
mbed_official 525:c320967f86b9 171 while(iflags)
mbed_official 525:c320967f86b9 172 {
mbed_official 525:c320967f86b9 173 irqIdx = GPIOINT_MASK2IDX(iflags);
mbed_official 525:c320967f86b9 174
mbed_official 525:c320967f86b9 175 /* clear flag*/
mbed_official 525:c320967f86b9 176 iflags &= ~(1 << irqIdx);
mbed_official 525:c320967f86b9 177
mbed_official 525:c320967f86b9 178 /* call user callback */
mbed_official 525:c320967f86b9 179 handle_interrupt_in(irqIdx);
mbed_official 525:c320967f86b9 180 }
mbed_official 525:c320967f86b9 181 }
mbed_official 525:c320967f86b9 182
mbed_official 525:c320967f86b9 183 /***************************************************************************//**
mbed_official 525:c320967f86b9 184 * @brief
mbed_official 525:c320967f86b9 185 * GPIO EVEN interrupt handler. Interrupt handler clears all IF even flags and
mbed_official 525:c320967f86b9 186 * call the dispatcher passing the flags which triggered the interrupt.
mbed_official 525:c320967f86b9 187 *
mbed_official 525:c320967f86b9 188 ******************************************************************************/
mbed_official 525:c320967f86b9 189 void GPIO_EVEN_IRQHandler(void)
mbed_official 525:c320967f86b9 190 {
mbed_official 525:c320967f86b9 191 uint32_t iflags;
mbed_official 525:c320967f86b9 192
mbed_official 525:c320967f86b9 193 /* Get all even interrupts. */
mbed_official 525:c320967f86b9 194 iflags = GPIO_IntGetEnabled() & 0x00005555;
mbed_official 525:c320967f86b9 195
mbed_official 525:c320967f86b9 196 /* Clean only even interrupts. */
mbed_official 525:c320967f86b9 197 GPIO_IntClear(iflags);
mbed_official 525:c320967f86b9 198
mbed_official 525:c320967f86b9 199 GPIOINT_IRQDispatcher(iflags);
mbed_official 525:c320967f86b9 200 }
mbed_official 525:c320967f86b9 201
mbed_official 525:c320967f86b9 202
mbed_official 525:c320967f86b9 203 /***************************************************************************//**
mbed_official 525:c320967f86b9 204 * @brief
mbed_official 525:c320967f86b9 205 * GPIO ODD interrupt handler. Interrupt handler clears all IF odd flags and
mbed_official 525:c320967f86b9 206 * call the dispatcher passing the flags which triggered the interrupt.
mbed_official 525:c320967f86b9 207 *
mbed_official 525:c320967f86b9 208 ******************************************************************************/
mbed_official 525:c320967f86b9 209 void GPIO_ODD_IRQHandler(void)
mbed_official 525:c320967f86b9 210 {
mbed_official 525:c320967f86b9 211 uint32_t iflags;
mbed_official 525:c320967f86b9 212
mbed_official 525:c320967f86b9 213 /* Get all odd interrupts. */
mbed_official 525:c320967f86b9 214 iflags = GPIO_IntGetEnabled() & 0x0000AAAA;
mbed_official 525:c320967f86b9 215
mbed_official 525:c320967f86b9 216 /* Clean only even interrupts. */
mbed_official 525:c320967f86b9 217 GPIO_IntClear(iflags);
mbed_official 525:c320967f86b9 218
mbed_official 525:c320967f86b9 219 GPIOINT_IRQDispatcher(iflags);
mbed_official 525:c320967f86b9 220 }
mbed_official 525:c320967f86b9 221
mbed_official 525:c320967f86b9 222 #endif