?? basic_rf.c
字號:
#endif
rxi.ackRequest = !!(pHdr->frameControlField & BASIC_RF_FCF_ACK_BM);
// Read the source address
rxi.srcAddr= pHdr->srcAddr;
// Read the packet payload
rxi.pPayload = rxMpdu+sizeof(basicRfPktHdr_t);
// 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->frameControlField & (BASIC_RF_FCF_BM)) ==
(BASIC_RF_FCF_NOACK | BASIC_RF_SEC_ENABLED_FCF_BM)) {
rxi.isReady = TRUE;
}
}
#else
if ( ((pHdr->frameControlField & (BASIC_RF_FCF_BM)) == BASIC_RF_FCF_NOACK) ) {
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
halRfIncNonceTx(); // Increment nonce value
#else
halRfWriteTxBuf((uint8*)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++;
}
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();
}
/***********************************************************************************
Copyright 2007 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED 揂S IS
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -