?? mac_rx_engine.c
字號(hào):
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + CHIPCON CC2430 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, 2005 *
*******************************************************************************************************
* This module contains the MAC RX engine (FIFOP interrupt), including packet processing functions, *
* and functions to control the RX state (on/off...) *
*******************************************************************************************************/
#include <mac_headers.h>
#include <string.h>
//-------------------------------------------------------------------------------------------------------
// 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
ROOT MLME_BEACON_NOTIFY_INDICATION *mrxMakeBeaconNotifyIndication(MAC_RX_PACKET *pPacket);
static ROOT void mrxHandleFifopInt(void);
static ROOT void mrxStartPayloadDmaTransfer(void);
//-------------------------------------------------------------------------------------------------------
/*******************************************************************************************************
*******************************************************************************************************
************************** RECEIVE STATE MANAGEMENT **************************
*******************************************************************************************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
// void mrxIncrOnCounter(void)
//
// DESCRIPTION:
// Increments the "RX on" counter, and turns on RX on a 0 -> 1 transition
//-------------------------------------------------------------------------------------------------------
void mrxIncrOnCounter(void) NEAR {
DISABLE_GLOBAL_INT();
if (!mrxInfo.onCounter) {
CSP_INDICATE_RX_ON(TRUE);
if (!msupIsTxActive()) {
ISRXON;
}
}
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) NEAR {
DISABLE_GLOBAL_INT();
mrxInfo.onCounter++;
CSP_INDICATE_RX_ON(TRUE);
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.
//
// Note: Because of the CSP handling, this function must only be called at the start of a backoff
// period
//-------------------------------------------------------------------------------------------------------
void mrxDecrOnCounter(void) NEAR {
DISABLE_GLOBAL_INT();
// Decrement counter and check for 1->0
if (mrxInfo.onCounter) mrxInfo.onCounter--;
if (mrxInfo.onCounter == 0) {
// Avoid interrupting RX or TX (come back later when busy)
if (msupIsSfdActive() || msupIsTxActive() || msupIsCspInCriticalSection()) {
mrxInfo.onCounter++;
mtimSetCallback(mrxDecrOnCounter, 1);
} else {
ISRFOFF;
CSP_INDICATE_RX_ON(FALSE);
}
}
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) NEAR {
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) NEAR {
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(pTask->priority, 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) NEAR {
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) NEAR {
DISABLE_GLOBAL_INT();
if (pTask->taskData & MRX_RESET_ON_COUNTER) mrxInfo.onCounter = 0;
ISRFOFF;
mrxResetRxEngine();
ENABLE_GLOBAL_INT();
mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
} // mrxForceRxOffTask
static ROOT void mrxStartPayloadDmaTransfer(void) {
pDma1234Configs[DMA_RFRX_CHANNEL - 1].destMsb = HIBYTE(mrxInfo.pPacket->mdi.pMsdu);
pDma1234Configs[DMA_RFRX_CHANNEL - 1].destLsb = LOBYTE(mrxInfo.pPacket->mdi.pMsdu);
pDma1234Configs[DMA_RFRX_CHANNEL - 1].lenLsb = mrxInfo.length;
while (RXFIFOCNT < 2);
DMA_ARM_CHANNEL(DMA_RFRX_CHANNEL);
DMA_START_CHANNEL(DMA_RFRX_CHANNEL);
DISABLE_FIFOP_INT_BIT();
}
//-------------------------------------------------------------------------------------------------------
// void mrxResetRxEngine(void)
//
// DESCRIPTION:
// Resets the RX engine by clearing the RX FIFO, freeing any recently acquired resources, and
// resetting the RX engine state.
//-------------------------------------------------------------------------------------------------------
ROOT void mrxResetRxEngine(void) {
DISABLE_GLOBAL_INT();
// Free resources
switch (mrxInfo.state) {
case MRX_STATE_LEN_FCF_SEQ:
// Nothing happened yet, so just flush the FIFO
break;
case MRX_STATE_FCS:
DMA_ABORT_CHANNEL(DMA_RFRX_CHANNEL);
// No break here!
case MRX_STATE_ADDR:
mschReleaseTask(mrxInfo.taskNumber);
mrxInfo.taskNumber = NO_TASK;
mrxpReleasePacket(mrxInfo.pPacket);
mrxInfo.pPacket = NULL;
// No break here!
case MRX_STATE_DISCARD:
mrxDecrOnCounter();
break;
}
// Flush the RX FIFO twice (chip bug)
ISFLUSHRX;
ISFLUSHRX;
// Clear the FIFOP interrupt flag
CLEAR_FIFOP_INT_BIT();
CLEAR_RFIF_INT();
if (mrxInfo.state == MRX_STATE_FCS) ENABLE_FIFOP_INT_BIT();
// Reset the RX engine state
mrxInfo.state = MRX_STATE_LEN_FCF_SEQ;
ENABLE_GLOBAL_INT();
} // mrxResetRxEngine
/*******************************************************************************************************
*******************************************************************************************************
************************** PACKET RECEPTION AND PROCESSING **************************
*******************************************************************************************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
// MLME_BEACON_NOTIFY_INDICATION* mrxMakeBeaconNotifyIndication(MAC_RX_PACKET *pPacket)
//
// DESCRIPTION:
// Modifies a MAC_RX_PACKET structure to become a beacon notify indication.
//
// ARGUMENTS:
// MAC_RX_PACKET *pPacket
// The packet that contains the beacon. This structure will be modified to contain the
// notification.
//
// RETURN VALUE:
// MLME_BEACON_NOTIFY_INDICATION*
// A pointer to the notification to be passed to the higher layer
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -