📄 mac_rx_engine.c
字号:
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + CHIPCON CC2420 INTEGRATED 802.15.4 MAC AND PHY *
* *** + + *** RX Engine *
* *** +++ *** *
* *** *** *
* ************ *
* ********** *
* *
*******************************************************************************************************
* CONFIDENTIAL *
* The use of this file is restricted by the signed MAC software license agreement. *
* *
* Copyright Chipcon AS, 2004 *
*******************************************************************************************************
* This module contains the MAC RX engine (FIFOP interrupt), including packet processing functions, *
* and functions to control the RX state (on/off...) *
*******************************************************************************************************
* Compiler: AVR-GCC *
* Target platform: CC2420DB, CC2420 + any ATMEGA MCU *
*******************************************************************************************************
* The revision history is located at the bottom of this file *
*******************************************************************************************************/
#pragma SFR
#pragma NOP
#pragma STOP
#pragma HALT
#pragma DI
#pragma EI
#pragma interrupt INTP1 MD_INTP1
#pragma section @@DATA rxengine at 0xE400///
#include "mac_headers.h"
int UART_StartTx(char *buffer);///
extern INT32 volatile test;////
extern char str1[4];///
extern char str2[32][4];///
extern INT8 volatile COMA;
extern INT8 volatile INTP;
extern INT8 array1[32];
//-------------------------------------------------------------------------------------------------------
// Variables related to the receive engine
MAC_RX_INFO mrxInfo;
// Variables related to the security within the receive engine
#if MAC_OPT_SECURITY
MAC_RX_SECURITY_INFO mrxSecurityInfo;
#endif
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
//Internal function declaration
void mrxSetFifopThreshold(UINT8 count);
void mrxHandleFifoUnderAndOverflow(void);
void mrxCommStatusIndication(MAC_TASK_INFO *pTask);
void mrxProcessMacCommand(MAC_TASK_INFO *pTask);
void mrxProcessAcknowledgment(MAC_TASK_INFO *pTask);
void mrxProcessData(MAC_TASK_INFO *pTask);
void mrxProcessBeacon(MAC_TASK_INFO *pTask);
MLME_BEACON_NOTIFY_INDICATION* mrxMakeBeaconNotifyIndication(MAC_RX_PACKET *pPacket);
//-------------------------------------------------------------------------------------------------------
/*******************************************************************************************************
*******************************************************************************************************
************************** RECEIVE STATE MANAGEMENT **************************
*******************************************************************************************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
// void mrxIncrOnCounter(void)
//
// DESCRIPTION:
// Increments the "RX on" counter, and turns on RX on a 0 -> 1 transition
//-------------------------------------------------------------------------------------------------------
void mrxIncrOnCounter(void) {
DISABLE_GLOBAL_INT();
if (!mrxInfo.onCounter) {
FASTSPI_STROBE(CC2420_SRXON);
}
mrxInfo.onCounter++;
ENABLE_GLOBAL_INT();
} // mrxIncrOnCounter
//-------------------------------------------------------------------------------------------------------
// void mrxAutoIncrOnCounter(void)
//
// DESCRIPTION:
// Increments the "RX on" counter, but does not turn on RX on a 0 -> 1 transition. This function
// should be used when issuing the STXON(CCA) or SACK(PEND) command strobes.
//-------------------------------------------------------------------------------------------------------
void mrxAutoIncrOnCounter(void) {
DISABLE_GLOBAL_INT();
mrxInfo.onCounter++;
ENABLE_GLOBAL_INT();
} // mrxAutoIncrOnCounter
//-------------------------------------------------------------------------------------------------------
// void mrxDecrOnCounter(void)
//
// DESCRIPTION:
// Decrements the "RX on" counter, and turns off RX on a 1 -> 0 transition if SFD is low. If SFD is
// high, the turn-off operation is delayed by one backoff period by using a callback.
//-------------------------------------------------------------------------------------------------------
void mrxDecrOnCounter(void) {
BYTE spiStatus;
DISABLE_GLOBAL_INT();
if (mrxInfo.onCounter) mrxInfo.onCounter--;
if (!mrxInfo.onCounter) {
FASTSPI_UPD_STATUS(spiStatus);
if (SFD_IS_ACTIVE() || (spiStatus & CC2420_TX_ACTIVE_BM)) {
mrxInfo.onCounter++;
mtimSetCallback(mrxDecrOnCounter, (INT32) 1);
} else {
FASTSPI_STROBE(CC2420_SRFOFF);
FASTSPI_STROBE(CC2420_SFLUSHRX);
FASTSPI_STROBE(CC2420_SFLUSHRX);
}
}
ENABLE_GLOBAL_INT();
} // mrxDecrOnCounter
//-------------------------------------------------------------------------------------------------------
// void mrxRxEnableRequestOff(void)
//
// DESCRIPTION:
// Used in connection with mrxRxEnableRequestTask() to make sure that a mtimCancelCallback operation
// only removes callbacks initiated by mrxRxEnableRequestTask()
//-------------------------------------------------------------------------------------------------------
void mrxRxEnableRequestOff(void) {
mrxDecrOnCounter();
} // mrxRxEnableRequestOff
//-------------------------------------------------------------------------------------------------------
// void mrxRxEnableRequestTask(MAC_TASK_INFO *pTask)
//
// DESCRIPTION:
// The task created by mlmeRxEnableRequest() to turn on RX for a period of time. The current version
// only supports non-beacon PANs.
//
// TASK DATA
// 0
//-------------------------------------------------------------------------------------------------------
void mrxRxEnableRequestTask(MAC_TASK_INFO *pTask) {
MAC_ENUM status;
// Only implemented for non-beacon PANs
if (mpib.macBeaconOrder == 15) {
// Turn off?
if (mrxInfo.rxEnableOnDuration == 0) {
if (mtimCancelCallback(mrxRxEnableRequestOff)) {
mrxDecrOnCounter();
status = SUCCESS;
} else {
status = INVALID_PARAMETER;
}
// Turn on + off after timeot?
} else {
// If there's a timer available to turn RX off, then turn it on now
if (mtimSetCallback(mrxRxEnableRequestOff, (INT32) mrxInfo.rxEnableOnDuration)) {
mrxIncrOnCounter();
status = SUCCESS;
} else {
// Come back later!
return;
}
}
// Not implemented for beacon-enabled PANs
} else {
status = INVALID_PARAMETER;
}
// Remove the task and confirm to the higher layer
mschRemoveTask((UINT8) pTask->priority, (BYTE) 0);
mlmeRxEnableConfirm(status);
} // mrxRxEnableRequestTask
//-------------------------------------------------------------------------------------------------------
// void mrxForceRxOff(void)
//
// DESCRIPTION:
// Creates the task that forces RX off at the end of a superframe, if we're not in scan mode.
//-------------------------------------------------------------------------------------------------------
void mrxForceRxOff(void) {
if (macInfo.state & MAC_STATE_SCAN_BM) return;
mschAddTask(mschReserveTask(), MAC_TASK_PRI_HIGHEST, mrxForceRxOffTask, MRX_RESET_ON_COUNTER);
} // mrxForceRxOff
//-------------------------------------------------------------------------------------------------------
// void mrxForceRxOffTask(MAC_TASK_INFO *pTask)
//
// DESCRIPTION:
// This task forces RX off by issuing a SRFOFF command strobe, regardless of whether the SFD pin
// state. If SFD was high before the command was issued, an RX engine cleanup is performed.
//
// TASK DATA:
// Flags (MRX_RESET_ON_COUNTER)
//-------------------------------------------------------------------------------------------------------
void mrxForceRxOffTask(MAC_TASK_INFO *pTask) {
BOOL sfdWasActiveBeforeStrobe;
// Avoid getting FIFOP interrupts...
mrxInfo.keepFifopIntOff = TRUE;
// Turn off RX at the backoff slot boundary
DISABLE_GLOBAL_INT();
if (pTask->taskData & MRX_RESET_ON_COUNTER) mrxInfo.onCounter = 0;
WAIT_FOR_BOUNDARY();
sfdWasActiveBeforeStrobe = SFD_IS_ACTIVE();
FASTSPI_STROBE(CC2420_SRFOFF);
FASTSPI_STROBE(CC2420_SFLUSHRX);
FASTSPI_STROBE(CC2420_SFLUSHRX);
ENABLE_GLOBAL_INT();
if (sfdWasActiveBeforeStrobe) mrxResetRxEngine();
mrxInfo.keepFifopIntOff = FALSE;
mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
} // mrxForceRxOffTask
//-------------------------------------------------------------------------------------------------------
// void mrxResetRxEngine(void)
//
// DESCRIPTION:
// Resets the RX engine by clearing the RX FIFO, freeing any recently acquired resources, and
// resetting the RX engine state. If there's a valid packet in the FIFO, it will be received, and
// the FIFO will be flushed afterwards.
//-------------------------------------------------------------------------------------------------------
void mrxResetRxEngine(void) {
BOOL doReset = FALSE;
WORD oldIocfg1;
WORD testIocfg0;
DISABLE_GLOBAL_INT();
// Just started receiving a new packet, or handling a garbage packet
switch (mrxInfo.state) {
case MRX_STATE_LEN_FCF_SEQ:
case MRX_STATE_DISCARD_ALL:
case MRX_STATE_DISCARD_REMAINING:
case MRX_STATE_DISCARD:
doReset = TRUE;
break;
// Have a closer look...
default:
// Modify the FIFOP threshold to see if there are multiple packets in the RX FIFO
FASTSPI_GETREG(CC2420_IOCFG0, oldIocfg1);
testIocfg0 = (WORD) mrxInfo.length + (WORD) 1;
FASTSPI_SETREG(CC2420_IOCFG0, testIocfg0);
// FIFOP is not inverted here!!!
if (!FIFOP_IS_ACTIVE()) {
// There is at least one whole packet in the RX FIFO which can be read out safely
mrxInfo.handleFifoUnderflow = TRUE;
} else {
doReset = TRUE;
}
// Restore the old value
FASTSPI_SETREG(CC2420_IOCFG0, oldIocfg1);
break;
}
// The reset procedure
if (doReset) {
// Flush the RX FIFO
FASTSPI_STROBE(CC2420_SFLUSHRX);
FASTSPI_STROBE(CC2420_SFLUSHRX);
// Free resources
switch (mrxInfo.state) {
case MRX_STATE_DEST_ADDR:
case MRX_STATE_SRC_ADDR:
case MRX_STATE_SECURITY_INIT:
case MRX_STATE_SECURITY_ACL_SEARCH:
case MRX_STATE_FIND_COUNTERS:
case MRX_STATE_CMD_IDENTIFIER:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -