📄 zmac.c
字号:
* FALSE otherwise.
*
* Side Effects: None
*
* Overview: Checks to see a beacon was received and if it is,
* it processes it.
*
* Note: None
********************************************************************/
BOOL MACIsScanComplete(void)
{
BOOL result = FALSE;
if ( MACIsGetReady() )
{
if ( MACIsBeacon() )
{
ConsolePutString("receive Beacon\n");
if ( MACProcessBeacon() )
{
result = TRUE;
}
}
MACDiscardRx();
}
else if ( TickGetDiff(TickGet(), macStartTick) >= MAC_ACTIVE_SCAN_PERIOD )
result = TRUE;
return result;
}
/*********************************************************************
* Function: static BOOL MACProcessBeacon(void)
*
* PreCondition: MACGetHeader() is called and a valid beacon
* frame was detected.
*
* Input: None
*
* Output: TRUE if this is a valid beacon frame
* FALSE otherwise.
*
* Side Effects: None
*
* Overview: Fetches rest of the frame and validates it as per
* IEEE spec.
*
* Note: None
********************************************************************/
static BOOL MACProcessBeacon(void)
{
BOOL lbResult;
lbResult = FALSE;
// There must be at least 4 bytes in MAC payload.
if( macCurrentFrame.frameLength >= 4 )
{
// Clear PAN Desc flags.
PANDesc.Flags.Val = 0x00;
//du 当前版本存贮short address(不一定真正coord)
if ( macCurrentFrame.src.addrMode == MAC_SRC_LONG_ADDR )
{
PANDesc.Flags.bits.CoordAddrMode = 1;
PANDesc.CoordAddress.longAddr.v[0] = macCurrentFrame.src.longAddr.v[0];
PANDesc.CoordAddress.longAddr.v[1] = macCurrentFrame.src.longAddr.v[1];
PANDesc.CoordAddress.longAddr.v[2] = macCurrentFrame.src.longAddr.v[2];
PANDesc.CoordAddress.longAddr.v[3] = macCurrentFrame.src.longAddr.v[3];
PANDesc.CoordAddress.longAddr.v[4] = macCurrentFrame.src.longAddr.v[4];
PANDesc.CoordAddress.longAddr.v[5] = macCurrentFrame.src.longAddr.v[5];
PANDesc.CoordAddress.longAddr.v[6] = macCurrentFrame.src.longAddr.v[6];
PANDesc.CoordAddress.longAddr.v[7] = macCurrentFrame.src.longAddr.v[7];
}
else
{
PANDesc.CoordAddress.shortAddr.Val = macCurrentFrame.src.shortAddr.Val;
}
PANDesc.CoordPANId.Val = macCurrentFrame.src.panID.Val;
PANDesc.LogicalChannel = macCurrentChannel;
// Now fetch data from Beacon frame and save it to PANDesc.
PANDesc.SuperFrameSpec.byte.LSB = MACGet();
PANDesc.SuperFrameSpec.byte.MSB = MACGet();
PANDesc.TimeStamp.Val = TickGet();
// per TABLE 41 NWK spec.
PANDesc.ACLEntry = 0x08;
// To be added - process GTS fields, Pending address fields and beacon payload.
PANDescCount++;
lbResult = TRUE;
}
return lbResult;
}
/*********************************************************************
* Function: void MACStartED(void)
*
* PreCondition: MACGetHeader() is called and a valid beacon
* frame was detected.
*
* Input: None
*
* Output: TRUE if this is a valid beacon frame
* FALSE otherwise.
*
* Side Effects: None
*
* Overview: Fetches rest of the frame and validates it as per
* IEEE spec.
*
* Note: None
********************************************************************/
void MACStartED(void)
{
macStartTick = TickGet();
PHYSetTRXState(PHY_TRX_RX_ON);
}
/*********************************************************************
* Function: BOOL MACIsEDComplete(void)
*
* PreCondition: MACStartED() is called
*
* Input: None
*
* Output: TRUE if this Energy detect is complete
* FALSE otherwise.
*
* Side Effects: None
*
* Overview: Simply determines if predefined time has passed or
* not.
*
* Note: None
********************************************************************/
BOOL MACIsEDComplete(void)
{
return ( TickGetDiff(TickGet(), macStartTick) >= MAC_ED_SCAN_PERIOD );
}
/*********************************************************************
* Function: void MACDiscardRx(void)
*
* PreCondition: MACIsGetReady() = TRUE
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Fetches remaining data bytes for current received
* frame.
*
* Note: None
********************************************************************/
void MACDiscardRx(void)
{
// Account for CRC/(RSSI + CORRELATION for CC2420)
macCurrentFrame.frameLength += 2;
if ( macCurrentFrame.frameLength != 2 )
macCurrentFrame.frameLength = macCurrentFrame.frameLength;
while( macCurrentFrame.frameLength )
{
MACGet();
}
// Mark this frame as empty (macCurrentFrame.Flags.bits.bIsGetReady = FALSE)
macCurrentFrame.Flags.Val = 0x00;
}
/*********************************************************************
* Function: void MACUpdateAddressInfo(void)
*
* PreCondition: MACEnable() is called
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Writes our MAC address, PAN ID and short address
* transciever configuration RAM.
*
* Note: None
********************************************************************/
void MACUpdateAddressInfo(void)
{
PHYBegin();
PHYSelectIEEEAddrWrite();
PHYPut(macInfo.longAddr.v[0]);
PHYPut(macInfo.longAddr.v[1]);
PHYPut(macInfo.longAddr.v[2]);
PHYPut(macInfo.longAddr.v[3]);
PHYPut(macInfo.longAddr.v[4]);
PHYPut(macInfo.longAddr.v[5]);
PHYPut(macInfo.longAddr.v[6]);
PHYPut(macInfo.longAddr.v[7]);
PHYEnd();
PHYBegin();
PHYSelectPANAddrWrite();
PHYPut(macInfo.panID.byte.LSB);
PHYPut(macInfo.panID.byte.MSB);
PHYEnd();
PHYBegin();
PHYSelectShortAddrWrite();
PHYPut(macInfo.shortAddr.byte.LSB);
PHYPut(macInfo.shortAddr.byte.MSB);
PHYEnd();
}
/*********************************************************************
* Function: static HFRAME AddDSNInQueue(BYTE dsn)
*
* PreCondition: MACInit() is called
*
* Input: dsn - Data Sequence Number
*
* Output: index to queue where given dsn was stored.
* HFRAME_INVALID if queue is full.
*
* Side Effects: None
*
* Overview: Searches DSN queue for empty entry and places given
* dsn into that entry.
*
* Note: None
********************************************************************/
static HFRAME AddDSNInQueue(BYTE dsn)
{
BYTE i;
MAC_FRAME_STATUS *pMACFrameStatus;
pMACFrameStatus = macFrameStatusQ;
for ( i = 0; i < sizeof(macFrameStatusQ)/sizeof(macFrameStatusQ[0]); i++ )
{
if ( !pMACFrameStatus->Flags.bits.bIsInUse )
{
pMACFrameStatus->Flags.bits.bIsInUse = TRUE;
pMACFrameStatus->Flags.bits.bIsConfirmed = FALSE;
pMACFrameStatus->macDSN = dsn;
pMACFrameStatus->lastTick = TickGet();
pMACFrameStatus->retryCount = MAC_MAX_FRAME_RETRIES;
macFrameStatusQLen++;
ConsolePut(i+48);
ConsolePutString("MAC: Added one frame to queue.\r\n");
return (HFRAME)i;
}
else
{
pMACFrameStatus++;
}
}
ConsolePutString("MAC:not added one frame to queue\n");
return HFRAME_INVALID;
}
/*********************************************************************
* Function: void MACFrameRemove(HFRAME h)
*
* PreCondition: MACPutHeader() is called
*
* Input: h - Handle to frame that is to be removed
* from DSN queue
*
* Output: None
*
* Side Effects: None
*
* Overview: Sets given DSN queue entry to free.
*
* Note: None
********************************************************************/
void MACFrameRemove(HFRAME h)
{
if ( macFrameStatusQ[h].Flags.bits.bIsInUse )
{
macFrameStatusQ[h].Flags.Val = 0x00;
macFrameStatusQLen--;
ConsolePut(h+48);
ConsolePutString("MAC: Removed one frame from queue.\r\n");
}
}
/*********************************************************************
* Function: BOOL MACFrameIsAcked(HFRAME h)
*
* PreCondition: MACPutHeader() is called
*
* Input: h - Handle to frame whose ack state
* is to be determined
*
* Output: None
*
* Side Effects: None
*
* Overview: Peeks into DSN queue and checks to see if
* dsn associated with this frame was ack'ed.
*
* Note: None
********************************************************************/
//TODO(DF13): possible code reduction (minor)
BOOL MACFrameIsAcked(HFRAME h)
{
BOOL result;
ConsolePut(h+48);
// If given frame does not exist in queue, it is said to be ack'ed.
if ( h == HFRAME_INVALID )
{
ConsolePutString("invalid hfame\n");
return FALSE;
}
// Save the ack result.
if ( macFrameStatusQ[h].Flags.bits.bIsInUse )
{
result = macFrameStatusQ[h].Flags.bits.bIsConfirmed;
if (result)
ConsolePutString("frame is confirmed\n");
else
ConsolePutString("frame is not confirmed\n");
}
else
{
ConsolePutString("frame is not in use\n");
result = FALSE;
}
return result;
}
/*********************************************************************
* Function: void MACPutHeader(NODE_INFO *dest, BYTE frameCON)
*
* PreCondition: MACIsPutReady() = TRUE
*
* Input: dest - Destination node info
* frameCON - Frame control for frame header
* Logical AND of
* "Frame Control flags" as defined
* in zMAC.h
*
* Output: None
*
* Side Effects: None
*
* Overview: Constructs and loads frame header as per
* IEEE spec.
* If frame requires ack, it makes an entry into
* DSN queue so that future ack can be matched
* against this frame.
*
* Note: None
********************************************************************/
void MACPutHeader(NODE_INFO *dest, BYTE frameCON)
{
BYTE destAddrMode;
BYTE srcAddrMode;
BYTE frameCONMSB;
// If ack is requested, remember the DSN so that we can match
// ack with right frame.
if ( frameCON & MAC_ACK_YES )
{
macCurrentFrame.Flags.bits.bToBeQueued = TRUE;
}
else
{
macCurrentFrame.Flags.bits.bToBeQueued = FALSE;
}
PHYBegin();
// Clear TXFIFO
PHYFlushTx();
PHYEnd();
ConsolePut(0x01);
ConsolePut(0x02);
ConsolePut(0x03);
ConsolePut(0x04);
ConsolePut(0x05);
// Now start writing packet header - actual write will be to either
// RF chip buffer or RAM tx indirect buffer.
PHYBeginTxFIFOAccess();
// Write length byte
PHYPutTxData(0x00);
// Extract and save src and dest address mode quick access
//#if defined(WIN32)
if ( (frameCON & MAC_FRAME_TYPE_MASK) != MAC_FRAME_ACK)
{
destAddrMode = dest->addrMode;
srcAddrMode = macInfo.addrMode;
}
else
{
destAddrMode = 0x00;
srcAddrMode = 0x00;
}
// Create Frame CON MSB.
frameCONMSB = destAddrMode | srcAddrMode;
// Put frame control LSB
PHYPutTxData(frameCON);
ConsolePut(frameCON);
// Now MSB
PHYPutTxData(frameCONMSB);
ConsolePut(frameCONMSB);
// Sequence number
if ( (frameCON & MAC_FRAME_TYPE_MASK) == MAC_FRAME_ACK )
{
PHYPutTxData(macCurrentFrame.macDSN);ConsolePut(macCurrentFrame.macDSN);
}
else
{
// For every non-ACK type frame, we will increment
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -