📄 zmac_receive.c
字号:
//每收到一帧的数据,往串口发送
/*********************************************************************
*
* 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 + -