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

📄 mac_tx_engine.c

📁 ucos在NEC平台下的移植
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************************************
 *                                                                                                     *
 *        **********                                                                                   *
 *       ************                                                                                  *
 *      ***        ***                                                                                 *
 *      ***   +++   ***                                                                                *
 *      ***   + +   ***                                                                                *
 *      ***   +                         CHIPCON CC2420 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, 2004                                                                          *
 *******************************************************************************************************
 * This module contains the MAC TX engine, which is used to transmit all RF packets.                   *
 *******************************************************************************************************
 * 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

#include "mac_headers.h"


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




//-------------------------------------------------------------------------------------------------------
//  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
//-------------------------------------------------------------------------------------------------------
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 = (*pTemp & DEST_ADDR_BM) >> (DEST_ADDR_MODE_IDX - 8);
    srcAddrMode = (*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(...)
//-------------------------------------------------------------------------------------------------------
void mtxFinishTransmission(MAC_ENUM status, MAC_TX_PACKET *pPacket, MAC_TASK_INFO *pTask) {
    BOOL isMacInternal;
    BOOL handleCmdSuccess;
    MAC_STATE_TYPE macState;
    
    ENABLE_FIFOP_INT();
    
    // 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->mc.commandType == CMD_ASSOCIATION_RESPONSE) || ///
                       (pPacket->mc.commandType == CMD_DISASSOCIATION_NOTIFICATION) ||///
                       (pPacket->mc.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->mc.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->mc.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, (aBaseSuperframeDuration / aUnitBackoffPeriod) * ((1 << mscInfo.scanDuration) + 1));
            break;
        case CMD_PAN_ID_CONFLICT_NOTIFICATION:
            break;
        case CMD_ORPHAN_NOTIFICATION:
            mtimSetCallback(mscChannelTimeout, aResponseWaitTime / 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 mtxLocateBeaconTimeout(void)
//
//  DESCRIPTION:
//      This timeout function is used when transmitting packets in a beacon network without tracking the
//      beacon (the packet is supposed to be transmitted using unslotted CSMA-CA if the beacon cannot be 
//      located). The timeout is also set when tracking the beacon, because the tracking could suddenly
//      stop. 
//-------------------------------------------------------------------------------------------------------
void mtxLocateBeaconTimeout(void) {
   
    // The beacon is currently being tracked (but we've missed at least one) -> continue waiting
    // Or we could be transmitting beacons.
    if (mbcnInfo.trackBeacon || GET_MF(MF_TRANSMIT_BEACON)) {
        mtimSetCallback(mtxLocateBeaconTimeout, msupCalcBeaconInterval());
    
    // Automatic beacon location has failed
    } else {
    
        // Stop the beacon search
        if (mtxInfo.searchForBeacon) {
            mtxInfo.searchForBeacon = FALSE;
            mrxDecrOnCounter();
        }
        
        // Switch to unslotted CSMA-CA and transmit immediately
        mtxInfo.waitForBeacon = FALSE;
        mtxInfo.nb = 0;
        mtxInfo.be = mpib.macMinBE;
        mtxInfo.pPacket->slotted = FALSE;
        mtxCreateStartTask();
    }
    
} // mtxLocateBeaconTimeout




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




//-------------------------------------------------------------------------------------------------------
//  void mtxStartAfterDelay(UINT8 delay)
//
//  DESCRIPTION:
//      Starts TX after the given number of backoff slots, using a callback timer when the delay is > 0
//  
//  PARAMETERS:
//      UINT8 delay
//          The number of backoff slots to delay the call to mtxCreateStartTask()
//-------------------------------------------------------------------------------------------------------
BOOL mtxStartAfterDelay(UINT8 delay) {
    if (delay) {
        return mtimSetCallback(mtxCreateStartTask, delay);
    } else {
        mtxCreateStartTask();
        return TRUE;
    }
} // mtxStartAfterDelay




//-------------------------------------------------------------------------------------------------------
//  void csmaSetStartupTime(void)

⌨️ 快捷键说明

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