Gpio_Rval_e Gpio_EnableIrq(const Gpio_adt * const port_ptr, const Gpio_IrqEdge_e edge) { Gpio_Rval_e gpioRet = GPIO_RVAL_Fail; //Return value of the function is updated to this variable uint32_t dirRegVal = 0; //The direction register is read here to check if the pin is configured as input uint32_t intMaskRegVal = 0; // Read and update the Interrupt Mask register gpioRet = ValidateGpioPtr(port_ptr); // DEFERRED Gpio_EnableIrq is require port & pin validation if(gpioRet == GPIO_RVAL_Success) { if (( edge == GPIO_IRQEDGE_Fall ) || ( edge == GPIO_IRQEDGE_Rise )) //GPIO_IRQEDGE_Fall = 11 GPIO_IRQEDGE_Rise = 10 { dirRegVal = GpioReg_g[port_ptr->port]->dir; // Check whether the requested pin is configured as Input if (!( dirRegVal & (uint32_t)( GPIO_SHIFT_DATA << port_ptr->pin ))) //GPIO_SHIFT_DATA = 1 { EnableIrq(port_ptr,edge); //! Interrupt Mask register value is getting modified. So lock is required. Lock(); //!Read the interrupt mask register intMaskRegVal = GpioReg_g[port_ptr->port]->imr; //!Update the interrupt mask register intMaskRegVal |= (uint32_t)(1 << port_ptr->pin); //!Set the Mask bit for the pin and port number passed GpioReg_g[port_ptr->port]->imr = intMaskRegVal; //!Set the Global flag for the interrupt enable bit GpioIrqEnableDone_g[port_ptr->port][port_ptr->pin] = GPIO_DATA_HIGH ; // GPIO_DATA_HIGH =1 Unlock(); gpioRet = Success; } else { gpioRet = NotConfigedAsInPin; } //end of pin configuration check for interrupt } else { gpioRet = InvalidEdge; } // end for edge check } return gpioRet; } static void EnableIrq(const Gpio_adt* const gpio_ptr,const Gpio_IrqEdge_e edge) { uint32_t *icr = NULL; uint32_t shift = 0; uint32_t icrVal = 0; // ICR for bits 0 thru 15 are on ICR1, rest are on ICR2 // 2 bits in ICR used per pin GPIOHW_PIN15 = 15 icr = (gpio_ptr->pin <= GPIOHW_PIN15)? (uint32_t *)&GpioReg_g[gpio_ptr->port]->icr1 : (uint32_t *)&GpioReg_g[gpio_ptr->port]->icr2; //!For pins less than 16 the interrupt //!configuration is to be done in ICR1 else in ICR2 //!Every pin configuration requires 2 bits in the //!The pin number greater than 15 and //!upto 31 has to be done in ICR2 and bit //!calculation is done by subtracting //!pin number with 16 .This is for pin 16 to 31 shift = (gpio_ptr->pin <= GPIOHW_PIN15)? gpio_ptr->pin*2:((gpio_ptr->pin - GPIOPIN_CALC )*2); // Interrupt Configuration register value is getting modified. So lock is required. Lock(); //Mutex lock icrVal = *icr; // Read the current ICR value icrVal &= (uint32_t)(0x00 << shift); // Clear out the bits of interrupt icrVal |= (uint32_t)(edge << shift); // Set the new ICR mode *icr |= icrVal; // Write back new value Unlock(); //Mutex unlock } const struct sigevent * Inthndler_ptr(void *gpio_ptr,int size) { uint32_t isrVal = 0; //!Get the interrupt info passed while attaching the interrupt //!to the interrupt handler GpioIntrInp_s *adtInfo_ptr = gpio_ptr; //! Read the interrupt status for the pin and check for the //! interrupt if it had occurred for the gpio pin of the port //! Clear the interrupt by writing 1 to the bit position Lock(); //!Read the status register isrVal= GpioReg_g[adtInfo_ptr->gpioData.port]->isr; IsrVal = isrVal; //!Check if the interrupt is set or not for the pin if( isrVal&(uint32_t)(1<gpioData.pin) ) { //!Clear the interrupt by clearing the status bit by writting 1 isrVal |= ((uint32_t)(1<gpioData.pin)); //!Update to the register back GpioReg_g[adtInfo_ptr->gpioData.port]->isr = isrVal; //!Call the call back function passed during the attach (adtInfo_ptr->func)(&adtInfo_ptr->gpioData); } Unlock(); return NULL; } Gpio_Rval_e Gpio_AttachIrq(const Gpio_adt * const port_ptr, Gpio_CbFnPtr cbfn_ptr) { Gpio_Rval_e gpioRet = GPIO_RVAL_Fail; uint8_t arrIndex = 0; uint16_t intrLinNo = 0; struct sigevent intrEvent = {0};//Interrupt event created for initialization using the SIGEV_INTR_INIT gpioRet = ValidateGpioPtr(port_ptr); if ( gpioRet == GPIO_RVAL_Success ) { //Check if the interrupt line is enabled or not if ( GpioIrqEnableDone_g[port_ptr->port][port_ptr->pin] != INITIAL_VALUE) { //!INIT the SIG EVENT SIGEV_INTR_INIT(&intrEvent); Lock(); //! Get the array index to select in the initial interrupt line number for a port //! The arrIndex obtained will be added with the pin number to get the actual //! interrupt number arrIndex = (port_ptr->pin <= GPIOHW_PIN15)? GPIO_INTR_ARR_IDX1 : GPIO_INTR_ARR_IDX2; //!Assign the call back function which will be call when interrupt occurs //!Assign the gpio port data which for its usage in the interrupt handler GpioIntrDat_g[port_ptr->port][port_ptr->pin].func = cbfn_ptr; GpioIntrDat_g[port_ptr->port][port_ptr->pin].gpioData = *port_ptr; //! Calculation of the interrupt line number //! Line number for pin number less than 16 else line number for pins greater than 15 //! for pins greater than 15 the pin number is subtracted with 16 to get the value which is //! added with the line number got from GpioIntLine_g intrLinNo = ( port_ptr->pin <= GPIOHW_PIN15 )? (GpioIntLine_g[port_ptr->port][arrIndex])+port_ptr->pin: (GpioIntLine_g[port_ptr->port][arrIndex])+(port_ptr->pin - GPIOPIN_CALC ); //! Attach the interrupt line for the port and pin GpioInterruptID_g[port_ptr->port][port_ptr->pin] = InterruptAttach (intrLinNo,Inthndler_ptr,(const void*)&GpioIntrDat_g[port_ptr->port][port_ptr->pin], 0,_NTO_INTR_CLASS_EXTERNAL); Unlock(); if(GpioInterruptID_g[port_ptr->port][port_ptr->pin] != -1 ) { //!Set the return value to Success gpioRet = Success; }else { //!Set the return to failure if interrupt attach function fails gpioRet = IntrAttachFailure; } }else { gpioRet = IrqEnableNotDone; } //end of IrqEnable check } return gpioRet; }