/************************************************************************************************** * @fn macMcuRfIsr * * @brief Interrupt service routine that handles all RF interrupts. There are a number * of conditions "ganged" onto this one ISR so each condition must be tested for. * * @param none * * @return none ************************************************************************************************** */ HAL_ISR_FUNCTION( macMcuRfIsr, RF_VECTOR ) { uint8 rfim; HAL_ENTER_ISR(); rfim = RFIRQM1; /* The CPU level RF interrupt flag must be cleared here (before clearing RFIRQFx). * to allow the interrupts to be nested. */ S1CON = 0x00; if ((RFIRQF1 & IRQ_CSP_MANINT) & rfim) { /* * Important! Because of how the CSP programs are written, CSP_INT interrupts should * be processed before CSP_STOP interrupts. This becomes an issue when there are * long critical sections. */ /* clear flag */ RFIRQF1 = ~IRQ_CSP_MANINT; macCspTxIntIsr(); } else if ((RFIRQF1 & IRQ_CSP_STOP) & rfim) { /* clear flag */ RFIRQF1 = ~IRQ_CSP_STOP; macCspTxStopIsr(); } else if ((RFIRQF1 & IRQ_TXACKDONE) & rfim) { /* disable interrupt - set up is for "one shot" operation */ RFIRQM1 &= ~IM_TXACKDONE; macRxAckTxDoneCallback(); } rfim = RFIRQM0; /* process RFIRQF0 next */ if ((RFIRQF0 & IRQ_FIFOP) & rfim) { /* continue to execute interrup t handler as long as FIFOP is active */ do { macRxThresholdIsr(); RFIRQF0 = ~IRQ_FIFOP; } while (FSMSTAT1 & FIFOP); } CLEAR_SLEEP_MODE(); HAL_EXIT_ISR(); }
/************************************************************************************************** * @fn halMacIoPortIsr * * @brief Radio interrupt service routine. * * @param none * * @return none ************************************************************************************************** */ HAL_ISR_FUNCTION( halMacFifopIsr, FIFOP_VECTOR() ) { uint8 pxie, excflag0; /* * Copy interrupt enable register. Used to avoid compiler warning regarding * undefined order of volatile acesses. */ pxie = PXIE; /* currently FIFO, FIFOP, and TX_ACK_DONE are the only signals that cause an interrupt on this port */ MAC_ASSERT(pxie & PXIFG & (BV(HAL_MAC_FIFOP_GPIO_BIT) | BV(HAL_MAC_TX_ACK_DONE_GPIO_BIT) | BV(HAL_MAC_FIFO_GPIO_BIT))); /* unrecognized interrupt */ /* * Test all bits in port that are used as interrupts. If the enable flag is set and * the interrupt pending flag is set, call the corresponding ISR. * * Note: the MSP430 requires that the software clear the interrupt pending flag. * This logic design of the ISR's themselves handles this. */ /* TX_ACK_DONE interrupt - processes TX_ACK_DONE before FIFOP when interrupts are simultaneous */ if (pxie & PXIFG & BV(HAL_MAC_TX_ACK_DONE_GPIO_BIT)) { excflag0 = macSpiReadReg(EXCFLAG0); /* Determine what caused the GPIO to go high */ if (MAC_RADIO_TX_ACK_AND_TX_FRM_DONE_EXCEPTION(excflag0)) { macDualchipTxAckDoneIsr(); macDualchipTxFrmDoneIsr(); MAC_RADIO_CLEAR_TX_ACK_AND_TX_FRM_DONE_PIN(); } else { if (MAC_RADIO_TX_ACK_DONE_EXCEPTION(excflag0)) { macDualchipTxAckDoneIsr(); MAC_RADIO_CLEAR_TX_ACK_DONE_PIN(); } else if (MAC_RADIO_TX_FRM_DONE_EXCEPTION(excflag0)) { macDualchipTxFrmDoneIsr(); MAC_RADIO_CLEAR_TX_FRM_DONE_PIN(); } } if ( !HAL_MAC_READ_TX_ACK_DONE_PIN() ) { /* Clear the flag only when the pin is phisically low */ HAL_MAC_CLEAR_TX_ACK_DONE_INT_FLAG(); } } /* * TX interrupt is very time consuming and it may trigger more transmissions. * Don't let RX run until all TXs are completed. */ else if (pxie & PXIFG & BV(HAL_MAC_FIFOP_GPIO_BIT)) /* FIFOP interrupt */ { /* To get here: FIFOP = 1, FIFO = X * See CC2520 Errata Note Bug 2, Glitches on the FIFOP Signal. */ if (!HAL_MAC_READ_FIFOP_PIN() && HAL_MAC_READ_FIFO_PIN()) { /* To get here: FIFOP = 0, FIFO = 1 * It appears that after rxPayloadIsr(), a FIFOP glitch can occur. If * this is happening, the FIFOP interrupt flag should not be cleared. * Instead, do nothing so that the FIFOP interrupt can be triggered * again when the RX FIFO threshold is reached. FIFOP pin should stay * high for the real FOFOP interrupt. */ if (!macRxActive) { /* If the FIFOP glitch occurs before RX is active, go ahead and * clear the FIFOP interrupt flag as if the glitch has never happened. */ HAL_MAC_CLEAR_FIFOP_INT_FLAG(); } } else if (HAL_MAC_READ_FIFOP_PIN()) { /* To get here: FIFOP = 1, FIFO = X */ do { /* Clear the FIFOP int flag. */ HAL_MAC_CLEAR_FIFOP_INT_FLAG(); macRxThresholdIsr(); } while(HAL_MAC_READ_FIFOP_PIN()); } else { /* To get here: FIFOP = 0, FIFO = 0 * This is the second half of the FIFOP glitch workaround. * Need to clear FIFOP interrupt so that the FIFOP interrupt will be * fired on the next rising edge. */ HAL_MAC_CLEAR_FIFOP_INT_FLAG(); } } /* The RXFIFO overflow must be checked last to ensure new FIFOP interrupt */ if (pxie & PXIFG & BV(HAL_MAC_FIFO_GPIO_BIT)) /* FIFO interrupt */ { /* Handle RX FIFO overflow */ if (MAC_RADIO_RX_FIFO_HAS_OVERFLOWED()) { macRxFifoOverflowIsr(); /* Clear RX FIFO overflow exception flag */ macSpiWriteReg(EXCFLAG0, RX_OVERFLOW_FLAG); } /* clear interrupt */ HAL_MAC_CLEAR_FIFO_INT_FLAG(); } }