📄 basic_rf.c
字号:
UINT16_NTOH(pHdr->panId);
UINT16_NTOH(pHdr->destAddr);
UINT16_NTOH(pHdr->srcAddr);
#ifdef SECURITY_CCM
UINT32_NTOH(pHdr->frameCounter);
#endif
rxi.ackRequest = !!(pHdr->fcf0 & BASIC_RF_FCF_ACK_BM_L);
// Read the source address
rxi.srcAddr= pHdr->srcAddr;
// Read the packet payload
rxi.pPayload = rxMpdu + BASIC_RF_HDR_SIZE;
// Read the FCS to get the RSSI and CRC
pStatusWord= rxi.pPayload+rxi.length;
#ifdef SECURITY_CCM
pStatusWord+= BASIC_RF_LEN_MIC;
#endif
rxi.rssi = pStatusWord[0];
// Notify the application about the received data packet if the CRC is OK
// Throw packet if the previous packet had the same sequence number
if( (pStatusWord[1] & BASIC_RF_CRC_OK_BM) && (rxi.seqNumber != pHdr->seqNumber) ) {
// If security is used check also that authentication passed
#ifdef SECURITY_CCM
if( authStatus==SUCCESS ) {
if ( (pHdr->fcf0 & BASIC_RF_FCF_BM_L) ==
(BASIC_RF_FCF_NOACK_L | BASIC_RF_SEC_ENABLED_FCF_BM_L)) {
rxi.isReady = TRUE;
}
}
#else
if ( ((pHdr->fcf0 & (BASIC_RF_FCF_BM_L)) == BASIC_RF_FCF_NOACK_L) ) {
rxi.isReady = TRUE;
}
#endif
}
rxi.seqNumber = pHdr->seqNumber;
}
// Enable RX frame done interrupt again
halIntOff();
halRfEnableRxInterrupt();
}
/*******************************************************************************
* GLOBAL FUNCTIONS
*/
/*******************************************************************************
* @fn basicRfInit
*
* @brief Initialise basic RF datastructures. Sets channel, short address and
* PAN id in the chip and configures interrupt on packet reception
*
* @param pRfConfig - pointer to BASIC_RF_CONFIG struct.
* This struct must be allocated by higher layer
* txState - file scope variable that keeps tx state info
* rxi - file scope variable info extracted from the last incoming
* frame
*
* @return none
*/
uint8 basicRfInit(basicRfCfg_t* pRfConfig)
{
if (halRfInit()==FAILED)
return FAILED;
halIntOff();
// Set the protocol configuration
pConfig = pRfConfig;
rxi.pPayload = NULL;
txState.receiveOn = TRUE;
txState.frameCounter = 0;
// Set channel
halRfSetChannel(pConfig->channel);
// Write the short address and the PAN ID to the CC2520 RAM
halRfSetShortAddr(pConfig->myAddr);
halRfSetPanId(pConfig->panId);
// if security is enabled, write key and nonce
#ifdef SECURITY_CCM
basicRfSecurityInit(pConfig);
#endif
// Set up receive interrupt (received data or acknowlegment)
halRfRxInterruptConfig(basicRfRxFrmDoneIsr);
halIntOn();
return SUCCESS;
}
/*******************************************************************************
* @fn basicRfSendPacket
*
* @brief Send packet
*
* @param destAddr - destination short address
* pPayload - pointer to payload buffer. This buffer must be
* allocated by higher layer.
* length - length of payload
* txState - file scope variable that keeps tx state info
* mpdu - file scope variable. Buffer for the frame to send
*
* @return basicRFStatus_t - SUCCESS or FAILED
*/
uint8 basicRfSendPacket(uint16 destAddr, uint8* pPayload, uint8 length)
{
uint8 mpduLength;
uint8 status;
// Turn on receiver if its not on
if(!txState.receiveOn) {
halRfReceiveOn();
}
// Check packet length
length = min(length, BASIC_RF_MAX_PAYLOAD_SIZE);
// Wait until the transceiver is idle
halRfWaitTransceiverReady();
// Turn off RX frame done interrupt to avoid interference on the SPI interface
halRfDisableRxInterrupt();
mpduLength = basicRfBuildMpdu(destAddr, pPayload, length);
#ifdef SECURITY_CCM
halRfWriteTxBufSecure(txMpdu, mpduLength, length, BASIC_RF_LEN_AUTH, BASIC_RF_SECURITY_M);
txState.frameCounter++; // Increment frame counter field
#else
halRfWriteTxBuf(txMpdu, mpduLength);
#endif
// Turn on RX frame done interrupt for ACK reception
halRfEnableRxInterrupt();
// Send frame with CCA. return FAILED if not successful
if(halRfTransmit() != SUCCESS) {
status = FAILED;
}
// Wait for the acknowledge to be received, if any
if (pConfig->ackRequest) {
txState.ackReceived = FALSE;
// We'll enter RX automatically, so just wait until we can be sure that the ack reception should have finished
// The timeout consists of a 12-symbol turnaround time, the ack packet duration, and a small margin
halMcuWaitUs((12 * BASIC_RF_SYMBOL_DURATION) + (BASIC_RF_ACK_DURATION) + (2 * BASIC_RF_SYMBOL_DURATION) + 10);
// If an acknowledgment has been received (by RxFrmDoneIsr), the ackReceived flag should be set
status = txState.ackReceived ? SUCCESS : FAILED;
} else {
status = SUCCESS;
}
// Turn off the receiver if it should not continue to be enabled
if (!txState.receiveOn) {
halRfReceiveOff();
}
if(status == SUCCESS) {
txState.txSeqNumber++;
}
#ifdef SECURITY_CCM
halRfIncNonceTx(); // Increment nonce value
#endif
return status;
}
/*******************************************************************************
* @fn basicRfPacketIsReady
*
* @brief Check if a new packet is ready to be read by next higher layer
*
* @param none
*
* @return uint8 - TRUE if a packet is ready to be read by higher layer
*/
uint8 basicRfPacketIsReady(void)
{
return rxi.isReady;
}
/**********************************************************************************
* @fn basicRfReceive
*
* @brief Copies the payload of the last incoming packet into a buffer
*
* @param pRxData - pointer to data buffer to fill. This buffer must be
* allocated by higher layer.
* len - Number of bytes to read in to buffer
* rxi - file scope variable holding the information of the last
* incoming packet
*
* @return uint8 - number of bytes actually copied into buffer
*/
uint8 basicRfReceive(uint8* pRxData, uint8 len, int16* pRssi)
{
// Accessing shared variables -> this is a critical region
// Critical region start
halIntOff();
memcpy(pRxData, rxi.pPayload, min(rxi.length, len));
if(pRssi != NULL) {
if(rxi.rssi < 128){
*pRssi = rxi.rssi - halRfGetRssiOffset();
}
else{
*pRssi = (rxi.rssi - 256) - halRfGetRssiOffset();
}
}
rxi.isReady = FALSE;
halIntOn();
// Critical region end
return min(rxi.length, len);
}
/**********************************************************************************
* @fn basicRfGetRssi
*
* @brief Copies the payload of the last incoming packet into a buffer
*
* @param none
* @return int8 - RSSI value
*/
int8 basicRfGetRssi(void)
{
if(rxi.rssi < 128){
return rxi.rssi - halRfGetRssiOffset();
}
else{
return (rxi.rssi - 256) - halRfGetRssiOffset();
}
}
/*******************************************************************************
* @fn basicRfReceiveOn
*
* @brief Turns on receiver on radio
*
* @param txState - file scope variable
*
* @return none
*/
void basicRfReceiveOn(void)
{
txState.receiveOn = TRUE;
halRfReceiveOn();
}
/*******************************************************************************
* @fn basicRfReceiveOff
*
* @brief Turns off receiver on radio
*
* @param txState - file scope variable
*
* @return none
*/
void basicRfReceiveOff(void)
{
txState.receiveOn = FALSE;
halRfReceiveOff();
}
/*------------------------------------------------------------------------------
0ooo
ooo0 ( )
( ) ) /
\ ( (_/
\_) Modify By:cuiqingwei [gary]
------------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -