gpiointerrupt.c

Go to the documentation of this file.
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