📄 mac.c
字号:
#include <mega128.h>
#include <spi.h>
#include <delay.h>
#include <string.h>
#include "CC2420.h"
#include "mac.h"
#include "phy.h"
#include "compiler.h"
#include "mcu.h"
#include "config.h"
// The RF settings structure is declared here, since we'll always need halRfInit()
volatile CC2420_SETTINGS rfSettings;
// Basic RF transmission and reception structures
CC2420_RX_INFO rfRxInfo;
CC2420_TX_INFO rfTxInfo;
unsigned char pTxBuffer[CC2420_MAX_PAYLOAD_SIZE];
unsigned char pRxBuffer[CC2420_MAX_PAYLOAD_SIZE];
unsigned char flag_ReceiveComplete;
/***********************************************************************************************
* 设置信道函数
* channel_temp 取值11~26
************************************************************************************************/
void CC2420_SetChannel(unsigned char channel_temp)
{
WriteConfigReg_spi(CC2420_FSCTRL,(0x4165 | 357+5*(unsigned int)(channel_temp-11)));
}
/***********************************************************************************************
* 设置PANid函数
* PanId_temp
************************************************************************************************/
void CC2420_SetPanId(unsigned int PanId_temp)
{
unsigned char PanIdtemp[2];
PanIdtemp[1] = (PanId_temp >> 8);
PanIdtemp[0] = (PanId_temp & 0x00FF);
WriteRAM_spi(CC2420_RAM_PANID,PanIdtemp,2);
}
/***********************************************************************************************
* 设置ShortAddress函数
* ShortAddress
************************************************************************************************/
void CC2420_SetShortAddress(unsigned int ShortAddress)
{
unsigned char ShortAddresstemp[2];
ShortAddresstemp[1] = (ShortAddress >> 8);
ShortAddresstemp[0] = (ShortAddress & 0x00FF);
WriteRAM_spi(CC2420_RAM_SHORTADDR,ShortAddresstemp,2);
}
/***********************************************************************************************
* 设置IEEEAddress函数
************************************************************************************************/
void CC2420_SetIEEEAddr(void)
{
unsigned char IEEE[8]={IEEEADDR0,IEEEADDR1,IEEEADDR2,IEEEADDR3,IEEEADDR4,IEEEADDR5,IEEEADDR6,IEEEADDR7};
IEEE[7] = PINC;
WriteRAM_spi(CC2420_RAM_IEEEADDR,IEEE,8);
}
/***********************************************************************************************
* 读取CC2420的64bit IEEE地址函数
* 返回一个指向IEEE地址的指针
************************************************************************************************/
unsigned char* CC2420_ReadIEEEAddr(void)
{
unsigned char i;
unsigned char IEEE[8];
SPI_ENABLE(); // 使能 CSn
ReadRAM(CC2420_RAM_IEEEADDR);
for(i=0;i<8;i++)
{
IEEE[i]=spi(0x00);
}
SPI_DISABLE();
return IEEE;
}
/***********************************************************************************************
* 打开接收函数
************************************************************************************************/
void CC2420_ReceiveOn(void)
{
unsigned char i;
rfSettings.receiveOn = TRUE;
i=WriteStrobeReg_spi(CC2420_SRXON);
i=WriteStrobeReg_spi(CC2420_SFLUSHRX);
i=WriteStrobeReg_spi(CC2420_SFLUSHRX);
FIFOP_INT_INIT();
ENABLE_FIFOP_INT();
}
/***********************************************************************************************
* 关闭接收函数
************************************************************************************************/
void CC2420_ReceiveOff(void)
{
unsigned char i;
rfSettings.receiveOn = FALSE;
i=WriteStrobeReg_spi(CC2420_SRFOFF);
DISABLE_FIFOP_INT();
}
/***********************************************************************************************
* CC2420初始化函数
************************************************************************************************/
void CC2420_Init()
{
unsigned char i;
// Make sure that the voltage regulator is on, and that the reset pin is inactive
SET_VREG_ACTIVE();
delay_ms(10);
SET_RESET_ACTIVE();
delay_ms(50);
SET_RESET_INACTIVE();
delay_ms(10);
// Turn off all interrupts while we're accessing the CC2420 registers
DISABLE_GLOBAL_INT();
// Register modifications
i = WriteStrobeReg_spi(CC2420_SXOSCON);
i = WriteConfigReg_spi(CC2420_MDMCTRL0, 0x0AE2); // Turn off automatic packet acknowledgment
i = WriteConfigReg_spi(CC2420_MDMCTRL1, 0x0500); // Set the correlation threshold = 20
i = WriteConfigReg_spi(CC2420_IOCFG0, 0x007F); // Set the FIFOP threshold to maximum
i = WriteConfigReg_spi(CC2420_SECCTRL0, 0x01C4); // Turn off "Security enable"
// Wait for the crystal oscillator to become stable
do
{
i = WriteStrobeReg_spi(CC2420_SXOSCON); // 开启晶体振荡
delay_ms(100);
}
while((i&0x40)==0);
}
/***********************************************************************************************
* CC2420发送函数
* pRTI : 发送数据结构体指针
* 成功返回1,失败返回0
************************************************************************************************/
unsigned char CC2420_SendPacket(CC2420_TX_INFO *pRTI,unsigned char AddrFormat)
{
unsigned int frameControlField;
unsigned char packetLength;
unsigned char success;
unsigned char SendDataTemp[CC2420_MAX]={''};
unsigned char i;
// Wait until the transceiver is idle
while (FIFOP_IS_1 || SFD_IS_1);
// Turn off global interrupts to avoid interference on the SPI interface
DISABLE_GLOBAL_INT();
// Flush the TX FIFO just in case...
WriteStrobeReg_spi(CC2420_SFLUSHTX);
// Write the packet to the TX FIFO (the FCS is appended automatically when AUTOCRC is enabled)
switch (AddrFormat)
{
case 0x01:
{
packetLength = pRTI->length + CC2420_PACKET_OVERHEAD_SIZE_DsSs;
frameControlField = CC2420_FCF_FRAMETYPE_DATA;
frameControlField |= pRTI->ackRequest ? CC2420_FCF_ACK_REQUEST : CC2420_FCF_NO_ACK_REQUEST;
frameControlField |= CC2420_FCF_INTRAPAN;
frameControlField |= CC2420_FCF_DESTADDR_16BIT;
frameControlField |= CC2420_FCF_SOURCEADDR_16BIT;
SendDataTemp[0] = packetLength; // Packet length
SendDataTemp[1] = frameControlField & 0x00FF; // Frame control field
SendDataTemp[2] = frameControlField >> 8;
SendDataTemp[3] = rfSettings.txSeqNumber; // Sequence number
SendDataTemp[4] = rfSettings.panId & 0x00FF;
SendDataTemp[5] = rfSettings.panId >> 8; // Dest. PAN ID
SendDataTemp[6] = pRTI->destAddr & 0x00FF; // Dest. address
SendDataTemp[7] = pRTI->destAddr >> 8;
SendDataTemp[8] = rfSettings.myAddr & 0x00FF; // Source address
SendDataTemp[9] = rfSettings.myAddr >> 8;
for(i=0;i<pRTI->length;i++) // Payload
{
SendDataTemp[i+10] = *pRTI->pPayload++;
}
Write_TXFIFO( SendDataTemp, packetLength+1 );
break;
}
case 0x02:
{
packetLength = pRTI->length + CC2420_PACKET_OVERHEAD_SIZE_DsSl;
frameControlField = CC2420_FCF_FRAMETYPE_DATA;
frameControlField |= pRTI->ackRequest ? CC2420_FCF_ACK_REQUEST : CC2420_FCF_NO_ACK_REQUEST;
frameControlField |= CC2420_FCF_INTRAPAN;
frameControlField |= CC2420_FCF_DESTADDR_16BIT;
frameControlField |= CC2420_FCF_SOURCEADDR_64BIT;
SendDataTemp[0] = packetLength; // Packet length
SendDataTemp[1] = frameControlField & 0x00FF; // Frame control field
SendDataTemp[2] = frameControlField >> 8;
SendDataTemp[3] = rfSettings.txSeqNumber; // Sequence number
SendDataTemp[4] = rfSettings.panId & 0x00FF; // Dest. PAN ID
SendDataTemp[5] = rfSettings.panId >> 8;
SendDataTemp[6] = pRTI->destAddr & 0x00FF; // Dest. address
SendDataTemp[7] = pRTI->destAddr >> 8;
for(i=0;i<8;i++) // Source address
{
SendDataTemp[i+8] = rfSettings.myIEEE[i];
}
for(i=0;i<pRTI->length;i++) // Payload
{
SendDataTemp[i+16] = *pRTI->pPayload++;
}
Write_TXFIFO( SendDataTemp, packetLength+1 );
break;
}
case 0x03:
{
packetLength = pRTI->length + CC2420_PACKET_OVERHEAD_SIZE_DlSs;
frameControlField = CC2420_FCF_FRAMETYPE_DATA;
frameControlField |= pRTI->ackRequest ? CC2420_FCF_ACK_REQUEST : CC2420_FCF_NO_ACK_REQUEST;
frameControlField |= CC2420_FCF_INTRAPAN;
frameControlField |= CC2420_FCF_DESTADDR_64BIT;
frameControlField |= CC2420_FCF_SOURCEADDR_16BIT;
SendDataTemp[0] = packetLength; // Packet length
SendDataTemp[1] = frameControlField & 0x00FF; // Frame control field
SendDataTemp[2] = frameControlField >> 8;
SendDataTemp[3] = rfSettings.txSeqNumber; // Sequence number
SendDataTemp[4] = rfSettings.panId & 0x00FF; // Dest. PAN ID
SendDataTemp[5] = rfSettings.panId >> 8;
for(i=0;i<8;i++) // Dest. address
{
SendDataTemp[i+6] = pRTI->destIEEE[i];
}
SendDataTemp[14] = rfSettings.myAddr & 0x00FF; // Source address
SendDataTemp[15] = rfSettings.myAddr >> 8;
for(i=0;i<pRTI->length;i++) // Payload
{
SendDataTemp[i+16] = *pRTI->pPayload++;
}
Write_TXFIFO( SendDataTemp, packetLength+1 );
break;
}
default:
break;
}
SPI_ENABLE(); // 使能 CSn
WriteStrobeReg(CC2420_STXON);
while (!SFD_IS_1);
while (SFD_IS_1);
SPI_DISABLE(); // 禁止 CSn
// Turn interrupts back on
ENABLE_GLOBAL_INT();
// Wait for the acknowledge to be received, if any
if (pRTI->ackRequest)
{
rfSettings.ackReceived = FALSE;
// We'll enter RX automatically, so just wait until we can be sure that the ack reception should have finished
// The timeout consists of a 12-symbol turnaround time, the ack packet duration, and a small margin
delay_ms((12 * CC2420_SYMBOL_DURATION) + (CC2420_ACK_DURATION) + (2 * CC2420_SYMBOL_DURATION) + 100);
// If an acknowledgment has been received (by the FIFOP interrupt), the ackReceived flag should be set
success = rfSettings.ackReceived;
}
else
{
success = TRUE;
}
// Increment the sequence number, and return the result
rfSettings.txSeqNumber++;
// Turn on RX mode
CC2420_ReceiveOn();
// 清空发送缓冲区
pRTI->pPayload = pTxBuffer;
memset(pRTI->pPayload,'',CC2420_MAX_PAYLOAD_SIZE);
return success;
}
void MAC_Init(void)
{
unsigned char *ieeeAddr;
unsigned char i;
PHY_Init();
delay_ms(200);
CC2420_Init(); // CC2420初始化
rfTxInfo.pPayload = pTxBuffer;
rfRxInfo.pPayload = pRxBuffer;
// Set the RF channel
CC2420_SetChannel(CHANNEL);
// Set the protocol configuration
rfSettings.pRxInfo = &rfRxInfo;
rfSettings.panId = PANID;
if(I_Am_What == COORDINATOR)
rfSettings.myAddr = COORDINATOR_ADDR;
CC2420_SetIEEEAddr();
ieeeAddr = CC2420_ReadIEEEAddr();
for(i=0;i<8;i++)
{
rfSettings.myIEEE[i] = *ieeeAddr++;
}
rfSettings.txSeqNumber = 0;
rfSettings.receiveOn = FALSE;
// Write the short address and the PAN ID to the CC2420 RAM (requires that the XOSC is on and stable)
CC2420_SetPanId(PANID); // 设置PANid
if(I_Am_What == COORDINATOR)
CC2420_SetShortAddress(COORDINATOR_ADDR); // 设置节点短地址
// Initialize the FIFOP external interrupt
FIFOP_INT_INIT();
ENABLE_FIFOP_INT();
// 开全局中断
ENABLE_GLOBAL_INT();
// Turn on RX mode
CC2420_ReceiveOn();
RLED_EN();
}
/***********************************************************************
* 清空MAC层发送缓冲区
************************************************************************/
void mac_pTxBuffer_Clear(void)
{
memset(pTxBuffer,'',CC2420_MAX_PAYLOAD_SIZE);
}
/***********************************************************************
* 清空MAC层接收缓冲区
************************************************************************/
void mac_pRxBuffer_Clear(void)
{
memset(pRxBuffer,'',CC2420_MAX_PAYLOAD_SIZE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -