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   GPIOINT_IrqCallbackPtr_t callback;
00138 
00139   /* check for all flags set in IF register */
00140   while(iflags)
00141   {
00142     irqIdx = GPIOINT_MASK2IDX(iflags);
00143 
00144     /* clear flag*/
00145     iflags &= ~(1 << irqIdx);
00146 
00147     callback = gpioCallbacks[irqIdx];
00148     if (callback)
00149     {
00150       /* call user callback */
00151       callback(irqIdx);
00152     }
00153   }
00154 }
00155 
00156 /***************************************************************************/
00162 void GPIO_EVEN_IRQHandler(void)
00163 {
00164   uint32_t iflags;
00165 
00166   /* Get all even interrupts. */
00167   iflags = GPIO_IntGetEnabled() & 0x00005555;
00168 
00169   /* Clean only even interrupts. */
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   /* Get all odd interrupts. */
00187   iflags = GPIO_IntGetEnabled() & 0x0000AAAA;
00188 
00189   /* Clean only even interrupts. */
00190   GPIO_IntClear(iflags);
00191 
00192   GPIOINT_IRQDispatcher(iflags);
00193 }
00194 
00201 /******** THE REST OF THE FILE IS DOCUMENTATION ONLY !**********************/