⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac_tx_engine.c

📁 zigbee location examples
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************************************
*                                                                                                      *
*        **********                                                                                    *
*       ************                                                                                   *
*      ***        ***                                                                                  *
*      ***   +++   ***                                                                                 *
*      ***   + +   ***                                                                                 *
*      ***   +                         CHIPCON CC2430 INTEGRATED 802.15.4 MAC AND PHY                  *
*      ***   + +   ***                                   TX 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 TX engine, which is used to transmit all RF packets.                    *
*******************************************************************************************************/
#include "mac_headers.h"

//-------------------------------------------------------------------------------------------------------
// Transmission related variables
MAC_TX_INFO mtxInfo;
//-------------------------------------------------------------------------------------------------------


//-------------------------------------------------------------------------------------------------------
//
//   Prototypes
//
//-------------------------------------------------------------------------------------------------------
static ROOT void HandleOutgoingClearText (MAC_TX_PACKET    *macTxPacket,
                                          FRAME            *frame);
static ROOT void HandleOutgoingFrame (MAC_TX_PACKET        *macTxPacket,
                                      FRAME                *frame,
                                      SECURITY_STATUS      *securityStatus);
static ROOT void HandleOutgoingSecurity (MAC_TX_PACKET     *macTxPacket,
                                         FRAME             *frame,
                                         SECURITY_STATUS   *securityStatus);
static ROOT void LoadAndStartStrobe (BYTE txMode,
                                     BOOL slotted,
                                     BYTE be,
                                     BYTE nb,
                                     BYTE randomBackoff,
                                     BYTE noOfBackoffsLeft);
static ROOT void ReadCsmaParams (BYTE   *be,
                                 BYTE   *nb,
                                 BYTE   *randomBackoff);
ROOT void WriteCsmaParams (BYTE be,
                           BYTE nb,
                           BYTE randomBackoff,
                           BYTE noOfBackoffsLeft);
ROOT void PrepareFrameAndWriteToRf (MAC_TX_PACKET     *macTxPacket,
                                    SECURITY_STATUS   *securityStatus);

//-------------------------------------------------------------------------------------------------------
//  void mtxCommStatusIndication(MAC_TX_PACKET *pPacket, BYTE status)
//
//  DESCRIPTION:
//      This function generates comm-status indications for transmitted packets, by parsing the
//      packet header.
//
//  ARGUMENTS:
//      MAC_TX_PACKET *pPacket
//          A pointer to the transmitted packet (which the address information will be extracted from)
//      BYTE status
//          The status to be passed in mlmeCommStatusIndication
//-------------------------------------------------------------------------------------------------------
ROOT void mtxCommStatusIndication(MAC_TX_PACKET   *pPacket, BYTE status) {
    BYTE dstAddrMode;
    ADDRESS   *pDstAddr;
    BYTE srcAddrMode;
    ADDRESS   *pSrcAddr;
    BYTE   *pTemp;

    // Point to the first byte of the frame control field
    pTemp = pPacket->pHeader;

    // Move on to the high byte, which contains the address modes
    pTemp += 1;
    dstAddrMode = (BYTE)((*pTemp & DEST_ADDR_BM) >> (DEST_ADDR_MODE_IDX - 8));
    srcAddrMode = (BYTE)((*pTemp & SRC_ADDR_BM) >> (SRC_ADDR_MODE_IDX - 8));

    // Move on to the PAN ID (skip the sequence number)
    pTemp += 2;

    // Get a pointer to each address, without modifying the pointer any further
    pDstAddr = (ADDRESS   *) (pTemp + 2);
    pSrcAddr = (ADDRESS   *) ((BYTE   *) pDstAddr + ((dstAddrMode == DEST_ADDR_SHORT) ?
                                  2 : 8) + ((*(pPacket->pHeader) & INTRA_PAN_BM) ? 0 : 2));

    // Make the call to the higher layer
    mlmeCommStatusIndication(*((WORD   *) pTemp), srcAddrMode, pSrcAddr, dstAddrMode, pDstAddr, status);

} // mtxCommStatusIndication

//-------------------------------------------------------------------------------------------------------
//  void mtxFinishTransmission(MAC_ENUM status, MAC_TX_PACKET *pPacket, MAC_TASK_INFO *pTask)
//
//  DESCRIPTION:
//      This function is used to avoid code duplication when finishing a packet transmission (using the
//      TX engine. This function is called by mtxScheduleTransmission(...) as the last step of the
//      transmission procedure.
//
//      This function handles failures for all transmission types, and success for all data, and some
//      MAC commands. The other MAC commands are handled by the RX engine.
//
//  PARAMETERS:
//      MAC_ENUM status
//          The result of the transmission (SUCCESS, CHANNEL_ACCESS_FAILURE, etc.)
//      MAC_TX_PACKET *pPacket
//          A pointer to the packet that was transmitted
//      MAC_TASK_INFO *pTask
//          A pointer to the task running mtxScheduleTransmission(...)
//-------------------------------------------------------------------------------------------------------
ROOT void mtxFinishTransmission(MAC_ENUM status, MAC_TX_PACKET   *pPacket, MAC_TASK_INFO   *pTask) {
    BOOL isMacInternal;
    BOOL handleCmdSuccess;
    MAC_STATE_TYPE macState;

    // Copy some variables from the packet structure, since we'll release the packet before we make the call to
    // the higher layer
    isMacInternal = pPacket->txMode & MTX_MODE_MAC_INTERNAL_BM;
    handleCmdSuccess = (pPacket->txMode & MTX_MODE_SCAN_RELATED_BM) ||
                       (pPacket->commandType == CMD_ASSOCIATION_RESPONSE) ||
                       (pPacket->commandType == CMD_DISASSOCIATION_NOTIFICATION) ||
                       (pPacket->commandType == CMD_COORDINATOR_REALIGNMENT);

    mtxInfo.status = MTX_STATUS_FINISHED;

    // Make the call to the higher layer
    switch (pPacket->type) {
    case FT_DATA:
        if (!isMacInternal) mcpsDataConfirm(status, pPacket->msduHandle);
        break;
    case FT_MAC_COMMAND:

        // SUCCESS is usually handled by the RX engine or not at all
        if ((status == SUCCESS) && !handleCmdSuccess) break;

        switch (pPacket->commandType) {
        case CMD_ASSOCIATION_REQUEST:
            macSetState(MAC_STATE_DEFAULT);
            mlmeAssociateConfirm(0xFFFF, status);
            break;
        case CMD_DISASSOCIATION_NOTIFICATION:
            mlmeDisassociateConfirm(status);
            break;
        case CMD_DATA_REQUEST:
            macState = macInfo.state;
            macSetState(MAC_STATE_DEFAULT);
            switch (macState) {
                case MAC_STATE_TX_MANUAL_DATA_REQUEST:  mlmePollConfirm(status); break;
                case MAC_STATE_TX_ASSOC_DATA_REQUEST: mlmeAssociateConfirm(0xFFFF, status); break;
                default: break;
            }
            break;
        case CMD_BEACON_REQUEST:
            mtimSetCallback(mscChannelTimeout, ((UINT32) aBaseSuperframeDuration / (UINT32) aUnitBackoffPeriod) * (((UINT32) 1 << mscInfo.scanDuration) + 1));
            break;
        case CMD_PAN_ID_CONFLICT_NOTIFICATION:
            break;
        case CMD_ORPHAN_NOTIFICATION:
            mtimSetCallback(mscChannelTimeout, (UINT32) aResponseWaitTime / (UINT32) aUnitBackoffPeriod);
            break;
#if MAC_OPT_FFD
        case CMD_ASSOCIATION_RESPONSE:
        case CMD_COORDINATOR_REALIGNMENT:
            if (!isMacInternal) mtxCommStatusIndication(pPacket, status);
            break;
#endif
        case CMD_GTS_REQUEST:
            break;
        default:
            break;
        }
        break;
    }

#if MAC_OPT_FFD
    // Remove the task and the packet
    if (pPacket->txOptions & TX_OPT_INDIRECT) {
        miqSetRequested(pPacket, FALSE);
        mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_RESERVED_BM | MSCH_KEEP_TASK_IN_PROGRESS_BM);
        DISABLE_GLOBAL_INT();

        mschAddTask(pTask->taskNumber, MAC_TASK_PRI_MEDIUM, miqRemoveIndirectPacket, (WORD) pPacket);
        ENABLE_GLOBAL_INT();
    } else {
        mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
        mtxpReleasePacket(pPacket);
    }
#else
    // Only direct transmission from a RFD
    mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
    mtxpReleasePacket(pPacket);
#endif


} // mtxFinishTransmission




//-------------------------------------------------------------------------------------------------------
//  void mtxCreateStartTask(void)
//
//  DESCRIPTION:
//      Creates the task that starts the transmission of the packet.
//-------------------------------------------------------------------------------------------------------
ROOT void mtxCreateStartTask(void) {
    mschAddTask(mtxInfo.startTxTask, MAC_TASK_PRI_HIGHEST,  mtxStartTransmission, (WORD) mtxInfo.pPacket);
} // mtxCreateStartTask




UINT8 mtxCalcCspTimeout(void) {
    INT32 bosLeft;

    // Calculate the number of FULL backoff slots left in the CAP, when transmission, ack and IFS is taken into consideration
    if (!mtxInfo.pPacket->slotted) {
        // Set bosLeft high enough to avoid CSP timeout
        bosLeft = CSP_TIMEOUT_RUN_FOREVER;
    } else {
        if (T2_IS_CAP_ACTIVE()) {
            if (mbcnInfo.lastSfSpec.battLifeExt && mtxInfo.pPacket->toCoord) {
                //        <----------------- The CAP duration -----------------> - <--------- Used CAP ----------> - <---- Overhead ----->
                bosLeft = (mbcnInfo.beaconDuration + mpib.macBattLifeExtPeriods) - (T2_GET_OVERFLOW_COUNTER() + 1) - (MTX_START_CSP_DELAY);
            } else {
                //        <- The CAP duration > - <--------- Used CAP ----------> - <------------- Overhead + duration -------------> - <-- Beacon margin -->
                bosLeft = msupCalcCapDuration() - (T2_GET_OVERFLOW_COUNTER() + 1) - (MTX_START_CSP_DELAY + mtxInfo.pPacket->duration) - mbcnGetBeaconMargin();
            }
        } else
            bosLeft = 0;
    }

    // Calculate the CSP timeout
    if (bosLeft >= CSP_TIMEOUT_RUN_FOREVER) {
        return CSP_TIMEOUT_RUN_FOREVER;
    } else if (bosLeft < 1) {
        return CSP_TIMEOUT_STOP;
    } else {
        return (UINT8) bosLeft;
    }

} // mtxCalcCspTimeout




//-------------------------------------------------------------------------------------------------------
//  void mtxResumeAfterBeacon(void)
//
//  DESCRIPTION:
//      Resumes transmission after the beacon has been received, if there is a sufficient number of
//      backoff slot left in the CAP.
//-------------------------------------------------------------------------------------------------------
void mtxResumeAfterBeaconCallback(void) NEAR { mschAddTask(mschReserveTask(), MAC_TASK_PRI_HIGH, mtxResumeAfterBeaconTask, NULL); }
void mtxResumeAfterBeaconTask(MAC_TASK_INFO   *pTask) NEAR { mtxResumeAfterBeacon(); mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM); }
void mtxResumeAfterBeacon(void) NEAR {
    if (mtxInfo.waitForBeacon) {

        // Cancel beacon search when enabled (the WAIT -> OUT_OF_CAP state will turn it back on if necessary)
        if (mtxInfo.beaconSearchEnabled) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -