00001 /***************************************************************************/ 00036 #include "em_gpio.h" 00037 #include "em_int.h" 00038 #include "gpiointerrupt.h" 00039 #include "em_assert.h" 00040 00041 /***************************************************************************/ 00046 /***************************************************************************/ 00066 /******************************************************************************* 00067 ******************************** MACROS *********************************** 00068 ******************************************************************************/ 00069 00072 /* Macro return index of the LSB flag which is set. */ 00073 #define GPIOINT_MASK2IDX(mask) (__CLZ(__RBIT(mask))) 00074 00077 /******************************************************************************* 00078 ******************************* STRUCTS *********************************** 00079 ******************************************************************************/ 00080 00083 typedef struct 00084 { 00085 /* Pin number in range of 0 to 15 */ 00086 uint32_t pin; 00087 00088 /* Pointer to the callback function */ 00089 GPIOINT_IrqCallbackPtr_t callback; 00090 00091 } GPIOINT_CallbackDesc_t; 00092 00093 00094 /******************************************************************************* 00095 ******************************** GLOBALS ********************************** 00096 ******************************************************************************/ 00097 00098 /* Array of user callbacks. One for each pin. */ 00099 static GPIOINT_IrqCallbackPtr_t gpioCallbacks[16] = {0}; 00100 00101 /******************************************************************************* 00102 ****************************** PROTOTYPES ********************************* 00103 ******************************************************************************/ 00104 static void GPIOINT_IRQDispatcher(uint32_t iflags); 00105 00108 /******************************************************************************* 00109 *************************** GLOBAL FUNCTIONS ****************************** 00110 ******************************************************************************/ 00111 00112 /***************************************************************************/ 00117 void GPIOINT_Init(void) 00118 { 00119 NVIC_ClearPendingIRQ(GPIO_ODD_IRQn); 00120 NVIC_EnableIRQ(GPIO_ODD_IRQn); 00121 NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn); 00122 NVIC_EnableIRQ(GPIO_EVEN_IRQn); 00123 } 00124 00125 00126 /***************************************************************************/ 00141 void GPIOINT_CallbackRegister(uint8_t pin, GPIOINT_IrqCallbackPtr_t callbackPtr) 00142 { 00143 INT_Disable(); 00144 00145 /* Dispatcher is used */ 00146 gpioCallbacks[pin] = callbackPtr; 00147 00148 INT_Enable(); 00149 } 00150 00153 /***************************************************************************/ 00166 static void GPIOINT_IRQDispatcher(uint32_t iflags) 00167 { 00168 uint32_t irqIdx; 00169 00170 /* check for all flags set in IF register */ 00171 while(iflags) 00172 { 00173 irqIdx = GPIOINT_MASK2IDX(iflags); 00174 00175 /* clear flag*/ 00176 iflags &= ~(1 << irqIdx); 00177 00178 if (gpioCallbacks[irqIdx]) 00179 { 00180 /* call user callback */ 00181 gpioCallbacks[irqIdx](irqIdx); 00182 } 00183 } 00184 } 00185 00186 /***************************************************************************/ 00192 void GPIO_EVEN_IRQHandler(void) 00193 { 00194 uint32_t iflags; 00195 00196 /* Get all even interrupts. */ 00197 iflags = GPIO_IntGetEnabled() & 0x00005555; 00198 00199 /* Clean only even interrupts. */ 00200 GPIO_IntClear(iflags); 00201 00202 GPIOINT_IRQDispatcher(iflags); 00203 } 00204 00205 00206 /***************************************************************************/ 00212 void GPIO_ODD_IRQHandler(void) 00213 { 00214 uint32_t iflags; 00215 00216 /* Get all odd interrupts. */ 00217 iflags = GPIO_IntGetEnabled() & 0x0000AAAA; 00218 00219 /* Clean only even interrupts. */ 00220 GPIO_IntClear(iflags); 00221 00222 GPIOINT_IRQDispatcher(iflags); 00223 } 00224