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

📄 zmac_receive.c

📁 通过cc2420+pic实现无线通信
💻 C
📖 第 1 页 / 共 5 页
字号:
//每收到一帧的数据,往串口发送
/*********************************************************************
 *
 *                  Zigbee MAC layer
 *
 *********************************************************************
 * FileName:        zMAC.c
 * Dependencies:
 * Processor:       PIC18F
 * Complier:        MCC18 v2.30 or higher
 *                  HITECH PICC-18 V8.10PL1 or higher
 * Company:         Microchip Technology, Inc.
 *
 * Software License Agreement
 *
 * The software supplied herewith by Microchip Technology Incorporated
 * (the 揅ompany? for its PICmicro?Microcontroller is intended and
 * supplied to you, the Company抯 customer, for use solely and
 * exclusively on Microchip PICmicro Microcontroller products. The
 * software is owned by the Company and/or its supplier, and is
 * protected under applicable copyright laws. All rights are reserved.
 * Any use in violation of the foregoing restrictions may subject the
 * user to criminal sanctions under applicable laws, as well as to
 * civil liability for the breach of the terms and conditions of this
 * license.
 *
 * THIS SOFTWARE IS PROVIDED IN AN 揂S IS?CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 *
 * Author               Date    Comment
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Nilesh Rajbharti     7/12/04 Rel 0.9
 * Nilesh Rajbharti     11/1/04 Pre-release version
 ********************************************************************/
// Uncomment ENABLE_DEBUG line to enable debug mode for this file.
// Or you may also globally enable debug by defining this macro
// in zigbee.def file or from compiler command-line.
#ifndef ENABLE_DEBUG
//#define ENABLE_DEBUG
#endif


#include <string.h>

#include "zigbee.h"
#include "Tick.h"

#include "Debug.h"
#include "zMAC.h"
#include "zPHY.h"

#include "sralloc.h"

#if defined(WIN32)
    #include "physim.h"
#endif

ZCODE zErrorCode;


// Association State Machine states.
typedef enum _SM_ASSOCIATION
{
    SM_SEND_ASSOCIATE_REQ,
    SM_WAIT_FOR_TX_COMPLETE,
    SM_WAIT_FOR_ACK,
    SM_SEND_DATA_REQ,
    SM_DATA_REQ_ACK_WAIT,
    SM_WAIT_FOR_ASSOC_RESP,
    SM_SEND_DISASSOCIATE_REQ,
    SM_SEND_ORPHAN_NOTICE,
    SM_WAIT_FOR_COORD_ALIGNMENT
} SM_ASSOCIATION;

#if defined(I_AM_END_DEVICE)
static SM_ASSOCIATION   smAssociation;


// Running count of transmit retries used to association/disassociation
BYTE                    macFrameRetryCount;
#endif

// MAC Module state info.
MAC_STATE               macState;

// Potential coordinator description - used when Associate process is started.
PAN_DESC                PANDesc;

// Number of coordinators found operating in radius.
BYTE                    PANDescCount;

// Current channel of operation.
BYTE                    macCurrentChannel;

// Running counter of MAC frame DSN.
BYTE                    macDSN;

BYTE                    lastMACDSN;

// Length of transmit packet that is being current loaded.
BYTE                    macPacketLen;

// MAC address info.
NODE_INFO               macInfo;

// Coordinator address info.
NODE_INFO               macCoordInfo;

// RF channel energy as of last energy scan.
BYTE                    macCurrentEnergy;

// Current MAC frame header.
MAC_FRAME               macCurrentFrame;


// Array of recently transmitted frames that are yet to be acknowledged
// by remote nodes.
MAC_FRAME_STATUS        macFrameStatusQ[MAX_MAC_FRAME_STATUS];
BYTE                    macFrameStatusQLen;

// Tick value used to calculate timeout conditions.
TICK                    macStartTick;

// Handle to a frame - used by many command state machines
HFRAME                  hFrame;


// This is the frame that we will be operating on next call to MACTask().
// This was done to reduce total time taken by MACTask().
// As per the logic, MACTask() needs to go through all of frames
// in queue and do timeout and retry operations. To reduce total time
// taken by MACTask(), the logic is modified to operate on one frame
// at a time.
// This variable keepds track of frame that needs to be operated
// on next call.
BYTE                    currentQueueItem;


// Only coordinator will process orphan notice.
#if defined(I_AM_COORDINATOR)
// A orphan notice is said to be valid if there is no data bytes in addition to
// the command identifier itself.
#define MACProcessOrphanNotice()        (macCurrentFrame.frameLength == 0)
#endif

// To be removed - TBD
#if !defined(WIN32)
    #define IsThisExpectedSeq(a)    (a == lastMACDSN)
#else
    #define IsThisExpectedSeq(a)    (1)
#endif


#if defined(MAC_USE_TX_INDIRECT_BUFFER)
// MAC_USE_TX_INDIRECT_BUFFER is used by coordinator only to hold outgoing (indirect) frames until
// remote end device request it.

    #define TX_INDIRECT_BUFFERS         (6)
    #define INVALID_INDIRECT_BUFFER     (0xFF)

    typedef struct
    {
        unsigned char *pBuffer;         // Pointer to dynamically allocated TX buffer

        struct                          // Flags about current frame.
        {
            unsigned int hFrame:7;
            unsigned int bIsSent:1;
            unsigned int bIsInUse:1;
        } Flags;

        BYTE frameDSN;                  // DSN assigned to this frame.
        SHORT_ADDR destShortAddr;       // Destination that it is addressed to.
        TICK lastTick;                  // Tick to calculate timeout condition.
    } TX_INDIRECT_BUFFER;

    // Array to hold individual tx indirect buffer entries.
    TX_INDIRECT_BUFFER txIndirectBuffer[TX_INDIRECT_BUFFERS];

    // Private table to keep track of the order in which the
    // txIndirectBuffer[] array is filled (and needs to be
    // retransmitted)
    BYTE OrderingTable[TX_INDIRECT_BUFFERS];

    // Private pointer to access current tx indirect buffer.
    BYTE currentTxIndirectBuffer;
    BYTE *pCurrentTxIndirectData;

    static void CompressOrderingTable(void);
    static void ProcessTxIndirectBuffer(void);
    static BOOL MACProcessDataReq(void);
    static void _MACIndirectTransmit(TX_INDIRECT_BUFFER *pIndirectTxBuffer);
#endif

// When tx indirect buffer is used, tx data can be placed in indirect buffer
// as required by higher level.
#if defined(MAC_USE_TX_INDIRECT_BUFFER)
    #define PHYBeginTxFIFOAccess()              \
        if ( !macState.bits.bUseTxRAM )         \
        {                                       \
            PHYBegin();                         \
            PHYSelectTxFIFO();                  \
        }

    #define PHYEndTxFIFOAccess()                \
        if ( !macState.bits.bUseTxRAM)          \
            PHYEnd()

    #define PHYPutTxData(v)                     \
        if ( !macState.bits.bUseTxRAM )         \
            { PHYPut(v);}                       \
        else                                    \
            { *pCurrentTxIndirectData++ =(v); }

#else
    #define PHYBeginTxFIFOAccess()      { PHYBegin(); PHYSelectTxFIFO(); }
    #define PHYEndTxFIFOAccess()        PHYEnd()
    #define PHYPutTxData(v)             PHYPut(v)
#endif

static HFRAME   AddDSNInQueue(BYTE dsn);
static void     UpdateQueue(BYTE dsn);
static BOOL     MACGetHeader(void);
static void     MACSendAck(void);
static void     TransmitIt(void);

#if defined(I_AM_COORDINATOR)
    static void     MACSendBeacon(void);
#endif

static void     MACSendBeaconReq(void);
static BOOL     MACProcessBeacon(void);


#if defined(WIN32)
    #define _MACIsGetReady()    PHYSimIsGetReady()
#else
    #define _MACIsGetReady()    PHYIsGetReady()
#endif



/*********************************************************************
 * Function:        void MACInit(void)
 *
 * PreCondition:    macInfo.longAddr must be initialized with
 *                  desired MAC address.
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Initializes data variables used by MAC module.
 *
 * Note:            None
 ********************************************************************/
void MACInit(void)
{
    // If tx indirect buffer is used, initialize the buffer array.
#if defined(MAC_USE_TX_INDIRECT_BUFFER)
    memset((void*)txIndirectBuffer, 0x00, sizeof(txIndirectBuffer));
    memset((void*)OrderingTable, INVALID_INDIRECT_BUFFER, sizeof(OrderingTable));

    SRAMInitHeap();

#endif

    // Also initialize frame DSN queue buffer.
    memset((void*)macFrameStatusQ, 0x00, sizeof(macFrameStatusQ));
    macFrameStatusQLen = 0;


    // Clear all mac state flags.
    macCurrentFrame.Flags.Val = 0x00;
    macState.Val = 0x00;

    // On start, there is no short address.
    MACSetShortAddrLSB(0xff);
    MACSetShortAddrMSB(0xff);

    // By default, PAN is assumed to be not assigned.
    MACSetPANIdLSB(0xff);
    MACSetPANIdMSB(0xff);

    // On next call to MACTask() operate on very first item.
    currentQueueItem = 0;

}

/*********************************************************************
 * Function:        void MACEnable(void)
 *
 * PreCondition:    macInfo.longAddr must be initialized with
 *                  desired MAC address.
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Enables PHY regulator and registers.
 *
 * Note:            None
 ********************************************************************/
void MACEnable(void)
{
    // Power up the PHY's internal regulator
    PHYEnable();

    // Initialize the PHY's registers/wait for it's oscillator to
    // become stable.  In the event the PHY malfunctions for too long
    // the watchdog timer will cause a reset to occur here.
    while( !PHYInit() );

    MACUpdateAddressInfo();

    PHYSetChannel(PHYGetChannel());

    macState.bits.bIsEnabled = TRUE;
}



/*********************************************************************
 * Function:        void MACISR(void)
 *
 * PreCondition:    MACInit() is previously called.
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Determines if a frame has completed transmission
 *                  or not.
 *
 * Note:            None
 ********************************************************************/
void MACISR(void)
{
    // SFD is tied to INT2.
    // When SFD goes low, it may mean that either a message was received or
    // transmission was complete. If we had pending message to transmit,
    // SFD going low would indicate that transmission is complete.
    if ( INT2IF )
    {
        if ( macState.bits.bIsTxBusy )
            macState.bits.bIsTxBusy = FALSE;

        INT2IF = 0;
    }


}


/*********************************************************************
 * Function:        BYTE MACGetArray(BYTE *b, BYTE len)
 *
 * PreCondition:    MACIsGetReady() == TRUE
 *
 * Input:           b       - Buffer to hold the data
 *                  len     - Number of bytes to get
 *
 * Output:          Number of bytes actually read.
 *
 * Side Effects:    None
 *
 * Overview:        Reads RF RX buffer until given len bytes are
 *                  are read or buffer is empty.
 *
 * Note:            Actual number of bytes read may be less than
 *                  asked. Caller must make sure that
 *                  RX buffer contains desired number of bytes.
 ********************************************************************/
BYTE MACGetArray(BYTE *b, BYTE len)
{
    BYTE count;

    // Counts actual number of bytes read.
    count = 0;

    // Being PHY RX buffer access.
    PHYBegin();
    PHYSelectRxFIFO();

    // Read one byte-at-a-time and update
    // remained bytes and read bytes.
    while( macCurrentFrame.frameLength && len )
    {
        len--;
        macCurrentFrame.frameLength--;

        *b = PHYGetMac();

        b++;
        count++;
    }

    PHYEnd();

    // Return actual bytes read.
    return count;
}


/*********************************************************************
 * Function:        BYTE MACGet(void)
 *
 * PreCondition:    MACIsGetReady() == TRUE
 *
 * Input:           None
 *
 * Output:          Byte that was read
 *
 * Side Effects:    None
 *
 * Overview:        Retrives one bytes from RF RX buffer.
 *
 * Note:            Caller must make sure that RX buffer contains
 *                  at least one byte calling MACIsGetReady()
 ********************************************************************/

⌨️ 快捷键说明

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