📄 mac.c
字号:
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + CHIPCON CC2430 INTEGRATED 802.15.4 MAC AND PHY *
* *** + + *** *
* *** +++ *** *
* *** *** *
* ************ *
* ********** *
* *
*******************************************************************************************************
* CONFIDENTIAL *
* The use of this file is restricted by the signed MAC software license agreement. *
* *
* Copyright Chipcon AS, 2005 *
*******************************************************************************************************
* This file implements the MAC functions (request and response) to be called by the higher layer *
*******************************************************************************************************/
#include "mac_headers.h"
//-------------------------------------------------------------------------------------------------------
// Extended address, must be set by higher layer
BYTE aExtendedAddress[8];
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// MAC_ENUM mlmeResetRequest(BOOL setDefaultPIB)
//
// DESCRIPTION:
// Reset the MAC and PHY layers, including CC2430, the microcontroller, and all state variables.
// NOTE: The initialization and power-up sequence must be performed according to
// the MAC documentation prior to calling mlmeResetRequest or other
// MAC primitives
//
// PARAMETERS:
// BOOL setDefaultPIB
// Reset the PHY and MAC PIBs
//
// RETURN VALUE:
// MAC_ENUM
// Always SUCCESS
//-------------------------------------------------------------------------------------------------------
ROOT MAC_ENUM mlmeResetRequest(BOOL setDefaultPIB) {
// Disable the FIFOP interrupt
DISABLE_TIMER2_INT();
// Clear ABORTRX_ON_SRXON and ACCEPT_ACKPKT
FSMTC1 = 0x00;
// Initialize the MAC timer
mtimInit(FALSE);
// Initialize the scheduler before the other modules (task reservation...)
mschInit();
// Initialize variables in the various modules
mrxpInit();
mtxpInit();
#if MAC_OPT_FFD
miqInit();
#endif
mtxInfo.startTxTask = mschReserveTask();
mrxInfo.state = MRX_STATE_LEN_FCF_SEQ;
mrxInfo.onCounter = 0;
mrxInfo.keepFifopIntOff = FALSE;
mrxInfo.handleFifoUnderflow = FALSE;
mbcnInfo.trackBeacon = FALSE;
mbcnInfo.findBeacon = FALSE;
mbcnInfo.rxTaskNumber = NO_TASK;
mbcnInfo.txTaskNumber = NO_TASK;
mbcnInfo.pTxPacket = NULL;
mscInfo.scanStatus = MSC_STATUS_FINISHED;
mtxInfo.beaconTransmissionInProgress = FALSE;
// Reset flags
RESET_MF();
// MAC command state
macInfo.state = MAC_STATE_DEFAULT;
// Other state variables
mbcnInfo.lastSfSpec.battLifeExt = FALSE;
mbcnInfo.lastSfSpec.finalCap = USE_WHOLE_SUPERFRAME_FOR_CAP;
// Set all MAC/PHY PIB attributes to their default values.
if (setDefaultPIB) {
ppib.phyCurrentChannel = 11;
ppib.phyTransmitPower = OUTPUT_POWER_0DBM; //0dBm an +/- 1dBm tolerance
ppib.phyCcaMode = 1;
mpib.macAckWaitDuration = 54;
mpib.macAssociationPermit = FALSE;
mpib.macAutoRequest = TRUE;
mpib.macBattLifeExt = FALSE;
mpib.macBattLifeExtPeriods = 6;
mpib.pMacBeaconPayload = NULL;
mpib.macBeaconPayloadLength = 0;
mpib.macBeaconOrder = 15;
mpib.macBeaconTxTime = 0;
mpib.macBSN = msupGetRandomByte();
mpib.macCoordShortAddress = 0xFFFF;
mpib.macDSN = msupGetRandomByte();
mpib.macGTSPermit = TRUE;
mpib.macMaxCsmaBackoffs = 4;
mpib.macMinBE = 3;
mpib.macPANId = 0xFFFF;
mpib.macPromiscuousMode = FALSE;
mpib.macRxOnWhenIdle = FALSE;
mpib.macShortAddress = 0xFFFF;
mpib.macSuperframeOrder = BEACON_ORDER_NO_BEACON;
mpib.macTransactionPersistenceTime = 0x01F4;
memset(mpib.pMacCoordExtendedAddress, 0xFF, sizeof(mpib.pMacCoordExtendedAddress));
mpib.macAssociatedPanCordinator = TRUE;
#if MAC_OPT_ACL_SIZE > 0
mpib.ppMacACLEntryDescriptorSet = NULL;
mpib.macACLEntryDescriptorSetSize = 0;
#endif
#if MAC_OPT_SECURITY
mpib.macDefaultSecurity = FALSE;
mpib.macDefaultSecurityMaterialLength = 0x15;
mpib.pMacDefaultSecurityMaterial = NULL;
mpib.macDefaultSecuritySuite = 0;
#endif
#if ((MAC_OPT_SECURITY) || (MAC_OPT_ACL_SIZE>0))
mpib.macSecurityMode = 0;
#endif
}
// Configure CC2430 registers
mpmRestoreRegsAndRam();
// Turn the interrupts back on
EnableRfInterrupts ();
ENABLE_TIMER2_INT();
// Confirm
return SUCCESS;
} // mlmeResetRequest
//-------------------------------------------------------------------------------------------------------
// void mcpsDataRequest(BYTE addrModes, WORD srcPanId, ADDRESS *pSrcAddr, WORD destPanId, ADDRESS ...)
//
// DESCRIPTION:
// Transmit a data packet.
//
// PARAMETERS:
// BYTE addrModes
// Address mode for source and destination
// (SRC_ADDR_SHORT, SRC_ADDR_EXT or 0) | (DEST_ADDR_SHORT, DEST_ADDR_EXT or 0)
// WORD srcPanId
// Source PAN identifier
// ADDRESS *pSrcAddr
// Pointer to the source address (short or extended)
// WORD destPanId,
// Destination PAN identifier
// ADDRESS *pDestAddr,
// Pointer to the destination address (short or extended)
// UINT8 msduLength,
// The length of pMsdu[]
// BYTE *pMsdu,
// A pointer to the packet payload
// BYTE msduHandle,
// A handle to this packet which is used later on with mcpsPurgeRequest)( and mcpsDataConfirm()
// BYTE txOptions
// (TX_OPT_SECURITY_ENABLE | TX_OPT_INDIRECT | TX_OPT_GTS | TX_OPT_ACK_REQ) or TX_OPT_NONE
// Note: Indirect transmission only available for MAC_OPT_FFD=1
//-------------------------------------------------------------------------------------------------------
ROOT void mcpsDataRequest(BYTE addrModes, WORD srcPanId, ADDRESS *pSrcAddr, WORD destPanId,
ADDRESS *pDestAddr, UINT8 msduLength, BYTE *pMsdu,
BYTE msduHandle, BYTE txOptions) {
MAC_TX_PACKET *pPacket;
UINT8 temp;
BYTE *pPayload,
taskNumber;
// Reserve a packet to use with the TX engine
#if MAC_OPT_FFD
reservePacket:
pPacket = mtxpReservePacket();
if (!pPacket) {
if (txOptions & TX_OPT_INDIRECT) {
mcpsDataConfirm(TRANSACTION_OVERFLOW, msduHandle);
return;
} else {
goto reservePacket;
}
}
#else // RFD
if (txOptions & TX_OPT_INDIRECT) {
mcpsDataConfirm(INVALID_PARAMETER, msduHandle);
return;
}
reservePacket:
pPacket = mtxpReservePacket();
if (!pPacket) {
goto reservePacket;
}
#endif
// Set transmission mode
pPacket->txMode = MTX_MODE_USE_CSMACA_BM;
// Set number of retries
pPacket->retriesLeft = aMaxFrameRetries;
// Store the msdu handle
pPacket->msduHandle = msduHandle;
// Generate the packet header (and find security material, if enabled)
msupPrepareHeader(pPacket, FT_DATA, addrModes, srcPanId, pSrcAddr, destPanId, pDestAddr, txOptions);
pPayload = pPacket->pPayload;
#if MAC_OPT_SECURITY
// Before calculating the PSDU length; make sure that the payload + MIC is less than aMaxMACFrameSize
// #bytes in frame counter + key sequence counter (0 or 5)
temp = msecProcessSecurityCounters(pPacket, pPayload);
// In case of frame counter overflow or missing key
// Generate error with FAILED_SECURITY_CHECK or UNAVAILABLE_KEY
if (pPacket->securitySuite >= 8) {
mtxpReleasePacket(pPacket);
mcpsDataConfirm(pPacket->securitySuite, msduHandle);
return;
}
// Increment payload pointer when counters inserted
pPayload += temp;
// Include msduLength and optional MIC (integrity code) length
temp += msduLength + pPacket->securitySetup.micLength;
#else
temp = msduLength;
#endif
// Is frame too long?
if (temp > aMaxMACFrameSize) {
mtxpReleasePacket(pPacket);
mcpsDataConfirm(FRAME_TOO_LONG, msduHandle);
return;
}
// Calculate total frame length
pPacket->length = (BYTE)(pPacket->headerLength + temp + MAC_FCS_LENGTH);
// Copy data into packet buffer
memcpy(pPayload, pMsdu, msduLength);
// Calculate the packet duration (including ack. and IFS)
pPacket->duration = msupCalcPacketDuration(pPacket->length, (BOOL)(pPacket->txOptions & TX_OPT_ACK_REQ));
do {
taskNumber = mschReserveTask();
} while (taskNumber == NO_TASK);
#if MAC_OPT_FFD
if (txOptions & TX_OPT_INDIRECT) {
mschAddTask(taskNumber, MAC_TASK_PRI_MEDIUM, miqAddIndirectPacket, (WORD) pPacket);
} else {
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pPacket);
}
#else // RFD
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pPacket);
#endif
} // mcpsDataRequest
//-------------------------------------------------------------------------------------------------------
// MAC_ENUM mlmeStartRequest(WORD panId, UINT8 logicalChannel, UINT8 beaconOrder, UINT8 ...)
//
// DESCRIPTION:
// As a coordinator: Start or stop transmitting beacons.
//
// PARAMETERS:
// WORD panId
// The new PAN identifier
// UINT8 logicalChannel
// The channel to operate on (11-26)
// UINT8 beaconOrder
// The beacon order, which defines the beacon interval (0-14 for beacon PAN, 15 for non-beacon PAN)
// UINT8 superframeOrder
// The superframe order, which defines the superframe duration (that is the active period of the
// beacon interval). superframeOrder must be <= beaconOrder
// BOOL panCoordinator
// TRUE if this node should be the PAN coordinator
// BOOL batteryLifeExtension
// Enable battery life extension
// BOOL coordRealignment
// Transmit a coordinator realignment frame before making the changes
// BOOL securityEnable
// Security is enabled?
//
// RETURN VALUE:
// MAC_ENUM
// SUCCESS, NO_SHORT_ADDRESS or INVALID_PARAMETER
//-------------------------------------------------------------------------------------------------------
#if MAC_OPT_FFD
ROOT MAC_ENUM mlmeStartRequest(WORD panId,
UINT8 logicalChannel,
UINT8 beaconOrder,
UINT8 superframeOrder,
BOOL panCoordinator,
BOOL batteryLifeExtension,
BOOL coordRealignment,
BOOL securityEnable)
{
BOOL firstBeaconNow;
WORD mdmctrl0;
BOOL waiting;
MAC_TX_PACKET *pPacket;
BYTE taskNumber;
// Is the short address OK?
if (mpib.macShortAddress == 0xFFFF) {
return NO_SHORT_ADDRESS;
// Are the parameters OK?
} else if ((!msupChannelValid(logicalChannel)) || (beaconOrder > BEACON_ORDER_NO_BEACON) || ((superframeOrder > beaconOrder) && (superframeOrder != BEACON_ORDER_NO_BEACON))) {
return INVALID_PARAMETER;
// Go ahead...
} else {
// Transmit coordinator realignment?
if (coordRealignment) {
// Reserve a packet to use with the TX engine
do {
pPacket = mtxpReservePacket();
} while (!pPacket);
// Prepare the packet data
mbcnPrepareCoordinatorRealignment(pPacket, NULL, 0xFFFF, securityEnable, panId, logicalChannel);
#if MAC_OPT_SECURITY
// In case of frame counter overflow or missing key
// Generate error with FAILED_SECURITY_CHECK or UNAVAILABLE_KEY
if (pPacket->securitySuite >= 8) {
mtxpReleasePacket(pPacket);
return pPacket->securitySuite;
}
#endif
// Initiate the transmission
do {
taskNumber = mschReserveTask();
} while (taskNumber == NO_TASK);
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pPacket);
// Dirty trick: Create another task to tell us when the transmission task has completed
do {
taskNumber = mschReserveTask();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -