[11U68]fix P0_11 to use GPIO

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Fri May 22 10:45:46 2015 +0100
Revision:
548:1abac31e188e
Parent:
526:7c4bdfe6a168
Synchronized with git revision 88d158e43b54f97c5e94da305ea9a096889cc81b

Full URL: https://github.com/mbedmicro/mbed/commit/88d158e43b54f97c5e94da305ea9a096889cc81b/

Silicon Labs - Cosmetic: apply mbed coding style to HAL

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 548:1abac31e188e 40 uint32_t zeros;
mbed_official 548:1abac31e188e 41 for(zeros=0; (zeros<32) && (0 == (mask&0x1)); zeros++, mask>>=1);
mbed_official 548:1abac31e188e 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 548:1abac31e188e 88 /* Init pins */
mbed_official 548:1abac31e188e 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 548:1abac31e188e 131
mbed_official 525:c320967f86b9 132 bool was_disabled = false;
mbed_official 525:c320967f86b9 133 if(GPIO->IEN == 0) was_disabled = true;
mbed_official 548:1abac31e188e 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 548:1abac31e188e 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 548:1abac31e188e 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 548:1abac31e188e 168 uint32_t irqIdx;
mbed_official 525:c320967f86b9 169
mbed_official 548:1abac31e188e 170 /* check for all flags set in IF register */
mbed_official 548:1abac31e188e 171 while(iflags) {
mbed_official 548:1abac31e188e 172 irqIdx = GPIOINT_MASK2IDX(iflags);
mbed_official 525:c320967f86b9 173
mbed_official 548:1abac31e188e 174 /* clear flag*/
mbed_official 548:1abac31e188e 175 iflags &= ~(1 << irqIdx);
mbed_official 525:c320967f86b9 176
mbed_official 548:1abac31e188e 177 /* call user callback */
mbed_official 548:1abac31e188e 178 handle_interrupt_in(irqIdx);
mbed_official 548:1abac31e188e 179 }
mbed_official 525:c320967f86b9 180 }
mbed_official 525:c320967f86b9 181
mbed_official 525:c320967f86b9 182 /***************************************************************************//**
mbed_official 525:c320967f86b9 183 * @brief
mbed_official 525:c320967f86b9 184 * GPIO EVEN interrupt handler. Interrupt handler clears all IF even flags and
mbed_official 525:c320967f86b9 185 * call the dispatcher passing the flags which triggered the interrupt.
mbed_official 525:c320967f86b9 186 *
mbed_official 525:c320967f86b9 187 ******************************************************************************/
mbed_official 525:c320967f86b9 188 void GPIO_EVEN_IRQHandler(void)
mbed_official 525:c320967f86b9 189 {
mbed_official 548:1abac31e188e 190 uint32_t iflags;
mbed_official 525:c320967f86b9 191
mbed_official 548:1abac31e188e 192 /* Get all even interrupts. */
mbed_official 548:1abac31e188e 193 iflags = GPIO_IntGetEnabled() & 0x00005555;
mbed_official 525:c320967f86b9 194
mbed_official 548:1abac31e188e 195 /* Clean only even interrupts. */
mbed_official 548:1abac31e188e 196 GPIO_IntClear(iflags);
mbed_official 525:c320967f86b9 197
mbed_official 548:1abac31e188e 198 GPIOINT_IRQDispatcher(iflags);
mbed_official 525:c320967f86b9 199 }
mbed_official 525:c320967f86b9 200
mbed_official 525:c320967f86b9 201
mbed_official 525:c320967f86b9 202 /***************************************************************************//**
mbed_official 525:c320967f86b9 203 * @brief
mbed_official 525:c320967f86b9 204 * GPIO ODD interrupt handler. Interrupt handler clears all IF odd flags and
mbed_official 525:c320967f86b9 205 * call the dispatcher passing the flags which triggered the interrupt.
mbed_official 525:c320967f86b9 206 *
mbed_official 525:c320967f86b9 207 ******************************************************************************/
mbed_official 525:c320967f86b9 208 void GPIO_ODD_IRQHandler(void)
mbed_official 525:c320967f86b9 209 {
mbed_official 548:1abac31e188e 210 uint32_t iflags;
mbed_official 525:c320967f86b9 211
mbed_official 548:1abac31e188e 212 /* Get all odd interrupts. */
mbed_official 548:1abac31e188e 213 iflags = GPIO_IntGetEnabled() & 0x0000AAAA;
mbed_official 525:c320967f86b9 214
mbed_official 548:1abac31e188e 215 /* Clean only even interrupts. */
mbed_official 548:1abac31e188e 216 GPIO_IntClear(iflags);
mbed_official 525:c320967f86b9 217
mbed_official 548:1abac31e188e 218 GPIOINT_IRQDispatcher(iflags);
mbed_official 525:c320967f86b9 219 }
mbed_official 525:c320967f86b9 220
mbed_official 525:c320967f86b9 221 #endif