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

📄 mac_tx_engine.c

📁 zigbee location examples
💻 C
📖 第 1 页 / 共 3 页
字号:
            mrxDecrOnCounter();
            mtxInfo.beaconSearchEnabled = FALSE;
            mtxInfo.beaconSearchTimeout = FALSE;
            mtimCancelCallback(mtxBeaconSearchTimeout);
        }

        // Go ahead if there's sufficient CAP left (otherwise remain in the OUT_OF_CAP state)
        if (T2_IS_CAP_ACTIVE()) {
            mtxInfo.waitForBeacon = FALSE;
            mtxInfo.status = MTX_STATUS_WAITING;
            mtxInfo.cspTimeout = mtxCalcCspTimeout();

            if (mtxInfo.cspTimeout) {
                mtxCreateStartTask();
                mtxInfo.status = MTX_STATUS_WAITING;
            } else {
                mtxInfo.status = MTX_STATUS_OUT_OF_CAP;
            }
        }
    }
} // mtxResumeAfterBeacon



void mtxResetBosCounter(void) NEAR {

    // New CAP begins
    T2_SET_OVERFLOW_COUNTER(0x00000);
    T2_SET_OVERFLOW_COUNTER_COMPARE_VALUE(msupCalcCapDuration());
    T2_SET_CAP_ACTIVE();

    // Schedule the next beacon handler
    if (mpib.macBeaconOrder != 15) {
        mtimSetCallback(mbcnTxPeriodicalBeacon, msupCalcBeaconInterval() - MBCN_TX_STARTUP_OVERHEAD - MBCN_TX_PREPARE_TIME);
    }
}




//-------------------------------------------------------------------------------------------------------
//  void mtxAckTimeout(void)
//
//  DESCRIPTION:
//-------------------------------------------------------------------------------------------------------
void mtxAckTimeout(void) NEAR {
    mrxDecrOnCounter();
    FSMTC1 &= ~FSMTC1_ACCEPT_ACKPKT_BM;
    if (mtxInfo.status == MTX_STATUS_WAITING_FOR_ACK) {
        mtxInfo.status = MTX_STATUS_ACK_TIMEOUT;
    }
} // mtxAckTimeout




//-------------------------------------------------------------------------------------------------------
//  void mtxScheduleTransmission(MAC_TASK_INFO *pTask)
//
//  DESCRIPTION:
//      This task is created to start a transmission. The task is responsible for setting up the CSMA-CA
//      mechanism, scheduling the transmission, and handle the result when the packet timeout is trigged.
//      Note: Periodically transmitted beacons bypass this task and uses mtxStartTransmission directly.
//-------------------------------------------------------------------------------------------------------
void mtxScheduleTransmission(MAC_TASK_INFO   *pTask) NEAR {
    MAC_TX_PACKET   *pPacket = (MAC_TX_PACKET   *) pTask->taskData;

    switch (pTask->state) {
    case MTX_STATE_INIT_TRANSMISSION:
        // Reschedule this task if we're in scan mode and the "scan related" flag is not set on this packet
        if ((macInfo.state & MAC_STATE_SCAN_BM) && !(pPacket->txMode & MTX_MODE_SCAN_RELATED_BM)) {
            mschRescheduleTask(pTask, MTX_STATE_INIT_TRANSMISSION);
            return;
        }

        // Set the TX engine packet pointer
        mtxInfo.pPacket = pPacket;

        // No break here!

    case MTX_STATE_PROCESS_SECURITY:
        pTask->state = MTX_STATE_PREPARE_STARTUP;
        break;

    case MTX_STATE_RETRY_TRANSMISSION:
    case MTX_STATE_PREPARE_STARTUP:

        // Bail out if beacon transmission is in progress
#if MAC_OPT_FFD
        if (mtxInfo.beaconTransmissionInProgress) {
            if ((pPacket->txOptions & TX_OPT_INDIRECT)) {
                miqSetRequested(pPacket, FALSE);
                pPacket->transmissionStarted = FALSE;
                mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
            }
            break;
        }
#endif

        // Reset CSMA-CA parameters
        mtxInfo.nb = mpib.macMaxCsmaBackoffs;
        mtxInfo.be = mpib.macMinBE;
        pPacket->slotted = !(BYTE)((mpib.macBeaconOrder == 15) || (pPacket->txMode & MTX_MODE_FORCE_UNSLOTTED_BM));
        if (pPacket->slotted && mpib.macBattLifeExt) {
            mtxInfo.be = (BYTE)(MIN(2, mtxInfo.be));
        }

        // No break here!

    case MTX_STATE_SWITCHED_TO_UNSLOTTED:
        mtxInfo.randomBackoff = msupGetRandomByte() & (BM(mtxInfo.be) - 1);

        mtxInfo.beaconSearchEnabled = FALSE;

        // Calculate the CSP timeout constant for slotted/unslotted transmissions, and go ahead if OK
        mtxInfo.cspTimeout = mtxCalcCspTimeout();
        if (mtxInfo.cspTimeout) {
            mtxCreateStartTask();
            mtxInfo.status = MTX_STATUS_WAITING;
        } else
        {
#if MAC_OPT_FFD
            if ((pPacket->txOptions & TX_OPT_INDIRECT)) {
                miqSetRequested(pPacket, FALSE);
                pPacket->transmissionStarted = FALSE;
                mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
            } else {
                mtxInfo.status = MTX_STATUS_OUT_OF_CAP;
            }
#else
            mtxInfo.status = MTX_STATUS_OUT_OF_CAP;
#endif
        }
        pTask->state = MTX_STATE_WAIT;
        break;

    case MTX_STATE_WAIT:

        switch (mtxInfo.status) {
        case MTX_STATUS_WAITING:
        case MTX_STATUS_WAIT_FOR_NEXT_BEACON:
        case MTX_STATUS_TRANSMISSION_STARTED:
        case MTX_STATUS_WAITING_FOR_ACK:
        case MTX_STATUS_ACK_HANDLER_CREATED:
            // Keep the current status/state
            break;

        case MTX_STATUS_CHANNEL_ACCESS_FAILURE:
            // For indirect packets with one or more retries left...
#if MAC_OPT_FFD
            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
            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--;

                // Indirect packets don't retry autmatically!
#if MAC_OPT_FFD
                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_RETRY_TRANSMISSION;
                }
#else
                pTask->state = MTX_STATE_RETRY_TRANSMISSION;
#endif
            }
            break;

        case MTX_STATUS_OUT_OF_CAP:
            mtxInfo.waitForBeacon = TRUE;

            // When searching for the beacon...
            if (mtxInfo.beaconSearchEnabled) {

                // Switch to unslotted transmission when the timeout is reached
                if (mtxInfo.beaconSearchTimeout) {
                    mtxInfo.beaconSearchEnabled = FALSE;
                    mtxInfo.beaconSearchTimeout = FALSE;
                    mtxInfo.waitForBeacon = FALSE;
                    mrxDecrOnCounter();
                    mtxInfo.nb = 0;
                    mtxInfo.be = mpib.macMinBE;
                    mtxInfo.pPacket->slotted = FALSE;
                    pTask->state = MTX_STATE_SWITCHED_TO_UNSLOTTED;
                }

            // Just wait when we're tracking the beacon or transmitting beacons
            } else if (mbcnInfo.trackBeacon || GET_MF(MF_TRANSMIT_BEACON)) {
                mtxInfo.status = MTX_STATUS_WAIT_FOR_NEXT_BEACON;

            // Otherwise, start searching for the beacon
            } else {
                // Come back later if there's a temporary resource shortage
                if (mtimSetCallback(mtxBeaconSearchTimeout, (INT32) msupCalcBeaconInterval() + (INT32)(aBaseSuperframeDuration / aUnitBackoffPeriod))) {
                    mtxInfo.beaconSearchEnabled = TRUE;
                    mtxInfo.beaconSearchTimeout = FALSE;
                    mrxIncrOnCounter();
                }
                mtxInfo.status = MTX_STATUS_WAIT_FOR_NEXT_BEACON;
            }
            break;

        case MTX_STATUS_ACK_RECEIVED:
        case MTX_STATUS_TX_FINISHED:
            mtxFinishTransmission(SUCCESS, pPacket, pTask);
            mtxInfo.status = MTX_STATUS_FINISHED;
            break;
        }
        break;
    }
} // mtxScheduleTransmission

void mtxBeaconSearchTimeout(void) NEAR {
    mtxInfo.beaconSearchTimeout = TRUE;
}



//-------------------------------------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------------------------------------
ROOT void mtxCspStopped(BOOL txStarted) {

    if (txStarted) {
        if (!mtxInfo.beaconTransmissionInProgress) {
            // Set the accept acknowledgment bit in good time
            if (mtxInfo.pPacket->txOptions & TX_OPT_ACK_REQ) FSMTC1 |= FSMTC1_ACCEPT_ACKPKT_BM;
            mtxInfo.status = MTX_STATUS_TRANSMISSION_STARTED;
        }

        if (FSMTC1 & FSMTC1_RX_INTERRUPTED_BM) {
            mrxResetRxEngine();
        }
        mrxAutoIncrOnCounter();
    } else {

        if (CSPT != 0) {
            mtxInfo.status = MTX_STATUS_CHANNEL_ACCESS_FAILURE;
        } else {
            mtxInfo.status = MTX_STATUS_OUT_OF_CAP;
            ReadCsmaParams (&mtxInfo.be, &mtxInfo.nb, &mtxInfo.randomBackoff);
        }
    }
}



⌨️ 快捷键说明

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