NXP / fsl_phy_mcr20a

Fork of fsl_phy_mcr20a by Freescale

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

MCR20A PHY Reference Manual

Committer:
andreikovacs
Date:
Tue Aug 18 12:41:42 2015 +0000
Revision:
0:764779eedf2d
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andreikovacs 0:764779eedf2d 1 /*!
andreikovacs 0:764779eedf2d 2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
andreikovacs 0:764779eedf2d 3 * All rights reserved.
andreikovacs 0:764779eedf2d 4 *
andreikovacs 0:764779eedf2d 5 * \file PhyStateMachine.c
andreikovacs 0:764779eedf2d 6 *
andreikovacs 0:764779eedf2d 7 * Redistribution and use in source and binary forms, with or without modification,
andreikovacs 0:764779eedf2d 8 * are permitted provided that the following conditions are met:
andreikovacs 0:764779eedf2d 9 *
andreikovacs 0:764779eedf2d 10 * o Redistributions of source code must retain the above copyright notice, this list
andreikovacs 0:764779eedf2d 11 * of conditions and the following disclaimer.
andreikovacs 0:764779eedf2d 12 *
andreikovacs 0:764779eedf2d 13 * o Redistributions in binary form must reproduce the above copyright notice, this
andreikovacs 0:764779eedf2d 14 * list of conditions and the following disclaimer in the documentation and/or
andreikovacs 0:764779eedf2d 15 * other materials provided with the distribution.
andreikovacs 0:764779eedf2d 16 *
andreikovacs 0:764779eedf2d 17 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
andreikovacs 0:764779eedf2d 18 * contributors may be used to endorse or promote products derived from this
andreikovacs 0:764779eedf2d 19 * software without specific prior written permission.
andreikovacs 0:764779eedf2d 20 *
andreikovacs 0:764779eedf2d 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
andreikovacs 0:764779eedf2d 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
andreikovacs 0:764779eedf2d 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
andreikovacs 0:764779eedf2d 24 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
andreikovacs 0:764779eedf2d 25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
andreikovacs 0:764779eedf2d 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
andreikovacs 0:764779eedf2d 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
andreikovacs 0:764779eedf2d 28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
andreikovacs 0:764779eedf2d 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
andreikovacs 0:764779eedf2d 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
andreikovacs 0:764779eedf2d 31 */
andreikovacs 0:764779eedf2d 32
andreikovacs 0:764779eedf2d 33
andreikovacs 0:764779eedf2d 34 #ifdef gSrcTask_d
andreikovacs 0:764779eedf2d 35 #undef gSrcTask_d
andreikovacs 0:764779eedf2d 36 #endif
andreikovacs 0:764779eedf2d 37
andreikovacs 0:764779eedf2d 38 #define gSrcTask_d PHY
andreikovacs 0:764779eedf2d 39
andreikovacs 0:764779eedf2d 40
andreikovacs 0:764779eedf2d 41 /************************************************************************************
andreikovacs 0:764779eedf2d 42 *************************************************************************************
andreikovacs 0:764779eedf2d 43 * Include
andreikovacs 0:764779eedf2d 44 *************************************************************************************
andreikovacs 0:764779eedf2d 45 ************************************************************************************/
andreikovacs 0:764779eedf2d 46 #include "EmbeddedTypes.h"
andreikovacs 0:764779eedf2d 47
andreikovacs 0:764779eedf2d 48 //#include "fsl_os_abstraction.h"
andreikovacs 0:764779eedf2d 49
andreikovacs 0:764779eedf2d 50 #include "PhyInterface.h"
andreikovacs 0:764779eedf2d 51 #include "Phy.h"
andreikovacs 0:764779eedf2d 52
andreikovacs 0:764779eedf2d 53
andreikovacs 0:764779eedf2d 54 #include "MemManager.h"
andreikovacs 0:764779eedf2d 55 #include "FunctionLib.h"
andreikovacs 0:764779eedf2d 56 #if 0
andreikovacs 0:764779eedf2d 57 #include "Messaging.h"
andreikovacs 0:764779eedf2d 58 #include "Panic.h"
andreikovacs 0:764779eedf2d 59 #endif
andreikovacs 0:764779eedf2d 60
andreikovacs 0:764779eedf2d 61 #include "MCR20Drv.h"
andreikovacs 0:764779eedf2d 62 #include "MCR20Reg.h"
andreikovacs 0:764779eedf2d 63
andreikovacs 0:764779eedf2d 64 #include "AspInterface.h"
andreikovacs 0:764779eedf2d 65 #include "MpmInterface.h"
andreikovacs 0:764779eedf2d 66
andreikovacs 0:764779eedf2d 67 /************************************************************************************
andreikovacs 0:764779eedf2d 68 *************************************************************************************
andreikovacs 0:764779eedf2d 69 * Public macros
andreikovacs 0:764779eedf2d 70 *************************************************************************************
andreikovacs 0:764779eedf2d 71 ************************************************************************************/
andreikovacs 0:764779eedf2d 72 #define mPhyMaxIdleRxDuration_c (0xF00000) /* [sym] */
andreikovacs 0:764779eedf2d 73
andreikovacs 0:764779eedf2d 74 #define ProtectFromXcvrInterrupt() ProtectFromMCR20Interrupt()
andreikovacs 0:764779eedf2d 75 #define UnprotectFromXcvrInterrupt() UnprotectFromMCR20Interrupt()
andreikovacs 0:764779eedf2d 76
andreikovacs 0:764779eedf2d 77 /************************************************************************************
andreikovacs 0:764779eedf2d 78 *************************************************************************************
andreikovacs 0:764779eedf2d 79 * Private type definitions
andreikovacs 0:764779eedf2d 80 *************************************************************************************
andreikovacs 0:764779eedf2d 81 ************************************************************************************/
andreikovacs 0:764779eedf2d 82
andreikovacs 0:764779eedf2d 83 /************************************************************************************
andreikovacs 0:764779eedf2d 84 *************************************************************************************
andreikovacs 0:764779eedf2d 85 * Private prototypes
andreikovacs 0:764779eedf2d 86 *************************************************************************************
andreikovacs 0:764779eedf2d 87 ************************************************************************************/
andreikovacs 0:764779eedf2d 88 static void Phy24Task(Phy_PhyLocalStruct_t *pPhyData);
andreikovacs 0:764779eedf2d 89
andreikovacs 0:764779eedf2d 90 static phyStatus_t Phy_HandlePdDataReq( Phy_PhyLocalStruct_t *pPhyData, macToPdDataMessage_t * pMsg );
andreikovacs 0:764779eedf2d 91
andreikovacs 0:764779eedf2d 92 static void Phy_EnterIdle( Phy_PhyLocalStruct_t *pPhyData );
andreikovacs 0:764779eedf2d 93
andreikovacs 0:764779eedf2d 94 static void PLME_SendMessage(Phy_PhyLocalStruct_t *pPhyData, phyMessageId_t msgType);
andreikovacs 0:764779eedf2d 95
andreikovacs 0:764779eedf2d 96 static void PD_SendMessage(Phy_PhyLocalStruct_t *pPhyData, phyMessageId_t msgType);
andreikovacs 0:764779eedf2d 97
andreikovacs 0:764779eedf2d 98
andreikovacs 0:764779eedf2d 99 static void MSG_InitQueue(macPhyInputQueue_t * pMacPhyQueue);
andreikovacs 0:764779eedf2d 100 static void MSG_Queue(macPhyInputQueue_t * pMacPhyQueue, void * pMsgIn);
andreikovacs 0:764779eedf2d 101 static void MSG_QueueHead(macPhyInputQueue_t * pMacPhyQueue, void * pMsgIn);
andreikovacs 0:764779eedf2d 102 static bool_t MSG_Pending(macPhyInputQueue_t * pMacPhyQueue);
andreikovacs 0:764779eedf2d 103 static void * MSG_DeQueue(macPhyInputQueue_t * pMacPhyQueue);
andreikovacs 0:764779eedf2d 104
andreikovacs 0:764779eedf2d 105 /************************************************************************************
andreikovacs 0:764779eedf2d 106 *************************************************************************************
andreikovacs 0:764779eedf2d 107 * Private memory declarations
andreikovacs 0:764779eedf2d 108 *************************************************************************************
andreikovacs 0:764779eedf2d 109 ************************************************************************************/
andreikovacs 0:764779eedf2d 110 Phy_PhyLocalStruct_t phyLocal[gPhyInstancesCnt_c];
andreikovacs 0:764779eedf2d 111 extern volatile uint32_t mPhySeqTimeout;
andreikovacs 0:764779eedf2d 112
andreikovacs 0:764779eedf2d 113 /************************************************************************************
andreikovacs 0:764779eedf2d 114 *************************************************************************************
andreikovacs 0:764779eedf2d 115 * Public functions
andreikovacs 0:764779eedf2d 116 *************************************************************************************
andreikovacs 0:764779eedf2d 117 ************************************************************************************/
andreikovacs 0:764779eedf2d 118
andreikovacs 0:764779eedf2d 119 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 120 * \brief This function creates the PHY task
andreikovacs 0:764779eedf2d 121 *
andreikovacs 0:764779eedf2d 122 ********************************************************************************** */
andreikovacs 0:764779eedf2d 123 void Phy_Init(void)
andreikovacs 0:764779eedf2d 124 {
andreikovacs 0:764779eedf2d 125 uint32_t i;
andreikovacs 0:764779eedf2d 126
andreikovacs 0:764779eedf2d 127 PhyHwInit();
andreikovacs 0:764779eedf2d 128 ASP_Init( 0, gAspInterfaceId );
andreikovacs 0:764779eedf2d 129 MPM_Init();
andreikovacs 0:764779eedf2d 130
andreikovacs 0:764779eedf2d 131 for( i=0; i<gPhyInstancesCnt_c; i++ )
andreikovacs 0:764779eedf2d 132 {
andreikovacs 0:764779eedf2d 133 phyLocal[i].flags = gPhyFlagDeferTx_c;
andreikovacs 0:764779eedf2d 134 phyLocal[i].rxParams.pRxData = NULL;
andreikovacs 0:764779eedf2d 135
andreikovacs 0:764779eedf2d 136 /* Prepare input queues.*/
andreikovacs 0:764779eedf2d 137 MSG_InitQueue( &phyLocal[i].macPhyInputQueue );
andreikovacs 0:764779eedf2d 138 }
andreikovacs 0:764779eedf2d 139
andreikovacs 0:764779eedf2d 140 PhyIsrPassRxParams( NULL );
andreikovacs 0:764779eedf2d 141 PhyPlmeSetPwrState( gPhyDefaultIdlePwrMode_c );
andreikovacs 0:764779eedf2d 142 }
andreikovacs 0:764779eedf2d 143
andreikovacs 0:764779eedf2d 144 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 145 * \brief This function binds a MAC instance to a PHY instance
andreikovacs 0:764779eedf2d 146 *
andreikovacs 0:764779eedf2d 147 * \param[in] instanceId The instance of the MAC
andreikovacs 0:764779eedf2d 148 *
andreikovacs 0:764779eedf2d 149 * \return The instance of the PHY.
andreikovacs 0:764779eedf2d 150 *
andreikovacs 0:764779eedf2d 151 ********************************************************************************** */
andreikovacs 0:764779eedf2d 152 instanceId_t BindToPHY( instanceId_t macInstance )
andreikovacs 0:764779eedf2d 153 {
andreikovacs 0:764779eedf2d 154 return 0;
andreikovacs 0:764779eedf2d 155 }
andreikovacs 0:764779eedf2d 156
andreikovacs 0:764779eedf2d 157 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 158 * \brief This function registers the MAC PD and PLME SAP handlers
andreikovacs 0:764779eedf2d 159 *
andreikovacs 0:764779eedf2d 160 * \param[in] pPD_MAC_SapHandler Pointer to the MAC PD handler function
andreikovacs 0:764779eedf2d 161 * \param[in] pPLME_MAC_SapHandler Pointer to the MAC PLME handler function
andreikovacs 0:764779eedf2d 162 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 163 *
andreikovacs 0:764779eedf2d 164 * \return The status of the operation.
andreikovacs 0:764779eedf2d 165 *
andreikovacs 0:764779eedf2d 166 ********************************************************************************** */
andreikovacs 0:764779eedf2d 167 void Phy_RegisterSapHandlers( PD_MAC_SapHandler_t pPD_MAC_SapHandler,
andreikovacs 0:764779eedf2d 168 PLME_MAC_SapHandler_t pPLME_MAC_SapHandler,
andreikovacs 0:764779eedf2d 169 instanceId_t instanceId )
andreikovacs 0:764779eedf2d 170 {
andreikovacs 0:764779eedf2d 171 phyLocal[instanceId].PD_MAC_SapHandler = pPD_MAC_SapHandler;
andreikovacs 0:764779eedf2d 172 phyLocal[instanceId].PLME_MAC_SapHandler = pPLME_MAC_SapHandler;
andreikovacs 0:764779eedf2d 173 }
andreikovacs 0:764779eedf2d 174
andreikovacs 0:764779eedf2d 175 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 176 * \brief This function represents the PHY's task
andreikovacs 0:764779eedf2d 177 *
andreikovacs 0:764779eedf2d 178 * \param[in] taskParam The instance of the PHY
andreikovacs 0:764779eedf2d 179 *
andreikovacs 0:764779eedf2d 180 ********************************************************************************** */
andreikovacs 0:764779eedf2d 181 static void Phy24Task(Phy_PhyLocalStruct_t *pPhyStruct)
andreikovacs 0:764779eedf2d 182 {
andreikovacs 0:764779eedf2d 183 uint8_t state;
andreikovacs 0:764779eedf2d 184 phyMessageHeader_t * pMsgIn;
andreikovacs 0:764779eedf2d 185 phyStatus_t status = gPhySuccess_c;
andreikovacs 0:764779eedf2d 186
andreikovacs 0:764779eedf2d 187 ProtectFromXcvrInterrupt();
andreikovacs 0:764779eedf2d 188 state = PhyGetSeqState();
andreikovacs 0:764779eedf2d 189
andreikovacs 0:764779eedf2d 190 /* Handling messages from upper layer */
andreikovacs 0:764779eedf2d 191 while( MSG_Pending(&pPhyStruct->macPhyInputQueue) )
andreikovacs 0:764779eedf2d 192 {
andreikovacs 0:764779eedf2d 193 /* PHY doesn't free dynamic alocated messages! */
andreikovacs 0:764779eedf2d 194 pMsgIn = MSG_DeQueue( &pPhyStruct->macPhyInputQueue );
andreikovacs 0:764779eedf2d 195 pPhyStruct->currentMacInstance = pMsgIn->macInstance;
andreikovacs 0:764779eedf2d 196
andreikovacs 0:764779eedf2d 197 if( gRX_c == state )
andreikovacs 0:764779eedf2d 198 {
andreikovacs 0:764779eedf2d 199 if( (pPhyStruct->flags & gPhyFlagDeferTx_c) && (pMsgIn->msgType == gPdDataReq_c) )
andreikovacs 0:764779eedf2d 200 {
andreikovacs 0:764779eedf2d 201 macToPdDataMessage_t *pPD = (macToPdDataMessage_t*)pMsgIn;
andreikovacs 0:764779eedf2d 202 uint8_t phyReg = MCR20Drv_DirectAccessSPIRead(SEQ_STATE) & 0x1F;
andreikovacs 0:764779eedf2d 203 /* Check for an Rx in progress, and if the packet can be defered.
andreikovacs 0:764779eedf2d 204 Packet cannot be defered */
andreikovacs 0:764779eedf2d 205 if( (pPD->msgData.dataReq.CCABeforeTx != gPhyNoCCABeforeTx_c) &&
andreikovacs 0:764779eedf2d 206 (pPD->msgData.dataReq.startTime == gPhySeqStartAsap_c) &&
andreikovacs 0:764779eedf2d 207 (pPD->msgData.dataReq.slottedTx == gPhyUnslottedMode_c) &&
andreikovacs 0:764779eedf2d 208 (phyReg <= 0x06 || phyReg == 0x15 || phyReg == 0x16) )
andreikovacs 0:764779eedf2d 209 {
andreikovacs 0:764779eedf2d 210 MSG_QueueHead( &pPhyStruct->macPhyInputQueue, pMsgIn );
andreikovacs 0:764779eedf2d 211 UnprotectFromXcvrInterrupt();
andreikovacs 0:764779eedf2d 212 return;
andreikovacs 0:764779eedf2d 213 }
andreikovacs 0:764779eedf2d 214 }
andreikovacs 0:764779eedf2d 215
andreikovacs 0:764779eedf2d 216 // if( pPhyStruct->flags & gPhyFlagIdleRx_c )
andreikovacs 0:764779eedf2d 217 {
andreikovacs 0:764779eedf2d 218 PhyPlmeForceTrxOffRequest();
andreikovacs 0:764779eedf2d 219 state = gIdle_c;
andreikovacs 0:764779eedf2d 220 pPhyStruct->flags &= ~(gPhyFlagIdleRx_c);
andreikovacs 0:764779eedf2d 221 }
andreikovacs 0:764779eedf2d 222 }
andreikovacs 0:764779eedf2d 223
andreikovacs 0:764779eedf2d 224 if( gIdle_c != state )
andreikovacs 0:764779eedf2d 225 {
andreikovacs 0:764779eedf2d 226 /* try again later */
andreikovacs 0:764779eedf2d 227 MSG_QueueHead( &pPhyStruct->macPhyInputQueue, pMsgIn );
andreikovacs 0:764779eedf2d 228 UnprotectFromXcvrInterrupt();
andreikovacs 0:764779eedf2d 229 return;
andreikovacs 0:764779eedf2d 230 }
andreikovacs 0:764779eedf2d 231
andreikovacs 0:764779eedf2d 232 #if gMpmIncluded_d
andreikovacs 0:764779eedf2d 233 if( status == gPhySuccess_c )
andreikovacs 0:764779eedf2d 234 {
andreikovacs 0:764779eedf2d 235 status = MPM_PrepareForTx( pMsgIn->macInstance );
andreikovacs 0:764779eedf2d 236 }
andreikovacs 0:764779eedf2d 237 #endif
andreikovacs 0:764779eedf2d 238
andreikovacs 0:764779eedf2d 239 if( status == gPhySuccess_c )
andreikovacs 0:764779eedf2d 240 {
andreikovacs 0:764779eedf2d 241 pPhyStruct->flags &= ~(gPhyFlagIdleRx_c);
andreikovacs 0:764779eedf2d 242
andreikovacs 0:764779eedf2d 243 switch( pMsgIn->msgType )
andreikovacs 0:764779eedf2d 244 {
andreikovacs 0:764779eedf2d 245 case gPdDataReq_c:
andreikovacs 0:764779eedf2d 246 status = Phy_HandlePdDataReq( pPhyStruct, (macToPdDataMessage_t *)pMsgIn );
andreikovacs 0:764779eedf2d 247 break;
andreikovacs 0:764779eedf2d 248 case gPlmeCcaReq_c:
andreikovacs 0:764779eedf2d 249 status = PhyPlmeCcaEdRequest(gPhyCCAMode1_c, gPhyContCcaDisabled);
andreikovacs 0:764779eedf2d 250 break;
andreikovacs 0:764779eedf2d 251 case gPlmeEdReq_c:
andreikovacs 0:764779eedf2d 252 status = PhyPlmeCcaEdRequest(gPhyEnergyDetectMode_c, gPhyContCcaDisabled);
andreikovacs 0:764779eedf2d 253 break;
andreikovacs 0:764779eedf2d 254 default:
andreikovacs 0:764779eedf2d 255 status = gPhyInvalidPrimitive_c;
andreikovacs 0:764779eedf2d 256 }
andreikovacs 0:764779eedf2d 257 }
andreikovacs 0:764779eedf2d 258
andreikovacs 0:764779eedf2d 259 /* Check status */
andreikovacs 0:764779eedf2d 260 if( gPhySuccess_c == status )
andreikovacs 0:764779eedf2d 261 {
andreikovacs 0:764779eedf2d 262 UnprotectFromXcvrInterrupt();
andreikovacs 0:764779eedf2d 263 return;
andreikovacs 0:764779eedf2d 264 }
andreikovacs 0:764779eedf2d 265 else
andreikovacs 0:764779eedf2d 266 {
andreikovacs 0:764779eedf2d 267 switch( pMsgIn->msgType )
andreikovacs 0:764779eedf2d 268 {
andreikovacs 0:764779eedf2d 269 case gPdDataReq_c:
andreikovacs 0:764779eedf2d 270 if( ((macToPdDataMessage_t*)pMsgIn)->msgData.dataReq.CCABeforeTx == gPhyNoCCABeforeTx_c )
andreikovacs 0:764779eedf2d 271 {
andreikovacs 0:764779eedf2d 272 PD_SendMessage(pPhyStruct, gPdDataCnf_c);
andreikovacs 0:764779eedf2d 273 break;
andreikovacs 0:764779eedf2d 274 }
andreikovacs 0:764779eedf2d 275 /* Fallthorough */
andreikovacs 0:764779eedf2d 276 case gPlmeCcaReq_c:
andreikovacs 0:764779eedf2d 277 pPhyStruct->channelParams.channelStatus = gPhyChannelBusy_c;
andreikovacs 0:764779eedf2d 278 PLME_SendMessage(pPhyStruct, gPlmeCcaCnf_c);
andreikovacs 0:764779eedf2d 279 break;
andreikovacs 0:764779eedf2d 280 case gPlmeEdReq_c:
andreikovacs 0:764779eedf2d 281 pPhyStruct->channelParams.energyLeveldB = 0;
andreikovacs 0:764779eedf2d 282 PLME_SendMessage(pPhyStruct, gPlmeEdCnf_c);
andreikovacs 0:764779eedf2d 283 break;
andreikovacs 0:764779eedf2d 284 default:
andreikovacs 0:764779eedf2d 285 PLME_SendMessage(pPhyStruct, gPlmeTimeoutInd_c);
andreikovacs 0:764779eedf2d 286 }
andreikovacs 0:764779eedf2d 287 }
andreikovacs 0:764779eedf2d 288 }/* while( MSG_Pending(&pPhyStruct->macPhyInputQueue) ) */
andreikovacs 0:764779eedf2d 289
andreikovacs 0:764779eedf2d 290 UnprotectFromXcvrInterrupt();
andreikovacs 0:764779eedf2d 291
andreikovacs 0:764779eedf2d 292 /* Check if PHY can enter Idle state */
andreikovacs 0:764779eedf2d 293 if( gIdle_c == state )
andreikovacs 0:764779eedf2d 294 {
andreikovacs 0:764779eedf2d 295 Phy_EnterIdle( pPhyStruct );
andreikovacs 0:764779eedf2d 296 }
andreikovacs 0:764779eedf2d 297 }
andreikovacs 0:764779eedf2d 298
andreikovacs 0:764779eedf2d 299 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 300 * \brief This is the PD SAP message handler
andreikovacs 0:764779eedf2d 301 *
andreikovacs 0:764779eedf2d 302 * \param[in] pMsg Pointer to the PD request message
andreikovacs 0:764779eedf2d 303 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 304 *
andreikovacs 0:764779eedf2d 305 * \return The status of the operation.
andreikovacs 0:764779eedf2d 306 *
andreikovacs 0:764779eedf2d 307 ********************************************************************************** */
andreikovacs 0:764779eedf2d 308 phyStatus_t MAC_PD_SapHandler(macToPdDataMessage_t *pMsg, instanceId_t phyInstance)
andreikovacs 0:764779eedf2d 309 {
andreikovacs 0:764779eedf2d 310 phyStatus_t result = gPhySuccess_c;
andreikovacs 0:764779eedf2d 311 uint8_t baseIndex = 0;
andreikovacs 0:764779eedf2d 312
andreikovacs 0:764779eedf2d 313 if( NULL == pMsg )
andreikovacs 0:764779eedf2d 314 {
andreikovacs 0:764779eedf2d 315 return gPhyInvalidParameter_c;
andreikovacs 0:764779eedf2d 316 }
andreikovacs 0:764779eedf2d 317
andreikovacs 0:764779eedf2d 318 #if gMpmIncluded_d
andreikovacs 0:764779eedf2d 319 if( pMsg->msgType == gPdIndQueueInsertReq_c || pMsg->msgType == gPdIndQueueRemoveReq_c )
andreikovacs 0:764779eedf2d 320 {
andreikovacs 0:764779eedf2d 321 baseIndex = MPM_GetRegSet( MPM_GetPanIndex( pMsg->macInstance ) ) *
andreikovacs 0:764779eedf2d 322 (gPhyIndirectQueueSize_c/gMpmPhyPanRegSets_c);
andreikovacs 0:764779eedf2d 323 }
andreikovacs 0:764779eedf2d 324 #endif
andreikovacs 0:764779eedf2d 325
andreikovacs 0:764779eedf2d 326 switch( pMsg->msgType )
andreikovacs 0:764779eedf2d 327 {
andreikovacs 0:764779eedf2d 328 case gPdIndQueueInsertReq_c:
andreikovacs 0:764779eedf2d 329 result = PhyPp_IndirectQueueInsert(baseIndex + pMsg->msgData.indQueueInsertReq.index,
andreikovacs 0:764779eedf2d 330 pMsg->msgData.indQueueInsertReq.checksum,
andreikovacs 0:764779eedf2d 331 phyInstance);
andreikovacs 0:764779eedf2d 332 break;
andreikovacs 0:764779eedf2d 333
andreikovacs 0:764779eedf2d 334 case gPdIndQueueRemoveReq_c:
andreikovacs 0:764779eedf2d 335 result = PhyPp_RemoveFromIndirect(baseIndex + pMsg->msgData.indQueueRemoveReq.index,
andreikovacs 0:764779eedf2d 336 phyInstance);
andreikovacs 0:764779eedf2d 337 break;
andreikovacs 0:764779eedf2d 338
andreikovacs 0:764779eedf2d 339 case gPdDataReq_c:
andreikovacs 0:764779eedf2d 340 MSG_Queue(&phyLocal[phyInstance].macPhyInputQueue, pMsg);
andreikovacs 0:764779eedf2d 341 Phy24Task( &phyLocal[phyInstance] );
andreikovacs 0:764779eedf2d 342 break;
andreikovacs 0:764779eedf2d 343
andreikovacs 0:764779eedf2d 344 default:
andreikovacs 0:764779eedf2d 345 result = gPhyInvalidPrimitive_c;
andreikovacs 0:764779eedf2d 346 }
andreikovacs 0:764779eedf2d 347
andreikovacs 0:764779eedf2d 348 return result;
andreikovacs 0:764779eedf2d 349 }
andreikovacs 0:764779eedf2d 350
andreikovacs 0:764779eedf2d 351 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 352 * \brief This is the PLME SAP message handler
andreikovacs 0:764779eedf2d 353 *
andreikovacs 0:764779eedf2d 354 * \param[in] pMsg Pointer to the PLME request message
andreikovacs 0:764779eedf2d 355 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 356 *
andreikovacs 0:764779eedf2d 357 * \return phyStatus_t The status of the operation.
andreikovacs 0:764779eedf2d 358 *
andreikovacs 0:764779eedf2d 359 ********************************************************************************** */
andreikovacs 0:764779eedf2d 360 phyStatus_t MAC_PLME_SapHandler(macToPlmeMessage_t * pMsg, instanceId_t phyInstance)
andreikovacs 0:764779eedf2d 361 {
andreikovacs 0:764779eedf2d 362 Phy_PhyLocalStruct_t *pPhyStruct = &phyLocal[phyInstance];
andreikovacs 0:764779eedf2d 363 uint8_t phyRegSet = 0;
andreikovacs 0:764779eedf2d 364 #if gMpmIncluded_d
andreikovacs 0:764779eedf2d 365 phyStatus_t result;
andreikovacs 0:764779eedf2d 366 int32_t panIdx = MPM_GetPanIndex( pMsg->macInstance );
andreikovacs 0:764779eedf2d 367
andreikovacs 0:764779eedf2d 368 phyRegSet = MPM_GetRegSet( panIdx );
andreikovacs 0:764779eedf2d 369 #endif
andreikovacs 0:764779eedf2d 370
andreikovacs 0:764779eedf2d 371 if( NULL == pMsg )
andreikovacs 0:764779eedf2d 372 {
andreikovacs 0:764779eedf2d 373 return gPhyInvalidParameter_c;
andreikovacs 0:764779eedf2d 374 }
andreikovacs 0:764779eedf2d 375
andreikovacs 0:764779eedf2d 376 switch( pMsg->msgType )
andreikovacs 0:764779eedf2d 377 {
andreikovacs 0:764779eedf2d 378 case gPlmeEdReq_c:
andreikovacs 0:764779eedf2d 379 case gPlmeCcaReq_c:
andreikovacs 0:764779eedf2d 380 MSG_Queue(&phyLocal[phyInstance].macPhyInputQueue, pMsg);
andreikovacs 0:764779eedf2d 381 Phy24Task( &phyLocal[phyInstance] );
andreikovacs 0:764779eedf2d 382 break;
andreikovacs 0:764779eedf2d 383
andreikovacs 0:764779eedf2d 384 case gPlmeSetReq_c:
andreikovacs 0:764779eedf2d 385 #if gMpmIncluded_d
andreikovacs 0:764779eedf2d 386 result = MPM_SetPIB(pMsg->msgData.setReq.PibAttribute,
andreikovacs 0:764779eedf2d 387 &pMsg->msgData.setReq.PibAttributeValue,
andreikovacs 0:764779eedf2d 388 panIdx );
andreikovacs 0:764779eedf2d 389 if( !MPM_isPanActive(panIdx) )
andreikovacs 0:764779eedf2d 390 {
andreikovacs 0:764779eedf2d 391 return result;
andreikovacs 0:764779eedf2d 392 }
andreikovacs 0:764779eedf2d 393 #endif
andreikovacs 0:764779eedf2d 394 return PhyPlmeSetPIBRequest(pMsg->msgData.setReq.PibAttribute, pMsg->msgData.setReq.PibAttributeValue, phyRegSet, phyInstance);
andreikovacs 0:764779eedf2d 395
andreikovacs 0:764779eedf2d 396 case gPlmeGetReq_c:
andreikovacs 0:764779eedf2d 397 #if gMpmIncluded_d
andreikovacs 0:764779eedf2d 398 if( gPhySuccess_c == MPM_GetPIB(pMsg->msgData.getReq.PibAttribute, pMsg->msgData.getReq.pPibAttributeValue, panIdx) )
andreikovacs 0:764779eedf2d 399 {
andreikovacs 0:764779eedf2d 400 break;
andreikovacs 0:764779eedf2d 401 }
andreikovacs 0:764779eedf2d 402 #endif
andreikovacs 0:764779eedf2d 403 return PhyPlmeGetPIBRequest( pMsg->msgData.getReq.PibAttribute, pMsg->msgData.getReq.pPibAttributeValue, phyRegSet, phyInstance);
andreikovacs 0:764779eedf2d 404
andreikovacs 0:764779eedf2d 405 case gPlmeSetTRxStateReq_c:
andreikovacs 0:764779eedf2d 406 if(gPhySetRxOn_c == pMsg->msgData.setTRxStateReq.state)
andreikovacs 0:764779eedf2d 407 {
andreikovacs 0:764779eedf2d 408 if( PhyIsIdleRx(phyInstance) )
andreikovacs 0:764779eedf2d 409 {
andreikovacs 0:764779eedf2d 410 PhyPlmeForceTrxOffRequest();
andreikovacs 0:764779eedf2d 411 }
andreikovacs 0:764779eedf2d 412 else if( gIdle_c != PhyGetSeqState() )
andreikovacs 0:764779eedf2d 413 {
andreikovacs 0:764779eedf2d 414 return gPhyBusy_c;
andreikovacs 0:764779eedf2d 415 }
andreikovacs 0:764779eedf2d 416 #if gMpmIncluded_d
andreikovacs 0:764779eedf2d 417 /* If another PAN has the RxOnWhenIdle PIB set, enable the DualPan Auto mode */
andreikovacs 0:764779eedf2d 418 if( gPhySuccess_c != MPM_PrepareForRx( pMsg->macInstance ) )
andreikovacs 0:764779eedf2d 419 return gPhyBusy_c;
andreikovacs 0:764779eedf2d 420 #endif
andreikovacs 0:764779eedf2d 421 pPhyStruct->flags &= ~(gPhyFlagIdleRx_c);
andreikovacs 0:764779eedf2d 422 Phy_SetSequenceTiming(pMsg->msgData.setTRxStateReq.startTime,
andreikovacs 0:764779eedf2d 423 pMsg->msgData.setTRxStateReq.rxDuration);
andreikovacs 0:764779eedf2d 424
andreikovacs 0:764779eedf2d 425 return PhyPlmeRxRequest(pMsg->msgData.setTRxStateReq.slottedMode, (phyRxParams_t *) &pPhyStruct->rxParams);
andreikovacs 0:764779eedf2d 426 }
andreikovacs 0:764779eedf2d 427 else if (gPhyForceTRxOff_c == pMsg->msgData.setTRxStateReq.state)
andreikovacs 0:764779eedf2d 428 {
andreikovacs 0:764779eedf2d 429 #if gMpmIncluded_d
andreikovacs 0:764779eedf2d 430 if( !MPM_isPanActive(panIdx) )
andreikovacs 0:764779eedf2d 431 return gPhySuccess_c;
andreikovacs 0:764779eedf2d 432 #endif
andreikovacs 0:764779eedf2d 433 pPhyStruct->flags &= ~(gPhyFlagIdleRx_c);
andreikovacs 0:764779eedf2d 434 PhyPlmeForceTrxOffRequest();
andreikovacs 0:764779eedf2d 435 }
andreikovacs 0:764779eedf2d 436 break;
andreikovacs 0:764779eedf2d 437
andreikovacs 0:764779eedf2d 438 default:
andreikovacs 0:764779eedf2d 439 return gPhyInvalidPrimitive_c;
andreikovacs 0:764779eedf2d 440 }
andreikovacs 0:764779eedf2d 441
andreikovacs 0:764779eedf2d 442 return gPhySuccess_c;
andreikovacs 0:764779eedf2d 443 }
andreikovacs 0:764779eedf2d 444
andreikovacs 0:764779eedf2d 445 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 446 * \brief This function programs a new TX sequence
andreikovacs 0:764779eedf2d 447 *
andreikovacs 0:764779eedf2d 448 * \param[in] pMsg Pointer to the PD request message
andreikovacs 0:764779eedf2d 449 * \param[in] pPhyData pointer to PHY data
andreikovacs 0:764779eedf2d 450 *
andreikovacs 0:764779eedf2d 451 * \return The status of the operation.
andreikovacs 0:764779eedf2d 452 *
andreikovacs 0:764779eedf2d 453 ********************************************************************************** */
andreikovacs 0:764779eedf2d 454 static phyStatus_t Phy_HandlePdDataReq( Phy_PhyLocalStruct_t *pPhyData, macToPdDataMessage_t * pMsg )
andreikovacs 0:764779eedf2d 455 {
andreikovacs 0:764779eedf2d 456 phyStatus_t status = gPhySuccess_c;
andreikovacs 0:764779eedf2d 457 uint32_t time;
andreikovacs 0:764779eedf2d 458
andreikovacs 0:764779eedf2d 459 if( NULL == pMsg->msgData.dataReq.pPsdu )
andreikovacs 0:764779eedf2d 460 {
andreikovacs 0:764779eedf2d 461 return gPhyInvalidParameter_c;
andreikovacs 0:764779eedf2d 462 }
andreikovacs 0:764779eedf2d 463
andreikovacs 0:764779eedf2d 464 ProtectFromXcvrInterrupt();
andreikovacs 0:764779eedf2d 465
andreikovacs 0:764779eedf2d 466 if( pMsg->msgData.dataReq.startTime != gPhySeqStartAsap_c )
andreikovacs 0:764779eedf2d 467 {
andreikovacs 0:764779eedf2d 468 PhyTimeSetEventTrigger( (uint16_t) pMsg->msgData.dataReq.startTime );
andreikovacs 0:764779eedf2d 469 }
andreikovacs 0:764779eedf2d 470
andreikovacs 0:764779eedf2d 471 status = PhyPdDataRequest(&pMsg->msgData.dataReq , &pPhyData->rxParams, &pPhyData->txParams);
andreikovacs 0:764779eedf2d 472
andreikovacs 0:764779eedf2d 473 if( pMsg->msgData.dataReq.txDuration != gPhySeqStartAsap_c )
andreikovacs 0:764779eedf2d 474 {
andreikovacs 0:764779eedf2d 475 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 476 PhyTimeReadClock( &time );
andreikovacs 0:764779eedf2d 477 time += pMsg->msgData.dataReq.txDuration;
andreikovacs 0:764779eedf2d 478 /* Compensate PHY overhead, including WU time */
andreikovacs 0:764779eedf2d 479 time += 54;
andreikovacs 0:764779eedf2d 480 PhyTimeSetEventTimeout( &time );
andreikovacs 0:764779eedf2d 481 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 482 }
andreikovacs 0:764779eedf2d 483
andreikovacs 0:764779eedf2d 484 UnprotectFromXcvrInterrupt();
andreikovacs 0:764779eedf2d 485
andreikovacs 0:764779eedf2d 486 if( gPhySuccess_c != status )
andreikovacs 0:764779eedf2d 487 {
andreikovacs 0:764779eedf2d 488 PhyTimeDisableEventTrigger();
andreikovacs 0:764779eedf2d 489 PhyTimeDisableEventTimeout();
andreikovacs 0:764779eedf2d 490 }
andreikovacs 0:764779eedf2d 491
andreikovacs 0:764779eedf2d 492 return status;
andreikovacs 0:764779eedf2d 493 }
andreikovacs 0:764779eedf2d 494
andreikovacs 0:764779eedf2d 495 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 496 * \brief This function sets the start time and the timeout value for a sequence.
andreikovacs 0:764779eedf2d 497 *
andreikovacs 0:764779eedf2d 498 * \param[in] startTime The absolute start time for the sequence.
andreikovacs 0:764779eedf2d 499 * If startTime is gPhySeqStartAsap_c, the start timer is disabled.
andreikovacs 0:764779eedf2d 500 * \param[in] seqDuration The duration of the sequence.
andreikovacs 0:764779eedf2d 501 * If seqDuration is 0xFFFFFFFF, the timeout is disabled.
andreikovacs 0:764779eedf2d 502 *
andreikovacs 0:764779eedf2d 503 ********************************************************************************** */
andreikovacs 0:764779eedf2d 504 void Phy_SetSequenceTiming(uint32_t startTime, uint32_t seqDuration)
andreikovacs 0:764779eedf2d 505 {
andreikovacs 0:764779eedf2d 506 uint32_t endTime;
andreikovacs 0:764779eedf2d 507
andreikovacs 0:764779eedf2d 508 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 509
andreikovacs 0:764779eedf2d 510 if( gPhySeqStartAsap_c == startTime )
andreikovacs 0:764779eedf2d 511 {
andreikovacs 0:764779eedf2d 512 PhyTimeReadClock( &endTime );
andreikovacs 0:764779eedf2d 513 }
andreikovacs 0:764779eedf2d 514 else
andreikovacs 0:764779eedf2d 515 {
andreikovacs 0:764779eedf2d 516 PhyTimeSetEventTrigger( (uint16_t) startTime );
andreikovacs 0:764779eedf2d 517 endTime = startTime & gPhyTimeMask_c;
andreikovacs 0:764779eedf2d 518 }
andreikovacs 0:764779eedf2d 519
andreikovacs 0:764779eedf2d 520 if( 0xFFFFFFFF != seqDuration )
andreikovacs 0:764779eedf2d 521 {
andreikovacs 0:764779eedf2d 522 endTime += seqDuration;
andreikovacs 0:764779eedf2d 523 endTime = endTime & gPhyTimeMask_c;
andreikovacs 0:764779eedf2d 524
andreikovacs 0:764779eedf2d 525 PhyTimeSetEventTimeout( &(endTime) );
andreikovacs 0:764779eedf2d 526 }
andreikovacs 0:764779eedf2d 527
andreikovacs 0:764779eedf2d 528 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 529 }
andreikovacs 0:764779eedf2d 530
andreikovacs 0:764779eedf2d 531 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 532 * \brief This function starts the IdleRX if the PhyRxOnWhenIdle PIB is set
andreikovacs 0:764779eedf2d 533 *
andreikovacs 0:764779eedf2d 534 * \param[in] pPhyData pointer to PHY data
andreikovacs 0:764779eedf2d 535 *
andreikovacs 0:764779eedf2d 536 ********************************************************************************** */
andreikovacs 0:764779eedf2d 537 void Phy_EnterIdle( Phy_PhyLocalStruct_t *pPhyData )
andreikovacs 0:764779eedf2d 538 {
andreikovacs 0:764779eedf2d 539 if( (pPhyData->flags & gPhyFlagRxOnWhenIdle_c)
andreikovacs 0:764779eedf2d 540 #if gMpmIncluded_d
andreikovacs 0:764779eedf2d 541 /* Prepare the Active PAN/PANs */
andreikovacs 0:764779eedf2d 542 && (gPhySuccess_c == MPM_PrepareForRx(gInvalidInstanceId_c))
andreikovacs 0:764779eedf2d 543 #endif
andreikovacs 0:764779eedf2d 544 )
andreikovacs 0:764779eedf2d 545 {
andreikovacs 0:764779eedf2d 546 pPhyData->flags |= gPhyFlagIdleRx_c;
andreikovacs 0:764779eedf2d 547 Phy_SetSequenceTiming( gPhySeqStartAsap_c, mPhyMaxIdleRxDuration_c );
andreikovacs 0:764779eedf2d 548 (void)PhyPlmeRxRequest( gPhyUnslottedMode_c, (phyRxParams_t*)&pPhyData->rxParams );
andreikovacs 0:764779eedf2d 549 }
andreikovacs 0:764779eedf2d 550 else
andreikovacs 0:764779eedf2d 551 {
andreikovacs 0:764779eedf2d 552 pPhyData->flags &= ~(gPhyFlagIdleRx_c);
andreikovacs 0:764779eedf2d 553 }
andreikovacs 0:764779eedf2d 554 }
andreikovacs 0:764779eedf2d 555
andreikovacs 0:764779eedf2d 556 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 557 * \brief This function sets the value of the maxFrameWaitTime PIB
andreikovacs 0:764779eedf2d 558 *
andreikovacs 0:764779eedf2d 559 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 560 * \param[in] time The maxFrameWaitTime value
andreikovacs 0:764779eedf2d 561 *
andreikovacs 0:764779eedf2d 562 ********************************************************************************** */
andreikovacs 0:764779eedf2d 563 void PhyPlmeSetFrameWaitTime( uint32_t time, instanceId_t instanceId )
andreikovacs 0:764779eedf2d 564 {
andreikovacs 0:764779eedf2d 565 phyLocal[instanceId].maxFrameWaitTime = time;
andreikovacs 0:764779eedf2d 566 }
andreikovacs 0:764779eedf2d 567
andreikovacs 0:764779eedf2d 568 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 569 * \brief This function sets the state of the PhyRxOnWhenIdle PIB
andreikovacs 0:764779eedf2d 570 *
andreikovacs 0:764779eedf2d 571 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 572 * \param[in] state The PhyRxOnWhenIdle value
andreikovacs 0:764779eedf2d 573 *
andreikovacs 0:764779eedf2d 574 ********************************************************************************** */
andreikovacs 0:764779eedf2d 575 void PhyPlmeSetRxOnWhenIdle( bool_t state, instanceId_t instanceId )
andreikovacs 0:764779eedf2d 576 {
andreikovacs 0:764779eedf2d 577 uint8_t radioState = PhyGetSeqState();
andreikovacs 0:764779eedf2d 578 #if gMpmIncluded_d
andreikovacs 0:764779eedf2d 579 /* Check if at least one PAN has RxOnWhenIdle set */
andreikovacs 0:764779eedf2d 580 if( FALSE == state )
andreikovacs 0:764779eedf2d 581 {
andreikovacs 0:764779eedf2d 582 uint32_t i;
andreikovacs 0:764779eedf2d 583
andreikovacs 0:764779eedf2d 584 for( i=0; i<gMpmMaxPANs_c; i++ )
andreikovacs 0:764779eedf2d 585 {
andreikovacs 0:764779eedf2d 586 MPM_GetPIB( gPhyPibRxOnWhenIdle, &state, i );
andreikovacs 0:764779eedf2d 587 if( state )
andreikovacs 0:764779eedf2d 588 break;
andreikovacs 0:764779eedf2d 589 }
andreikovacs 0:764779eedf2d 590 }
andreikovacs 0:764779eedf2d 591 #endif
andreikovacs 0:764779eedf2d 592 if( state )
andreikovacs 0:764779eedf2d 593 {
andreikovacs 0:764779eedf2d 594 phyLocal[instanceId].flags |= gPhyFlagRxOnWhenIdle_c;
andreikovacs 0:764779eedf2d 595 if( radioState == gIdle_c)
andreikovacs 0:764779eedf2d 596 {
andreikovacs 0:764779eedf2d 597 Phy_EnterIdle( &phyLocal[instanceId] );
andreikovacs 0:764779eedf2d 598 }
andreikovacs 0:764779eedf2d 599 #if gMpmIncluded_d
andreikovacs 0:764779eedf2d 600 else if( (radioState == gRX_c) && (phyLocal[instanceId].flags & gPhyFlagIdleRx_c) )
andreikovacs 0:764779eedf2d 601 {
andreikovacs 0:764779eedf2d 602 PhyPlmeForceTrxOffRequest();
andreikovacs 0:764779eedf2d 603 Phy_EnterIdle( &phyLocal[instanceId] );
andreikovacs 0:764779eedf2d 604 }
andreikovacs 0:764779eedf2d 605 #endif
andreikovacs 0:764779eedf2d 606 }
andreikovacs 0:764779eedf2d 607 else
andreikovacs 0:764779eedf2d 608 {
andreikovacs 0:764779eedf2d 609 phyLocal[instanceId].flags &= ~gPhyFlagRxOnWhenIdle_c;
andreikovacs 0:764779eedf2d 610 if( (radioState == gRX_c) && (phyLocal[instanceId].flags & gPhyFlagIdleRx_c) )
andreikovacs 0:764779eedf2d 611 {
andreikovacs 0:764779eedf2d 612 PhyPlmeForceTrxOffRequest();
andreikovacs 0:764779eedf2d 613 phyLocal[instanceId].flags &= ~gPhyFlagIdleRx_c;
andreikovacs 0:764779eedf2d 614 }
andreikovacs 0:764779eedf2d 615 }
andreikovacs 0:764779eedf2d 616 }
andreikovacs 0:764779eedf2d 617
andreikovacs 0:764779eedf2d 618 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 619 * \brief This function starts the IdleRX if the PhyRxOnWhenIdle PIB is set
andreikovacs 0:764779eedf2d 620 *
andreikovacs 0:764779eedf2d 621 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 622 *
andreikovacs 0:764779eedf2d 623 ********************************************************************************** */
andreikovacs 0:764779eedf2d 624 bool_t PhyIsIdleRx( instanceId_t instanceId )
andreikovacs 0:764779eedf2d 625 {
andreikovacs 0:764779eedf2d 626 if( (phyLocal[instanceId].flags & gPhyFlagIdleRx_c) && (gRX_c == PhyGetSeqState()))
andreikovacs 0:764779eedf2d 627 return TRUE;
andreikovacs 0:764779eedf2d 628
andreikovacs 0:764779eedf2d 629 return FALSE;
andreikovacs 0:764779eedf2d 630 }
andreikovacs 0:764779eedf2d 631
andreikovacs 0:764779eedf2d 632 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 633 * \brief This function signals the PHY task that a TX operation completed successfully.
andreikovacs 0:764779eedf2d 634 * If the received ACK has FP=1, then the radio will enter RX state for
andreikovacs 0:764779eedf2d 635 * maxFrameWaitTime duration.
andreikovacs 0:764779eedf2d 636 *
andreikovacs 0:764779eedf2d 637 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 638 * \param[in] framePending The value of the framePending bit for the received ACK
andreikovacs 0:764779eedf2d 639 *
andreikovacs 0:764779eedf2d 640 ********************************************************************************** */
andreikovacs 0:764779eedf2d 641 void Radio_Phy_PdDataConfirm(instanceId_t instanceId, bool_t framePending)
andreikovacs 0:764779eedf2d 642 {
andreikovacs 0:764779eedf2d 643 PhyTimeDisableEventTimeout();
andreikovacs 0:764779eedf2d 644
andreikovacs 0:764779eedf2d 645 if( framePending )
andreikovacs 0:764779eedf2d 646 {
andreikovacs 0:764779eedf2d 647 phyLocal[instanceId].flags |= gPhyFlagFramePending_c;
andreikovacs 0:764779eedf2d 648 if( phyLocal[instanceId].maxFrameWaitTime > 0 )
andreikovacs 0:764779eedf2d 649 {
andreikovacs 0:764779eedf2d 650 /* Restart Rx asap if an ACK with FP=1 is received */
andreikovacs 0:764779eedf2d 651 phyLocal[instanceId].flags &= ~(gPhyFlagIdleRx_c);
andreikovacs 0:764779eedf2d 652 Phy_SetSequenceTiming( gPhySeqStartAsap_c, phyLocal[instanceId].maxFrameWaitTime );
andreikovacs 0:764779eedf2d 653 PhyPlmeRxRequest( gPhyUnslottedMode_c, (phyRxParams_t *) &phyLocal[instanceId].rxParams );
andreikovacs 0:764779eedf2d 654 }
andreikovacs 0:764779eedf2d 655 }
andreikovacs 0:764779eedf2d 656 else
andreikovacs 0:764779eedf2d 657 {
andreikovacs 0:764779eedf2d 658 phyLocal[instanceId].flags &= ~gPhyFlagFramePending_c;
andreikovacs 0:764779eedf2d 659 }
andreikovacs 0:764779eedf2d 660
andreikovacs 0:764779eedf2d 661 PD_SendMessage(&phyLocal[instanceId], gPdDataCnf_c);
andreikovacs 0:764779eedf2d 662 Phy24Task(&phyLocal[instanceId]);
andreikovacs 0:764779eedf2d 663 }
andreikovacs 0:764779eedf2d 664
andreikovacs 0:764779eedf2d 665 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 666 * \brief This function signals the PHY task that new data has been received
andreikovacs 0:764779eedf2d 667 *
andreikovacs 0:764779eedf2d 668 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 669 *
andreikovacs 0:764779eedf2d 670 ********************************************************************************** */
andreikovacs 0:764779eedf2d 671 void Radio_Phy_PdDataIndication(instanceId_t instanceId)
andreikovacs 0:764779eedf2d 672 {
andreikovacs 0:764779eedf2d 673 PhyTimeDisableEventTimeout();
andreikovacs 0:764779eedf2d 674
andreikovacs 0:764779eedf2d 675 PD_SendMessage(&phyLocal[instanceId], gPdDataInd_c);
andreikovacs 0:764779eedf2d 676 Phy24Task(&phyLocal[instanceId]);
andreikovacs 0:764779eedf2d 677 }
andreikovacs 0:764779eedf2d 678
andreikovacs 0:764779eedf2d 679 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 680 * \brief This function signals the PHY task that timer1 compare match occured
andreikovacs 0:764779eedf2d 681 *
andreikovacs 0:764779eedf2d 682 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 683 *
andreikovacs 0:764779eedf2d 684 ********************************************************************************** */
andreikovacs 0:764779eedf2d 685 void Radio_Phy_TimeWaitTimeoutIndication(instanceId_t instanceId)
andreikovacs 0:764779eedf2d 686 {
andreikovacs 0:764779eedf2d 687 PhyTime_ISR();
andreikovacs 0:764779eedf2d 688 }
andreikovacs 0:764779eedf2d 689
andreikovacs 0:764779eedf2d 690 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 691 * \brief This function signals the PHY task that a CCA sequence has finished
andreikovacs 0:764779eedf2d 692 *
andreikovacs 0:764779eedf2d 693 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 694 * \param[in] phyChannelStatus The status of the channel: Idle/Busy
andreikovacs 0:764779eedf2d 695 *
andreikovacs 0:764779eedf2d 696 * \return None.
andreikovacs 0:764779eedf2d 697 *
andreikovacs 0:764779eedf2d 698 ********************************************************************************** */
andreikovacs 0:764779eedf2d 699 void Radio_Phy_PlmeCcaConfirm(phyStatus_t phyChannelStatus, instanceId_t instanceId)
andreikovacs 0:764779eedf2d 700 {
andreikovacs 0:764779eedf2d 701 PhyTimeDisableEventTimeout();
andreikovacs 0:764779eedf2d 702
andreikovacs 0:764779eedf2d 703 phyLocal[instanceId].channelParams.channelStatus = phyChannelStatus;
andreikovacs 0:764779eedf2d 704
andreikovacs 0:764779eedf2d 705 PLME_SendMessage(&phyLocal[instanceId], gPlmeCcaCnf_c);
andreikovacs 0:764779eedf2d 706 Phy24Task(&phyLocal[instanceId]);
andreikovacs 0:764779eedf2d 707 }
andreikovacs 0:764779eedf2d 708
andreikovacs 0:764779eedf2d 709 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 710 * \brief This function signals the PHY task that a ED sequence has finished
andreikovacs 0:764779eedf2d 711 *
andreikovacs 0:764779eedf2d 712 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 713 * \param[in] energyLevel The enetgy level on the channel.
andreikovacs 0:764779eedf2d 714 * \param[in] energyLeveldB The energy level in DB
andreikovacs 0:764779eedf2d 715 *
andreikovacs 0:764779eedf2d 716 ********************************************************************************** */
andreikovacs 0:764779eedf2d 717 void Radio_Phy_PlmeEdConfirm(uint8_t energyLeveldB, instanceId_t instanceId)
andreikovacs 0:764779eedf2d 718 {
andreikovacs 0:764779eedf2d 719 PhyTimeDisableEventTimeout();
andreikovacs 0:764779eedf2d 720
andreikovacs 0:764779eedf2d 721 phyLocal[instanceId].channelParams.energyLeveldB = energyLeveldB;
andreikovacs 0:764779eedf2d 722
andreikovacs 0:764779eedf2d 723 PLME_SendMessage(&phyLocal[instanceId], gPlmeEdCnf_c);
andreikovacs 0:764779eedf2d 724 Phy24Task(&phyLocal[instanceId]);
andreikovacs 0:764779eedf2d 725 }
andreikovacs 0:764779eedf2d 726
andreikovacs 0:764779eedf2d 727 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 728 * \brief This function signals the PHY task that the programmed sequence has timed out
andreikovacs 0:764779eedf2d 729 * The Radio is forced to Idle.
andreikovacs 0:764779eedf2d 730 *
andreikovacs 0:764779eedf2d 731 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 732 *
andreikovacs 0:764779eedf2d 733 ********************************************************************************** */
andreikovacs 0:764779eedf2d 734 void Radio_Phy_TimeRxTimeoutIndication(instanceId_t instanceId)
andreikovacs 0:764779eedf2d 735 {
andreikovacs 0:764779eedf2d 736 if( !(phyLocal[instanceId].flags & gPhyFlagIdleRx_c) )
andreikovacs 0:764779eedf2d 737 PLME_SendMessage(&phyLocal[instanceId], gPlmeTimeoutInd_c);
andreikovacs 0:764779eedf2d 738
andreikovacs 0:764779eedf2d 739 Phy24Task(&phyLocal[instanceId]);
andreikovacs 0:764779eedf2d 740 }
andreikovacs 0:764779eedf2d 741
andreikovacs 0:764779eedf2d 742 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 743 * \brief This function signals the PHY task that the programmed sequence has started
andreikovacs 0:764779eedf2d 744 *
andreikovacs 0:764779eedf2d 745 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 746 *
andreikovacs 0:764779eedf2d 747 * \return None.
andreikovacs 0:764779eedf2d 748 *
andreikovacs 0:764779eedf2d 749 ********************************************************************************** */
andreikovacs 0:764779eedf2d 750 void Radio_Phy_TimeStartEventIndication(instanceId_t instanceId)
andreikovacs 0:764779eedf2d 751 {
andreikovacs 0:764779eedf2d 752 #ifdef MAC_PHY_DEBUG
andreikovacs 0:764779eedf2d 753 PLME_SendMessage(&phyLocal[instanceId], gPlme_StartEventInd_c);
andreikovacs 0:764779eedf2d 754 Phy24Task(&phyLocal[instanceId]);
andreikovacs 0:764779eedf2d 755 #endif
andreikovacs 0:764779eedf2d 756 }
andreikovacs 0:764779eedf2d 757
andreikovacs 0:764779eedf2d 758 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 759 * \brief This function signals the PHY task that a SFD was detected.
andreikovacs 0:764779eedf2d 760 * Also, if there is not enough time to receive the entire packet, the
andreikovacs 0:764779eedf2d 761 * RX timeout will be extended.
andreikovacs 0:764779eedf2d 762 *
andreikovacs 0:764779eedf2d 763 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 764 * \param[in] frameLen the length of the PSDU
andreikovacs 0:764779eedf2d 765 *
andreikovacs 0:764779eedf2d 766 ********************************************************************************** */
andreikovacs 0:764779eedf2d 767 void Radio_Phy_PlmeRxSfdDetect(instanceId_t instanceId, uint32_t frameLen)
andreikovacs 0:764779eedf2d 768 {
andreikovacs 0:764779eedf2d 769 if( phyLocal[instanceId].flags & gPhyFlagDeferTx_c )
andreikovacs 0:764779eedf2d 770 {
andreikovacs 0:764779eedf2d 771 uint32_t currentTime;
andreikovacs 0:764779eedf2d 772 uint32_t time;
andreikovacs 0:764779eedf2d 773
andreikovacs 0:764779eedf2d 774 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 775
andreikovacs 0:764779eedf2d 776 //Read currentTime and Timeout values [sym]
andreikovacs 0:764779eedf2d 777 PhyTimeReadClock(&currentTime);
andreikovacs 0:764779eedf2d 778
andreikovacs 0:764779eedf2d 779 frameLen = frameLen * 2 + 12 + 22 + 2; //Convert to symbols and add IFS and ACK duration
andreikovacs 0:764779eedf2d 780
andreikovacs 0:764779eedf2d 781 if( mPhySeqTimeout > currentTime )
andreikovacs 0:764779eedf2d 782 {
andreikovacs 0:764779eedf2d 783 time = mPhySeqTimeout - currentTime;
andreikovacs 0:764779eedf2d 784 }
andreikovacs 0:764779eedf2d 785 else
andreikovacs 0:764779eedf2d 786 {
andreikovacs 0:764779eedf2d 787 time = (gPhyTimeMask_c - currentTime + mPhySeqTimeout) & gPhyTimeMask_c;
andreikovacs 0:764779eedf2d 788 }
andreikovacs 0:764779eedf2d 789
andreikovacs 0:764779eedf2d 790 if( time > 4 )
andreikovacs 0:764779eedf2d 791 {
andreikovacs 0:764779eedf2d 792 mPhySeqTimeout = (currentTime + frameLen) & gPhyTimeMask_c;
andreikovacs 0:764779eedf2d 793 MCR20Drv_DirectAccessSPIMultiByteWrite( T3CMP_LSB, (uint8_t *)&mPhySeqTimeout, 3);
andreikovacs 0:764779eedf2d 794 }
andreikovacs 0:764779eedf2d 795
andreikovacs 0:764779eedf2d 796 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 797 }
andreikovacs 0:764779eedf2d 798
andreikovacs 0:764779eedf2d 799 #ifdef MAC_PHY_DEBUG
andreikovacs 0:764779eedf2d 800 PLME_SendMessage(&phyLocal[instanceId], gPlme_RxSfdDetectInd_c);
andreikovacs 0:764779eedf2d 801 Phy24Task(&phyLocal[instanceId]);
andreikovacs 0:764779eedf2d 802 #endif
andreikovacs 0:764779eedf2d 803 }
andreikovacs 0:764779eedf2d 804
andreikovacs 0:764779eedf2d 805 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 806 * \brief This function signals the PHY task that a Sync Loss occured (PLL unlock)
andreikovacs 0:764779eedf2d 807 * The Radio is forced to Idle.
andreikovacs 0:764779eedf2d 808 *
andreikovacs 0:764779eedf2d 809 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 810 *
andreikovacs 0:764779eedf2d 811 ********************************************************************************** */
andreikovacs 0:764779eedf2d 812 void Radio_Phy_PlmeSyncLossIndication(instanceId_t instanceId)
andreikovacs 0:764779eedf2d 813 {
andreikovacs 0:764779eedf2d 814 PhyPlmeForceTrxOffRequest();
andreikovacs 0:764779eedf2d 815 #ifdef MAC_PHY_DEBUG
andreikovacs 0:764779eedf2d 816 PLME_SendMessage(&phyLocal[instanceId], gPlme_SyncLossInd_c);
andreikovacs 0:764779eedf2d 817 #endif
andreikovacs 0:764779eedf2d 818 Radio_Phy_TimeRxTimeoutIndication(instanceId);
andreikovacs 0:764779eedf2d 819 }
andreikovacs 0:764779eedf2d 820
andreikovacs 0:764779eedf2d 821 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 822 * \brief This function signals the PHY task that a Filter Fail occured
andreikovacs 0:764779eedf2d 823 *
andreikovacs 0:764779eedf2d 824 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 825 *
andreikovacs 0:764779eedf2d 826 ********************************************************************************** */
andreikovacs 0:764779eedf2d 827 void Radio_Phy_PlmeFilterFailRx(instanceId_t instanceId)
andreikovacs 0:764779eedf2d 828 {
andreikovacs 0:764779eedf2d 829 #ifdef MAC_PHY_DEBUG
andreikovacs 0:764779eedf2d 830 PLME_SendMessage(&phyLocal[instanceId], gPlme_FilterFailInd_c);
andreikovacs 0:764779eedf2d 831 Phy24Task(&phyLocal[instanceId]);
andreikovacs 0:764779eedf2d 832 #endif
andreikovacs 0:764779eedf2d 833 }
andreikovacs 0:764779eedf2d 834
andreikovacs 0:764779eedf2d 835 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 836 * \brief This function signals the PHY task that an unexpected Transceiver Reset
andreikovacs 0:764779eedf2d 837 * occured and force the TRX to Off
andreikovacs 0:764779eedf2d 838 *
andreikovacs 0:764779eedf2d 839 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 840 *
andreikovacs 0:764779eedf2d 841 ********************************************************************************** */
andreikovacs 0:764779eedf2d 842 void Radio_Phy_UnexpectedTransceiverReset(instanceId_t instanceId)
andreikovacs 0:764779eedf2d 843 {
andreikovacs 0:764779eedf2d 844 PhyPlmeForceTrxOffRequest();
andreikovacs 0:764779eedf2d 845 #ifdef MAC_PHY_DEBUG
andreikovacs 0:764779eedf2d 846 PLME_SendMessage(&phyLocal[instanceId], gPlme_UnexpectedRadioResetInd_c);
andreikovacs 0:764779eedf2d 847 #endif
andreikovacs 0:764779eedf2d 848 Radio_Phy_TimeRxTimeoutIndication(instanceId);
andreikovacs 0:764779eedf2d 849 }
andreikovacs 0:764779eedf2d 850
andreikovacs 0:764779eedf2d 851 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 852 * \brief Senf a PLME message to upper layer
andreikovacs 0:764779eedf2d 853 *
andreikovacs 0:764779eedf2d 854 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 855 * \param[in] msgType The type of message to be sent
andreikovacs 0:764779eedf2d 856 *
andreikovacs 0:764779eedf2d 857 ********************************************************************************** */
andreikovacs 0:764779eedf2d 858 static void PLME_SendMessage(Phy_PhyLocalStruct_t *pPhyStruct, phyMessageId_t msgType)
andreikovacs 0:764779eedf2d 859 {
andreikovacs 0:764779eedf2d 860 plmeToMacMessage_t * pMsg = MEM_BufferAlloc(sizeof(plmeToMacMessage_t));
andreikovacs 0:764779eedf2d 861
andreikovacs 0:764779eedf2d 862 if(NULL == pMsg)
andreikovacs 0:764779eedf2d 863 {
andreikovacs 0:764779eedf2d 864 //panic(0,(uint32_t)PLME_SendMessage,0,msgType);
andreikovacs 0:764779eedf2d 865 return;
andreikovacs 0:764779eedf2d 866 }
andreikovacs 0:764779eedf2d 867
andreikovacs 0:764779eedf2d 868 pMsg->msgType = msgType;
andreikovacs 0:764779eedf2d 869
andreikovacs 0:764779eedf2d 870 switch(msgType)
andreikovacs 0:764779eedf2d 871 {
andreikovacs 0:764779eedf2d 872 case gPlmeCcaCnf_c:
andreikovacs 0:764779eedf2d 873 pMsg->msgData.ccaCnf.status = pPhyStruct->channelParams.channelStatus;
andreikovacs 0:764779eedf2d 874 break;
andreikovacs 0:764779eedf2d 875
andreikovacs 0:764779eedf2d 876 case gPlmeEdCnf_c:
andreikovacs 0:764779eedf2d 877 pMsg->msgData.edCnf.status = gPhySuccess_c;
andreikovacs 0:764779eedf2d 878 pMsg->msgData.edCnf.energyLeveldB = pPhyStruct->channelParams.energyLeveldB;
andreikovacs 0:764779eedf2d 879 pMsg->msgData.edCnf.energyLevel = Phy_GetEnergyLevel(pPhyStruct->channelParams.energyLeveldB);
andreikovacs 0:764779eedf2d 880 break;
andreikovacs 0:764779eedf2d 881
andreikovacs 0:764779eedf2d 882 default:
andreikovacs 0:764779eedf2d 883 /* No aditional info needs to be filled */
andreikovacs 0:764779eedf2d 884 break;
andreikovacs 0:764779eedf2d 885 }
andreikovacs 0:764779eedf2d 886
andreikovacs 0:764779eedf2d 887 pPhyStruct->PLME_MAC_SapHandler(pMsg, pPhyStruct->currentMacInstance);
andreikovacs 0:764779eedf2d 888 }
andreikovacs 0:764779eedf2d 889
andreikovacs 0:764779eedf2d 890 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 891 * \brief Senf a PD message to upper layer
andreikovacs 0:764779eedf2d 892 *
andreikovacs 0:764779eedf2d 893 * \param[in] instanceId The instance of the PHY
andreikovacs 0:764779eedf2d 894 * \param[in] msgType The type of message to be sent
andreikovacs 0:764779eedf2d 895 *
andreikovacs 0:764779eedf2d 896 ********************************************************************************** */
andreikovacs 0:764779eedf2d 897 static void PD_SendMessage(Phy_PhyLocalStruct_t *pPhyStruct, phyMessageId_t msgType)
andreikovacs 0:764779eedf2d 898 {
andreikovacs 0:764779eedf2d 899 pdDataToMacMessage_t *pMsg;
andreikovacs 0:764779eedf2d 900
andreikovacs 0:764779eedf2d 901 if( msgType == gPdDataInd_c )
andreikovacs 0:764779eedf2d 902 {
andreikovacs 0:764779eedf2d 903 uint32_t temp;
andreikovacs 0:764779eedf2d 904 uint16_t len = pPhyStruct->rxParams.psduLength - 2; //Excluding FCS (2 bytes);
andreikovacs 0:764779eedf2d 905
andreikovacs 0:764779eedf2d 906 pMsg = pPhyStruct->rxParams.pRxData;
andreikovacs 0:764779eedf2d 907 pPhyStruct->rxParams.pRxData = NULL;
andreikovacs 0:764779eedf2d 908
andreikovacs 0:764779eedf2d 909 #if !gUsePBTransferThereshold_d
andreikovacs 0:764779eedf2d 910 MCR20Drv_PB_SPIBurstRead( (uint8_t *)(pMsg->msgData.dataInd.pPsdu), len );
andreikovacs 0:764779eedf2d 911 #endif
andreikovacs 0:764779eedf2d 912
andreikovacs 0:764779eedf2d 913 pMsg->msgType = gPdDataInd_c;
andreikovacs 0:764779eedf2d 914 pMsg->msgData.dataInd.ppduLinkQuality = pPhyStruct->rxParams.linkQuality;
andreikovacs 0:764779eedf2d 915 pMsg->msgData.dataInd.psduLength = len;
andreikovacs 0:764779eedf2d 916
andreikovacs 0:764779eedf2d 917 pMsg->msgData.dataInd.timeStamp = PhyTime_GetTimestamp(); //current timestamp (64bit)
andreikovacs 0:764779eedf2d 918 temp = (uint32_t)(pMsg->msgData.dataInd.timeStamp & gPhyTimeMask_c); //convert to 24bit
andreikovacs 0:764779eedf2d 919 pMsg->msgData.dataInd.timeStamp -= (temp - pPhyStruct->rxParams.timeStamp) & gPhyTimeMask_c;
andreikovacs 0:764779eedf2d 920 #if !(gMpmIncluded_d)
andreikovacs 0:764779eedf2d 921 pPhyStruct->PD_MAC_SapHandler(pMsg, pPhyStruct->currentMacInstance);
andreikovacs 0:764779eedf2d 922 #else
andreikovacs 0:764779eedf2d 923 {
andreikovacs 0:764779eedf2d 924 uint32_t i, bitMask = PhyPpGetPanOfRxPacket();
andreikovacs 0:764779eedf2d 925
andreikovacs 0:764779eedf2d 926 for( i=0; i<gMpmPhyPanRegSets_c; i++ )
andreikovacs 0:764779eedf2d 927 {
andreikovacs 0:764779eedf2d 928 if( bitMask & (1 << i) )
andreikovacs 0:764779eedf2d 929 {
andreikovacs 0:764779eedf2d 930 bitMask &= ~(1 << i);
andreikovacs 0:764779eedf2d 931 pPhyStruct->currentMacInstance = MPM_GetMacInstanceFromRegSet(i);
andreikovacs 0:764779eedf2d 932
andreikovacs 0:764779eedf2d 933 /* If the packet passed filtering on muliple PANs, send a copy to each one */
andreikovacs 0:764779eedf2d 934 if( bitMask )
andreikovacs 0:764779eedf2d 935 {
andreikovacs 0:764779eedf2d 936 pdDataToMacMessage_t *pDataIndCopy;
andreikovacs 0:764779eedf2d 937
andreikovacs 0:764779eedf2d 938 pDataIndCopy = MEM_BufferAlloc(sizeof(pdDataToMacMessage_t) + len);
andreikovacs 0:764779eedf2d 939
andreikovacs 0:764779eedf2d 940 if( pDataIndCopy )
andreikovacs 0:764779eedf2d 941 {
andreikovacs 0:764779eedf2d 942 FLib_MemCpy(pDataIndCopy, pMsg, sizeof(pdDataToMacMessage_t) + len);
andreikovacs 0:764779eedf2d 943 pPhyStruct->PD_MAC_SapHandler(pDataIndCopy, pPhyStruct->currentMacInstance);
andreikovacs 0:764779eedf2d 944 }
andreikovacs 0:764779eedf2d 945 }
andreikovacs 0:764779eedf2d 946 else
andreikovacs 0:764779eedf2d 947 {
andreikovacs 0:764779eedf2d 948 pPhyStruct->PD_MAC_SapHandler(pMsg, pPhyStruct->currentMacInstance);
andreikovacs 0:764779eedf2d 949 break;
andreikovacs 0:764779eedf2d 950 }
andreikovacs 0:764779eedf2d 951 }
andreikovacs 0:764779eedf2d 952 }
andreikovacs 0:764779eedf2d 953 }
andreikovacs 0:764779eedf2d 954 #endif
andreikovacs 0:764779eedf2d 955 }
andreikovacs 0:764779eedf2d 956 else
andreikovacs 0:764779eedf2d 957 {
andreikovacs 0:764779eedf2d 958 pMsg = MEM_BufferAlloc( sizeof(pdDataToMacMessage_t) );
andreikovacs 0:764779eedf2d 959
andreikovacs 0:764779eedf2d 960 if(NULL == pMsg)
andreikovacs 0:764779eedf2d 961 {
andreikovacs 0:764779eedf2d 962 //panic(0,(uint32_t)PD_SendMessage,0,gPdDataCnf_c);
andreikovacs 0:764779eedf2d 963 return;
andreikovacs 0:764779eedf2d 964 }
andreikovacs 0:764779eedf2d 965
andreikovacs 0:764779eedf2d 966 pMsg->msgType = gPdDataCnf_c;
andreikovacs 0:764779eedf2d 967
andreikovacs 0:764779eedf2d 968 if( pPhyStruct->flags & gPhyFlagFramePending_c )
andreikovacs 0:764779eedf2d 969 {
andreikovacs 0:764779eedf2d 970 pPhyStruct->flags &= ~(gPhyFlagFramePending_c);
andreikovacs 0:764779eedf2d 971 pMsg->msgData.dataCnf.status = gPhyFramePending_c;
andreikovacs 0:764779eedf2d 972 }
andreikovacs 0:764779eedf2d 973 else
andreikovacs 0:764779eedf2d 974 {
andreikovacs 0:764779eedf2d 975 pMsg->msgData.dataCnf.status = gPhySuccess_c;
andreikovacs 0:764779eedf2d 976 }
andreikovacs 0:764779eedf2d 977
andreikovacs 0:764779eedf2d 978 pPhyStruct->PD_MAC_SapHandler(pMsg, pPhyStruct->currentMacInstance);
andreikovacs 0:764779eedf2d 979 }
andreikovacs 0:764779eedf2d 980 }
andreikovacs 0:764779eedf2d 981
andreikovacs 0:764779eedf2d 982 void MSG_InitQueue(macPhyInputQueue_t * pMacPhyQueue)
andreikovacs 0:764779eedf2d 983 {
andreikovacs 0:764779eedf2d 984 pMacPhyQueue->msgInIdx = 0;
andreikovacs 0:764779eedf2d 985 FLib_MemSet(&pMacPhyQueue->pMsgIn[0], 0x00, gPhyMsgQueueMax_c * sizeof(void*));
andreikovacs 0:764779eedf2d 986 }
andreikovacs 0:764779eedf2d 987
andreikovacs 0:764779eedf2d 988 /* Check if a message is pending in a queue. Returns */
andreikovacs 0:764779eedf2d 989 /* TRUE if any pending messages, and FALSE otherwise. */
andreikovacs 0:764779eedf2d 990 bool_t MSG_Pending(macPhyInputQueue_t * pMacPhyQueue)
andreikovacs 0:764779eedf2d 991 {
andreikovacs 0:764779eedf2d 992 return (pMacPhyQueue->msgInIdx > 0);
andreikovacs 0:764779eedf2d 993 }
andreikovacs 0:764779eedf2d 994
andreikovacs 0:764779eedf2d 995 /* Get a message from a queue. Returns NULL if no messages in queue. */
andreikovacs 0:764779eedf2d 996 void * MSG_DeQueue(macPhyInputQueue_t * pMacPhyQueue)
andreikovacs 0:764779eedf2d 997 {
andreikovacs 0:764779eedf2d 998 phyMessageHeader_t * pMsgIn = NULL;
andreikovacs 0:764779eedf2d 999 uint32_t i = 0;
andreikovacs 0:764779eedf2d 1000
andreikovacs 0:764779eedf2d 1001 if(MSG_Pending(pMacPhyQueue))
andreikovacs 0:764779eedf2d 1002 {
andreikovacs 0:764779eedf2d 1003 pMsgIn = pMacPhyQueue->pMsgIn[0];
andreikovacs 0:764779eedf2d 1004
andreikovacs 0:764779eedf2d 1005 while(i < pMacPhyQueue->msgInIdx)
andreikovacs 0:764779eedf2d 1006 {
andreikovacs 0:764779eedf2d 1007 pMacPhyQueue->pMsgIn[i] = pMacPhyQueue->pMsgIn[i+1];
andreikovacs 0:764779eedf2d 1008 i++;
andreikovacs 0:764779eedf2d 1009 }
andreikovacs 0:764779eedf2d 1010
andreikovacs 0:764779eedf2d 1011 pMacPhyQueue->msgInIdx--;
andreikovacs 0:764779eedf2d 1012 pMacPhyQueue->pMsgIn[pMacPhyQueue->msgInIdx] = NULL;
andreikovacs 0:764779eedf2d 1013 }
andreikovacs 0:764779eedf2d 1014
andreikovacs 0:764779eedf2d 1015 return pMsgIn;
andreikovacs 0:764779eedf2d 1016 }
andreikovacs 0:764779eedf2d 1017
andreikovacs 0:764779eedf2d 1018
andreikovacs 0:764779eedf2d 1019 void MSG_Queue(macPhyInputQueue_t * pMacPhyQueue, void * pMsgIn)
andreikovacs 0:764779eedf2d 1020 {
andreikovacs 0:764779eedf2d 1021 if(pMacPhyQueue->msgInIdx < gPhyMsgQueueMax_c)
andreikovacs 0:764779eedf2d 1022 {
andreikovacs 0:764779eedf2d 1023 pMacPhyQueue->pMsgIn[pMacPhyQueue->msgInIdx] = pMsgIn;
andreikovacs 0:764779eedf2d 1024 pMacPhyQueue->msgInIdx++;
andreikovacs 0:764779eedf2d 1025 }
andreikovacs 0:764779eedf2d 1026 }
andreikovacs 0:764779eedf2d 1027
andreikovacs 0:764779eedf2d 1028 void MSG_QueueHead(macPhyInputQueue_t * pMacPhyQueue, void * pMsgIn)
andreikovacs 0:764779eedf2d 1029 {
andreikovacs 0:764779eedf2d 1030 uint32_t i = gPhyMsgQueueMax_c - 1;
andreikovacs 0:764779eedf2d 1031
andreikovacs 0:764779eedf2d 1032 if(pMacPhyQueue->msgInIdx < gPhyMsgQueueMax_c)
andreikovacs 0:764779eedf2d 1033 {
andreikovacs 0:764779eedf2d 1034 while(i > 0)
andreikovacs 0:764779eedf2d 1035 {
andreikovacs 0:764779eedf2d 1036 pMacPhyQueue->pMsgIn[i] = pMacPhyQueue->pMsgIn[i-1];
andreikovacs 0:764779eedf2d 1037 i--;
andreikovacs 0:764779eedf2d 1038 }
andreikovacs 0:764779eedf2d 1039 pMacPhyQueue->pMsgIn[0] = pMsgIn;
andreikovacs 0:764779eedf2d 1040 pMacPhyQueue->msgInIdx++;
andreikovacs 0:764779eedf2d 1041 }
andreikovacs 0:764779eedf2d 1042 }
andreikovacs 0:764779eedf2d 1043
andreikovacs 0:764779eedf2d 1044