📄 mac_support.c
字号:
//-------------------------------------------------------------------------------------------------------
// void msupSetChannel(UINT8 logicalChannel, BOOL changePib)
//
// DESCRIPTION:
// Changes the radio channel if necessary. The function calculates the new value for the FSCTRL
// register, and compares it to the current value. When different, the frequency will be changed.
// The function will clean up the RX engine if we're interrupting a reception. When finished, it
// will restore the previous RX state.
//
// PARAMETERS:
// UINT8 logicalChannel
// The channel number, 11 - 26
// BOOL changePib
// Set ppib.phyCurrentChannel = logicalChannel?
//-------------------------------------------------------------------------------------------------------
void msupSetChannel(UINT8 logicalChannel, BOOL changePib) {
UINT16 newFreq, oldFreq;
BOOL sfdWasActiveBeforeStrobe;
// Derive frequency programming from the given channel number
newFreq = (UINT16) (logicalChannel - 11); // Subtract the base channel
newFreq = newFreq + (newFreq << 2); // Multiply with 5, which is the channel spacing
newFreq = newFreq + 357 + 0x4000; // 357 is 2405-2048, 0x4000 is LOCK_THR = 1
// Do we need to change the frequency at all?
DISABLE_GLOBAL_INT();
FASTSPI_GETREG(CC2420_FSCTRL, oldFreq);
ENABLE_GLOBAL_INT();
if ((newFreq ^ oldFreq) & 0x03FF) {
// Force RX off
DISABLE_GLOBAL_INT();
sfdWasActiveBeforeStrobe = SFD_IS_ACTIVE();
FASTSPI_STROBE(CC2420_SRFOFF);
FASTSPI_STROBE(CC2420_SFLUSHRX);
FASTSPI_STROBE(CC2420_SFLUSHRX);
// Clean up if we interrupted the receiver
DISABLE_FIFOP_INT();
ENABLE_GLOBAL_INT();
if (sfdWasActiveBeforeStrobe) mrxResetRxEngine();
ENABLE_FIFOP_INT();
// Change the PIB attribute (?) and update the frequency register
DISABLE_GLOBAL_INT();
if (changePib) ppib.phyCurrentChannel = logicalChannel;
FASTSPI_SETREG(CC2420_FSCTRL, newFreq);
// Return to the previous RX state
if (mrxInfo.onCounter) {
FASTSPI_STROBE(CC2420_SRXON);
}
ENABLE_GLOBAL_INT();
}
} // msupSetChannel
/*******************************************************************************************************
*******************************************************************************************************
************************** TX PACKET GENERATION **************************
*******************************************************************************************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
// msupPrepareHeader(MAC_TX_PACKET *pPacket, BYTE type, BYTE addrModes, WORD srcPanId, ADDRESS ...)
//
// DESCRIPTION:
// Packet header assembly function, used for beacon, data and command frames.
//
// PARAMETERS:
// MAC_TX_PACKET *pPacket
// The packet structure to update (this function affects the header part)
// BYTE type
// FT_BEACON, FT_DATA or FT_COMMAND
// 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)
// BYTE txOptions
// (TX_OPT_SECURITY_ENABLE | TX_OPT_INDIRECT | TX_OPT_GTS | TX_OPT_ACK_REQ) or TX_OPT_NONE
//-------------------------------------------------------------------------------------------------------
void msupPrepareHeader(MAC_TX_PACKET *pPacket, BYTE type, BYTE addrModes, WORD srcPanId, ADDRESS *pSrcAddr, WORD destPanId, ADDRESS *pDestAddr, BYTE txOptions) {
BYTE temp;
UINT8 length = 0;
// Packet type and options
pPacket->type = type;
pPacket->txOptions = txOptions;
// Frame control field
temp = type & FRAME_TYPE_BM;
#if MAC_OPT_SECURITY
pPacket->securitySetup.micLength = 0;
if (txOptions & TX_OPT_SECURITY_ENABLE) {
temp |= SECURITY_ENABLED_BM;
// Set securitySuite or securityStatus (UNAVAILABLE_KEY)
msecFindTxSecurityMaterial(pPacket, TRUE, ((addrModes & DEST_ADDR_BM) >> 2), destPanId, pDestAddr);
} else {
pPacket->securitySuite = MAC_SECURITY_NONE;
}
#endif
if (txOptions & TX_OPT_ACK_REQ) temp |= ACK_REQ_BM;
if (((addrModes & BOTH_ADDR_USED) == BOTH_ADDR_USED) && (srcPanId == destPanId)) temp |= INTRA_PAN_BM;
pPacket->pHeader[length++] = temp;
pPacket->pHeader[length++] = addrModes;
// Sequence number
if (type == FT_BEACON) {
pPacket->pHeader[length++] = mpib.macBSN++;
} else {
pPacket->pHeader[length++] = mpib.macDSN++;
}
// Destination PAN ID
if (addrModes & DEST_ADDR_BM) {
memcpy(pPacket->pHeader + length, &destPanId, 2);
length += 2;
pPacket->toCoord = (mpib.macPANId == destPanId);
} else {
pPacket->toCoord = FALSE;
}
// Destination address
if ((addrModes & DEST_ADDR_BM) == DEST_ADDR_SHORT) {
memcpy(pPacket->pHeader + length, (BYTE*) &pDestAddr->Short, 2);
length += 2;
pPacket->toCoord &= (mpib.macCoordShortAddress == pDestAddr->Short);
} else if ((addrModes & DEST_ADDR_BM) == DEST_ADDR_EXT) {
memcpy(pPacket->pHeader + length, (BYTE*) &pDestAddr->Extended, 8);
length += 8;
pPacket->toCoord &= msupCompareQword(&mpib.macCoordExtendedAddress, &pDestAddr->Extended);
}
// Source PAN ID
if (!(temp & INTRA_PAN_BM) && (addrModes & SRC_ADDR_BM)) {
memcpy(pPacket->pHeader + length, &srcPanId, 2);
length += 2;
}
// Source address
if ((addrModes & SRC_ADDR_BM) == SRC_ADDR_SHORT) {
memcpy(pPacket->pHeader + length, (BYTE*) &pSrcAddr->Short, 2);
length += 2;
} else if ((addrModes & SRC_ADDR_BM) == SRC_ADDR_EXT) {
memcpy(pPacket->pHeader + length, (BYTE*) &pSrcAddr->Extended, 8);
length += 8;
}
pPacket->headerLength = length;
#if MAC_OPT_SECURITY
// By default, set cleartextLenght to header length
// Include command frame identifier for MAC command frames
// Note: clearTextLength must be incremented for beacon frames
pPacket->securitySetup.clearTextLength = length + (type == FT_MAC_COMMAND);
// Decode security suite and find setup information
// Set clearTextLength to 0 for CBC-MAC
msecDecodeSecuritySuite(&pPacket->securitySetup, pPacket->securitySuite);
#endif
} // msupPrepareHeader
//-------------------------------------------------------------------------------------------------------
// UINT8 msupCalcPacketDuration(UINT8 length, BOOL ackRequest)
//
// DESCRIPTION:
// Calculates the number of backoff slots required to transmit a packet, including (turnaround time,
// acknowledgment and) inter-frame spacing.
//
// PARAMETERS:
// UINT8 length
// The packet length in bytes (PHY frame length field)
// BOOL ackRequest
// Acknowledged packet?
//
// RETURN VALUE:
// UINT8
// The number of backoff slots required to transmit the packet
//-------------------------------------------------------------------------------------------------------
UINT8 msupCalcPacketDuration(UINT8 length, BOOL ackRequest) {
UINT8 totalByteCount, lastBosByteCount;
// Calculate the number of bytes in the whole packet (not including the preamble, but including
// SFD, length-byte and PSDU)
totalByteCount = 1 + 1 + length;
// Acknowledgment request
if (ackRequest) {
// The number of bytes in the last backoff slot
lastBosByteCount = totalByteCount % (aUnitBackoffPeriod / 2);
// Round up the total count to N * (aUnitBackoffPeriod / 2), and add an extra slot if there isn't enough turnaround time before the ack (12-32 symbols)
if (lastBosByteCount) totalByteCount += (aUnitBackoffPeriod / 2) - lastBosByteCount;
// Add the bytes in the acknowledgment frame
totalByteCount += (aUnitBackoffPeriod / 2) + (1 + 1 + 5);
}
// Add interframe spacing
if (length > aMaxSIFSFrameSize) {
totalByteCount += (aMinLIFSPeriod / 2);
} else {
totalByteCount += (aMinSIFSPeriod / 2);
}
// Round up
return ((BYTE) (totalByteCount + ((aUnitBackoffPeriod / 2) - 1))) / (aUnitBackoffPeriod / 2);
} // msupCalcPacketDuration
/*******************************************************************************************************
*******************************************************************************************************
************************** CC2420 RAM/FIFO ACCESS **************************
*******************************************************************************************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
// void msupWriteRam(void *pData, UINT16 address, UINT8 count, BOOL disableInterrupts)
//
// DESCRIPTION:
// Write data to the CC2420 RAM-space
// Used for setup of addresses and security
//
// PARAMETERS:
// void *pData
// Pointer to data to be written
// UINT16 address
// CC2420 RAM Address
// UNIT8 count
// Number of bytes to be written
// BOOL disableInterrupts
// Disable global interrupts while writing?
//-------------------------------------------------------------------------------------------------------
void msupWriteRam(BYTE*pData, UINT16 address, UINT8 count, BOOL disableInterrupts) {///
if (count) {
do {
if (disableInterrupts) DISABLE_GLOBAL_INT();
SPI_ENABLE();
FASTSPI_TX(0x80 | (address & 0x7F)); \
FASTSPI_TX((address >> 1) & 0xC0); \
do {
FASTSPI_TX(*((BYTE*) pData));
pData++;
} while ((--count) & 0x07);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -