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
00138
00139 while(iflags)
00140 {
00141 irqIdx = GPIOINT_MASK2IDX(iflags);
00142
00143
00144 iflags &= ~(1 << irqIdx);
00145
00146 if (gpioCallbacks[irqIdx])
00147 {
00148
00149 gpioCallbacks[irqIdx](irqIdx);
00150 }
00151 }
00152 }
00153
00154
00160 void GPIO_EVEN_IRQHandler(void)
00161 {
00162 uint32_t iflags;
00163
00164
00165 iflags = GPIO_IntGetEnabled() & 0x00005555;
00166
00167
00168 GPIO_IntClear(iflags);
00169
00170 GPIOINT_IRQDispatcher(iflags);
00171 }
00172
00173
00174
00180 void GPIO_ODD_IRQHandler(void)
00181 {
00182 uint32_t iflags;
00183
00184
00185 iflags = GPIO_IntGetEnabled() & 0x0000AAAA;
00186
00187
00188 GPIO_IntClear(iflags);
00189
00190 GPIOINT_IRQDispatcher(iflags);
00191 }
00192
00199