Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of fsl_phy_mcr20a by
PhyStateMachine.c
00001 /*! 00002 * Copyright (c) 2015, Freescale Semiconductor, Inc. 00003 * All rights reserved. 00004 * 00005 * \file PhyStateMachine.c 00006 * 00007 * Redistribution and use in source and binary forms, with or without modification, 00008 * are permitted provided that the following conditions are met: 00009 * 00010 * o Redistributions of source code must retain the above copyright notice, this list 00011 * of conditions and the following disclaimer. 00012 * 00013 * o Redistributions in binary form must reproduce the above copyright notice, this 00014 * list of conditions and the following disclaimer in the documentation and/or 00015 * other materials provided with the distribution. 00016 * 00017 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its 00018 * contributors may be used to endorse or promote products derived from this 00019 * software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00022 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00023 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00024 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00025 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00026 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00027 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00028 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00029 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 00033 00034 #ifdef gSrcTask_d 00035 #undef gSrcTask_d 00036 #endif 00037 00038 #define gSrcTask_d PHY 00039 00040 00041 /************************************************************************************ 00042 ************************************************************************************* 00043 * Include 00044 ************************************************************************************* 00045 ************************************************************************************/ 00046 #include "EmbeddedTypes.h " 00047 00048 //#include "fsl_os_abstraction.h" 00049 00050 #include "PhyInterface.h " 00051 #include "Phy.h " 00052 00053 00054 #include "MemManager.h " 00055 #include "FunctionLib.h " 00056 #if 0 00057 #include "Messaging.h" 00058 #include "Panic.h" 00059 #endif 00060 00061 #include "MCR20Drv.h " 00062 #include "MCR20Reg.h" 00063 00064 #include "AspInterface.h" 00065 #include "MpmInterface.h " 00066 00067 /************************************************************************************ 00068 ************************************************************************************* 00069 * Public macros 00070 ************************************************************************************* 00071 ************************************************************************************/ 00072 #define mPhyMaxIdleRxDuration_c (0xF00000) /* [sym] */ 00073 00074 #define ProtectFromXcvrInterrupt() ProtectFromMCR20Interrupt() 00075 #define UnprotectFromXcvrInterrupt() UnprotectFromMCR20Interrupt() 00076 00077 /************************************************************************************ 00078 ************************************************************************************* 00079 * Private type definitions 00080 ************************************************************************************* 00081 ************************************************************************************/ 00082 00083 /************************************************************************************ 00084 ************************************************************************************* 00085 * Private prototypes 00086 ************************************************************************************* 00087 ************************************************************************************/ 00088 static void Phy24Task(Phy_PhyLocalStruct_t *pPhyData); 00089 00090 static phyStatus_t Phy_HandlePdDataReq( Phy_PhyLocalStruct_t *pPhyData, macToPdDataMessage_t * pMsg ); 00091 00092 static void Phy_EnterIdle( Phy_PhyLocalStruct_t *pPhyData ); 00093 00094 static void PLME_SendMessage(Phy_PhyLocalStruct_t *pPhyData, phyMessageId_t msgType); 00095 00096 static void PD_SendMessage(Phy_PhyLocalStruct_t *pPhyData, phyMessageId_t msgType); 00097 00098 00099 static void MSG_InitQueue(macPhyInputQueue_t * pMacPhyQueue); 00100 static void MSG_Queue(macPhyInputQueue_t * pMacPhyQueue, void * pMsgIn); 00101 static void MSG_QueueHead(macPhyInputQueue_t * pMacPhyQueue, void * pMsgIn); 00102 static bool_t MSG_Pending(macPhyInputQueue_t * pMacPhyQueue); 00103 static void * MSG_DeQueue(macPhyInputQueue_t * pMacPhyQueue); 00104 00105 /************************************************************************************ 00106 ************************************************************************************* 00107 * Private memory declarations 00108 ************************************************************************************* 00109 ************************************************************************************/ 00110 Phy_PhyLocalStruct_t phyLocal[gPhyInstancesCnt_c]; 00111 extern volatile uint32_t mPhySeqTimeout; 00112 00113 /************************************************************************************ 00114 ************************************************************************************* 00115 * Public functions 00116 ************************************************************************************* 00117 ************************************************************************************/ 00118 00119 /*! ********************************************************************************* 00120 * \brief This function creates the PHY task 00121 * 00122 ********************************************************************************** */ 00123 void Phy_Init(void) 00124 { 00125 uint32_t i; 00126 00127 PhyHwInit(); 00128 ASP_Init( 0, gAspInterfaceId ); 00129 MPM_Init(); 00130 00131 for( i=0; i<gPhyInstancesCnt_c; i++ ) 00132 { 00133 phyLocal[i].flags = gPhyFlagDeferTx_c; 00134 phyLocal[i].rxParams.pRxData = NULL; 00135 00136 /* Prepare input queues.*/ 00137 MSG_InitQueue( &phyLocal[i].macPhyInputQueue ); 00138 } 00139 00140 PhyIsrPassRxParams( NULL ); 00141 PhyPlmeSetPwrState( gPhyDefaultIdlePwrMode_c ); 00142 } 00143 00144 /*! ********************************************************************************* 00145 * \brief This function binds a MAC instance to a PHY instance 00146 * 00147 * \param[in] instanceId The instance of the MAC 00148 * 00149 * \return The instance of the PHY. 00150 * 00151 ********************************************************************************** */ 00152 instanceId_t BindToPHY( instanceId_t macInstance ) 00153 { 00154 return 0; 00155 } 00156 00157 /*! ********************************************************************************* 00158 * \brief This function registers the MAC PD and PLME SAP handlers 00159 * 00160 * \param[in] pPD_MAC_SapHandler Pointer to the MAC PD handler function 00161 * \param[in] pPLME_MAC_SapHandler Pointer to the MAC PLME handler function 00162 * \param[in] instanceId The instance of the PHY 00163 * 00164 * \return The status of the operation. 00165 * 00166 ********************************************************************************** */ 00167 void Phy_RegisterSapHandlers( PD_MAC_SapHandler_t pPD_MAC_SapHandler, 00168 PLME_MAC_SapHandler_t pPLME_MAC_SapHandler, 00169 instanceId_t instanceId ) 00170 { 00171 phyLocal[instanceId].PD_MAC_SapHandler = pPD_MAC_SapHandler; 00172 phyLocal[instanceId].PLME_MAC_SapHandler = pPLME_MAC_SapHandler; 00173 } 00174 00175 /*! ********************************************************************************* 00176 * \brief This function represents the PHY's task 00177 * 00178 * \param[in] taskParam The instance of the PHY 00179 * 00180 ********************************************************************************** */ 00181 static void Phy24Task(Phy_PhyLocalStruct_t *pPhyStruct) 00182 { 00183 uint8_t state; 00184 phyMessageHeader_t * pMsgIn; 00185 phyStatus_t status = gPhySuccess_c; 00186 00187 ProtectFromXcvrInterrupt(); 00188 state = PhyGetSeqState(); 00189 00190 /* Handling messages from upper layer */ 00191 while( MSG_Pending(&pPhyStruct->macPhyInputQueue) ) 00192 { 00193 /* PHY doesn't free dynamic alocated messages! */ 00194 pMsgIn = MSG_DeQueue( &pPhyStruct->macPhyInputQueue ); 00195 pPhyStruct->currentMacInstance = pMsgIn->macInstance; 00196 00197 if( gRX_c == state ) 00198 { 00199 if( (pPhyStruct->flags & gPhyFlagDeferTx_c) && (pMsgIn->msgType == gPdDataReq_c) ) 00200 { 00201 macToPdDataMessage_t *pPD = (macToPdDataMessage_t*)pMsgIn; 00202 uint8_t phyReg = MCR20Drv_DirectAccessSPIRead(SEQ_STATE) & 0x1F; 00203 /* Check for an Rx in progress, and if the packet can be defered. 00204 Packet cannot be defered */ 00205 if( (pPD->msgData.dataReq.CCABeforeTx != gPhyNoCCABeforeTx_c) && 00206 (pPD->msgData.dataReq.startTime == gPhySeqStartAsap_c) && 00207 (pPD->msgData.dataReq.slottedTx == gPhyUnslottedMode_c) && 00208 (phyReg <= 0x06 || phyReg == 0x15 || phyReg == 0x16) ) 00209 { 00210 MSG_QueueHead( &pPhyStruct->macPhyInputQueue, pMsgIn ); 00211 UnprotectFromXcvrInterrupt(); 00212 return; 00213 } 00214 } 00215 00216 // if( pPhyStruct->flags & gPhyFlagIdleRx_c ) 00217 { 00218 PhyPlmeForceTrxOffRequest(); 00219 state = gIdle_c; 00220 pPhyStruct->flags &= ~(gPhyFlagIdleRx_c); 00221 } 00222 } 00223 00224 if( gIdle_c != state ) 00225 { 00226 /* try again later */ 00227 MSG_QueueHead( &pPhyStruct->macPhyInputQueue, pMsgIn ); 00228 UnprotectFromXcvrInterrupt(); 00229 return; 00230 } 00231 00232 #if gMpmIncluded_d 00233 if( status == gPhySuccess_c ) 00234 { 00235 status = MPM_PrepareForTx( pMsgIn->macInstance ); 00236 } 00237 #endif 00238 00239 if( status == gPhySuccess_c ) 00240 { 00241 pPhyStruct->flags &= ~(gPhyFlagIdleRx_c); 00242 00243 switch( pMsgIn->msgType ) 00244 { 00245 case gPdDataReq_c: 00246 status = Phy_HandlePdDataReq( pPhyStruct, (macToPdDataMessage_t *)pMsgIn ); 00247 break; 00248 case gPlmeCcaReq_c: 00249 status = PhyPlmeCcaEdRequest(gPhyCCAMode1_c, gPhyContCcaDisabled); 00250 break; 00251 case gPlmeEdReq_c: 00252 status = PhyPlmeCcaEdRequest(gPhyEnergyDetectMode_c, gPhyContCcaDisabled); 00253 break; 00254 default: 00255 status = gPhyInvalidPrimitive_c; 00256 } 00257 } 00258 00259 /* Check status */ 00260 if( gPhySuccess_c == status ) 00261 { 00262 UnprotectFromXcvrInterrupt(); 00263 return; 00264 } 00265 else 00266 { 00267 switch( pMsgIn->msgType ) 00268 { 00269 case gPdDataReq_c: 00270 if( ((macToPdDataMessage_t*)pMsgIn)->msgData.dataReq.CCABeforeTx == gPhyNoCCABeforeTx_c ) 00271 { 00272 PD_SendMessage(pPhyStruct, gPdDataCnf_c); 00273 break; 00274 } 00275 /* Fallthorough */ 00276 case gPlmeCcaReq_c: 00277 pPhyStruct->channelParams.channelStatus = gPhyChannelBusy_c; 00278 PLME_SendMessage(pPhyStruct, gPlmeCcaCnf_c); 00279 break; 00280 case gPlmeEdReq_c: 00281 pPhyStruct->channelParams.energyLeveldB = 0; 00282 PLME_SendMessage(pPhyStruct, gPlmeEdCnf_c); 00283 break; 00284 default: 00285 PLME_SendMessage(pPhyStruct, gPlmeTimeoutInd_c); 00286 } 00287 } 00288 }/* while( MSG_Pending(&pPhyStruct->macPhyInputQueue) ) */ 00289 00290 UnprotectFromXcvrInterrupt(); 00291 00292 /* Check if PHY can enter Idle state */ 00293 if( gIdle_c == state ) 00294 { 00295 Phy_EnterIdle( pPhyStruct ); 00296 } 00297 } 00298 00299 /*! ********************************************************************************* 00300 * \brief This is the PD SAP message handler 00301 * 00302 * \param[in] pMsg Pointer to the PD request message 00303 * \param[in] instanceId The instance of the PHY 00304 * 00305 * \return The status of the operation. 00306 * 00307 ********************************************************************************** */ 00308 phyStatus_t MAC_PD_SapHandler(macToPdDataMessage_t *pMsg, instanceId_t phyInstance) 00309 { 00310 phyStatus_t result = gPhySuccess_c; 00311 uint8_t baseIndex = 0; 00312 00313 if( NULL == pMsg ) 00314 { 00315 return gPhyInvalidParameter_c; 00316 } 00317 00318 #if gMpmIncluded_d 00319 if( pMsg->msgType == gPdIndQueueInsertReq_c || pMsg->msgType == gPdIndQueueRemoveReq_c ) 00320 { 00321 baseIndex = MPM_GetRegSet( MPM_GetPanIndex( pMsg->macInstance ) ) * 00322 (gPhyIndirectQueueSize_c/gMpmPhyPanRegSets_c); 00323 } 00324 #endif 00325 00326 switch( pMsg->msgType ) 00327 { 00328 case gPdIndQueueInsertReq_c: 00329 result = PhyPp_IndirectQueueInsert(baseIndex + pMsg->msgData.indQueueInsertReq.index, 00330 pMsg->msgData.indQueueInsertReq.checksum, 00331 phyInstance); 00332 break; 00333 00334 case gPdIndQueueRemoveReq_c: 00335 result = PhyPp_RemoveFromIndirect(baseIndex + pMsg->msgData.indQueueRemoveReq.index, 00336 phyInstance); 00337 break; 00338 00339 case gPdDataReq_c: 00340 MSG_Queue(&phyLocal[phyInstance].macPhyInputQueue, pMsg); 00341 Phy24Task( &phyLocal[phyInstance] ); 00342 break; 00343 00344 default: 00345 result = gPhyInvalidPrimitive_c; 00346 } 00347 00348 return result; 00349 } 00350 00351 /*! ********************************************************************************* 00352 * \brief This is the PLME SAP message handler 00353 * 00354 * \param[in] pMsg Pointer to the PLME request message 00355 * \param[in] instanceId The instance of the PHY 00356 * 00357 * \return phyStatus_t The status of the operation. 00358 * 00359 ********************************************************************************** */ 00360 phyStatus_t MAC_PLME_SapHandler(macToPlmeMessage_t * pMsg, instanceId_t phyInstance) 00361 { 00362 Phy_PhyLocalStruct_t *pPhyStruct = &phyLocal[phyInstance]; 00363 uint8_t phyRegSet = 0; 00364 #if gMpmIncluded_d 00365 phyStatus_t result; 00366 int32_t panIdx = MPM_GetPanIndex( pMsg->macInstance ); 00367 00368 phyRegSet = MPM_GetRegSet( panIdx ); 00369 #endif 00370 00371 if( NULL == pMsg ) 00372 { 00373 return gPhyInvalidParameter_c; 00374 } 00375 00376 switch( pMsg->msgType ) 00377 { 00378 case gPlmeEdReq_c: 00379 case gPlmeCcaReq_c: 00380 MSG_Queue(&phyLocal[phyInstance].macPhyInputQueue, pMsg); 00381 Phy24Task( &phyLocal[phyInstance] ); 00382 break; 00383 00384 case gPlmeSetReq_c: 00385 #if gMpmIncluded_d 00386 result = MPM_SetPIB(pMsg->msgData.setReq.PibAttribute, 00387 &pMsg->msgData.setReq.PibAttributeValue, 00388 panIdx ); 00389 if( !MPM_isPanActive(panIdx) ) 00390 { 00391 return result; 00392 } 00393 #endif 00394 return PhyPlmeSetPIBRequest(pMsg->msgData.setReq.PibAttribute, pMsg->msgData.setReq.PibAttributeValue, phyRegSet, phyInstance); 00395 00396 case gPlmeGetReq_c: 00397 #if gMpmIncluded_d 00398 if( gPhySuccess_c == MPM_GetPIB(pMsg->msgData.getReq.PibAttribute, pMsg->msgData.getReq.pPibAttributeValue, panIdx) ) 00399 { 00400 break; 00401 } 00402 #endif 00403 return PhyPlmeGetPIBRequest( pMsg->msgData.getReq.PibAttribute, pMsg->msgData.getReq.pPibAttributeValue, phyRegSet, phyInstance); 00404 00405 case gPlmeSetTRxStateReq_c: 00406 if(gPhySetRxOn_c == pMsg->msgData.setTRxStateReq.state) 00407 { 00408 if( PhyIsIdleRx(phyInstance) ) 00409 { 00410 PhyPlmeForceTrxOffRequest(); 00411 } 00412 else if( gIdle_c != PhyGetSeqState() ) 00413 { 00414 return gPhyBusy_c; 00415 } 00416 #if gMpmIncluded_d 00417 /* If another PAN has the RxOnWhenIdle PIB set, enable the DualPan Auto mode */ 00418 if( gPhySuccess_c != MPM_PrepareForRx( pMsg->macInstance ) ) 00419 return gPhyBusy_c; 00420 #endif 00421 pPhyStruct->flags &= ~(gPhyFlagIdleRx_c); 00422 Phy_SetSequenceTiming(pMsg->msgData.setTRxStateReq.startTime, 00423 pMsg->msgData.setTRxStateReq.rxDuration); 00424 00425 return PhyPlmeRxRequest(pMsg->msgData.setTRxStateReq.slottedMode, (phyRxParams_t *) &pPhyStruct->rxParams); 00426 } 00427 else if (gPhyForceTRxOff_c == pMsg->msgData.setTRxStateReq.state) 00428 { 00429 #if gMpmIncluded_d 00430 if( !MPM_isPanActive(panIdx) ) 00431 return gPhySuccess_c; 00432 #endif 00433 pPhyStruct->flags &= ~(gPhyFlagIdleRx_c); 00434 PhyPlmeForceTrxOffRequest(); 00435 } 00436 break; 00437 00438 default: 00439 return gPhyInvalidPrimitive_c; 00440 } 00441 00442 return gPhySuccess_c; 00443 } 00444 00445 /*! ********************************************************************************* 00446 * \brief This function programs a new TX sequence 00447 * 00448 * \param[in] pMsg Pointer to the PD request message 00449 * \param[in] pPhyData pointer to PHY data 00450 * 00451 * \return The status of the operation. 00452 * 00453 ********************************************************************************** */ 00454 static phyStatus_t Phy_HandlePdDataReq( Phy_PhyLocalStruct_t *pPhyData, macToPdDataMessage_t * pMsg ) 00455 { 00456 phyStatus_t status = gPhySuccess_c; 00457 uint32_t time; 00458 00459 if( NULL == pMsg->msgData.dataReq.pPsdu ) 00460 { 00461 return gPhyInvalidParameter_c; 00462 } 00463 00464 ProtectFromXcvrInterrupt(); 00465 00466 if( pMsg->msgData.dataReq.startTime != gPhySeqStartAsap_c ) 00467 { 00468 PhyTimeSetEventTrigger( (uint16_t) pMsg->msgData.dataReq.startTime ); 00469 } 00470 00471 status = PhyPdDataRequest(&pMsg->msgData.dataReq , &pPhyData->rxParams, &pPhyData->txParams); 00472 00473 if( pMsg->msgData.dataReq.txDuration != gPhySeqStartAsap_c ) 00474 { 00475 OSA_EnterCritical(kCriticalDisableInt); 00476 PhyTimeReadClock( &time ); 00477 time += pMsg->msgData.dataReq.txDuration; 00478 /* Compensate PHY overhead, including WU time */ 00479 time += 54; 00480 PhyTimeSetEventTimeout( &time ); 00481 OSA_ExitCritical(kCriticalDisableInt); 00482 } 00483 00484 UnprotectFromXcvrInterrupt(); 00485 00486 if( gPhySuccess_c != status ) 00487 { 00488 PhyTimeDisableEventTrigger(); 00489 PhyTimeDisableEventTimeout(); 00490 } 00491 00492 return status; 00493 } 00494 00495 /*! ********************************************************************************* 00496 * \brief This function sets the start time and the timeout value for a sequence. 00497 * 00498 * \param[in] startTime The absolute start time for the sequence. 00499 * If startTime is gPhySeqStartAsap_c, the start timer is disabled. 00500 * \param[in] seqDuration The duration of the sequence. 00501 * If seqDuration is 0xFFFFFFFF, the timeout is disabled. 00502 * 00503 ********************************************************************************** */ 00504 void Phy_SetSequenceTiming(uint32_t startTime, uint32_t seqDuration) 00505 { 00506 uint32_t endTime; 00507 00508 OSA_EnterCritical(kCriticalDisableInt); 00509 00510 if( gPhySeqStartAsap_c == startTime ) 00511 { 00512 PhyTimeReadClock( &endTime ); 00513 } 00514 else 00515 { 00516 PhyTimeSetEventTrigger( (uint16_t) startTime ); 00517 endTime = startTime & gPhyTimeMask_c; 00518 } 00519 00520 if( 0xFFFFFFFF != seqDuration ) 00521 { 00522 endTime += seqDuration; 00523 endTime = endTime & gPhyTimeMask_c; 00524 00525 PhyTimeSetEventTimeout( &(endTime) ); 00526 } 00527 00528 OSA_ExitCritical(kCriticalDisableInt); 00529 } 00530 00531 /*! ********************************************************************************* 00532 * \brief This function starts the IdleRX if the PhyRxOnWhenIdle PIB is set 00533 * 00534 * \param[in] pPhyData pointer to PHY data 00535 * 00536 ********************************************************************************** */ 00537 void Phy_EnterIdle( Phy_PhyLocalStruct_t *pPhyData ) 00538 { 00539 if( (pPhyData->flags & gPhyFlagRxOnWhenIdle_c) 00540 #if gMpmIncluded_d 00541 /* Prepare the Active PAN/PANs */ 00542 && (gPhySuccess_c == MPM_PrepareForRx(gInvalidInstanceId_c)) 00543 #endif 00544 ) 00545 { 00546 pPhyData->flags |= gPhyFlagIdleRx_c; 00547 Phy_SetSequenceTiming( gPhySeqStartAsap_c, mPhyMaxIdleRxDuration_c ); 00548 (void)PhyPlmeRxRequest( gPhyUnslottedMode_c, (phyRxParams_t*)&pPhyData->rxParams ); 00549 } 00550 else 00551 { 00552 pPhyData->flags &= ~(gPhyFlagIdleRx_c); 00553 } 00554 } 00555 00556 /*! ********************************************************************************* 00557 * \brief This function sets the value of the maxFrameWaitTime PIB 00558 * 00559 * \param[in] instanceId The instance of the PHY 00560 * \param[in] time The maxFrameWaitTime value 00561 * 00562 ********************************************************************************** */ 00563 void PhyPlmeSetFrameWaitTime( uint32_t time, instanceId_t instanceId ) 00564 { 00565 phyLocal[instanceId].maxFrameWaitTime = time; 00566 } 00567 00568 /*! ********************************************************************************* 00569 * \brief This function sets the state of the PhyRxOnWhenIdle PIB 00570 * 00571 * \param[in] instanceId The instance of the PHY 00572 * \param[in] state The PhyRxOnWhenIdle value 00573 * 00574 ********************************************************************************** */ 00575 void PhyPlmeSetRxOnWhenIdle( bool_t state, instanceId_t instanceId ) 00576 { 00577 uint8_t radioState = PhyGetSeqState(); 00578 #if gMpmIncluded_d 00579 /* Check if at least one PAN has RxOnWhenIdle set */ 00580 if( FALSE == state ) 00581 { 00582 uint32_t i; 00583 00584 for( i=0; i<gMpmMaxPANs_c; i++ ) 00585 { 00586 MPM_GetPIB( gPhyPibRxOnWhenIdle, &state, i ); 00587 if( state ) 00588 break; 00589 } 00590 } 00591 #endif 00592 if( state ) 00593 { 00594 phyLocal[instanceId].flags |= gPhyFlagRxOnWhenIdle_c; 00595 if( radioState == gIdle_c) 00596 { 00597 Phy_EnterIdle( &phyLocal[instanceId] ); 00598 } 00599 #if gMpmIncluded_d 00600 else if( (radioState == gRX_c) && (phyLocal[instanceId].flags & gPhyFlagIdleRx_c) ) 00601 { 00602 PhyPlmeForceTrxOffRequest(); 00603 Phy_EnterIdle( &phyLocal[instanceId] ); 00604 } 00605 #endif 00606 } 00607 else 00608 { 00609 phyLocal[instanceId].flags &= ~gPhyFlagRxOnWhenIdle_c; 00610 if( (radioState == gRX_c) && (phyLocal[instanceId].flags & gPhyFlagIdleRx_c) ) 00611 { 00612 PhyPlmeForceTrxOffRequest(); 00613 phyLocal[instanceId].flags &= ~gPhyFlagIdleRx_c; 00614 } 00615 } 00616 } 00617 00618 /*! ********************************************************************************* 00619 * \brief This function starts the IdleRX if the PhyRxOnWhenIdle PIB is set 00620 * 00621 * \param[in] instanceId The instance of the PHY 00622 * 00623 ********************************************************************************** */ 00624 bool_t PhyIsIdleRx( instanceId_t instanceId ) 00625 { 00626 if( (phyLocal[instanceId].flags & gPhyFlagIdleRx_c) && (gRX_c == PhyGetSeqState())) 00627 return TRUE; 00628 00629 return FALSE; 00630 } 00631 00632 /*! ********************************************************************************* 00633 * \brief This function signals the PHY task that a TX operation completed successfully. 00634 * If the received ACK has FP=1, then the radio will enter RX state for 00635 * maxFrameWaitTime duration. 00636 * 00637 * \param[in] instanceId The instance of the PHY 00638 * \param[in] framePending The value of the framePending bit for the received ACK 00639 * 00640 ********************************************************************************** */ 00641 void Radio_Phy_PdDataConfirm(instanceId_t instanceId, bool_t framePending) 00642 { 00643 PhyTimeDisableEventTimeout(); 00644 00645 if( framePending ) 00646 { 00647 phyLocal[instanceId].flags |= gPhyFlagFramePending_c; 00648 if( phyLocal[instanceId].maxFrameWaitTime > 0 ) 00649 { 00650 /* Restart Rx asap if an ACK with FP=1 is received */ 00651 phyLocal[instanceId].flags &= ~(gPhyFlagIdleRx_c); 00652 Phy_SetSequenceTiming( gPhySeqStartAsap_c, phyLocal[instanceId].maxFrameWaitTime ); 00653 PhyPlmeRxRequest( gPhyUnslottedMode_c, (phyRxParams_t *) &phyLocal[instanceId].rxParams ); 00654 } 00655 } 00656 else 00657 { 00658 phyLocal[instanceId].flags &= ~gPhyFlagFramePending_c; 00659 } 00660 00661 PD_SendMessage(&phyLocal[instanceId], gPdDataCnf_c); 00662 Phy24Task(&phyLocal[instanceId]); 00663 } 00664 00665 /*! ********************************************************************************* 00666 * \brief This function signals the PHY task that new data has been received 00667 * 00668 * \param[in] instanceId The instance of the PHY 00669 * 00670 ********************************************************************************** */ 00671 void Radio_Phy_PdDataIndication(instanceId_t instanceId) 00672 { 00673 PhyTimeDisableEventTimeout(); 00674 00675 PD_SendMessage(&phyLocal[instanceId], gPdDataInd_c); 00676 Phy24Task(&phyLocal[instanceId]); 00677 } 00678 00679 /*! ********************************************************************************* 00680 * \brief This function signals the PHY task that timer1 compare match occured 00681 * 00682 * \param[in] instanceId The instance of the PHY 00683 * 00684 ********************************************************************************** */ 00685 void Radio_Phy_TimeWaitTimeoutIndication(instanceId_t instanceId) 00686 { 00687 PhyTime_ISR(); 00688 } 00689 00690 /*! ********************************************************************************* 00691 * \brief This function signals the PHY task that a CCA sequence has finished 00692 * 00693 * \param[in] instanceId The instance of the PHY 00694 * \param[in] phyChannelStatus The status of the channel: Idle/Busy 00695 * 00696 * \return None. 00697 * 00698 ********************************************************************************** */ 00699 void Radio_Phy_PlmeCcaConfirm(phyStatus_t phyChannelStatus, instanceId_t instanceId) 00700 { 00701 PhyTimeDisableEventTimeout(); 00702 00703 phyLocal[instanceId].channelParams.channelStatus = phyChannelStatus; 00704 00705 PLME_SendMessage(&phyLocal[instanceId], gPlmeCcaCnf_c); 00706 Phy24Task(&phyLocal[instanceId]); 00707 } 00708 00709 /*! ********************************************************************************* 00710 * \brief This function signals the PHY task that a ED sequence has finished 00711 * 00712 * \param[in] instanceId The instance of the PHY 00713 * \param[in] energyLevel The enetgy level on the channel. 00714 * \param[in] energyLeveldB The energy level in DB 00715 * 00716 ********************************************************************************** */ 00717 void Radio_Phy_PlmeEdConfirm(uint8_t energyLeveldB, instanceId_t instanceId) 00718 { 00719 PhyTimeDisableEventTimeout(); 00720 00721 phyLocal[instanceId].channelParams.energyLeveldB = energyLeveldB; 00722 00723 PLME_SendMessage(&phyLocal[instanceId], gPlmeEdCnf_c); 00724 Phy24Task(&phyLocal[instanceId]); 00725 } 00726 00727 /*! ********************************************************************************* 00728 * \brief This function signals the PHY task that the programmed sequence has timed out 00729 * The Radio is forced to Idle. 00730 * 00731 * \param[in] instanceId The instance of the PHY 00732 * 00733 ********************************************************************************** */ 00734 void Radio_Phy_TimeRxTimeoutIndication(instanceId_t instanceId) 00735 { 00736 if( !(phyLocal[instanceId].flags & gPhyFlagIdleRx_c) ) 00737 PLME_SendMessage(&phyLocal[instanceId], gPlmeTimeoutInd_c); 00738 00739 Phy24Task(&phyLocal[instanceId]); 00740 } 00741 00742 /*! ********************************************************************************* 00743 * \brief This function signals the PHY task that the programmed sequence has started 00744 * 00745 * \param[in] instanceId The instance of the PHY 00746 * 00747 * \return None. 00748 * 00749 ********************************************************************************** */ 00750 void Radio_Phy_TimeStartEventIndication(instanceId_t instanceId) 00751 { 00752 #ifdef MAC_PHY_DEBUG 00753 PLME_SendMessage(&phyLocal[instanceId], gPlme_StartEventInd_c); 00754 Phy24Task(&phyLocal[instanceId]); 00755 #endif 00756 } 00757 00758 /*! ********************************************************************************* 00759 * \brief This function signals the PHY task that a SFD was detected. 00760 * Also, if there is not enough time to receive the entire packet, the 00761 * RX timeout will be extended. 00762 * 00763 * \param[in] instanceId The instance of the PHY 00764 * \param[in] frameLen the length of the PSDU 00765 * 00766 ********************************************************************************** */ 00767 void Radio_Phy_PlmeRxSfdDetect(instanceId_t instanceId, uint32_t frameLen) 00768 { 00769 if( phyLocal[instanceId].flags & gPhyFlagDeferTx_c ) 00770 { 00771 uint32_t currentTime; 00772 uint32_t time; 00773 00774 OSA_EnterCritical(kCriticalDisableInt); 00775 00776 //Read currentTime and Timeout values [sym] 00777 PhyTimeReadClock(¤tTime); 00778 00779 frameLen = frameLen * 2 + 12 + 22 + 2; //Convert to symbols and add IFS and ACK duration 00780 00781 if( mPhySeqTimeout > currentTime ) 00782 { 00783 time = mPhySeqTimeout - currentTime; 00784 } 00785 else 00786 { 00787 time = (gPhyTimeMask_c - currentTime + mPhySeqTimeout) & gPhyTimeMask_c; 00788 } 00789 00790 if( time > 4 ) 00791 { 00792 mPhySeqTimeout = (currentTime + frameLen) & gPhyTimeMask_c; 00793 MCR20Drv_DirectAccessSPIMultiByteWrite( T3CMP_LSB, (uint8_t *)&mPhySeqTimeout, 3); 00794 } 00795 00796 OSA_ExitCritical(kCriticalDisableInt); 00797 } 00798 00799 #ifdef MAC_PHY_DEBUG 00800 PLME_SendMessage(&phyLocal[instanceId], gPlme_RxSfdDetectInd_c); 00801 Phy24Task(&phyLocal[instanceId]); 00802 #endif 00803 } 00804 00805 /*! ********************************************************************************* 00806 * \brief This function signals the PHY task that a Sync Loss occured (PLL unlock) 00807 * The Radio is forced to Idle. 00808 * 00809 * \param[in] instanceId The instance of the PHY 00810 * 00811 ********************************************************************************** */ 00812 void Radio_Phy_PlmeSyncLossIndication(instanceId_t instanceId) 00813 { 00814 PhyPlmeForceTrxOffRequest(); 00815 #ifdef MAC_PHY_DEBUG 00816 PLME_SendMessage(&phyLocal[instanceId], gPlme_SyncLossInd_c); 00817 #endif 00818 Radio_Phy_TimeRxTimeoutIndication(instanceId); 00819 } 00820 00821 /*! ********************************************************************************* 00822 * \brief This function signals the PHY task that a Filter Fail occured 00823 * 00824 * \param[in] instanceId The instance of the PHY 00825 * 00826 ********************************************************************************** */ 00827 void Radio_Phy_PlmeFilterFailRx(instanceId_t instanceId) 00828 { 00829 #ifdef MAC_PHY_DEBUG 00830 PLME_SendMessage(&phyLocal[instanceId], gPlme_FilterFailInd_c); 00831 Phy24Task(&phyLocal[instanceId]); 00832 #endif 00833 } 00834 00835 /*! ********************************************************************************* 00836 * \brief This function signals the PHY task that an unexpected Transceiver Reset 00837 * occured and force the TRX to Off 00838 * 00839 * \param[in] instanceId The instance of the PHY 00840 * 00841 ********************************************************************************** */ 00842 void Radio_Phy_UnexpectedTransceiverReset(instanceId_t instanceId) 00843 { 00844 PhyPlmeForceTrxOffRequest(); 00845 #ifdef MAC_PHY_DEBUG 00846 PLME_SendMessage(&phyLocal[instanceId], gPlme_UnexpectedRadioResetInd_c); 00847 #endif 00848 Radio_Phy_TimeRxTimeoutIndication(instanceId); 00849 } 00850 00851 /*! ********************************************************************************* 00852 * \brief Senf a PLME message to upper layer 00853 * 00854 * \param[in] instanceId The instance of the PHY 00855 * \param[in] msgType The type of message to be sent 00856 * 00857 ********************************************************************************** */ 00858 static void PLME_SendMessage(Phy_PhyLocalStruct_t *pPhyStruct, phyMessageId_t msgType) 00859 { 00860 plmeToMacMessage_t * pMsg = MEM_BufferAlloc(sizeof(plmeToMacMessage_t)); 00861 00862 if(NULL == pMsg) 00863 { 00864 //panic(0,(uint32_t)PLME_SendMessage,0,msgType); 00865 return; 00866 } 00867 00868 pMsg->msgType = msgType; 00869 00870 switch(msgType) 00871 { 00872 case gPlmeCcaCnf_c: 00873 pMsg->msgData.ccaCnf.status = pPhyStruct->channelParams.channelStatus; 00874 break; 00875 00876 case gPlmeEdCnf_c: 00877 pMsg->msgData.edCnf.status = gPhySuccess_c; 00878 pMsg->msgData.edCnf.energyLeveldB = pPhyStruct->channelParams.energyLeveldB; 00879 pMsg->msgData.edCnf.energyLevel = Phy_GetEnergyLevel(pPhyStruct->channelParams.energyLeveldB); 00880 break; 00881 00882 default: 00883 /* No aditional info needs to be filled */ 00884 break; 00885 } 00886 00887 pPhyStruct->PLME_MAC_SapHandler(pMsg, pPhyStruct->currentMacInstance); 00888 } 00889 00890 /*! ********************************************************************************* 00891 * \brief Senf a PD message to upper layer 00892 * 00893 * \param[in] instanceId The instance of the PHY 00894 * \param[in] msgType The type of message to be sent 00895 * 00896 ********************************************************************************** */ 00897 static void PD_SendMessage(Phy_PhyLocalStruct_t *pPhyStruct, phyMessageId_t msgType) 00898 { 00899 pdDataToMacMessage_t *pMsg; 00900 00901 if( msgType == gPdDataInd_c ) 00902 { 00903 uint32_t temp; 00904 uint16_t len = pPhyStruct->rxParams.psduLength - 2; //Excluding FCS (2 bytes); 00905 00906 pMsg = pPhyStruct->rxParams.pRxData; 00907 pPhyStruct->rxParams.pRxData = NULL; 00908 00909 #if !gUsePBTransferThereshold_d 00910 MCR20Drv_PB_SPIBurstRead( (uint8_t *)(pMsg->msgData.dataInd.pPsdu), len ); 00911 #endif 00912 00913 pMsg->msgType = gPdDataInd_c; 00914 pMsg->msgData.dataInd.ppduLinkQuality = pPhyStruct->rxParams.linkQuality; 00915 pMsg->msgData.dataInd.psduLength = len; 00916 00917 pMsg->msgData.dataInd.timeStamp = PhyTime_GetTimestamp(); //current timestamp (64bit) 00918 temp = (uint32_t)(pMsg->msgData.dataInd.timeStamp & gPhyTimeMask_c); //convert to 24bit 00919 pMsg->msgData.dataInd.timeStamp -= (temp - pPhyStruct->rxParams.timeStamp) & gPhyTimeMask_c; 00920 #if !(gMpmIncluded_d) 00921 pPhyStruct->PD_MAC_SapHandler(pMsg, pPhyStruct->currentMacInstance); 00922 #else 00923 { 00924 uint32_t i, bitMask = PhyPpGetPanOfRxPacket(); 00925 00926 for( i=0; i<gMpmPhyPanRegSets_c; i++ ) 00927 { 00928 if( bitMask & (1 << i) ) 00929 { 00930 bitMask &= ~(1 << i); 00931 pPhyStruct->currentMacInstance = MPM_GetMacInstanceFromRegSet(i); 00932 00933 /* If the packet passed filtering on muliple PANs, send a copy to each one */ 00934 if( bitMask ) 00935 { 00936 pdDataToMacMessage_t *pDataIndCopy; 00937 00938 pDataIndCopy = MEM_BufferAlloc(sizeof(pdDataToMacMessage_t) + len); 00939 00940 if( pDataIndCopy ) 00941 { 00942 FLib_MemCpy(pDataIndCopy, pMsg, sizeof(pdDataToMacMessage_t) + len); 00943 pPhyStruct->PD_MAC_SapHandler(pDataIndCopy, pPhyStruct->currentMacInstance); 00944 } 00945 } 00946 else 00947 { 00948 pPhyStruct->PD_MAC_SapHandler(pMsg, pPhyStruct->currentMacInstance); 00949 break; 00950 } 00951 } 00952 } 00953 } 00954 #endif 00955 } 00956 else 00957 { 00958 pMsg = MEM_BufferAlloc( sizeof(pdDataToMacMessage_t) ); 00959 00960 if(NULL == pMsg) 00961 { 00962 //panic(0,(uint32_t)PD_SendMessage,0,gPdDataCnf_c); 00963 return; 00964 } 00965 00966 pMsg->msgType = gPdDataCnf_c; 00967 00968 if( pPhyStruct->flags & gPhyFlagFramePending_c ) 00969 { 00970 pPhyStruct->flags &= ~(gPhyFlagFramePending_c); 00971 pMsg->msgData.dataCnf.status = gPhyFramePending_c; 00972 } 00973 else 00974 { 00975 pMsg->msgData.dataCnf.status = gPhySuccess_c; 00976 } 00977 00978 pPhyStruct->PD_MAC_SapHandler(pMsg, pPhyStruct->currentMacInstance); 00979 } 00980 } 00981 00982 void MSG_InitQueue(macPhyInputQueue_t * pMacPhyQueue) 00983 { 00984 pMacPhyQueue->msgInIdx = 0; 00985 FLib_MemSet(&pMacPhyQueue->pMsgIn[0], 0x00, gPhyMsgQueueMax_c * sizeof(void*)); 00986 } 00987 00988 /* Check if a message is pending in a queue. Returns */ 00989 /* TRUE if any pending messages, and FALSE otherwise. */ 00990 bool_t MSG_Pending(macPhyInputQueue_t * pMacPhyQueue) 00991 { 00992 return (pMacPhyQueue->msgInIdx > 0); 00993 } 00994 00995 /* Get a message from a queue. Returns NULL if no messages in queue. */ 00996 void * MSG_DeQueue(macPhyInputQueue_t * pMacPhyQueue) 00997 { 00998 phyMessageHeader_t * pMsgIn = NULL; 00999 uint32_t i = 0; 01000 01001 if(MSG_Pending(pMacPhyQueue)) 01002 { 01003 pMsgIn = pMacPhyQueue->pMsgIn[0]; 01004 01005 while(i < pMacPhyQueue->msgInIdx) 01006 { 01007 pMacPhyQueue->pMsgIn[i] = pMacPhyQueue->pMsgIn[i+1]; 01008 i++; 01009 } 01010 01011 pMacPhyQueue->msgInIdx--; 01012 pMacPhyQueue->pMsgIn[pMacPhyQueue->msgInIdx] = NULL; 01013 } 01014 01015 return pMsgIn; 01016 } 01017 01018 01019 void MSG_Queue(macPhyInputQueue_t * pMacPhyQueue, void * pMsgIn) 01020 { 01021 if(pMacPhyQueue->msgInIdx < gPhyMsgQueueMax_c) 01022 { 01023 pMacPhyQueue->pMsgIn[pMacPhyQueue->msgInIdx] = pMsgIn; 01024 pMacPhyQueue->msgInIdx++; 01025 } 01026 } 01027 01028 void MSG_QueueHead(macPhyInputQueue_t * pMacPhyQueue, void * pMsgIn) 01029 { 01030 uint32_t i = gPhyMsgQueueMax_c - 1; 01031 01032 if(pMacPhyQueue->msgInIdx < gPhyMsgQueueMax_c) 01033 { 01034 while(i > 0) 01035 { 01036 pMacPhyQueue->pMsgIn[i] = pMacPhyQueue->pMsgIn[i-1]; 01037 i--; 01038 } 01039 pMacPhyQueue->pMsgIn[0] = pMsgIn; 01040 pMacPhyQueue->msgInIdx++; 01041 } 01042 } 01043 01044
Generated on Fri Jul 15 2022 21:41:17 by
