A library implementing IEEE 802.15.4 PHY functionality for the MCR20A transceiver. The PHY sublayer provides two services: the PHY data service and the PHY management service interfacing to the PHY sublayer management entity (PLME) service access point (SAP) (known as PLME-SAP). The PHY data service enables the transmission and reception of PHY protocol data units (PSDUs) over the media (radio).
Fork of fsl_phy_mcr20a by
The Freescale PHY Layer deals with the physical burst which is to be sent and/or received. It performs modulation and demodulation, transmitter and receiver switching, fragmentation, scrambling, interleaving, and error correction coding. The communication to the upper protocol layers is carried out through the Layer 1 Interface.
The PHY Layer is capable of executing the following sequences:
- I (Idle)
- R (Receive Sequence conditionally followed by a TxAck)
- T (Transmit Sequence)
- C (Standalone CCA)
- CCCA (Continuous CCA)
- TR (Transmit/Receive Sequence - transmit unconditionally followed by either an R or RxAck)
In addition to these sequences the PHY Layer also integrates a packet processor which determines whether the packet is MAC-compliant, and if it is, whether it is addressed to the end device. Another feature of the packet processor is Source Address Matching which can be viewed as an extension of packet filtering; however its function is very specific to its intended application (data-polling and indirect queue management by a PAN Coordinator).
Documentation
PHY/PhyISR.c
- Committer:
- andreikovacs
- Date:
- 2015-08-18
- Revision:
- 0:764779eedf2d
File content as of revision 0:764779eedf2d:
/*! * Copyright (c) 2015, Freescale Semiconductor, Inc. * All rights reserved. * * \file PhyISR.c * PHY ISR Functions * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, this list * of conditions and the following disclaimer. * * o Redistributions in binary form must reproduce the above copyright notice, this * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * * o Neither the name of Freescale Semiconductor, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /************************************************************************************ ************************************************************************************* * Include ************************************************************************************* ************************************************************************************/ #include "EmbeddedTypes.h" //#include "board.h" #include "MCR20Drv.h" #include "MCR20Reg.h" #include "Phy.h" #include "PhyInterface.h" //#include "Gpio_IrqAdapter.h" //#include "fsl_os_abstraction.h" #include "XcvrSpi.h" /************************************************************************************ ************************************************************************************* * Private macros ************************************************************************************* ************************************************************************************/ #if defined(MCU_MKL46Z4) #define MCR20_Irq_Priority (0xC0) #else #define MCR20_Irq_Priority (0x80) #endif #define PHY_IRQSTS1_INDEX_c 0x00 #define PHY_IRQSTS2_INDEX_c 0x01 #define PHY_IRQSTS3_INDEX_c 0x02 #define PHY_CTRL1_INDEX_c 0x03 #define PHY_CTRL2_INDEX_c 0x04 #define PHY_CTRL3_INDEX_c 0x05 #define PHY_RX_FRM_LEN_INDEX_c 0x06 #define PHY_CTRL4_INDEX_c 0x07 /************************************************************************************ ************************************************************************************* * Private memory declarations ************************************************************************************* ************************************************************************************/ extern Phy_PhyLocalStruct_t phyLocal[]; static volatile phyRxParams_t * mpRxParams = NULL; static uint32_t mPhyTaskInstance; uint8_t mStatusAndControlRegs[8]; uint8_t mPhyLastRxLQI = 0; uint8_t mPhyLastRxRSSI = 0; void (*gpfPhyPreprocessData)(uint8_t *pData) = NULL; #if gUsePBTransferThereshold_d static uint8_t mPhyWatermarkLevel; #define mPhyGetPBTransferThreshold(len) ((len) - 2) //#define mPhyGetPBTransferThreshold(len) ((len)*93/100) //#define mPhyGetPBTransferThreshold(len) (((len) < 20) ? ((len) - 2) : ((len) * 93 / 100)) #endif /************************************************************************************ ************************************************************************************* * Public functions ************************************************************************************* ************************************************************************************/ /*! ********************************************************************************* * \brief Sets the current PHY instance waiting for an IRQ * * \param[in] instanceId instance of the PHY * ********************************************************************************** */ void PhyIsrPassTaskParams ( instanceId_t instanceId ) { mPhyTaskInstance = instanceId; } /*! ********************************************************************************* * \brief Sets the location of the Rx parameters * * \param[in] pRxParam pointer to Rx parameters * ********************************************************************************** */ void PhyIsrPassRxParams ( volatile phyRxParams_t * pRxParam ) { mpRxParams = pRxParam; } /*! ********************************************************************************* * \brief Clear and mask PHY IRQ, set sequence to Idle * ********************************************************************************** */ void PhyIsrSeqCleanup ( void ) { mStatusAndControlRegs[PHY_IRQSTS3_INDEX_c] &= 0xF0; mStatusAndControlRegs[PHY_IRQSTS3_INDEX_c] &= (uint8_t) ~( cIRQSTS3_TMR3MSK ); // unmask TMR3 interrupt mStatusAndControlRegs[PHY_CTRL1_INDEX_c] &= (uint8_t) ~( cPHY_CTRL1_XCVSEQ ); mStatusAndControlRegs[PHY_CTRL2_INDEX_c] |= (uint8_t) ( cPHY_CTRL2_CCAMSK | \ cPHY_CTRL2_RXMSK | \ cPHY_CTRL2_TXMSK | \ cPHY_CTRL2_SEQMSK ); // clear transceiver interrupts, mask SEQ, RX, TX and CCA interrupts and set the PHY sequencer back to IDLE MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 5); } /*! ********************************************************************************* * \brief Clear and mask PHY IRQ, disable timeout, set sequence to Idle * ********************************************************************************** */ void PhyIsrTimeoutCleanup ( void ) { mStatusAndControlRegs[PHY_IRQSTS3_INDEX_c] &= 0xF0; mStatusAndControlRegs[PHY_IRQSTS3_INDEX_c] |= (uint8_t) ( cIRQSTS3_TMR3MSK | \ cIRQSTS3_TMR3IRQ); // mask and clear TMR3 interrupt mStatusAndControlRegs[PHY_CTRL1_INDEX_c] &= (uint8_t) ~( cPHY_CTRL1_XCVSEQ ); mStatusAndControlRegs[PHY_CTRL2_INDEX_c] |= (uint8_t) ( cPHY_CTRL2_CCAMSK | \ cPHY_CTRL2_RXMSK | \ cPHY_CTRL2_TXMSK | \ cPHY_CTRL2_SEQMSK ); // disable TMR3 comparator and timeout mStatusAndControlRegs[PHY_CTRL3_INDEX_c] &= (uint8_t) ~( cPHY_CTRL3_TMR3CMP_EN ); mStatusAndControlRegs[PHY_CTRL4_INDEX_c] &= (uint8_t) ~( cPHY_CTRL4_TC3TMOUT ); // clear transceiver interrupts, mask mask SEQ, RX, TX, TMR3 and CCA interrupts interrupts and set the PHY sequencer back to IDLE MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 8); } /*! ********************************************************************************* * \brief Scales energy level to 0-255 * * \param[in] energyLevel the energ level reported by HW * * \return uint8_t the energy level scaled in 0x00-0xFF * ********************************************************************************** */ uint8_t Phy_GetEnergyLevel ( uint8_t energyLevel /* db */ ) { if(energyLevel >= 90) { /* ED value is below minimum. Return 0x00. */ energyLevel = 0x00; } else if(energyLevel <= 26) { /* ED value is above maximum. Return 0xFF. */ energyLevel = 0xFF; } else { /* Energy level (-90 dBm to -26 dBm ) --> varies form 0 to 64 */ energyLevel = (90 - energyLevel); /* Rescale the energy level values to the 0x00-0xff range (0 to 64 translates in 0 to 255) */ /* energyLevel * 3.9844 ~= 4 */ /* Multiply with 4=2^2 by shifting left. The multiplication will not overflow beacause energyLevel has values between 0 and 63 */ energyLevel <<= 2; } return energyLevel; } /*! ********************************************************************************* * \brief Scales LQI to 0-255 * * \param[in] hwLqi the LQI reported by HW * * \return uint8_t the LQI scaled in 0x00-0xFF * ********************************************************************************** */ static uint8_t Phy_LqiConvert ( uint8_t hwLqi ) { uint32_t tmpLQI; /* LQI Saturation Level */ if (hwLqi >= 230) { return 0xFF; } else if (hwLqi <= 9) { return 0; } else { /* Rescale the LQI values from min to saturation to the 0x00 - 0xFF range */ /* The LQI value mst be multiplied by ~1.1087 */ /* tmpLQI = hwLqi * 7123 ~= hwLqi * 65536 * 0.1087 = hwLqi * 2^16 * 0.1087*/ tmpLQI = ((uint32_t)hwLqi * (uint32_t)7123 ); /* tmpLQI = (tmpLQI / 2^16) + hwLqi */ tmpLQI = (uint32_t)(tmpLQI >> 16) + (uint32_t)hwLqi; return (uint8_t)tmpLQI; } } /*! ********************************************************************************* * \brief This function returns the LQI for the las received packet * * \return uint8_t LQI value * ********************************************************************************** */ uint8_t PhyGetLastRxLqiValue(void) { return mPhyLastRxLQI; } /*! ********************************************************************************* * \brief This function returns the RSSI for the las received packet * * \return uint8_t RSSI value * ********************************************************************************** */ uint8_t PhyGetLastRxRssiValue(void) { uint32_t tempRSSI = mPhyLastRxRSSI; uint8_t comp = MCR20Drv_IndirectAccessSPIRead(LQI_OFFSET_COMP); tempRSSI += comp; tempRSSI >>= 1; comp >>=1; if(25*(tempRSSI+comp) > 4360) { return mPhyLastRxRSSI; } /*liniarization 4360 - 25* RSSI (4360 - 25* RSSI)*7085 >> 18; abs(rssi)=--------------- <=> 37 */ tempRSSI = ((4360 - 25*(tempRSSI + comp))*7085)>>18; return (uint8_t)(0x000000FF & tempRSSI); } /*! ********************************************************************************* * \brief PHY ISR * ********************************************************************************** */ void PHY_InterruptHandler(void) { uint8_t xcvseqCopy; /* The ISR may be called even if another PORTx pin has changed */ //if( !PORT_HAL_IsPinIntPending(g_portBaseAddr[GPIO_EXTRACT_PORT(kGpioXcvrIrqPin)], GPIO_EXTRACT_PIN(kGpioXcvrIrqPin)) ) if( !RF_isIRQ_Pending() ) { return; } /* Disable and clear transceiver(IRQ_B) interrupt */ MCR20Drv_IRQ_Disable(); MCR20Drv_IRQ_Clear(); /* Read transceiver interrupt status and control registers */ mStatusAndControlRegs[PHY_IRQSTS1_INDEX_c] = MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &mStatusAndControlRegs[1], 7); xcvseqCopy = mStatusAndControlRegs[PHY_CTRL1_INDEX_c] & cPHY_CTRL1_XCVSEQ; /* clear transceiver interrupts */ MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 3); if( (mStatusAndControlRegs[PHY_IRQSTS2_INDEX_c] & cIRQSTS2_WAKE_IRQ) && !(mStatusAndControlRegs[PHY_CTRL3_INDEX_c] & cPHY_CTRL3_WAKE_MSK) ) { #ifdef MAC_PHY_DEBUG Radio_Phy_UnexpectedTransceiverReset(mPhyTaskInstance); #endif MCR20Drv_IRQ_Enable(); return; } /* Flter Fail IRQ */ if( (mStatusAndControlRegs[PHY_IRQSTS1_INDEX_c] & cIRQSTS1_FILTERFAIL_IRQ) && !(mStatusAndControlRegs[PHY_CTRL2_INDEX_c] & cPHY_CTRL2_FILTERFAIL_MSK) ) { #if gUsePBTransferThereshold_d /* Reset the RX_WTR_MARK level since packet was dropped. */ mPhyWatermarkLevel = 0; MCR20Drv_IndirectAccessSPIWrite(RX_WTR_MARK, mPhyWatermarkLevel); #endif Radio_Phy_PlmeFilterFailRx(mPhyTaskInstance); } /* Rx Watermark IRQ */ else if( (mStatusAndControlRegs[PHY_IRQSTS1_INDEX_c] & cIRQSTS1_RXWTRMRKIRQ) && !(mStatusAndControlRegs[PHY_CTRL2_INDEX_c] & cPHY_CTRL2_RX_WMRK_MSK) ) { #if gUsePBTransferThereshold_d if( 0 == mPhyWatermarkLevel ) { /* Check if this is a standalone RX because we could end up here during a TR sequence also. */ if( xcvseqCopy == gRX_c ) { /* Set the thereshold packet length at which to start the PB Burst Read.*/ mPhyWatermarkLevel = mPhyGetPBTransferThreshold( mStatusAndControlRegs[PHY_RX_FRM_LEN_INDEX_c] ); MCR20Drv_IndirectAccessSPIWrite(RX_WTR_MARK, mPhyWatermarkLevel); } #endif Radio_Phy_PlmeRxSfdDetect(mPhyTaskInstance, mStatusAndControlRegs[PHY_RX_FRM_LEN_INDEX_c]); #if gUsePBTransferThereshold_d } else { /* Reset RX_WTR_MARK here, because if the FCS fails, no other IRQ will arrive * and the RX will restart automatically. */ mPhyWatermarkLevel = 0; MCR20Drv_IndirectAccessSPIWrite(RX_WTR_MARK, mPhyWatermarkLevel); if( mpRxParams ) { // Read data from PB MCR20Drv_PB_SPIBurstRead(mpRxParams->pRxData->msgData.dataInd.pPsdu, (uint8_t)(mStatusAndControlRegs[PHY_RX_FRM_LEN_INDEX_c] - 2)); if( gpfPhyPreprocessData ) gpfPhyPreprocessData(mpRxParams->pRxData->msgData.dataInd.pPsdu); } } #endif } /* Timer 1 Compare Match */ if( (mStatusAndControlRegs[PHY_IRQSTS3_INDEX_c] & cIRQSTS3_TMR1IRQ) && !(mStatusAndControlRegs[PHY_IRQSTS3_INDEX_c] & cIRQSTS3_TMR1MSK)) { // disable TMR1 comparator mStatusAndControlRegs[PHY_CTRL3_INDEX_c] &= (uint8_t) ~( cPHY_CTRL3_TMR1CMP_EN); MCR20Drv_DirectAccessSPIWrite(PHY_CTRL3, mStatusAndControlRegs[PHY_CTRL3_INDEX_c]); Radio_Phy_TimeWaitTimeoutIndication(mPhyTaskInstance); } /* Sequencer interrupt, the autosequence has completed */ if( (mStatusAndControlRegs[PHY_IRQSTS1_INDEX_c] & cIRQSTS1_SEQIRQ) && !(mStatusAndControlRegs[PHY_CTRL2_INDEX_c] & cPHY_CTRL2_SEQMSK) ) { // PLL unlock, the autosequence has been aborted due to PLL unlock if( mStatusAndControlRegs[PHY_IRQSTS1_INDEX_c] & cIRQSTS1_PLL_UNLOCK_IRQ ) { PhyIsrSeqCleanup(); Radio_Phy_PlmeSyncLossIndication(mPhyTaskInstance); MCR20Drv_IRQ_Enable(); return; } // TMR3 timeout, the autosequence has been aborted due to TMR3 timeout if( (mStatusAndControlRegs[PHY_IRQSTS3_INDEX_c] & cIRQSTS3_TMR3IRQ) && !(mStatusAndControlRegs[PHY_IRQSTS1_INDEX_c] & cIRQSTS1_RXIRQ) && (gTX_c != xcvseqCopy) ) { PhyIsrTimeoutCleanup(); Radio_Phy_TimeRxTimeoutIndication(mPhyTaskInstance); MCR20Drv_IRQ_Enable(); return; } PhyIsrSeqCleanup(); switch(xcvseqCopy) { case gTX_c: if( (mStatusAndControlRegs[PHY_IRQSTS2_INDEX_c] & cIRQSTS2_CCA) && (mStatusAndControlRegs[PHY_CTRL1_INDEX_c] & cPHY_CTRL1_CCABFRTX) ) { Radio_Phy_PlmeCcaConfirm(gPhyChannelBusy_c, mPhyTaskInstance); } else { Radio_Phy_PdDataConfirm(mPhyTaskInstance, FALSE); } break; case gTR_c: if( (mStatusAndControlRegs[PHY_IRQSTS2_INDEX_c] & cIRQSTS2_CCA) && (mStatusAndControlRegs[PHY_CTRL1_INDEX_c] & cPHY_CTRL1_CCABFRTX) ) { Radio_Phy_PlmeCcaConfirm(gPhyChannelBusy_c, mPhyTaskInstance); } else { if(NULL != mpRxParams) { // reports value of 0x00 for -105 dBm of received input power and 0xFF for 0 dBm of received input power mPhyLastRxRSSI = MCR20Drv_DirectAccessSPIRead((uint8_t) LQI_VALUE); mpRxParams->linkQuality = Phy_LqiConvert(mPhyLastRxRSSI); mPhyLastRxLQI = mpRxParams->linkQuality; MCR20Drv_DirectAccessSPIMultiByteRead( (uint8_t) TIMESTAMP_LSB, (uint8_t *)&mpRxParams->timeStamp, 3); mpRxParams->psduLength = (uint8_t)(mStatusAndControlRegs[PHY_RX_FRM_LEN_INDEX_c]); //Including FCS (2 bytes) } if( (mStatusAndControlRegs[PHY_IRQSTS1_INDEX_c] & cIRQSTS1_RX_FRM_PEND) == cIRQSTS1_RX_FRM_PEND ) { Radio_Phy_PdDataConfirm(mPhyTaskInstance, TRUE); } else { Radio_Phy_PdDataConfirm(mPhyTaskInstance, FALSE); } } break; case gRX_c: if( NULL != mpRxParams ) { // reports value of 0x00 for -105 dBm of received input power and 0xFF for 0 dBm of received input power mPhyLastRxRSSI = MCR20Drv_DirectAccessSPIRead((uint8_t) LQI_VALUE); mpRxParams->linkQuality = Phy_LqiConvert(mPhyLastRxRSSI); mPhyLastRxLQI = mpRxParams->linkQuality; MCR20Drv_DirectAccessSPIMultiByteRead( (uint8_t) TIMESTAMP_LSB, (uint8_t *)&mpRxParams->timeStamp, 3); mpRxParams->psduLength = (uint8_t)(mStatusAndControlRegs[PHY_RX_FRM_LEN_INDEX_c]); //Including FCS (2 bytes) } Radio_Phy_PdDataIndication(mPhyTaskInstance); break; case gCCA_c: if( (mStatusAndControlRegs[PHY_CTRL4_INDEX_c] & (cPHY_CTRL4_CCATYPE << cPHY_CTRL4_CCATYPE_Shift_c)) == (gCcaED_c << cPHY_CTRL4_CCATYPE_Shift_c) ) { // Ed Radio_Phy_PlmeEdConfirm(MCR20Drv_DirectAccessSPIRead((uint8_t) CCA1_ED_FNL), mPhyTaskInstance); } else { // CCA if( mStatusAndControlRegs[PHY_IRQSTS2_INDEX_c] & cIRQSTS2_CCA ) { #if (gUseStandaloneCCABeforeTx_d == 1) phyLocal[mPhyTaskInstance].txParams.numOfCca = 0; #endif Radio_Phy_PlmeCcaConfirm(gPhyChannelBusy_c, mPhyTaskInstance); } else { #if (gUseStandaloneCCABeforeTx_d == 1) if( phyLocal[mPhyTaskInstance].txParams.numOfCca > 0 ) { mStatusAndControlRegs[PHY_CTRL1] &= (uint8_t) ~(cPHY_CTRL1_XCVSEQ); if( --phyLocal[mPhyTaskInstance].txParams.numOfCca == 0 ) { // perform TxRxAck sequence if required by phyTxMode if( gPhyRxAckRqd_c == phyLocal[mPhyTaskInstance].txParams.ackRequired ) { mStatusAndControlRegs[PHY_CTRL1] |= (uint8_t) (cPHY_CTRL1_RXACKRQD); mStatusAndControlRegs[PHY_CTRL1] |= gTR_c; } else { mStatusAndControlRegs[PHY_CTRL1] &= (uint8_t) ~(cPHY_CTRL1_RXACKRQD); mStatusAndControlRegs[PHY_CTRL1] |= gTX_c; } } else { mStatusAndControlRegs[PHY_CTRL1] |= gCCA_c; } mStatusAndControlRegs[PHY_CTRL2] &= (uint8_t) ~(cPHY_CTRL2_SEQMSK); // unmask SEQ interrupt // start the sequence immediately MCR20Drv_DirectAccessSPIMultiByteWrite(PHY_CTRL1, &mStatusAndControlRegs[PHY_CTRL1], 2); } else #endif { Radio_Phy_PlmeCcaConfirm(gPhyChannelIdle_c, mPhyTaskInstance); } } } break; case gCCCA_c: Radio_Phy_PlmeCcaConfirm(gPhyChannelIdle_c, mPhyTaskInstance); break; default: Radio_Phy_PlmeSyncLossIndication(mPhyTaskInstance); break; } } // timers interrupt else { if( mStatusAndControlRegs[PHY_IRQSTS3_INDEX_c] & cIRQSTS3_TMR2IRQ ) { // disable TMR2 comparator and time triggered action mStatusAndControlRegs[PHY_CTRL3_INDEX_c] &= (uint8_t) ~( cPHY_CTRL3_TMR2CMP_EN); mStatusAndControlRegs[PHY_CTRL1_INDEX_c] &= (uint8_t) ~( cPHY_CTRL1_TMRTRIGEN); MCR20Drv_DirectAccessSPIWrite(PHY_CTRL3, mStatusAndControlRegs[PHY_CTRL3_INDEX_c]); MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1_INDEX_c]); Radio_Phy_TimeStartEventIndication(mPhyTaskInstance); } if( mStatusAndControlRegs[PHY_IRQSTS3_INDEX_c] & cIRQSTS3_TMR3IRQ ) { /* disable TMR3 comparator and timeout */ mStatusAndControlRegs[PHY_CTRL3_INDEX_c] &= (uint8_t) ~( cPHY_CTRL3_TMR3CMP_EN); mStatusAndControlRegs[PHY_CTRL4_INDEX_c] &= (uint8_t) ~( cPHY_CTRL4_TC3TMOUT); MCR20Drv_DirectAccessSPIWrite(PHY_CTRL3, mStatusAndControlRegs[PHY_CTRL3_INDEX_c]); MCR20Drv_DirectAccessSPIWrite(PHY_CTRL4, mStatusAndControlRegs[PHY_CTRL4_INDEX_c]); /* Ensure that we're not issuing TimeoutIndication while the Automated sequence is still in progress */ /* TMR3 can expire during R-T turnaround for example, case in which the sequence is not interrupted */ if( gIdle_c == xcvseqCopy ) { Radio_Phy_TimeRxTimeoutIndication(mPhyTaskInstance); } } /* Timer 4 Compare Match */ if( mStatusAndControlRegs[PHY_IRQSTS3_INDEX_c] & cIRQSTS3_TMR4IRQ ) { /* disable TMR4 comparator */ mStatusAndControlRegs[PHY_CTRL3_INDEX_c] &= (uint8_t) ~( cPHY_CTRL3_TMR4CMP_EN); MCR20Drv_DirectAccessSPIWrite(PHY_CTRL3, mStatusAndControlRegs[PHY_CTRL3_INDEX_c]); } } MCR20Drv_IRQ_Enable(); } /*! ********************************************************************************* * \brief This function installs the PHY ISR * ********************************************************************************** */ void PHY_InstallIsr( void ) { /*Initialise RF interrupt pin*/ RF_IRQ_Init(); //GpioInstallIsr(PHY_InterruptHandler, gGpioIsrPrioHigh_c, MCR20_Irq_Priority, kGpioXcvrIrqPin); }