gpiointerrupt.c
Go to the documentation of this file.00001
00017 #include "em_gpio.h"
00018 #include "em_int.h"
00019 #include "gpiointerrupt.h"
00020 #include "em_assert.h"
00021
00022
00023
00024
00025
00028
00029 #if ((__CORTEX_M == 3) || (__CORTEX_M == 4))
00030 #define GPIOINT_MASK2IDX(mask) (__CLZ(__RBIT(mask)))
00031 #elif __CORTEX_M == 0
00032 #define GPIOINT_MASK2IDX(mask) (countTrailingZeros(mask))
00033 __STATIC_INLINE uint32_t countTrailingZeros(uint32_t mask)
00034 {
00035 uint32_t zeros;
00036 for(zeros=0; (zeros<32) && (0 == (mask&0x1)); zeros++, mask>>=1);
00037 return zeros;
00038 }
00039 #else
00040 #error Unsupported architecture.
00041 #endif
00042
00045
00046
00047
00048
00051 typedef struct
00052 {
00053
00054 uint32_t pin;
00055
00056
00057 GPIOINT_IrqCallbackPtr_t callback;
00058
00059 } GPIOINT_CallbackDesc_t;
00060
00061
00062
00063
00064
00065
00066
00067 static GPIOINT_IrqCallbackPtr_t gpioCallbacks[16] = {0};
00068
00069
00070
00071
00072 static void GPIOINT_IRQDispatcher(uint32_t iflags);
00073
00076
00077
00078
00079
00080
00085 void GPIOINT_Init(void)
00086 {
00087 NVIC_ClearPendingIRQ(GPIO_ODD_IRQn);
00088 NVIC_EnableIRQ(GPIO_ODD_IRQn);
00089 NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn);
00090 NVIC_EnableIRQ(GPIO_EVEN_IRQn);
00091 }
00092
00093
00094
00109 void GPIOINT_CallbackRegister(uint8_t pin, GPIOINT_IrqCallbackPtr_t callbackPtr)
00110 {
00111 INT_Disable();
00112
00113
00114 gpioCallbacks[pin] = callbackPtr;
00115
00116 INT_Enable();
00117 }
00118
00121
00134 static void GPIOINT_IRQDispatcher(uint32_t iflags)
00135 {
00136 uint32_t irqIdx;
00137 GPIOINT_IrqCallbackPtr_t callback;
00138
00139
00140 while(iflags)
00141 {
00142 irqIdx = GPIOINT_MASK2IDX(iflags);
00143
00144
00145 iflags &= ~(1 << irqIdx);
00146
00147 callback = gpioCallbacks[irqIdx];
00148 if (callback)
00149 {
00150
00151 callback(irqIdx);
00152 }
00153 }
00154 }
00155
00156
00162 void GPIO_EVEN_IRQHandler(void)
00163 {
00164 uint32_t iflags;
00165
00166
00167 iflags = GPIO_IntGetEnabled() & 0x00005555;
00168
00169
00170 GPIO_IntClear(iflags);
00171
00172 GPIOINT_IRQDispatcher(iflags);
00173 }
00174
00175
00176
00182 void GPIO_ODD_IRQHandler(void)
00183 {
00184 uint32_t iflags;
00185
00186
00187 iflags = GPIO_IntGetEnabled() & 0x0000AAAA;
00188
00189
00190 GPIO_IntClear(iflags);
00191
00192 GPIOINT_IRQDispatcher(iflags);
00193 }
00194
00201