Watchdog Timer

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Fri Sep 25 14:15:10 2015 +0100
Revision:
628:4fa1328d9c60
Parent:
594: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 628:4fa1328d9c60 1 /***************************************************************************//**
mbed_official 628:4fa1328d9c60 2 * @file gpio_irq_api.h
mbed_official 628:4fa1328d9c60 3 *******************************************************************************
mbed_official 628:4fa1328d9c60 4 * @section License
mbed_official 628:4fa1328d9c60 5 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
mbed_official 628:4fa1328d9c60 6 *******************************************************************************
mbed_official 525:c320967f86b9 7 *
mbed_official 628:4fa1328d9c60 8 * Permission is granted to anyone to use this software for any purpose,
mbed_official 628:4fa1328d9c60 9 * including commercial applications, and to alter it and redistribute it
mbed_official 628:4fa1328d9c60 10 * freely, subject to the following restrictions:
mbed_official 525:c320967f86b9 11 *
mbed_official 628:4fa1328d9c60 12 * 1. The origin of this software must not be misrepresented; you must not
mbed_official 628:4fa1328d9c60 13 * claim that you wrote the original software.
mbed_official 628:4fa1328d9c60 14 * 2. Altered source versions must be plainly marked as such, and must not be
mbed_official 628:4fa1328d9c60 15 * misrepresented as being the original software.
mbed_official 628:4fa1328d9c60 16 * 3. This notice may not be removed or altered from any source distribution.
mbed_official 525:c320967f86b9 17 *
mbed_official 628:4fa1328d9c60 18 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
mbed_official 628:4fa1328d9c60 19 * obligation to support this Software. Silicon Labs is providing the
mbed_official 628:4fa1328d9c60 20 * Software "AS IS", with no express or implied warranties of any kind,
mbed_official 628:4fa1328d9c60 21 * including, but not limited to, any implied warranties of merchantability
mbed_official 628:4fa1328d9c60 22 * or fitness for any particular purpose or warranties against infringement
mbed_official 628:4fa1328d9c60 23 * of any proprietary rights of a third party.
mbed_official 628:4fa1328d9c60 24 *
mbed_official 628:4fa1328d9c60 25 * Silicon Labs will not be liable for any consequential, incidental, or
mbed_official 628:4fa1328d9c60 26 * special damages, or any other relief, or for any claim by any third party,
mbed_official 628:4fa1328d9c60 27 * arising from your use of this Software.
mbed_official 628:4fa1328d9c60 28 *
mbed_official 628: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 594: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 594:78ee8643776a 74 //we are storing two ports in each uint8, so we must aquire the one we want.
mbed_official 594: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 594: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 594: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 594:78ee8643776a 103 // Init pins
mbed_official 548:1abac31e188e 104 gpio_irq_preinit(obj, pin);
mbed_official 594: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 594:78ee8643776a 112 channel_ids[obj->pin & 0xF] = id;
mbed_official 594:78ee8643776a 113
mbed_official 594: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 594: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 594: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 594:78ee8643776a 126 channel_ids[obj->pin & 0xF] = 0;
mbed_official 525:c320967f86b9 127 gpio_irq_disable(obj); // Disable interrupt channel
mbed_official 594: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 594: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 594: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 594: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 594: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 594:78ee8643776a 206 /* Get all even interrupts */
mbed_official 548:1abac31e188e 207 iflags = GPIO_IntGetEnabled() & 0x00005555;
mbed_official 525:c320967f86b9 208
mbed_official 594:78ee8643776a 209 /* Clean only even interrupts*/
mbed_official 594: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 594:78ee8643776a 226 /* Get all odd interrupts */
mbed_official 548:1abac31e188e 227 iflags = GPIO_IntGetEnabled() & 0x0000AAAA;
mbed_official 525:c320967f86b9 228
mbed_official 594: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