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  ********************************   MACROS   ***********************************
00024  ******************************************************************************/
00025 
00028 /* Macro return index of the LSB flag which is set. */
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  *******************************   STRUCTS   ***********************************
00047  ******************************************************************************/
00048 
00051 typedef struct
00052 {
00053   /* Pin number in range of 0 to 15 */
00054   uint32_t pin;
00055 
00056   /* Pointer to the callback function */
00057   GPIOINT_IrqCallbackPtr_t callback;
00058 
00059 } GPIOINT_CallbackDesc_t;
00060 
00061 
00062 /*******************************************************************************
00063  ********************************   GLOBALS   **********************************
00064  ******************************************************************************/
00065 
00066 /* Array of user callbacks. One for each pin. */
00067 static GPIOINT_IrqCallbackPtr_t gpioCallbacks[16] = {0};
00068 
00069 /*******************************************************************************
00070  ******************************   PROTOTYPES   *********************************
00071  ******************************************************************************/
00072 static void GPIOINT_IRQDispatcher(uint32_t iflags);
00073 
00076 /*******************************************************************************
00077  ***************************   GLOBAL FUNCTIONS   ******************************
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   /* Dispatcher is used */
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   /* check for all flags set in IF register */
00139   while(iflags)
00140   {
00141     irqIdx = GPIOINT_MASK2IDX(iflags);
00142 
00143     /* clear flag*/
00144     iflags &= ~(1 << irqIdx);
00145 
00146     if (gpioCallbacks[irqIdx])
00147     {
00148       /* call user callback */
00149       gpioCallbacks[irqIdx](irqIdx);
00150     }
00151   }
00152 }
00153 
00154 /***************************************************************************/
00160 void GPIO_EVEN_IRQHandler(void)
00161 {
00162   uint32_t iflags;
00163 
00164   /* Get all even interrupts. */
00165   iflags = GPIO_IntGetEnabled() & 0x00005555;
00166 
00167   /* Clean only even interrupts. */
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   /* Get all odd interrupts. */
00185   iflags = GPIO_IntGetEnabled() & 0x0000AAAA;
00186 
00187   /* Clean only even interrupts. */
00188   GPIO_IntClear(iflags);
00189 
00190   GPIOINT_IRQDispatcher(iflags);
00191 }
00192 
00199 /******** THE REST OF THE FILE IS DOCUMENTATION ONLY !**********************/