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

📄 mac_rx_engine.c

📁 zigbee location examples
💻 C
📖 第 1 页 / 共 4 页
字号:

    default:
        break;
    }

    // Clean up (used when there are no calls to the upper layer
    if (cleanUpAfterSwitch) {
        mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
        mrxpReleasePacket(pPacket);
    }

} // mrxProcessMacCommand




//-------------------------------------------------------------------------------------------------------
//  void mrxCommStatusIndication(MAC_TASK_INFO *pTask)
//
//  DESCRIPTION:
//      This task is responsible for generating mlme-comm-status.indication upon security failures.
//
//  TASK DATA:
//      A pointer to the MAC_RX_PACKET to be processed
//-------------------------------------------------------------------------------------------------------
void mrxCommStatusIndication(MAC_TASK_INFO   *pTask) NEAR {
    MAC_RX_PACKET   *pPacket = (MAC_RX_PACKET   *) pTask->taskData;
    MCPS_DATA_INDICATION   *pMDI = &pPacket->mdi;

    mlmeCommStatusIndication(pMDI->srcPanId, pMDI->srcAddrMode, &pMDI->srcAddr, pMDI->dstAddrMode, &pMDI->dstAddr, pPacket->securityStatus);

    mschRemoveTask(pTask->priority, 0);
    mrxpReleasePacket(pPacket);
} //mrxCommStatusIndication




#pragma vector = DMA_VECTOR
__near_func __interrupt void DmaIsr(void) {
    CLEAR_DMA_INT();
    if (DMAIRQ & DMA_RFRX_CHANNEL_BM) {
        CLEAR_FIFOP_INT_BIT();
        ENABLE_FIFOP_INT_BIT();
        DMAIRQ = ~DMA_RFRX_CHANNEL_BM;
    }
}




#pragma vector=RF_VECTOR
__near_func __interrupt void RfIsr (void) {
    BYTE clearedFlagN,
         rfim;

    clearedFlagN = 0xFF;
    rfim = RFIM;

    if ((RFIF & RFIF_FIFOP_BM) & rfim) {
        mrxHandleFifopInt();
        clearedFlagN = ~RFIF_FIFOP_BM;

    } else if ((RFIF & RFIF_CSP_STOP_BM) & rfim) {
        mtxCspStopped(RFIF & RFIF_CSP_MANINT_BM);
        clearedFlagN = ~(RFIF_CSP_STOP_BM | RFIF_CSP_MANINT_BM | RFIF_CSP_WAIT_BM);

    } else if ((RFIF & RFIF_TXDONE_BM) & rfim) {
        mtxTxDone();
        clearedFlagN = ~RFIF_TXDONE_BM;
    }

    SET_RFIF(clearedFlagN);
    CLEAR_RFIF_INT();
}




static ROOT void mrxHandleFifopInt(void) {
    BYTE reservedTask;
    BYTE dstAddrMode;
    BYTE srcAddrMode;
    BOOL createProcessTask;
    TFPTR pProcessTask;
    WORD processTaskData;

    // Copy the pointer for fast access
    MAC_RX_PACKET   *pPacket = mrxInfo.pPacket;
    MCPS_DATA_INDICATION *pMDI = &pPacket->mdi;

    switch (mrxInfo.state) {
    case MRX_STATE_LEN_FCF_SEQ:

        // Keep RX on while receiving
        mrxAutoIncrOnCounter();

        // Reserve processing task and make sure that we're not doing energy detection
        reservedTask = mschReserveTask();
        if ((macInfo.state != MAC_STATE_ENERGY_SCAN) && (reservedTask != NO_TASK)) {
            mrxInfo.taskNumber = reservedTask;

            // Reserve packet
            pPacket = mrxpReservePacket();
            if (pPacket) {
                mrxInfo.pPacket = pPacket;
                pMDI = &pPacket->mdi;

                // Read the packet length, the frame control field and the sequence number
                halReadRxFifo((BYTE  *) &mrxInfo.length, 4);
                mrxInfo.length &= 0x7F;
                mrxInfo.length -= 5; // 3 for FCF and SN + 2 for FCS

                // Get the time stamp (do it now to make sure that it is not overwritten by the acknowledgment)
                pPacket->timestamp.counter = T2_GET_CAPTURED_COUNTER();
                pPacket->timestamp.overflowCounter = T2_GET_CAPTURED_OVERFLOW_COUNTER();

                // Security is currently not supported
                pMDI->securityUse = FALSE;

                // This packet will be acknowledged if the ack request bit is set
                if ((BYTE) mrxInfo.frameControlField & ACK_REQ_BM) {
                    ENABLE_AUTOACK();
#if MAC_OPT_FFD
                    // Acknowledge with the pending flag set if there is at least one packet in the pending queue
                    if (miqInfo.firstIndirectPacket != NO_PACKET) {
                        pPacket->flags |= MRXP_FLAG_SACKPEND_ISSUED_BM;
                        AUTOACK_WITH_PENDING_BIT();
                    } else {
                        AUTOACK_WITHOUT_PENDING_BIT();
                    }
#endif
                }

                // Set the destination address mode and length (of the fields)
                dstAddrMode = BF(mrxInfo.frameControlField, DEST_ADDR_MODE_BM, DEST_ADDR_MODE_IDX);
                pMDI->dstAddrMode = dstAddrMode;
                if (dstAddrMode) {
                    mrxInfo.destAddrLength = (dstAddrMode == AM_SHORT_16) ? 4 : 10;
                } else {
                    mrxInfo.destAddrLength = 0;
                }

                // Set the source address mode and length (of the fields)
                srcAddrMode = BF(mrxInfo.frameControlField, SRC_ADDR_MODE_BM, SRC_ADDR_MODE_IDX);
                pMDI->srcAddrMode = srcAddrMode;
                if (srcAddrMode) {
                    mrxInfo.srcAddrLength = (srcAddrMode == AM_SHORT_16) ? 4 : 10;
                    if (mrxInfo.frameControlField & INTRA_PAN_BM) mrxInfo.srcAddrLength -= 2;
                } else {
                    mrxInfo.srcAddrLength = 0;
                }

                // Calculate the MSDU length
                pMDI->msduLength = mrxInfo.length - (mrxInfo.destAddrLength + mrxInfo.srcAddrLength);

                // Set the next state
                if ((pMDI->msduLength < 0) || (pMDI->msduLength > aMaxMACFrameSize)) {
                    mrxpReleasePacket(pPacket);
                    mschReleaseTask(mrxInfo.taskNumber);
                    DISABLE_AUTOACK();
                    SET_FIFOP_THRESHOLD(mrxInfo.length + 2);
                    mrxInfo.state = MRX_STATE_DISCARD;
                } else if (mrxInfo.destAddrLength + mrxInfo.srcAddrLength) {
                    SET_FIFOP_THRESHOLD(mrxInfo.destAddrLength + mrxInfo.srcAddrLength);
                    mrxInfo.state = MRX_STATE_ADDR;
                } else {
                    // Configure payload DMA transfer
                    if (mrxInfo.length) {
                        mrxStartPayloadDmaTransfer();
                    }
                    SET_FIFOP_THRESHOLD(2);
                    mrxInfo.state = MRX_STATE_FCS;
                }
                break;
            }
        }

        // This packet will be discarded because
        // - There was no available task to handle the packet processing
        // - There was no packet structure to store the incoming data
        // - We're performing an energy detection scan, where all incoming packets are discarded
        mschReleaseTask(reservedTask);
        mrxInfo.length = (RFD & 0x7F) - 2;
        DISABLE_AUTOACK();
        SET_FIFOP_THRESHOLD(mrxInfo.length + 2);
        mrxInfo.state = MRX_STATE_DISCARD;
        break;

    case MRX_STATE_ADDR:

        // Read the source and destination addresses
        halReadRxFifo((BYTE  *) &pMDI->dstPanId, mrxInfo.destAddrLength);
        pMDI->srcPanId = pMDI->dstPanId;
        halReadRxFifo((mrxInfo.frameControlField & INTRA_PAN_BM) ? (BYTE  *) &pMDI->srcAddr : (BYTE  *) &pMDI->srcPanId, mrxInfo.srcAddrLength);
        mrxInfo.length = pMDI->msduLength;

        // Configure payload DMA transfer
        if (mrxInfo.length) {
            mrxStartPayloadDmaTransfer();
        }
        SET_FIFOP_THRESHOLD(2);
        mrxInfo.state = MRX_STATE_FCS;
        break;

    case MRX_STATE_FCS:

        // Get the footer (RSSI, CRCOK and LQI)
        halReadRxFifo(mrxInfo.pFooter, 2);
        pMDI->mpduLinkQuality = ED_2_LQI(RSSI_2_ED((INT8) mrxInfo.pFooter[0]));

        // If the CRC is OK, then spawn a task to do the further processing
        pProcessTask = NULL;
        processTaskData = (WORD) pPacket;
        if (mrxInfo.pFooter[1] & 0x80) {

            switch ((BYTE) mrxInfo.frameControlField & FRAME_TYPE_BM) {
            case FT_BEACON:
                // Get the sequence number (overwrites pPacket->framePending)
                pPacket->sequenceNumber = mrxInfo.sequenceNumber;
                pProcessTask = mrxProcessBeacon;
                break;
            case FT_DATA:
                pProcessTask = mrxProcessData;
                break;
            case FT_ACKNOWLEDGMENT:
                if (((mtxInfo.status == MTX_STATUS_TRANSMISSION_STARTED) || (mtxInfo.status == MTX_STATUS_ACK_TIMEOUT) ||
                    (mtxInfo.status == MTX_STATUS_WAITING_FOR_ACK)) && (mrxInfo.sequenceNumber == mtxInfo.pPacket->pHeader[2])) {
                    // Note: If a timeout has occurred, but not been handled by the low-priority task, it will be undone here :)
                    // We'll use an intermediate state until the mrxProcessAcknowledgment task has started, because we could already
                    // be inside the transmission task (interrupted by the FIFOP ISR). It must be done this way, because otherwise the
                    // TX engine would release the packet, and we wouldn't be able to tie this acknowledgment to a packet.
                    mtxInfo.status = MTX_STATUS_ACK_HANDLER_CREATED;
                    pProcessTask = mrxProcessAcknowledgment;
                    processTaskData = mrxInfo.frameControlField & FRAME_PENDING_BM;
                }
                break;
            case FT_MAC_COMMAND:
                // TBD: Handle security errors for MAC command frames
                pProcessTask = mrxProcessMacCommand;
                break;
            }
        }

        // If a handler function has been set, the task is created. If not, then free the acquired resources.
        if (pProcessTask) {

            // Apply filtering while scanning
            if (macInfo.state & MAC_STATE_SCAN_BM) {
                switch (macInfo.state) {
                case MAC_STATE_ACTIVE_OR_PASSIVE_SCAN:
                    createProcessTask = (pProcessTask == mrxProcessBeacon);
                    break;
                case MAC_STATE_ORPHAN_SCAN:
                    createProcessTask = ((pProcessTask == mrxProcessMacCommand) && (((MAC_COMMAND_TYPE) pMDI->pMsdu[0]) == CMD_COORDINATOR_REALIGNMENT));
                    break;
                default:
                    createProcessTask = FALSE;
                    break;
                }
            } else {
                createProcessTask = TRUE;
            }

            // Create the processing task?
            if (createProcessTask) {
                if ((pProcessTask == mrxProcessBeacon) && mpib.macRxOnWhenIdle) {
                    pPacket->flags |= MRXP_FLAG_RX_NOT_TURNED_OFF_BM;
                } else {
                    if (pProcessTask == mrxProcessAcknowledgment) mrxpReleasePacket(pPacket);
                    mrxDecrOnCounter();
                }
                mschAddTask(mrxInfo.taskNumber, MAC_TASK_PRI_HIGH, (TFPTR) pProcessTask, processTaskData);

            // If not (for instance during scanning), clean up
            } else {
                mrxDecrOnCounter();
                mrxpReleasePacket(pPacket);
                mschReleaseTask(mrxInfo.taskNumber);
            }

        // No handler function found, so just clean up
        } else {
            mrxDecrOnCounter();
            mrxpReleasePacket(pPacket);
            mschReleaseTask(mrxInfo.taskNumber);
        }

        RESET_FIFOP_THRESHOLD();
        mrxInfo.state = MRX_STATE_LEN_FCF_SEQ;
        break;

    case MRX_STATE_DISCARD:
        halDiscardRxFifo(mrxInfo.length + 2);
        mrxDecrOnCounter();
        RESET_FIFOP_THRESHOLD();
        mrxInfo.state = MRX_STATE_LEN_FCF_SEQ;
        break;
    }
}



#pragma vector=RFERR_VECTOR
__near_func __interrupt void RferrIsr(void) {
    switch (FSMSTATE) {
    case RF_RX_OVERFLOW:
        mrxResetRxEngine();
        break;
    case RF_TX_UNDERFLOW:
        // This should never happen
        break;
    }
    RFERRIF = 0;
}

⌨️ 快捷键说明

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