The Freescale MCR20A Simple Media Access Controller (MCR20A SMAC) is a simple ANSI C based codebase available as sample source code. The MCR20A SMAC is used for developing proprietary RF transceiver applications using Freescale’s MCR20A 2.4 GHz transceiver
Fork of fsl_smac by
The MCR20A SMAC is a small codebase that provides simple communication and test applications based on drivers, (802.15.4 compliant) PHY, and framework utilities available as source code. This environment is useful for hardware and RF debug, hardware standards certification, and developing proprietary applications. The MCR20A SMAC is provided as part of the Example Application Demos available for MCR20A and also as a standalone set of files.
SMAC features include:
- Compact footprint.
- Very low power, proprietary, bidirectional RF communication link.
- The MCR20A radio allows packet filtering by hardware by checking the preamble and the synchronization word, which reduces software overhead and memory footprint.
- Broadcast communication.
- Unicast communication — MCR20A SMAC includes a Node Address 16-bit field. This allows SMAC to perform unicast transmissions. To change the address of a node, modify this constant: gNodeAddress_c inside the SMAC_Config.h file, or call SMACSetShortSrcAddress(uint16_t nwShortAddress). The address is set to 0xBEAD by default. Some of the Demo Applications allow the user to change this address at runtime.
- Change of current PAN. The SMAC packet uses a short 802.15.4 compliant header with a hard-coded configuration for frame control which allows the user to switch between PANs. The PAN address has also 16 bits (gDefaultPanID_c). This address can be modified by changing the default value from SMAC_Config.h file or by calling SMACSetPanID(uint16_t nwShortPanID.
- There are no blocking functions within the MCR20A SMAC.
- Easy-to-use sample applications included.
- Light-weight, custom LBT algorithm.
- Light-weight, custom, AA mechanism which is transparent to the user after enabling the feature.
- Encryption using Advanced Encryption Standard in Cipher Block Chaining mode with configurable initial vector and key.
- Configurable number of retries and backoff interval.
- Inter-layer communication using SAPs.
- The MCR20A SMAC also filters packets that have correct addressing information (pass address filtering) but are not in the expected format (short addressing, no security, data frame).
Documentation
Revision 0:401ba973869e, committed 2015-08-18
- Comitter:
- andreikovacs
- Date:
- Tue Aug 18 12:48:33 2015 +0000
- Commit message:
- Initial commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SMAC.cpp Tue Aug 18 12:48:33 2015 +0000 @@ -0,0 +1,1416 @@ +/************************************************************************************************** +* SMAC implementation. +* +* Freescale Semiconductor Inc. +* (c) Copyright 2004-2014 Freescale Semiconductor, Inc. +* ALL RIGHTS RESERVED. +* +*************************************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +***********************************************************************************************//*! +**************************************************************************************************/ +#include "SMAC.h" +#include "PhyInterface.h" +#include "EmbeddedTypes.h" + +#include "SMAC_Config.h" + +#include "MemManager.h" +#include "FunctionLib.h" +#if 0 +#include "panic.h" +#endif + +#include "cmsis_os.h" +#include "rtos.h" + +/************************************************************************************ +************************************************************************************* +* Public memory declarations +************************************************************************************* +************************************************************************************/ +uint8_t gTotalChannels; + +/************************************************************************************ +************************************************************************************* +* Private memory declarations +************************************************************************************* +************************************************************************************/ +static smacStates_t smacState; +/*volatile*/ static prssPacketPtr_t smacProccesPacketPtr; +static phyRxParams_t smacLastDataRxParams; +#if defined (gPHY_802_15_4g_d) +static smacPacket_t smacPacketConfig; +#endif +static macToPdDataMessage_t * gSmacDataMessage; +static macToPlmeMessage_t * gSmacMlmeMessage; + +static uint16_t u16PanID; +static uint16_t u16ShortSrcAddress; + +static uint8_t u8AckRetryCounter = 0; +static uint8_t u8CCARetryCounter = 0; + +static uint8_t mSmacInitialized; +static uint8_t mSmacTimeoutAsked; +static uint8_t u8BackoffTimerId; +static txContextConfig_t txConfigurator; +static uint8_t u8SmacSeqNo; +//Sap Handlers Called by PHY +phyStatus_t PD_SMAC_SapHandler(void* pMsg, instanceId_t smacInstanceId); +phyStatus_t PLME_SMAC_SapHandler(void* pMsg, instanceId_t smacInstanceId); + +/************************************************************************************ +************************************************************************************* +* Private functions +************************************************************************************* +************************************************************************************/ +static bool_t SMACPacketCheck(pdDataToMacMessage_t* pMsgFromPhy); +static void BackoffTimeElapsed(void const *arg); + +osTimerDef (SmacTimer, BackoffTimeElapsed); +/************************************************************************************ +************************************************************************************* +* Interface functions +************************************************************************************* +************************************************************************************/ +uint8_t TMR_AllocateTimer +( + void +) +{ + //RtosTimer smac_timer(u8BackoffTimerId, osTimerOnce , NULL); + return 0; +} + +uint8_t TMR_StartSingleShotTimer +( + uint8_t timerID, + uint32_t timeInMilliseconds, + void (*pfTimerCallBack)(const void *), + void *param +) +{ + //RtosTimer smac_timer(pfTimerCallBack, osTimerOnce , NULL); + + osTimerId id = osTimerCreate (osTimer(SmacTimer), osTimerOnce, NULL); + osTimerStart (id, timeInMilliseconds); + return 0; +} + + +/***********************************************************************************/ +/******************************** SMAC Data primitives *****************************/ +/***********************************************************************************/ + +/************************************************************************************ +* MCPSDataRequest +* +* This data primitive is used to send an over the air packet. This is an asynchronous +* function, it means it asks SMAC to transmit one OTA packet, but when the function +* returns it is not sent already. +* +************************************************************************************/ +smacErrors_t MCPSDataRequest +( +txPacket_t *psTxPacket //IN:Pointer to the packet to be transmitted +) +{ + macToPdDataMessage_t *pMsg; + phyStatus_t u8PhyRes = gPhySuccess_c; + +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + +#if(TRUE == smacParametersValidation_d) + uint8_t u8MaxLen=0; + + u8MaxLen = gMaxSmacSDULength_c; + + if((NULL == psTxPacket) || (u8MaxLen < psTxPacket->u8DataLength)) + { + return gErrorOutOfRange_c; + } +#endif /* TRUE == smacParametersValidation_d */ + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + + u8SmacSeqNo++; + u8AckRetryCounter = 0; + u8CCARetryCounter = 0; + + psTxPacket->u8DataLength = psTxPacket->u8DataLength + gSmacHeaderBytes_c; + + pMsg = (macToPdDataMessage_t*)MEM_BufferAlloc( sizeof(macToPdDataMessage_t) + + psTxPacket->u8DataLength); + if(pMsg == NULL ) + { + return gErrorNoResourcesAvailable_c; + } + /* Fill with Phy related data */ + pMsg->macInstance = smacInstance; + pMsg->msgType = gPdDataReq_c; + //SMAC doesn't use slotted mode + pMsg->msgData.dataReq.slottedTx = gPhyUnslottedMode_c; + //start transmission immediately + pMsg->msgData.dataReq.startTime = gPhySeqStartAsap_c; +#ifdef gPHY_802_15_4g_d + //for sub-Gig phy handles duration in case of ACK + pMsg->msgData.dataReq.txDuration = 0xFFFFFFFF; +#else + if(txConfigurator.autoAck && + psTxPacket->smacHeader.destAddr != 0xFFFF && + psTxPacket->smacHeader.panId != 0xFFFF) + { + //Turn@ + phy payload(symbols)+ Turn@ + ACK + pMsg->msgData.dataReq.txDuration = 12 + (6 + psTxPacket->u8DataLength + 2)*2 + 12 + 42; + if(txConfigurator.ccaBeforeTx) + { + pMsg->msgData.dataReq.txDuration += 0x08; //CCA Duration: 8 symbols + } + } + else + { + pMsg->msgData.dataReq.txDuration = 0xFFFFFFFF; + } +#endif + pMsg->msgData.dataReq.psduLength = psTxPacket->u8DataLength; + pMsg->msgData.dataReq.pPsdu = (uint8_t*)&pMsg->msgData.dataReq.pPsdu + + sizeof(pMsg->msgData.dataReq.pPsdu); + + FLib_MemCpy(pMsg->msgData.dataReq.pPsdu, &(psTxPacket->smacHeader), gSmacHeaderBytes_c); + FLib_MemCpy(pMsg->msgData.dataReq.pPsdu + gSmacHeaderBytes_c, + &(psTxPacket->smacPdu), + psTxPacket->u8DataLength - gSmacHeaderBytes_c); + + if(txConfigurator.ccaBeforeTx) + { + //tell phy to perform CCA before transmission + pMsg->msgData.dataReq.CCABeforeTx = gPhyCCAMode1_c; + } + else + { + pMsg->msgData.dataReq.CCABeforeTx = gPhyNoCCABeforeTx_c; + } + + if(txConfigurator.autoAck && + psTxPacket->smacHeader.destAddr != 0xFFFF && + psTxPacket->smacHeader.panId != 0xFFFF) + { + //set frame control option: ACK. + pMsg->msgData.dataReq.pPsdu[0] |= FRAME_CTRL_ACK_FIELD_SET; + pMsg->msgData.dataReq.ackRequired = gPhyRxAckRqd_c; + } + else + { + pMsg->msgData.dataReq.ackRequired = gPhyNoAckRqd_c; + } + //set sequence number; + pMsg->msgData.dataReq.pPsdu[2] = u8SmacSeqNo; + gSmacDataMessage = pMsg; //Store pointer for freeing later + u8PhyRes = MAC_PD_SapHandler(pMsg, 0); + + psTxPacket->u8DataLength -= gSmacHeaderBytes_c; + + if(u8PhyRes == gPhySuccess_c) + { + smacState= mSmacStateTransmitting_c; + return gErrorNoError_c; + } + else + { + MEM_BufferFree(gSmacDataMessage); + gSmacDataMessage = NULL; + return gErrorNoResourcesAvailable_c; + } +} + +/************************************************************************************ +* MLMEConfigureTxContext +* +* This management primitive is used to configure the conditions under which SMAC will +* perform a transmission OTA. +* +************************************************************************************/ +smacErrors_t MLMEConfigureTxContext(txContextConfig_t* pTxConfig) +{ + if( (pTxConfig->autoAck == FALSE && pTxConfig->retryCountAckFail !=0) || + (pTxConfig->ccaBeforeTx == FALSE && pTxConfig->retryCountCCAFail !=0) ) + { + return gErrorNoValidCondition_c; + } + if( pTxConfig->retryCountAckFail > gMaxRetriesAllowed_c || + pTxConfig->retryCountCCAFail > gMaxRetriesAllowed_c) + { + return gErrorOutOfRange_c; + } + txConfigurator.autoAck = pTxConfig->autoAck; + txConfigurator.ccaBeforeTx = pTxConfig->ccaBeforeTx; + txConfigurator.retryCountAckFail = pTxConfig->retryCountAckFail; + txConfigurator.retryCountCCAFail = pTxConfig->retryCountCCAFail; + + return gErrorNoError_c; +} + +/************************************************************************************ +* MLMERXEnableRequest +* +* Function used to place the radio into receive mode +* +************************************************************************************/ +smacErrors_t MLMERXEnableRequest +( +rxPacket_t *gsRxPacket, //OUT: Pointer to the structure where the reception results +// will be stored. +smacTime_t stTimeout //IN: 64-bit timeout value, absolute value in symbols +) +{ + + uint8_t u8PhyRes = 0; + macToPlmeMessage_t lMsg; + +#if(TRUE == smacParametersValidation_d) + uint8_t u8MaxLen=0; + + u8MaxLen = gMaxSmacSDULength_c; +#endif /* TRUE == smacParametersValidation_d */ + +#if(TRUE == smacParametersValidation_d) + if((NULL == gsRxPacket) || (u8MaxLen < gsRxPacket->u8MaxDataLength)) + { + return gErrorOutOfRange_c; + } +#endif /* TRUE == smacParametersValidation_d */ + +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + if(stTimeout) + { + lMsg.msgType = gPlmeSetTRxStateReq_c; + lMsg.msgData.setTRxStateReq.startTime = gPhySeqStartAsap_c; + lMsg.macInstance = smacInstance; + lMsg.msgData.setTRxStateReq.state = gPhySetRxOn_c; + mSmacTimeoutAsked = TRUE; + lMsg.msgData.setTRxStateReq.rxDuration = stTimeout; + } + else + { + lMsg.msgType = gPlmeSetReq_c; + lMsg.msgData.setReq.PibAttribute = gPhyPibRxOnWhenIdle; + lMsg.msgData.setReq.PibAttributeValue = (uint64_t)1; + } + u8PhyRes = MAC_PLME_SapHandler(&lMsg, 0); + if(u8PhyRes == gPhySuccess_c) + { + gsRxPacket->rxStatus = rxProcessingReceptionStatus_c; + smacProccesPacketPtr.smacRxPacketPointer = gsRxPacket; + + smacState= mSmacStateReceiving_c; + return gErrorNoError_c; + } + else + { + return gErrorNoResourcesAvailable_c; + } +} +#if defined (gPHY_802_15_4g_d) +/************************************************************************************ +* MLMESetPreambleLength +* +* Function used to change the preamble size in the OTA Packet +* +************************************************************************************/ +smacErrors_t MLMESetPreambleLength +( +uint16_t u16preambleLength +) +{ +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + smacPacketConfig.u16PreambleLength = u16preambleLength; + gPhyPib.mPIBphyFSKPreambleRepetitions = u16preambleLength; + PhyPib_RFUpdatePreambleLength(); + + return gErrorNoError_c; + +} + +/************************************************************************************ +* MLMESetSyncWordSize +* +* Function used to change the synchronization word size. Values from 0 to 8 required. +* IMPORTANT-> Use below arguments only (indicating a direct value from 1-8 will not work) +* Inputs : +* SyncConfig_SyncSize_1 +* SyncConfig_SyncSize_2 +* SyncConfig_SyncSize_3 +* SyncConfig_SyncSize_4 +* SyncConfig_SyncSize_5 +* SyncConfig_SyncSize_6 +* SyncConfig_SyncSize_7 +* SyncConfig_SyncSize_8 +* +************************************************************************************/ +smacErrors_t MLMESetSyncWordSize +( +uint8_t u8syncWordSize +) +{ + + phyStatus_t status; +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + + status = (phyStatus_t)Phy_SetSyncWordSize(u8syncWordSize); + if(status == gPhyInvalidParameter_c) + return gErrorOutOfRange_c; + + smacPacketConfig.u8SyncWordSize = u8syncWordSize; + + return gErrorNoError_c; + +} + +/************************************************************************************ +* MLMESetSyncWordValue +* +* Function used to change the synchronization word value. +* +* +************************************************************************************/ +smacErrors_t MLMESetSyncWordValue +( +uint8_t *u8syncWordValue +) +{ + uint8_t syncWordSizeTemp = smacPacketConfig.u8SyncWordSize; + uint8_t syncValueRegIndex = 0; + +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + + smacPacketConfig.u8SyncWordValue = u8syncWordValue; + + while (syncWordSizeTemp--) + { + Phy_SetSyncWordValue(syncValueRegIndex, (uint8_t)*u8syncWordValue); + syncValueRegIndex++; + u8syncWordValue++; + } + while(syncValueRegIndex < 8) + { + Phy_SetSyncWordValue(syncValueRegIndex, 0x00); + syncValueRegIndex++; + } + + return gErrorNoError_c; + +} + +/************************************************************************************ +* MLMEPacketConfig +* +* +* +************************************************************************************/ +smacErrors_t MLMEPacketConfig +( +packetConfig_t *pPacketCfg +) +{ + smacErrors_t err = gErrorNoError_c; +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + err = MLMESetSyncWordSize(pPacketCfg->u8SyncWordSize); + err |= MLMESetSyncWordValue(pPacketCfg->pu8SyncWord); + err |= MLMESetPreambleLength(pPacketCfg->u16PreambleSize); + if(err != gErrorNoError_c) + return gErrorOutOfRange_c; + + return gErrorNoError_c; +} + +#endif + +/************************************************************************************ +* MLMESetChannelRequest +* +* +* +************************************************************************************/ +smacErrors_t MLMESetChannelRequest +( +channels_t newChannel +) +{ + uint8_t errorVal; + smacErrors_t err = gErrorNoError_c; + + macToPlmeMessage_t lMsg; +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + lMsg.msgType = gPlmeSetReq_c; + lMsg.macInstance = smacInstance; + lMsg.msgData.setReq.PibAttribute = gPhyPibCurrentChannel_c; + lMsg.msgData.setReq.PibAttributeValue = (uint64_t) newChannel; + + errorVal = MAC_PLME_SapHandler(&lMsg, 0); + switch (errorVal) + { + case gPhyBusy_c: + err = gErrorBusy_c; + break; + + case gPhyInvalidParameter_c: + err = gErrorOutOfRange_c; + break; + + case gPhySuccess_c: + err = gErrorNoError_c; + break; + + default: + err = gErrorOutOfRange_c; + break; + } + + return err; +} + + +/************************************************************************************ +* MLMESetAdditionalRFOffset +* +*************************************************************************************/ +smacErrors_t MLMESetAdditionalRFOffset (uint32_t additionalRFOffset) +{ +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + +#ifdef gIncludeCalibrationOption + gPhyPib.mPIBAdditionalRFFrequencyOffset = additionalRFOffset; + return gErrorNoError_c; +#else + return gErrorNoResourcesAvailable_c; +#endif +} + + +/************************************************************************************ +* MLMEGetAdditionalRFOffset +* +*************************************************************************************/ +uint32_t MLMEGetAdditionalRFOffset( void ) +{ +#ifdef gIncludeCalibrationOption + return gPhyPib.mPIBAdditionalRFFrequencyOffset; +#else + return 0; +#endif +} + +#if defined (gPHY_802_15_4g_d) +/************************************************************************************ +* MLMESetFreqBand +* +************************************************************************************/ +smacErrors_t MLMESetFreqBand +( +smacFrequencyBands_t freqBand, +smacRFModes_t phyMode +) +{ + return gErrorNoResourcesAvailable_c; +} + +smacErrors_t MLMESetPhyMode(smacRFModes_t phyMode) +{ +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + phyStatus_t err; + macToPlmeMessage_t lMsg; + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + lMsg.macInstance = smacInstance; + lMsg.msgType = gPlmeSetReq_c; + lMsg.msgData.setReq.PibAttribute = gPhyPibCurrentMode_c; + lMsg.msgData.setReq.PibAttributeValue = (uint64_t)phyMode; + err = MAC_PLME_SapHandler(&lMsg, 0); + if(err == gPhyInvalidParameter_c) + return gErrorOutOfRange_c; + if(err == gPhyBusy_c) + return gErrorBusy_c; + + gTotalChannels = gPhyPib.pPIBphyRfConstants->totalNumChannels; + + return gErrorNoError_c; +} + +#endif +/************************************************************************************ +* MLMEGetChannelRequest +* +* +* +************************************************************************************/ +channels_t MLMEGetChannelRequest +( +void +) +{ + channels_t currentChannel; + macToPlmeMessage_t lMsg; +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + //panic(0,0,0,0); + } +#endif /* TRUE == smacInitializationValidation_d */ + lMsg.msgType = gPlmeGetReq_c; + lMsg.macInstance = smacInstance; + lMsg.msgData.getReq.PibAttribute = gPhyPibCurrentChannel_c; + lMsg.msgData.getReq.pPibAttributeValue = (uint64_t*)¤tChannel; + MAC_PLME_SapHandler(&lMsg, 0); + return currentChannel; +} + +#if defined (gPHY_802_15_4g_d) +/************************************************************************************ +* MLMERssi +* +* +* +************************************************************************************/ +uint8_t MLMERssi(void ) +{ + uint8_t rssiVal; + +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + + rssiVal = Phy_GetRssi(); + return rssiVal; +} + +/************************************************************************************ +* MLMESetCCADuration +* +* +* +************************************************************************************/ +smacErrors_t MLMESetCCADuration(uint64_t usCCADuration ) +{ + macToPlmeMessage_t lMsg; + phyStatus_t status; + +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + + usCCADuration = TIME_US_TO_TICKS(usCCADuration); + Phy_TimeDivider((phyTime_t*)&usCCADuration); + + lMsg.msgType = gPlmeSetReq_c; + lMsg.msgData.setReq.PibAttribute = gPhyPibCCADuration_c; + lMsg.msgData.setReq.PibAttributeValue = usCCADuration; + status = MAC_PLME_SapHandler(&lMsg, 0); + + if(status == gPhySuccess_c) + return gErrorNoError_c; + else + return gErrorNoResourcesAvailable_c; +} + +/************************************************************************************ +* MLMESetInterPacketRxDelay +* +* IMPORTANT-> Use below arguments only (indicating a direct value from 1-12 will not work) +* Inputs : +* +* InterPacketRxDelay_0 +* InterPacketRxDelay_1 +* InterPacketRxDelay_2 +* InterPacketRxDelay_3 +* InterPacketRxDelay_4 +* InterPacketRxDelay_5 +* InterPacketRxDelay_6 +* InterPacketRxDelay_7 +* InterPacketRxDelay_8 +* InterPacketRxDelay_9 +* InterPacketRxDelay_A +* InterPacketRxDelay_B +************************************************************************************/ +smacErrors_t MLMESetInterPacketRxDelay +( +uint8_t u8InterPacketRxDelay +) +{ +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + + if (gPhySuccess_c != Phy_SetInterPacketRxDelay(u8InterPacketRxDelay)) + { + return gErrorOutOfRange_c; + } + return gErrorNoError_c; +} + +#endif +/************************************************************************************ +* MLMERXDisableRequest +* +* Returns the radio to idle mode from receive mode. +* +************************************************************************************/ +smacErrors_t MLMERXDisableRequest(void) +{ + macToPlmeMessage_t lMsg; + phyStatus_t err; +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif + if((mSmacStateReceiving_c != smacState) && (mSmacStateIdle_c != smacState)) + { + return gErrorNoValidCondition_c; + } + lMsg.macInstance = smacInstance; + if(!mSmacTimeoutAsked) + { + lMsg.msgType = gPlmeSetReq_c; + lMsg.msgData.setReq.PibAttribute = gPhyPibRxOnWhenIdle; + lMsg.msgData.setReq.PibAttributeValue = (uint64_t)0; + err = MAC_PLME_SapHandler(&lMsg, 0); + if(err != gPhySuccess_c) + return gErrorBusy_c; + } + else + { + lMsg.msgType = gPlmeSetTRxStateReq_c; + lMsg.msgData.setTRxStateReq.state = gPhyForceTRxOff_c; + (void)MAC_PLME_SapHandler(&lMsg, 0); + mSmacTimeoutAsked = FALSE; + } + smacState= mSmacStateIdle_c; + + return gErrorNoError_c; + +} + +/*@CMA, Conn Test Added*/ +/************************************************************************************ +* MLMETXDisableRequest +* +* Returns the radio to idle mode from Tx mode. +* +************************************************************************************/ +void MLMETXDisableRequest(void) +{ + macToPlmeMessage_t lMsg; + lMsg.macInstance = smacInstance; + lMsg.msgType = gPlmeSetTRxStateReq_c; + lMsg.msgData.setTRxStateReq.state = gPhyForceTRxOff_c; + (void)MAC_PLME_SapHandler(&lMsg, 0); + if(gSmacDataMessage != NULL) + { + (void)MEM_BufferFree(gSmacDataMessage); + gSmacDataMessage = NULL; + } + smacState= mSmacStateIdle_c; +} + +/************************************************************************************ +* MLMELinkQuality +* +* This function returns an integer value that is the link quality from the last +* received packet of the form: dBm = (-Link Quality/2). +* +************************************************************************************/ +uint8_t MLMELinkQuality(void) +{ +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return 0; + } +#endif + return smacLastDataRxParams.linkQuality; +} + +/************************************************************************************ +* MLMEPAOutputAdjust +* +* +************************************************************************************/ +smacErrors_t MLMEPAOutputAdjust +( +uint8_t u8PaValue +) +{ + macToPlmeMessage_t lMsg; + smacErrors_t err = gErrorNoError_c; + uint8_t errorVal; +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + lMsg.macInstance = smacInstance; + lMsg.msgType = gPlmeSetReq_c; + lMsg.msgData.setReq.PibAttribute = gPhyPibTransmitPower_c; + lMsg.msgData.setReq.PibAttributeValue = (uint64_t) u8PaValue; + errorVal = MAC_PLME_SapHandler(&lMsg, 0); + switch (errorVal) + { + case gPhyBusy_c: + err = gErrorBusy_c; + break; + + case gPhyInvalidParameter_c: + err = gErrorOutOfRange_c; + break; + + case gPhySuccess_c: + err = gErrorNoError_c; + break; + + default: + err = gErrorOutOfRange_c; + break; + } + + return err; +} + +/************************************************************************************ +* MLMEScanRequest +* +* This function returns the RSSI value of the channel passes as a parameter +* +* +************************************************************************************/ +smacErrors_t MLMEScanRequest(channels_t u8ChannelToScan) +{ + smacErrors_t err = gErrorNoError_c; + phyStatus_t u8PhyRes; +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + if(u8ChannelToScan != MLMEGetChannelRequest()) + err = MLMESetChannelRequest(u8ChannelToScan); + if(err != gErrorNoError_c) + return err; + + macToPlmeMessage_t* pMsg = (macToPlmeMessage_t*)MEM_BufferAlloc(sizeof(macToPlmeMessage_t)); + pMsg->msgType = gPlmeEdReq_c; + pMsg->msgData.edReq.startTime = gPhySeqStartAsap_c; + pMsg->macInstance = smacInstance; + gSmacMlmeMessage = pMsg; + u8PhyRes = MAC_PLME_SapHandler(pMsg,0); + if(u8PhyRes != gPhySuccess_c) + { + MEM_BufferFree(gSmacMlmeMessage); + gSmacMlmeMessage = NULL; + return gErrorBusy_c; + } + smacState = mSmacStateScanningChannels_c; + return gErrorNoError_c; +} + + +/************************************************************************************ +* MLMECcaRequest +* +* This function performs Clear Channel Assessment on the active channel +* +* +************************************************************************************/ +smacErrors_t MLMECcaRequest() +{ + phyStatus_t u8PhyRes; +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ + + if(mSmacStateIdle_c != smacState) + { + return gErrorBusy_c; + } + macToPlmeMessage_t* pMsg = (macToPlmeMessage_t*)MEM_BufferAlloc(sizeof(macToPlmeMessage_t)); + pMsg->msgType = gPlmeCcaReq_c; + pMsg->msgData.ccaReq.ccaType = gPhyCCAMode1_c; + pMsg->msgData.ccaReq.contCcaMode = gPhyContCcaDisabled; + pMsg->macInstance = smacInstance; + gSmacMlmeMessage = pMsg; + u8PhyRes = MAC_PLME_SapHandler(pMsg,0); + if(u8PhyRes != gPhySuccess_c) + { + MEM_BufferFree(gSmacMlmeMessage); + gSmacMlmeMessage = NULL; + return gErrorBusy_c; + } + smacState = mSmacStatePerformingCca_c; + return gErrorNoError_c; +} +/************************************************************************************ +* MLMEPhySoftReset +* +* This function performs a software reset on the radio, PHY and SMAC state machines. +* +* +************************************************************************************/ +smacErrors_t MLMEPhySoftReset +( +void +) +{ + macToPlmeMessage_t lMsg; +#if(TRUE == smacInitializationValidation_d) + if(FALSE == mSmacInitialized) + { + return gErrorNoValidCondition_c; + } +#endif /* TRUE == smacInitializationValidation_d */ +// +// if(mSmacStateIdle_c != smacState) +// { +// return gErrorBusy_c; +// } + lMsg.macInstance = smacInstance; + lMsg.msgType = gPlmeSetTRxStateReq_c; + lMsg.msgData.setTRxStateReq.state = gPhyForceTRxOff_c; + (void)MAC_PLME_SapHandler(&lMsg, 0); + smacState= mSmacStateIdle_c; + + return gErrorNoError_c; +} +/************************************************************************************ +* PD_SMAC_SapHandler +* +* This SAP handles data confirm and data indication from PHY. +* +************************************************************************************/ +phyStatus_t PD_SMAC_SapHandler(void* pMsg, instanceId_t smacInstanceId) +{ + phyStatus_t status = gPhyInvalidPrimitive_c; + smacToAppDataMessage_t* pSmacMsg; + pdDataToMacMessage_t* pDataMsg = (pdDataToMacMessage_t*)pMsg; + (void)smacInstanceId; + + switch(pDataMsg->msgType) + { + case gPdDataCnf_c: + //no data request was fired + if(NULL == gSmacDataMessage) + { + status = gPhySuccess_c; + } + else + { + //phy finished work with the data request packet so it can be freed + MEM_BufferFree(gSmacDataMessage); + gSmacDataMessage = NULL; + + pSmacMsg = (smacToAppDataMessage_t*)MEM_BufferAlloc(sizeof(smacToAppDataMessage_t)); + if(pSmacMsg == NULL) + { + status = gPhySuccess_c; + } + else + { + pSmacMsg->msgType = gMcpsDataCnf_c; + pSmacMsg->msgData.dataCnf.status = gErrorNoError_c; + // call App Sap + gSMAC_APP_MCPS_SapHandler(pSmacMsg,smacInstance); + } + smacState = mSmacStateIdle_c; + } + break; + case gPdDataInd_c: + if(FALSE == SMACPacketCheck(pDataMsg)) + { + MEM_BufferFree(pDataMsg); + status = gPhySuccess_c; + } + else + { + smacLastDataRxParams.linkQuality = ((pdDataToMacMessage_t*)pMsg)->msgData.dataInd.ppduLinkQuality; + smacLastDataRxParams.timeStamp = (phyTime_t)((pdDataToMacMessage_t*)pMsg)->msgData.dataInd.timeStamp; + smacProccesPacketPtr.smacRxPacketPointer->rxStatus = rxSuccessStatus_c; + + // in case no timeout was asked we need to unset RXOnWhenIdle Pib. + if(!mSmacTimeoutAsked) + { + (void)MLMERXDisableRequest(); + } + smacProccesPacketPtr.smacRxPacketPointer->u8DataLength = + pDataMsg->msgData.dataInd.psduLength - gSmacHeaderBytes_c; + FLib_MemCpy(&smacProccesPacketPtr.smacRxPacketPointer->smacHeader, + ((smacHeader_t*)pDataMsg->msgData.dataInd.pPsdu), + gSmacHeaderBytes_c); + FLib_MemCpy(&smacProccesPacketPtr.smacRxPacketPointer->smacPdu, + ((smacPdu_t*)(pDataMsg->msgData.dataInd.pPsdu + gSmacHeaderBytes_c)), + smacProccesPacketPtr.smacRxPacketPointer->u8DataLength); + + pSmacMsg = (smacToAppDataMessage_t*)MEM_BufferAlloc(sizeof(smacToAppDataMessage_t)); + if(pSmacMsg == NULL) + { + status = gPhySuccess_c; + } + else + { + pSmacMsg->msgType = gMcpsDataInd_c; + pSmacMsg->msgData.dataInd.pRxPacket = smacProccesPacketPtr.smacRxPacketPointer; + pSmacMsg->msgData.dataInd.u8LastRxRssi = PhyGetLastRxRssiValue(); + gSMAC_APP_MCPS_SapHandler(pSmacMsg,smacInstance); + } + smacState = mSmacStateIdle_c; + } + break; + default: + break; + } + MEM_BufferFree(pMsg); + return status; +} + +/************************************************************************************ +* PLME_SMAC_SapHandler +* +* This SAP handles management for confirms and indications from PHY. +* +************************************************************************************/ + +phyStatus_t PLME_SMAC_SapHandler(void* pMsg, instanceId_t smacInstanceId) +{ + MEM_BufferFree(gSmacMlmeMessage); + gSmacMlmeMessage = NULL; + uint32_t backOffTime; + + plmeToMacMessage_t* pPlmeMsg = (plmeToMacMessage_t*)pMsg; + + smacToAppMlmeMessage_t* pSmacToApp; + smacToAppDataMessage_t* pSmacMsg; + switch(pPlmeMsg->msgType) + { + case gPlmeCcaCnf_c: + if(pPlmeMsg->msgData.ccaCnf.status == gPhyChannelBusy_c && + smacState == mSmacStateTransmitting_c) + { + if(txConfigurator.ccaBeforeTx) + { + if(txConfigurator.retryCountCCAFail > u8CCARetryCounter) + { + //increment cca fail counter + u8CCARetryCounter++; + //get random number for backoff time. + RNG_GetRandomNo(&backOffTime); + //start event timer. After time elapses, Data request will be fired. + TMR_StartSingleShotTimer(u8BackoffTimerId, ((backOffTime & gMaxBackoffTime_c) + gMinBackoffTime_c), BackoffTimeElapsed, NULL); + } + else + { + MEM_BufferFree(gSmacDataMessage); + gSmacDataMessage = NULL; + + //retries failed so create message for the application + pSmacMsg = (smacToAppDataMessage_t*)MEM_BufferAlloc(sizeof(smacToAppDataMessage_t)); + if(pSmacMsg != NULL) + { + //error type : Channel Busy + pSmacMsg->msgData.dataCnf.status = gErrorChannelBusy_c; + //type is Data Confirm + pSmacMsg->msgType = gMcpsDataCnf_c; + gSMAC_APP_MCPS_SapHandler(pSmacMsg, smacInstance); + } + //place SMAC into idle state + smacState = mSmacStateIdle_c; + } + } + MEM_BufferFree(pMsg); + return gPhySuccess_c; + } + //if SMAC isn't in TX then definitely it is a CCA confirm + //allocate a message for the application + pSmacToApp = (smacToAppMlmeMessage_t*)MEM_BufferAlloc(sizeof(smacToAppMlmeMessage_t)); + if(pSmacToApp != NULL) + { + //type is CCA Confirm + pSmacToApp->msgType = gMlmeCcaCnf_c; + //Channel status translated into SMAC messages: idle channel means no error. + if(pPlmeMsg->msgData.ccaCnf.status == gPhyChannelIdle_c) + { + pSmacToApp->msgData.ccaCnf.status = gErrorNoError_c; + } + else + { + pSmacToApp->msgData.ccaCnf.status = gErrorChannelBusy_c; + } + } + break; + case gPlmeEdCnf_c: + //allocate a message for the application + pSmacToApp = (smacToAppMlmeMessage_t*)MEM_BufferAlloc(sizeof(smacToAppMlmeMessage_t)); + if(pSmacToApp != NULL) + { + //message type is ED Confirm + pSmacToApp->msgType = gMlmeEdCnf_c; + if(pPlmeMsg->msgData.edCnf.status == gPhySuccess_c) + { + pSmacToApp->msgData.edCnf.status = gErrorNoError_c; + pSmacToApp->msgData.edCnf.energyLevel = pPlmeMsg->msgData.edCnf.energyLevel; + pSmacToApp->msgData.edCnf.energyLeveldB = pPlmeMsg->msgData.edCnf.energyLeveldB; + pSmacToApp->msgData.edCnf.scannedChannel = MLMEGetChannelRequest(); + } + else + { + pSmacToApp->msgData.edCnf.status = gErrorBusy_c; + } + } + break; + case gPlmeTimeoutInd_c: + if(smacState == mSmacStateTransmitting_c) + { + if(txConfigurator.autoAck) + { + //re-arm retries for channel busy at retransmission. + u8CCARetryCounter = 0; + + if(txConfigurator.retryCountAckFail > u8AckRetryCounter) + { + u8AckRetryCounter++; + + RNG_GetRandomNo(&backOffTime); + //start event timer. After time elapses, Data request will be fired. + TMR_StartSingleShotTimer(u8BackoffTimerId, ((backOffTime & gMaxBackoffTime_c) + gMinBackoffTime_c), BackoffTimeElapsed, NULL); + } + else + { + (void)MEM_BufferFree(gSmacDataMessage); + gSmacDataMessage = NULL; + + //retries failed so create message for the application + pSmacMsg = (smacToAppDataMessage_t*)MEM_BufferAlloc(sizeof(smacToAppDataMessage_t)); + if(pSmacMsg != NULL) + { + //set error code: No Ack + pSmacMsg->msgData.dataCnf.status = gErrorNoAck_c; + //type is Data Confirm + pSmacMsg->msgType = gMcpsDataCnf_c; + + gSMAC_APP_MCPS_SapHandler(pSmacMsg, smacInstance); + } + //place SMAC into idle state + smacState = mSmacStateIdle_c; + } + } + MEM_BufferFree(pMsg); + return gPhySuccess_c; + } + //if no ack timeout was received then it is definitely a RX timeout + pSmacToApp = (smacToAppMlmeMessage_t*)MEM_BufferAlloc(sizeof(smacToAppMlmeMessage_t)); + if(pSmacToApp != NULL) + { + if(smacState == mSmacStateReceiving_c) + { + smacProccesPacketPtr.smacRxPacketPointer->rxStatus = rxTimeOutStatus_c; + } + pSmacToApp->msgType = gMlmeTimeoutInd_c; + } + break; + case gPlme_UnexpectedRadioResetInd_c: + pSmacToApp = (smacToAppMlmeMessage_t*)MEM_BufferAlloc(sizeof(smacToAppMlmeMessage_t)); + if(pSmacToApp != NULL) + pSmacToApp->msgType = gMlme_UnexpectedRadioResetInd_c; + break; + default: + //MEM_BufferFree(pSmacToApp); + MEM_BufferFree(pMsg); + return gPhySuccess_c; + } + smacState = mSmacStateIdle_c; + //send message to upper layer if it is not NULL + if(pSmacToApp != NULL) + (gSMAC_APP_MLME_SapHandler)(pSmacToApp,0); + MEM_BufferFree(pMsg); + return gPhySuccess_c; +} + +/************************************************************************************ +* Smac_RegisterSapHandlers +* +* This function helps the user register the handlers for the messages that come from +* SMAC. +* +************************************************************************************/ + +void Smac_RegisterSapHandlers( + SMAC_APP_MCPS_SapHandler_t pSMAC_APP_MCPS_SapHandler, + SMAC_APP_MLME_SapHandler_t pSMAC_APP_MLME_SapHandler, + instanceId_t smacInstanceId + ) +{ + gSMAC_APP_MCPS_SapHandler = pSMAC_APP_MCPS_SapHandler; + gSMAC_APP_MLME_SapHandler = pSMAC_APP_MLME_SapHandler; + (void)smacInstanceId; +} + +/************************************************************************************ +* SMACFillHeader +* +* This function helps the user fill the SMAC header(short hardcoded MAC header) with +* the desired short destination address. +* +************************************************************************************/ + +void SMACFillHeader(smacHeader_t* pSmacHeader, uint16_t destAddr) +{ + pSmacHeader->frameControl = gSmacDefaultFrameCtrl; + pSmacHeader->panId = u16PanID; + pSmacHeader->seqNo = gSmacDefaultSeqNo; + pSmacHeader->srcAddr = u16ShortSrcAddress; + pSmacHeader->destAddr = destAddr; +} + +/************************************************************************************ +* InitSmac +* +* Basic SMAC initialisation. +* +************************************************************************************/ +void InitSmac(void) +{ + /* SMAC Initialization */ + smacState = mSmacStateIdle_c; + smacLastDataRxParams.linkQuality = 0; + smacLastDataRxParams.timeStamp = 0; + uint32_t u32RandomNo; +#if defined(gPHY_802_15_4g_d) + gTotalChannels = gPhyPib.pPIBphyRfConstants->totalNumChannels; +#else + gTotalChannels = 26; +#endif + + +#if(TRUE == smacInitializationValidation_d) + mSmacInitialized = TRUE; +#endif + txConfigurator.autoAck = FALSE; + txConfigurator.ccaBeforeTx = FALSE; + txConfigurator.retryCountAckFail = 0; + txConfigurator.retryCountCCAFail = 0; + u8BackoffTimerId = (uint8_t)TMR_AllocateTimer(); + RNG_Init(); + RNG_GetRandomNo(&u32RandomNo); + u8SmacSeqNo = (uint8_t)u32RandomNo; + //Notify the PHY what function to call for communicating with SMAC + Phy_RegisterSapHandlers((PD_MAC_SapHandler_t)PD_SMAC_SapHandler, (PLME_MAC_SapHandler_t)PLME_SMAC_SapHandler, 0); + u16PanID = gDefaultPanID_c; + u16ShortSrcAddress = gNodeAddress_c; + (void)SMACSetShortSrcAddress(u16ShortSrcAddress); + (void)SMACSetPanID(u16PanID); +} + +/************************************************************************************ +* SMACSetShortSrcAddress +* +* This function sets the short source address so that PHY can perform filtering +* +************************************************************************************/ + +smacErrors_t SMACSetShortSrcAddress(uint16_t nwShortAddress) +{ + macToPlmeMessage_t lMsg; + lMsg.msgType = gPlmeSetReq_c; + lMsg.msgData.setReq.PibAttribute = gPhyPibShortAddress_c; + lMsg.msgData.setReq.PibAttributeValue = (uint64_t)nwShortAddress; + + phyStatus_t u8PhyRes = MAC_PLME_SapHandler(&lMsg,0); + if(u8PhyRes == gPhyBusy_c || u8PhyRes == gPhyBusyTx_c || u8PhyRes == gPhyBusyRx_c) + return gErrorBusy_c; + if(u8PhyRes != gPhySuccess_c) + return gErrorNoResourcesAvailable_c; + u16ShortSrcAddress = nwShortAddress; + return gErrorNoError_c; +} + +/************************************************************************************ +* SMACSetPanID +* +* This function sets the pan ID so that PHY can perform filtering +* +************************************************************************************/ + +smacErrors_t SMACSetPanID(uint16_t nwShortPanID) +{ + macToPlmeMessage_t lMsg; + lMsg.msgType = gPlmeSetReq_c; + lMsg.msgData.setReq.PibAttribute = gPhyPibPanId_c; + lMsg.msgData.setReq.PibAttributeValue = (uint64_t)nwShortPanID; + + phyStatus_t u8PhyRes = MAC_PLME_SapHandler(&lMsg,0); + if(u8PhyRes == gPhyBusy_c || u8PhyRes == gPhyBusyTx_c || u8PhyRes == gPhyBusyRx_c) + return gErrorBusy_c; + if(u8PhyRes != gPhySuccess_c) + return gErrorNoResourcesAvailable_c; + u16PanID = nwShortPanID; + return gErrorNoError_c; +} + +void BackoffTimeElapsed(void const *arg) +{ + uint8_t u8PhyRes = MAC_PD_SapHandler(gSmacDataMessage, 0); + if(u8PhyRes != gPhySuccess_c) + { + smacState = mSmacStateIdle_c; + MEM_BufferFree(gSmacDataMessage); + gSmacDataMessage = NULL; + } +} + +/************************************************************************************ +* SMACPacketCheck +* +* This function returns TRUE if Phy payload can be of SMAC packet type +* +************************************************************************************/ + +bool_t SMACPacketCheck(pdDataToMacMessage_t* pMsgFromPhy) +{ + //check if packet is of type Data + if( (pMsgFromPhy->msgData.dataInd.pPsdu[0] & 0x07) != 0x01 ) + return FALSE; + //check if PSDU length is at least of smac header size. + if( (pMsgFromPhy->msgData.dataInd.psduLength < gSmacHeaderBytes_c) ) + return FALSE; + + return TRUE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SMAC.h Tue Aug 18 12:48:33 2015 +0000 @@ -0,0 +1,118 @@ +/************************************************************************************************** +* SMAC implementation. +* +* Freescale Semiconductor Inc. +* (c) Copyright 2004-2010 Freescale Semiconductor, Inc. +* ALL RIGHTS RESERVED. +* +*************************************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +***********************************************************************************************//*! +**************************************************************************************************/ + +#ifndef SMAC_H_ +#define SMAC_H_ + +/************************************************************************************ +************************************************************************************* +* Includes +************************************************************************************* +************************************************************************************/ + +#include "SMAC_Interface.h" +#include "Phy.h" +#include "PhyInterface.h" +//#include "TimersManager.h" +#include "RNG_Interface.h" + +#if defined (gPHY_802_15_4g_d) +#include "PhyPib.h" +#include "PhyExtended.h" +#include "PhyTime.h" +#endif +/************************************************************************************ +************************************************************************************* +* Private Prototypes +************************************************************************************* +************************************************************************************/ +void SmacSetRxTimeout(smacTime_t timeoutSymbols); + +#if defined (gPHY_802_15_4g_d) + +#define smacPreambleSizeOf16_c (16) +#define smacPreambleSizeOf3_c (3) + +#endif +/*smacParametersValidation_d: +TRUE : SMAC primitives validate their incoming parameters. +FALSE: SMAC primitives do their stuff without validating their incoming +parameters +*Note: Setting this as FALSE will compile a smaller foot print SMAC. +*/ +#define smacParametersValidation_d TRUE + +/*smacInitializationValidation_d: +TRUE : SMAC primitives validate whether SMAC is initialized or not. +FALSE: SMAC primitives don't care about SMAC's initialization. +*Note: Setting this as FALSE will compile a smaller foot print SMAC. +*/ +#define smacInitializationValidation_d TRUE + +#define FRAME_CTRL_ACK_FIELD_SET (1 << 5) +/************************************************************************************ +************************************************************************************* +* Module Type definitions +************************************************************************************* +************************************************************************************/ +typedef enum smacStates_tag { + mSmacStateIdle_c, + mSmacStateTransmitting_c, + mSmacStateReceiving_c, + mSmacStateScanningChannels_c, + mSmacStatePerformingCca_c, + mSmacStatePerformingEd_c, + mSmacStatePerformingTest_c, + mSmacStateHibernate_c, + mSmacStateDoze_c +} smacStates_t; + +typedef union prssPacketPtr_tag +{ + uint8_t* smacScanResultsPointer; + rxPacket_t *smacRxPacketPointer; + pdDataReq_t *smacTxPacketPointer; +}prssPacketPtr_t; + +/*********************************************************************************** +* Phy to SMAC SAP prototype +************************************************************************************/ +typedef phyStatus_t ( * PD_SMAC_SapHandler_t)(pdDataToMacMessage_t * pMsg, instanceId_t instanceId); + +typedef phyStatus_t ( * PLME_SMAC_SapHandler_t)(plmeToMacMessage_t * pMsg, instanceId_t instanceId); + +/*********************************************************************************** +* SMAC to App SAP handlers +************************************************************************************/ +static SMAC_APP_MCPS_SapHandler_t gSMAC_APP_MCPS_SapHandler; +static SMAC_APP_MLME_SapHandler_t gSMAC_APP_MLME_SapHandler; +/************************************************************************************ +************************************************************************************* +* Private definitions +************************************************************************************* +************************************************************************************/ + +#define smacInstance 0 + +#endif /* SMAC_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SMAC_Channels.h Tue Aug 18 12:48:33 2015 +0000 @@ -0,0 +1,224 @@ +/*! +* Copyright (c) 2014, Freescale Semiconductor, Inc. +* All rights reserved. +* +* \file SMAC_Channels.h +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _SMAC_CHANNELS_H +#define _SMAC_CHANNELS_H + + +/************************************************************************************ +************************************************************************************* +* Include +************************************************************************************* +************************************************************************************/ + +/************************************************************************************ +************************************************************************************* +* Public macros +************************************************************************************* +************************************************************************************/ + +/************************************************************************************ +************************************************************************************* +* Public prototypes +************************************************************************************* +************************************************************************************/ + +/************************************************************************************ +************************************************************************************* +* Public type definitions +************************************************************************************* +************************************************************************************/ + +/************************************************************************************ +************************************************************************************* +* Public memory declarations +************************************************************************************* +************************************************************************************/ + +/************************************************************************************ +************************************************************************************* +* Public functions +************************************************************************************* +************************************************************************************/ + +/* 802.15.4-2006 maximum channel enumeration */ +#if defined (gPHY_802_15_4g_d) +gChannel0_c = 0, +gChannel1_c, +gChannel2_c, +gChannel3_c, +gChannel4_c, +gChannel5_c, +gChannel6_c, +gChannel7_c, +gChannel8_c, +gChannel9_c, +gChannel10_c, +gChannel11_c, +gChannel12_c, +gChannel13_c, +gChannel14_c, +gChannel15_c, +gChannel16_c, +gChannel17_c, +gChannel18_c, +gChannel19_c, +gChannel20_c, +gChannel21_c, +gChannel22_c, +gChannel23_c, +gChannel24_c, +gChannel25_c, +gChannel26_c, +gChannel27_c, +gChannel28_c, +gChannel29_c, +gChannel30_c, +gChannel31_c, +gChannel32_c, +gChannel33_c, +gChannel34_c, +gChannel35_c, +gChannel36_c, +gChannel37_c, +gChannel38_c, +gChannel39_c, +gChannel40_c, +gChannel41_c, +gChannel42_c, +gChannel43_c, +gChannel44_c, +gChannel45_c, +gChannel46_c, +gChannel47_c, +gChannel48_c, +gChannel49_c, +gChannel50_c, +gChannel51_c, +gChannel52_c, +gChannel53_c, +gChannel54_c, +gChannel55_c, +gChannel56_c, +gChannel57_c, +gChannel58_c, +gChannel59_c, +gChannel60_c, +gChannel61_c, +gChannel62_c, +gChannel63_c, +gChannel64_c, +gChannel65_c, +gChannel66_c, +gChannel67_c, +gChannel68_c, +gChannel69_c, +gChannel70_c, +gChannel71_c, +gChannel72_c, +gChannel73_c, +gChannel74_c, +gChannel75_c, +gChannel76_c, +gChannel77_c, +gChannel78_c, +gChannel79_c, +gChannel80_c, +gChannel81_c, +gChannel82_c, +gChannel83_c, +gChannel84_c, +gChannel85_c, +gChannel86_c, +gChannel87_c, +gChannel88_c, +gChannel89_c, +gChannel90_c, +gChannel91_c, +gChannel92_c, +gChannel93_c, +gChannel94_c, +gChannel95_c, +gChannel96_c, +gChannel97_c, +gChannel98_c, +gChannel99_c, +gChannel100_c, +gChannel101_c, +gChannel102_c, +gChannel103_c, +gChannel104_c, +gChannel105_c, +gChannel106_c, +gChannel107_c, +gChannel108_c, +gChannel109_c, +gChannel110_c, +gChannel111_c, +gChannel112_c, +gChannel113_c, +gChannel114_c, +gChannel115_c, +gChannel116_c, +gChannel117_c, +gChannel118_c, +gChannel119_c, +gChannel120_c, +gChannel121_c, +gChannel122_c, +gChannel123_c, +gChannel124_c, +gChannel125_c, +gChannel126_c, +gChannel127_c, +gChannel128_c +#else + +gChannel11_c = 0x0B, +gChannel12_c, +gChannel13_c, +gChannel14_c, +gChannel15_c, +gChannel16_c, +gChannel17_c, +gChannel18_c, +gChannel19_c, +gChannel20_c, +gChannel21_c, +gChannel22_c, +gChannel23_c, +gChannel24_c, +gChannel25_c, +gChannel26_c +#endif + +#endif /* _SMAC_CHANNELS_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SMAC_Config.h Tue Aug 18 12:48:33 2015 +0000 @@ -0,0 +1,47 @@ +/************************************************************************************************** +* This header contains SMAC basic configuration. +* +* Freescale Semiconductor Inc. +* (c) Copyright 2004-2010 Freescale Semiconductor, Inc. +* ALL RIGHTS RESERVED. +* +*************************************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +***********************************************************************************************//*! +**************************************************************************************************/ + +#ifndef SMAC_CONFIG_H_ +#define SMAC_CONFIG_H_ + +/* BEGIN SMAC Config Options Definition */ + +#define gNodeAddress_c (0xBEAD) +#define gDefaultPanID_c (0xFACE) +#define CCA_BEFORE_TX (FALSE) +#define gMaxRetriesAllowed_c ( 0x05 ) +//Make sure gMaxBackoffTime_c is of value (1<<n)-1. Ex: (1<<3)-1 = 7, (1<<4)-1 = 15; +#define gMaxBackoffTime_c ( 0x1F ) +#define gMinBackoffTime_c ( 0x00 ) +/* END SMAC Config Options Definition */ + +/* BEGIN Configuration Parameters Definition */ +#define gMaxOutputPower_c ( 0x1F ) +#define gMinOutputPower_c ( 0x03 ) +#define gDefaultOutputPower_c ( 0x0F ) +#define gDefaultChannelNumber_c gChannel11_c +#define gDefaultAddress_c (gBroadcastAddress_c) +/* END Configuration Parameters Definition */ + +#endif /* SMAC_CONFIG_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SMAC_Interface.h Tue Aug 18 12:48:33 2015 +0000 @@ -0,0 +1,729 @@ +/************************************************************************************************** +* SMAC Interface header file +* +* Freescale Semiconductor Inc. +* (c) Copyright 2004-2014 Freescale Semiconductor, Inc. +* ALL RIGHTS RESERVED. +* +*************************************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +***********************************************************************************************//*! +**************************************************************************************************/ + +#ifndef SMAC_INTERFACE_H_ +#define SMAC_INTERFACE_H_ + +/************************************************************************************ +************************************************************************************* +* Includes +************************************************************************************* +************************************************************************************/ +#include "EmbeddedTypes.h" +#include "PhyTypes.h" +/************************************************************************************ +************************************************************************************* +* Interface macro definitions +************************************************************************************* +************************************************************************************/ + +#define gSmacHeaderBytes_c ( sizeof(smacHeader_t) ) +#define gMaxSmacSDULength_c (gMaxPHYPacketSize_c -(sizeof(smacHeader_t) + 2) ) +#define gMinSmacSDULength_c (0) + +#define gBroadcastAddress_c (0xFFFF) +#define gSmacDefaultFrameCtrl (0x8841) +#define gSmacDefaultSeqNo (0xAB) +/************************************************************************************ +************************************************************************************* +* Public memory declarations +************************************************************************************* +************************************************************************************/ +// extern bool_t smacStandalone; +extern uint8_t gTotalChannels; + +/************************************************************************************ +************************************************************************************* +* Interface Type definitions +************************************************************************************* +************************************************************************************/ + +typedef enum smacMessageDefs_tag +{ + gMcpsDataReq_c, + gMcpsDataCnf_c, + gMcpsDataInd_c, + + gMcpsIndQueueInsertReq_c, + gMcpsIndQueueInsertCnf_c, + gMcpsIndQueueRemoveReq_c, + + gMlmeCcaReq_c, + gMlmeCcaCnf_c, + + gMlmeEdReq_c, + gMlmeEdCnf_c, + + gMlmeSetTRxStateReq_c, + gMlmeSetTRxStateCnf_c, + + gMlmeSetReq_c, + gMlmeSetCnf_c, + + gMlmeGetReq_c, + gMlmeGetCnf_c, + + gMlmeTimeoutInd_c, + + gMlme_StartEventInd_c, + gMlme_SyncLossInd_c, + gMlme_RxSfdDetectInd_c, + gMlme_FilterFailInd_c, + gMlme_UnexpectedRadioResetInd_c, +}smacMessageDefs_t; + +typedef uint64_t smacTime_t; + +typedef struct smacPdu_tag +{ + uint8_t smacPdu[1]; +}smacPdu_t; + +typedef PACKED_STRUCT smacHeader_tag +{ + uint16_t frameControl; + uint8_t seqNo; + uint16_t panId; + uint16_t destAddr; + uint16_t srcAddr; +}smacHeader_t; + +typedef struct txPacket_tag +{ + uint8_t u8DataLength; + smacHeader_t smacHeader; + smacPdu_t smacPdu; +}txPacket_t; + +typedef struct txContextConfig_tag +{ + bool_t ccaBeforeTx; + bool_t autoAck; + uint8_t retryCountCCAFail; + uint8_t retryCountAckFail; +}txContextConfig_t; + +typedef enum rxStatus_tag +{ + rxInitStatus, + rxProcessingReceptionStatus_c, + rxSuccessStatus_c, + rxTimeOutStatus_c, + rxAbortedStatus_c, + rxMaxStatus_c +} rxStatus_t; + +typedef struct rxPacket_tag +{ + uint8_t u8MaxDataLength; + rxStatus_t rxStatus; + uint8_t u8DataLength; + smacHeader_t smacHeader; + smacPdu_t smacPdu; +}rxPacket_t; + +typedef enum txStatus_tag +{ + txSuccessStatus_c, + txFailureStatus_c, + txMaxStatus_c +} txStatus_t; + +typedef enum smacErrors_tag +{ + gErrorNoError_c = 0, + gErrorBusy_c, + gErrorChannelBusy_c, + gErrorNoAck_c, + gErrorOutOfRange_c, + gErrorNoResourcesAvailable_c, + gErrorNoValidCondition_c, + gErrorCorrupted_c, + gErrorMaxError_c +} smacErrors_t; + +#if defined (gPHY_802_15_4g_d) + +typedef enum smacRFModes_tag +{ + gRFMode1_c = gPhyMode1_c, + gRFMode2_c = gPhyMode2_c, + gRFMode3_c = gPhyMode3_c, + gRFMode4_c = gPhyMode4_c, + gRFMode5_c = gPhyMode1ARIB_c, /*ARIB mode 1*/ + gRFMode6_c = gPhyMode2ARIB_c, /*ARIB mode 2*/ + gRFMaxMode_c +} smacRFModes_t; + +typedef enum smacFrequencyBands_tag +{ + gSMAC_863_870MHz_c = gFreq863__870MHz_c, /* 863-870 (Europe) */ + gSMAC_902_928MHz_c = gFreq902__928MHz_c, /* 902-928 (US) */ + gSMAC_920_928MHz_c = gFreq920__928MHz_c, /* 920-928 (Japan) */ + gSMAC_169_400__169_475MHz_c = gFreq169_400__169_475MHz_c /* 169-475 */ +}smacFrequencyBands_t; + +#endif +typedef struct smacPacket_tag +{ + uint8_t u8SyncWordSize; + uint8_t *u8SyncWordValue; + uint16_t u16PreambleLength; +}smacPacket_t; + +typedef enum scanModes_tag +{ + gScanModeCCA_c = 0, + gScanModeED_c, + gMaxScanMode_c +} scanModes_t; + +#if defined (gPHY_802_15_4g_d) + +typedef struct packetConfig_tag +{ + uint16_t u16PreambleSize; + uint8_t u8SyncWordSize; + uint8_t *pu8SyncWord; +} packetConfig_t; + +#endif + +/*@CMA, Connectivity Test_Start*/ +typedef enum channels_tag +{ +#include "SMAC_Channels.h" +} channels_t; + +typedef enum smacTestMode_tag +{ + gTestModeForceIdle_c = 0, + gTestModeContinuousTxModulated_c, + gTestModeContinuousTxUnmodulated_c, + gTestModePRBS9_c, + gTestModeContinuousRxBER_c, + gMaxTestMode_c +} smacTestMode_t; + +typedef struct smacDataCnf_tag +{ + smacErrors_t status; +} smacDataCnf_t; + +typedef struct smacDataInd_tag +{ + //phyTimeTimestamp_t timeStamp; + uint8_t ppduLinkQuality; + uint8_t u8LastRxRssi; + rxPacket_t * pRxPacket; +} smacDataInd_t; + +typedef struct smacEdReq_tag +{ + channels_t scanChannel; + smacTime_t startTime; // absolute +} smacEdReq_t; + +typedef struct smacCcaReq_tag +{ + scanModes_t ccaType; +} smacCcaReq_t; + +typedef struct smacCcaCnf_tag +{ + smacErrors_t status; +} smacCcaCnf_t; + +typedef struct smacEdCnf_tag +{ + smacErrors_t status; + uint8_t energyLevel; + uint8_t energyLeveldB; + channels_t scannedChannel; +} smacEdCnf_t; + +typedef struct smacToAppMlmeMessage_tag +{ + smacMessageDefs_t msgType; + uint8_t appInstanceId; + union + { + smacCcaCnf_t ccaCnf; + smacEdCnf_t edCnf; + }msgData; +} smacToAppMlmeMessage_t; + +typedef struct smacToAppDataMessage_tag +{ + smacMessageDefs_t msgType; + uint8_t appInstanceId; + union + { + smacDataCnf_t dataCnf; + smacDataInd_t dataInd; + }msgData; +} smacToAppDataMessage_t; + +typedef smacErrors_t ( * SMAC_APP_MCPS_SapHandler_t)(smacToAppDataMessage_t * pMsg, instanceId_t instanceId); + +typedef smacErrors_t ( * SMAC_APP_MLME_SapHandler_t)(smacToAppMlmeMessage_t * pMsg, instanceId_t instanceId); + +/************************************************************************************ +************************************************************************************* +* External Prototypes +************************************************************************************* +************************************************************************************/ +extern void InitSmac(void); + +/*********************************************************************************** +* Smac_RegisterSapHandlers +* This function registers the data and management components callbacks to the application +* After calling this function and providing two function pointers, SMAC will call +* one of these two, for each async request, based on request type (data or management) +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Return value: +* None +************************************************************************************/ +extern void Smac_RegisterSapHandlers(SMAC_APP_MCPS_SapHandler_t pSMAC_APP_MCPS_SapHandler, + SMAC_APP_MLME_SapHandler_t pSMAC_APP_MLME_SapHandler, + instanceId_t smacInstanceId); + +/*********************************************************************************** +* App to Smac SAP HANDLERS +************************************************************************************/ +//smacErrors_t AppToSmac_Data_SapHandler(AppToSmacDataMessage_t* pMsg, uint8_t MACInstance); +//smacErrors_t AppToSmac_Mlme_SapHandler(AppToSmacMlmeMessage_t* pMsg, uint8_t MACInstance); +/***********************************************************************************/ + +/******************************** SMAC Data primitives *****************************/ +/***********************************************************************************/ + +/************************************************************************************ +* MCPSDataRequest +* +* This data primitive is used to send an over the air packet. This is an asyncronous +* function, it means it ask SMAC to transmit one OTA packet, but when the function +* returns it is not sent already. +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Return value: +* gErrorNoError_c: Everything is ok and the transmission will be performed. +* gErrorOutOfRange_c: One of the members in the pTxMessage structure is out of +* range (no valid bufer size or data buffer pointer is NULL) +* gErrorNoResourcesAvailable_c: the radio is performing another action. +* gErrorNoValidCondition_c: The SMAC has not been initialized +* +************************************************************************************/ +extern smacErrors_t MCPSDataRequest(txPacket_t *psTxPacket); + + +/************************************************************************************ +* MLMEConfigureTxContext +* +* This management primitive sets up the transmission conditions used by MCPSDataRequest +* +* Interface assumptions: +* SMAC is initialized +* +* Return value: +* gErrorNoError_c: Everything is set accordingly. +* gErrorOutOfRange_c: More than gMaxRetriesAllowed_c are required +* gErrorNoValidCondition_c: Retries are required but neither Ack nor CCA are requested +* +************************************************************************************/ +extern smacErrors_t MLMEConfigureTxContext(txContextConfig_t* pTxConfig); +/************************************************************************************ +* MLMERXEnableRequest +* +* Function used to place the radio into receive mode +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Arguments: +* +* rxPacket_t *gsRxPacket: Pointer to the structure where the reception results will be stored. +* smacTime_t stTimeout: 64-bit timeout value, absolute time in symbols +* +* Return Value: +* gErrorNoError_c: Everything is ok and the reception will be performed. +* gErrorOutOfRange_c: One of the members in the pRxMessage structure is out of range (no valid bufer size or data buffer pointer is NULL). +* gErrorBusy_c: the radio is performing another action. +* gErrorNoValidCondition_c: The SMAC has not been initialized. +*************************************************************************************/ +extern smacErrors_t MLMERXEnableRequest(rxPacket_t *gsRxPacket, smacTime_t stTimeout); + + +/************************************************************************************ +* MLMERXDisableRequest +* +* Returns the radio to idle mode from receive mode. +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Arguments: +* None +* +* Return Value: +* gErrorNoValidCondition_c If the Radio is not in Rx state. +* gErrorNoError_c When the message was aborted or disabled. +*************************************************************************************/ +extern smacErrors_t MLMERXDisableRequest(void); + +/************************************************************************************ +* MLMELinkQuality +* +* This function returns an integer value that is the link quality from the last received +* packet of the form: dBm = (-Link Quality/2). +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Arguments: +* None +* +* Return Value: +* uint8_t: 8 bit value representing the link quality value in dBm. +* Returns the result in smacLastDataRxParams.linkQuality. +*************************************************************************************/ +extern uint8_t MLMELinkQuality(void); + +/************************************************************************************ +* MLMESetInterPacketRxDelay +* +* This sets the inter packet delay for the packet handler +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Arguments: +* uint8_t u8InterPacketRxDelay: interpacket delay in ms +* +* Return Value: +* gErrorNoValidCondition_c If the Radio is not in Rx state. +* gErrorNoError_c When the message was aborted or disabled. +* +*************************************************************************************/ +#if defined(gPHY_802_15_4g_d) +extern smacErrors_t MLMESetInterPacketRxDelay(uint8_t u8InterPacketRxDelay); +#endif + +/***********************************************************************************/ +/******************************** SMAC Radio primitives ****************************/ +/***********************************************************************************/ + +/************************************************************************************ +* MLMESetChannelRequest +* +* This sets the frequency on which the radio will transmit or receive on. +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Arguments: +* channels_t newChannel: channel to be set +* +* Return Value: +* gErrorNoError_c: The channel set has been performed +* gErrorOutOfRange_c : channel requested is not valid +* gErrorBusy_c: when SMAC is busy in other radio activity as transmitting or receiving data. Or performing a channel scan. +*************************************************************************************/ +extern smacErrors_t MLMESetChannelRequest (channels_t newChannel); + +#ifdef gIncludeCalibrationOption +/************************************************************************************ +* MLMESetAdditionalRFOffset +* +* This sets the frequency offset in respect to the current channel. Used for calibration. +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Arguments: +* uint32_t additionalRFOffset: offset used in frequency Calculation +* +* Return Value: +* gErrorNoError_c: The PIB is set +* gErrorNoValidCondition_c: SMAC is not initialized +*************************************************************************************/ +extern smacErrors_t MLMESetAdditionalRFOffset (uint32_t additionalRFOffset); + +/************************************************************************************ +* MLMEGetAdditionalRFOffset +* +* This gets the frequency offset in respect to the current channel. Used for calibration. +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Arguments: +* None +* +* Return Value: +* calibration offset +*************************************************************************************/ +extern uint32_t MLMEGetAdditionalRFOffset( void ); + +#endif +/************************************************************************************ +* MLMEGetChannelRequest +* +* This function returns the current channel, if an error is detected it returns gChannelOutOfRange_c. +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Arguments: +* None +* +* Return Value: +* channels_t (uint8_t): The current RF channel. +* gChannelOutOfRange_c: If current channel could not be detected +*************************************************************************************/ +extern channels_t MLMEGetChannelRequest(void); + + +/************************************************************************************ +* MLMERssi +* +* This call starts an energy detect (ED) cycle and returns the energy value (-power/2) +* via the returned argument. For example, if the Energy Detect returns 80 then the +* interpreted value is -80/2 or -40 dBm +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Arguments: +* None +* +* Return Value: +* uint8_t: An unsigned 8-bit value representing the energy on the current channel. +*************************************************************************************/ +#if defined(gPHY_802_15_4g_d) +extern uint8_t MLMERssi(void); +#endif + +/************************************************************************************ +* MLMESetCCADuration +* +* This call sets the amount of time necessary to perform CCA or ED +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Arguments: +* uint64_t usCCADuration: duration in microseconds +* +* Return Value: +* gErrorNoError_c in case of success, error code otherwise. +*************************************************************************************/ +#if defined(gPHY_802_15_4g_d) +extern smacErrors_t MLMESetCCADuration(uint64_t usCCADuration ); +#endif +/************************************************************************************ +* MLMEPacketConfig +* +* This function sets the following parameters for OTA packets in radio�s registers: +* Preamble size, synchronization word size, and synchronization word value. +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Arguments: +* packetConfig_t *pPacketCfg +* +* Return Value: +* gErrorBusy_c: when SMAC is busy in other radio activity as transmitting or receiving data. +* Or performing a channel scan. +* gErrorNoError_c: the packet has been configured +*************************************************************************************/ +#if defined(gPHY_802_15_4g_d) +extern smacErrors_t MLMEPacketConfig(packetConfig_t *pPacketCfg); +#endif +/************************************************************************************ +* MLMERadioInit +* +* This function initializes the Radio parameters. +* +* Interface assumptions: +* None +* +* Arguments: +* None +* +* Return Value: +* gErrorNoError_c: the Radio initialization has been done successfully +*************************************************************************************/ +#if defined(gPHY_802_15_4g_d) +extern smacErrors_t MLMERadioInit(void); +#endif +/************************************************************************************ +* MLMEPhySoftReset +* +* This function performs a software reset on the radio, PHY and SMAC state machines. +* +* Interface assumptions: +* None +* +* Arguments: +* None +* +* Return Value: +* gErrorNoError_c: If the action is performed. +*************************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif +smacErrors_t MLMEPhySoftReset(void); + +#ifdef __cplusplus +} //extern "C" +#endif + +/************************************************************************************ +* MLMEPAOutputAdjust +* +* +*************************************************************************************/ +extern smacErrors_t MLMEPAOutputAdjust(uint8_t u8PaValue); + +/************************************************************************************ +* MLMESetPreambleLength +* +* +*************************************************************************************/ +#if defined(gPHY_802_15_4g_d) +extern smacErrors_t MLMESetPreambleLength(uint16_t u16preambleLength); +#endif +/************************************************************************************ +* MLMESetSyncWordValue +* +* +*************************************************************************************/ +#if defined(gPHY_802_15_4g_d) +extern smacErrors_t MLMESetSyncWordValue(uint8_t *u8syncWordValue); +#endif +/************************************************************************************ +* MLMESetSyncWordSize +* +* +*************************************************************************************/ +#if defined(gPHY_802_15_4g_d) +extern smacErrors_t MLMESetSyncWordSize(uint8_t u8syncWordSize); +#endif +/************************************************************************************ +* MLMESetFreqBand +* +* +* +************************************************************************************/ +#if defined(gPHY_802_15_4g_d) +extern smacErrors_t MLMESetFreqBand(smacFrequencyBands_t freqBand, smacRFModes_t phyMode); +#endif +/************************************************************************************ +* MLMESetPhyMode +* +* +* +************************************************************************************/ +#if defined(gPHY_802_15_4g_d) +extern smacErrors_t MLMESetPhyMode(smacRFModes_t phyMode); +#endif +/***********************************************************************************/ +/***************************** SMAC Management primitives **************************/ +/***********************************************************************************/ + +/************************************************************************************ +* MLMEScanRequest +* +* This function scans the channel passed as parameter using CCA or ED mode +* returns the RSSI in that channel. +* +* Interface assumptions: +* The SMAC and radio driver have been initialized and are ready to be used. +* +* Arguments: +* channels_t u8ChannelToScan: channel to scan +* uint8_t *u8ChannelScanResult: to return the RSSI value +* +* Return Value: +* gErrorNoError_c: If the action was performed correctly. +* gErrorBusy_c: If SMAC is busy. +*************************************************************************************/ +extern smacErrors_t MLMEScanRequest(channels_t u8ChannelToScan); + +/*@CMA, Conn Test Added*/ +/************************************************************************************ +* MLMECcaRequest +* +* This function performs Clear Channel Assessment on the active channel +* +* Return value: +* gErrorNoError_c: SMAC will perform Cca +* gErrorBusy_c: SMAC is busy +************************************************************************************/ +extern smacErrors_t MLMECcaRequest(void); + +/************************************************************************************ +* MLMETXDisableRequest +* +* Returns the radio to idle mode from Tx mode. +* +************************************************************************************/ +extern void MLMETXDisableRequest(void); + +/*********************************************************************************** +******************************** SMAC MCU primitives ******************************* +***********************************************************************************/ + +/************************************************************************************ +*SMAC auxiliary functions +*************************************************************************************/ + +/************************************************************************************ +*SMACFillHeader +*This is a replacement for the u8DestAddress in the txPacket_t structure +*To set the destination address simply call this function with a pointer to +*txPacket->smacHeader and a uint16_t variable resembling the address. +*Also, to change the default source address and panID, modify gDefaultPanID_c and +*gNodeAddress_c from SMAC_Config.h or call SMACSetShortSrcAddress and SMACSetPanID. +*************************************************************************************/ +extern void SMACFillHeader(smacHeader_t* pSmacHeader, uint16_t destAddr); + +/***********************************************************************************/ +extern smacErrors_t SMACSetShortSrcAddress(uint16_t nwShortAddress); + +/***********************************************************************************/ +extern smacErrors_t SMACSetPanID(uint16_t nwShortPanID); + +/***********************************************************************************/ + + + +#endif /* SMAC_INTERFACE_H_ */