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

📄 mac_tx_engine.c

📁 ucos在NEC平台下的移植
💻 C
📖 第 1 页 / 共 3 页
字号:
        case MTX_STATUS_ACK_HANDLER_CREATED:
            // Keep the current status/state
            return;    
            
        case MTX_STATUS_CHANNEL_ACCESS_FAILURE:
            
            // Increment the number of backoffs
            mtxInfo.nb++;
            
            // Fail because of "channel access failure"?
            if (mtxInfo.nb > mpib.macMaxCsmaBackoffs) {
                
#if MAC_OPT_FFD
                // For indirect packets with one or more retries left...
                if ((pPacket->txOptions & TX_OPT_INDIRECT) && pPacket->retriesLeft) {
                    pPacket->retriesLeft--;
                    miqSetRequested(pPacket, FALSE);
                    pPacket->transmissionStarted = FALSE;
                    mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
                    
                // Otherwise...
                } else {
                    mtxFinishTransmission(CHANNEL_ACCESS_FAILURE, pPacket, pTask);
                }
#else
                mtxFinishTransmission(CHANNEL_ACCESS_FAILURE, pPacket, pTask);
#endif
            
            // Or retry?
            } else {
        
                // Update counters
                pPacket->slotted = !((mpib.macBeaconOrder == 15) || (pPacket->txMode & MTX_MODE_FORCE_UNSLOTTED_BM));
                mtxInfo.be = MIN(mtxInfo.be + 1, aMaxBE);
        
                // Random delay before the next attempt
                pTask->state = MTX_STATE_SET_STARTUP_TIME;
            }
            break;
            
        case MTX_STATUS_ACK_TIMEOUT:
        
            // Fail because of "no acknowledgment"?
            if (pPacket->retriesLeft == 0) {
                mtxFinishTransmission(NO_ACK, pPacket, pTask);
                
            // Or retry?
            } else {
                pPacket->retriesLeft--;
                
#if MAC_OPT_FFD
                // Indirect packets don't retry autmatically!
                if (pPacket->txOptions & TX_OPT_INDIRECT) {
                    miqSetRequested(pPacket, FALSE);
                    pPacket->transmissionStarted = FALSE;
                    mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
                } else {                    
                    pTask->state = MTX_STATE_INIT_CSMACA;
                }
#else
                pTask->state = MTX_STATE_INIT_CSMACA;
#endif
            }     
            break;
            
        case MTX_STATUS_ACK_RECEIVED:
        case MTX_STATUS_TX_FINISHED:
            mtxFinishTransmission(SUCCESS, pPacket, pTask);
            break;
        }
        mtxInfo.status = MTX_STATUS_FINISHED;
        break;        
    }    
} // mtxScheduleTransmission
    



//-------------------------------------------------------------------------------------------------------
//  mtxStartTransmission(MAC_TASK_INFO *pTask)
//
//  DESCRIPTION:
//      This task is responsible for transmitting a packet when the time has come. The task turns on RX,
//      performs CCA-checking, issues the STXON(CCA) command strobe, and writes to the TX FIFO.
//
//      The FIFOP interrupt is disabled throughout this process, and the RX engine is cleaned up
//      afterwards, if necessary.
//-------------------------------------------------------------------------------------------------------
void mtxStartTransmission(MAC_TASK_INFO *pTask) {
    BYTE temp;
    BOOL sfdWasActiveBeforeStrobe;
    MAC_TX_PACKET *pPacket = (MAC_TX_PACKET*) pTask->taskData;
#if MAC_OPT_SECURITY
    BYTE *pCounters;
#endif

    switch (pTask->state) {
    
    case MTX_STATE_TURN_ON_RX:
        
        // Make sure that the FIFOP interrupt is off during the CSMA-CA procedure and the timing-critical TX FIFO access
        mrxInfo.keepFifopIntOff = TRUE;
    
        // Turn on RX to be able to do the CCA check in the CSMA-CA algorithm
        if (pPacket->txMode & MTX_MODE_USE_CSMACA_BM) {
            mrxIncrOnCounter();
            if (pPacket->slotted) {
                pTask->state = MTX_STATE_CCA;
            } else {
                pTask->state = MTX_STATE_START_TRANSMISSION;
            }
        } else {
            mrxAutoIncrOnCounter();
            pTask->state = MTX_STATE_START_TRANSMISSION;
        }
                    
        // Flush the TX FIFO
        DISABLE_GLOBAL_INT();
        FASTSPI_STROBE(CC2420_SFLUSHTX);
        ENABLE_GLOBAL_INT();
        
#if MAC_OPT_SECURITY
        // Write key and nonce to RAM (this will not interfere with RX)
        pCounters = (BYTE*) pPacket->pPayload + (pPacket->securitySetup.clearTextLength - pPacket->headerLength);
        msecSetupCC2420KeyAndNonce(TRUE, &pPacket->securitySetup, pPacket->pSecurityMaterial->pSymmetricKey, pCounters);
#endif
        break;
        
    case MTX_STATE_CCA:
        
        // CCA check on the backoff slot boundary
        DISABLE_GLOBAL_INT();
        WAIT_FOR_BOUNDARY();
        if (CCA_IS_ACTIVE()) {
            pTask->state = MTX_STATE_START_TRANSMISSION;
        } else {
            mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_RESERVED_BM | MSCH_KEEP_TASK_IN_PROGRESS_BM);
            mtxInfo.status = MTX_STATUS_CHANNEL_ACCESS_FAILURE;
            mrxDecrOnCounter();
            mrxInfo.keepFifopIntOff = FALSE;
        }
        ENABLE_GLOBAL_INT();
        break;
                
    case MTX_STATE_START_TRANSMISSION:

#if MAC_OPT_SECURITY
        // Write to the SECCTRL registers (this could interfere with RX, however SFD_IS_1 should 
        // have indicated that RX has started, and the coming CCA check should handle the case where RX is 
        // just about to start (the security registers are written after the header has been received)
        msecSetupCC2420Regs(&pPacket->securitySetup);
#endif        
        
        // Start TX
        DISABLE_GLOBAL_INT();
        if (pPacket->txMode & MTX_MODE_USE_CSMACA_BM) {
            
            // Wait for the backoff slot boundary before transmitting ...
            if (pPacket->slotted) {
                WAIT_FOR_BOUNDARY();
                
            // ... or just wait for the RSSI value to become valid?
            } else {
                do {
                    FASTSPI_UPD_STATUS(temp);
                } while (!(temp & CC2420_RSSI_VALID_BM));
            }
            
            // Start TX if the CCA check passes
#if MAC_OPT_TRANSMIT_POWER
            msupSetTransmitPower();
#endif            
            sfdWasActiveBeforeStrobe = SFD_IS_ACTIVE();
            FASTSPI_STROBE(CC2420_STXONCCA);
                        
            // Was TX started?
            FASTSPI_UPD_STATUS(temp);
            if (!(temp & CC2420_TX_ACTIVE_BM)) {
                mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_RESERVED_BM | MSCH_KEEP_TASK_IN_PROGRESS_BM);
                mtxInfo.status = MTX_STATUS_CHANNEL_ACCESS_FAILURE;
                mrxDecrOnCounter();
                mrxInfo.keepFifopIntOff = FALSE;
                ENABLE_GLOBAL_INT();
                break;
            }
            
        } else {
            
            // Wait for the backoff slot boundary before transmitting?
            if (pPacket->slotted) {
                WAIT_FOR_BOUNDARY();
            }
            
            // Start TX without any CCA check
#if MAC_OPT_TRANSMIT_POWER
            msupSetTransmitPower();
#endif            
            sfdWasActiveBeforeStrobe = SFD_IS_ACTIVE();
            FASTSPI_STROBE(CC2420_STXON);

        }
        ENABLE_GLOBAL_INT();
            
        // Set the TX finished / no acknowledgment timeout
        // An additional backoff period has been added to take 
        mtimSetCallback(mtxPacketTimeout, pPacket->duration + 1);
        
        // Write length and header to the TX FIFO        
        msupWriteFifo((BYTE*)&pPacket->length, pPacket->headerLength + 1);///
    
        // Calculate the payload length, and write the payload to the TX FIFO
#if MAC_OPT_SECURITY
        temp = pPacket->length - pPacket->headerLength - pPacket->securitySetup.micLength - MAC_FCS_LENGTH;
#else
        temp = pPacket->length - pPacket->headerLength - MAC_FCS_LENGTH;
#endif        
        msupWriteFifo((BYTE*)pPacket->pPayload, temp);///
        
        // Clean up the RX engine if necessary
        if (sfdWasActiveBeforeStrobe) {
            mrxResetRxEngine();
        }
        mrxInfo.keepFifopIntOff = FALSE;
        
        
        // Done :)
        //Need to verify that it is actualy the data frame and not a becon we are sendig. If it is a beacon 
        //it will bypass the mtxSchedueleTransmission task and send frame at once. If a nother packet is queed while
        //we are sending beacon it need to continue after beacon is finished. This check solved this.
        if (pPacket == mtxInfo.pPacket)
       	    mtxInfo.status = MTX_STATUS_TRANSMISSION_STARTED;
       	    
        mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_RESERVED_BM | MSCH_KEEP_TASK_IN_PROGRESS_BM);
        break;
    }
    
} // mtxStartTransmission




/*******************************************************************************************************
 * Revision history:
 *
 * $Log: mac_tx_engine.c,v $
 * Revision 1.17  2005/02/04 14:15:41  thl
 * removed flushing of rx buffer after seting cc2420 to tx
 *
 * Revision 1.16  2005/02/04 13:16:06  thl
 * Fixed problem with oncounter and CC2420 when disabling RX
 *
 * Revision 1.15  2005/01/05 10:45:29  thl
 * Added full suport for ppib.phyTransmitPower, will also now adjust the transmit power
 * of the radio chip. to include set compile switch MAC_OPT_TRANSMIT_POWER=1 in
 * make file.
 *
 * Revision 1.14  2004/12/07 09:47:50  thl
 * Fixed potential coruption of memmory when max payload is recived.
 *
 * Revision 1.13  2004/11/18 15:07:58  thl
 * Added support for pending frame bit in outgoing data frames.
 * Only apply to outgoing data frames and wherer the address matches
 * one or more packet in the indirect packet quee.
 *
 * Revision 1.12  2004/11/10 09:33:16  thl
 * Fixed a number of bugs according to: MAC software check lists.xls
 *
 * Revision 1.11  2004/08/13 13:04:48  jol
 * CC2420 MAC Release v0.7
 *
 *
 *******************************************************************************************************/

⌨️ 快捷键说明

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