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

📄 zphy_cc2420.cpp

📁 一个Zigbee开放协议栈移植到VC环境下的版本.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                }

                packetSize = RxBuffer[RxRead];

                params.PD_DATA_indication.psdu = SRAMalloc(packetSize);

                if(params.PD_DATA_indication.psdu == NULL)
                {
                    phyError.failedToMallocRx = 1;
                    PHYTasksPending.bits.PHY_RX = 0;
                    return NO_PRIMITIVE;
                }

                /* save the packet head somewhere so that it can be freed later */
                if(CurrentRxPacket == NULL)
                {
                    CurrentRxPacket = params.PD_DATA_indication.psdu;

                    params.PD_DATA_indication.psduLength = packetSize;
                    RxRead++;
                    if(RxRead == RX_BUFFER_SIZE)
                    {
                        RxRead = 0;
                    }

                    while(packetSize--)
                    {
                        *params.PD_DATA_indication.psdu++ = PHYGet();
                    }

                    /* reset the psdu to the head of the alloc-ed RAM, just happens to me CurrentRxPacket */
                    params.PD_DATA_indication.psdu = CurrentRxPacket;

                    /* disable interrupts before checking to see if this was the
                        last packet in the FIFO so that if we get a packet(interrupt) after the check,
                        but before the clearing of the bit then the new indication will not
                        get cleared */

                    savedBits.bGIEH = GIEH;
                    GIEH = 0;

                    if(RxRead == RxWrite)
                    {
                        PHYTasksPending.bits.PHY_RX = 0;
                    }

                    GIEH = savedBits.bGIEH;

                    return PD_DATA_indication;
                }
            }
            if(ZigBeeStatus.flags.bits.bRxBufferOverflow == 1)
            {
                ZigBeeStatus.flags.bits.bRxBufferOverflow = 0;
                CCP2IF = 1;
            }
        }
        else
        {
            // if tx is already busy sending a packet then we can't RX a packet because of resource control issues
            return NO_PRIMITIVE;
        }
    }
    else
    {
        /* handle primitive here */
        switch(inputPrimitive)
        {
//            case PD_DATA_request:
//                  This is handled by CC2420 hardware
//                break;
//            case PLME_CCA_request:
//                  This is handled by CC2420 hardware
//                break;
//            case PLME_ED_request:
//                    This is handled by CC2420 hardware, just read variable out of CC2420
//                break;
//            case PLME_SET_request:
//                  User will access variables directly
//                break;
//            case PLME_GET_request:
//                  User will access variables directly
//                break;
            case PLME_SET_TRX_STATE_request:
                /* input_state RX_ON, TRX_OFF, FORCE_TRX_OFF, or TX_ON */
                /* returns PLME_SET_TRX_STATE_confirm with SUCCESS, RX_ON, TRX_OFF, TX_ON, BUSY_RX, or BUSY_TX */

                if(params.PLME_SET_TRX_STATE_request.state == TRXCurrentState)
                {
                    params.PLME_SET_TRX_STATE_confirm.status = params.PLME_SET_TRX_STATE_request.state;
                    break;
                }

                if(params.PLME_SET_TRX_STATE_request.state == phyRX_ON || params.PLME_SET_TRX_STATE_request.state == phyTRX_OFF)
                {
                    BYTE_VAL status;
                    /* get status of CC2420 */
                    status.Val = CC2420GetStatus();

                    if(status.bits.b3 == 1)
                    {
                        params.PLME_SET_TRX_STATE_confirm.status = phyBUSY_TX;
                        break;
                    }
                }

                /* if we are in the middle of an RX then don't allow switch to TX */
                if((params.PLME_SET_TRX_STATE_request.state == phyTX_ON || params.PLME_SET_TRX_STATE_request.state == phyTRX_OFF) && (TRXCurrentState == phyRX_ON) )
                {
                    if(PHY_SFD == 1)
                    {
                        params.PLME_SET_TRX_STATE_confirm.status = phyBUSY_RX;
                        PHYTasksPending.bits.PLME_SET_TRX_STATE_request_task = 1;
                        return PLME_SET_TRX_STATE_confirm;
                    }
                }

                if(params.PLME_SET_TRX_STATE_request.state == phyFORCE_TRX_OFF || params.PLME_SET_TRX_STATE_request.state == phyTRX_OFF)
                {
                    /* force it off here */
                    PHY_CSn_0();
                    SPIPut(STROBE_SRFOFF);
                    PHY_CSn_1();
                    TRXCurrentState = phyTRX_OFF;
                    /* SUCCESS */
                    params.PLME_SET_TRX_STATE_confirm.status = phySUCCESS;
                    break;
                }
                else if(params.PLME_SET_TRX_STATE_request.state == phyRX_ON)
                {
                    PHY_CSn_0();
                    SPIPut(STROBE_SRXON);
                    PHY_CSn_1();
                }
//don't use this one because it is automatically handled in the CC2420 when we use the STXONCCA command strobe
//                else if(params.PLME_SET_TRX_STATE_request.state == phyTX_ON)
//                {
//                    PHY_CSn_0();
//                    SPIPut(STROBE_STXON);
//                    PHY_CSn_1();
//                }

                /* passed all of the tests to change the state of the TRX */
                TRXCurrentState = params.PLME_SET_TRX_STATE_request.state;
                /* SUCCESS */
                params.PLME_SET_TRX_STATE_confirm.status = phySUCCESS;
                break;
        }
    }
    return NO_PRIMITIVE;
}

BYTE CC2420GetStatus(void)
{
    BYTE GIEHsave;
    BYTE status;

    GIEHsave = GIEH;
    GIEH = 0;
    PHY_CSn_0();
    status = SPIGet();
    PHY_CSn_1();
    GIEH = GIEHsave;
    return status;
}


#if defined(MCHP_C18)
    #pragma interruptlow HighISR
    void HighISR(void)
#elif defined(HITECH_C18)
    void interrupt HighISR(void)
#else
    void HighISR(void)
#endif
{
    if(CCP2IF)
    {
        if(CCP2IE)
        {
            BYTE_VAL ack_status;
            BYTE count;
            BYTE_VAL w;

    #if (RX_BUFFER_SIZE > 256)
            #error "Rx buffer must be <= 256"
    #else
            #define BUFFER_CAST BYTE
            BYTE RxBytesRemaining;
            BYTE OldRxWrite;
    #endif

            CCP2IF = 0;
            ack_status.Val = 0;
            count = 0;

            if(RxData.inUse == 0)
            {
                if(PHY_FIFO == 0)
                {
                    // Flush the RX FIFO
                    iPHY_CSn_0();
                    SPIPut(REG_RXFIFO | CMD_READ);
                    SPIGet();
                    iPHY_CSn_1();
                    iPHY_CSn_0();
                    SPIPut(STROBE_SFLUSHRX);
                    SPIPut(STROBE_SFLUSHRX);
                    iPHY_CSn_1();
                    RxData.inUse = 0;
                    ZigBeeStatus.flags.bits.bRxBufferOverflow = 0;
                    return;
                }

                iPHY_CSn_0();
                SPIPut(REG_RXFIFO | CMD_READ);
                RxData.size=SPIGet();
                RxData.inUse=1;
            }
            else
            {
                // We are recovering from an overflow.  We already have the size.
                iPHY_CSn_0();
                SPIPut(REG_RXFIFO | CMD_READ);
            }

            /* save the old write so that we can restore it if there isn't enough room left */
            OldRxWrite = RxWrite;

            if(RxWrite < RxRead)
            {
                RxBytesRemaining = (BUFFER_CAST)(RxRead - RxWrite - 1);
            }
            else
            {
                RxBytesRemaining = (BUFFER_CAST)(RX_BUFFER_SIZE - 1 - RxWrite + RxRead);
            }

            w.Val = RxData.size;

            /* this is less then because we need one extra byte for the length (which worst case would make it equivent to less then or equal to )*/
            if(w.Val < RxBytesRemaining)
            {
                MAC_FRAME_CONTROL mfc;

                /* there is room in the buffer */
                RxData.inUse = 0;

                /* add the packet */
                RxBuffer[RxWrite++]=w.Val;

                if(RxWrite==RX_BUFFER_SIZE)
                {
                    RxWrite = 0;
                }

                while(w.Val--)
                {
                    //Note: I am counting on the fact that RxWrite doesn't get incremented here anymore such that the ACK packet doesn't get written into the Buffer and the RxWrite doesn't get modified.
                    RxBuffer[RxWrite]=SPIGet();

                    if(count==0)
                    {
                        //if the frame control indicates that this packet is an ack

                        mfc.word.byte.LSB=RxBuffer[RxWrite];

//only enable this code if you don't want to use autoAck
//                        if(mfc.bits.ACKRequest == 1)
//                        {
//                            iPHY_CSn_1();
//                            iPHY_CSn_0();
//                            SPIPut(STROBE_SACKPEND);
//                            iPHY_CSn_1();
//
//                            iPHY_CSn_0();
//                            SPIPut(REG_RXFIFO | CMD_READ);
//                        }

                        if(mfc.bits.FrameType == 0x02)
                        {
                            //it was an ack then set the ack_status.bits.b0 to 1 showing it was an ack
                            ack_status.bits.b0 = 1;
                            //ConsolePut('@');
                        }
                    }
                    else if(count==2)
                    {
                        //if we are reading the sequence number and the packet was an ack
                        if(ack_status.bits.b0)
                        {

                              if ((macTasksPending.bits.packetPendingAck) &&
                                  (RxBuffer[RxWrite] == currentPacket.sequenceNumber))
                              {
                                  // If this is the ACK we've been waiting for, set the flag to
                                  // send up the confirm and save the Frame Control.
                                  macTasksPending.bits.bSendUpMACConfirm = 1;
                                  pendingAckFrameControl = mfc;
                              }

                              // Throw away the ACK
                              while(w.Val--)
                              {
                                  SPIGet();
                              }
                              RxWrite = OldRxWrite;
                              goto DoneReceivingPacket;

                        }
                    }
                    count++;
                    RxWrite++;
                    //roll buffer if required
                    if(RxWrite==RX_BUFFER_SIZE)
                    {
                        RxWrite = 0;
                    }
                }

                if(RxWrite==0)
                {
                    w.Val = RxBuffer[RX_BUFFER_SIZE-1];
                }
                else
                {
                    w.Val = RxBuffer[RxWrite - 1];
                }

                if(w.bits.b7 == 0)
                {
                    /* crc failed.  Erase packet from the array */
                    RxWrite = OldRxWrite;
                    // Flush the RX FIFO
                    iPHY_CSn_0();
                    SPIPut(REG_RXFIFO | CMD_READ);
                    SPIGet();
                    iPHY_CSn_1();
                    iPHY_CSn_0();
                    SPIPut(STROBE_SFLUSHRX);
                    SPIPut(STROBE_SFLUSHRX);
                    iPHY_CSn_1();
                    RxData.inUse = 0;
                    ZigBeeStatus.flags.bits.bRxBufferOverflow = 0;
                }
                else
                {
                    PHYTasksPending.bits.PHY_RX = 1;
                }
            }
            else
            {
                RxWrite = OldRxWrite;
                ZigBeeStatus.flags.bits.bRxBufferOverflow = 1;
            }

DoneReceivingPacket:

            iPHY_CSn_1();
        }
    }
    if(TMR0IF)
    {
        if(TMR0IE)
        {
            /* there was a timer overflow */
            TMR0IF = 0;
            timerExtension1++;

            if(timerExtension1 == 0)
            {
                timerExtension2++;
            }
        }
    }

    UserInterruptHandler();
}

//******************************************************************************
// Interrupt Vectors
//******************************************************************************

#if defined(MCHP_C18)
#pragma code highVector=0x08
void HighVector (void)
{
    //_asm goto HighISR _endasm
}
#pragma code /* return to default code section */
#endif

#if defined(MCHP_C18)
#pragma code lowhVector=0x18
void LowVector (void)
{
//    _asm goto HighISR _endasm
}
#pragma code /* return to default code section */
#endif


#else
    #error Please link the appropriate PHY file for the selected transceiver.
#endif

⌨️ 快捷键说明

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