ZigBee学习之6无线电2.docx
《ZigBee学习之6无线电2.docx》由会员分享,可在线阅读,更多相关《ZigBee学习之6无线电2.docx(29页珍藏版)》请在冰豆网上搜索。
ZigBee学习之6无线电2
#1楼主:
【原创】ZigBee学习之6——无线电2
文章发表于:
2010-02-0511:
17
今天把TI的例子程序里的基本RF看了下,有的地方还没有完全看懂,发上来和大家分享一下
/***********************************************************************************
Filename:
basic_rf.c
Description:
BasicRFlibrary
***********************************************************************************/
/***********************************************************************************
*INCLUDES
*/
//hal_int.h包含了控制中断的宏
#include"hal_int.h"
//UsinghalMcuWaitUs(),hal_mcu.h中是一些延时函数
#include"hal_mcu.h"
//通道编程的宏,以及硬件RF初始化,SECURITY_CCM宏是用来控制安全MAC的
#include"hal_rf.h"
#ifdefSECURITY_CCM
#include"hal_rf_security.h"
#endif
//basic_rf.h中定义了RF配置用的数据结构
#include"basic_rf.h"
#ifdefSECURITY_CCM
#include"basic_rf_security.h"
#endif
#include"util.h"//Usingmin()
#include"string.h"
/***********************************************************************************
*CONSTANTSANDDEFINES
*/
//Packetandpacketpartlengths
#definePKT_LEN_MIC8
#definePKT_LEN_SECPKT_LEN_UNSEC+PKT_LEN_MIC
#definePKT_LEN_AUTH8
#definePKT_LEN_ENCR24
//Packetoverhead((framecontrolfield,sequencenumber,PANID,
//destinationandsource)+(footer))
//Notethatthelengthbyteitselfisnotincludedincludedinthepacketlength
//MPDU的长度宏,(2字节幀控制域+1字节数据序列号+2字节PANID+2字节目标地址+2字节源地址+2字节MAC尾)
#defineBASIC_RF_PACKET_OVERHEAD_SIZE((2+1+2+2+2)+
(2))
//MPDU最大有效载荷的长度(利用FIFO只有128字节空间),BASIC_RF_AUX_HDR_LENGTH和BASIC_RF_LEN_MIC是辅助安全头宏定义的长度分别是5和8,可以将其设置为0,即不具备安全功能
#defineBASIC_RF_MAX_PAYLOAD_SIZE(127-BASIC_RF_PACKET_OVERHEAD_SIZE-\
BASIC_RF_AUX_HDR_LENGTH-BASIC_RF_LEN_MIC)
//应答帧的长度宏(2字节帧首界定符+1字节数据序列号+2字节帧校验序列),不包括帧长度域
#defineBASIC_RF_ACK_PACKET_SIZE5
//MAC帧尾的长度宏
#defineBASIC_RF_FOOTER_SIZE2
#defineBASIC_RF_HDR_SIZE10
//Thetimeittakesfortheacknowledgmentpackettobereceivedafterthe
//datapackethasbeentransmitted.
#defineBASIC_RF_ACK_DURATION(0.5*32*2*((4+1)+
(1)+(2+1)+
(2)))
#defineBASIC_RF_SYMBOL_DURATION(32*0.5)
//Thelengthbyte
#defineBASIC_RF_PLD_LEN_MASK0x7F
//帧控制域
//帧类型子域:
000信标帧
//001数据帧
//010应答帧
//011MAC命令
//100~110保留
//安全允许子域:
0帧无安全保护
//1帧采用安全保护
//帧待定子域:
0传输没有附加数据的帧
//1当前传输后有附加的数据要发送
//应答请求子域:
0不需要接收器发送应答帧
//1需要接收器发送应答帧
//内部PAN子域:
决定MAC帧是在内部还是在其他PAN之间发送
//0如果目的地址和源地址都存在帧将包括目标和源PAN标志域
//1如果目的地址和源地址都存在帧不包括源PAN标志域
//目的地址模式子域:
若为0,并且帧类型没有指定这是个应答帧或信标帧且源地址域非0,则暗含此帧发送到PAN协调器将其PAN标志作为源PAN标志域
//源地址模式子域:
若为0,且帧类型没有指定这是个应答帧或信标帧,目的地址不为0,则暗含此帧来自PAN协调器,用其PAN标志作为目的PAN标志域
//00PAN标志器且地址域未提交
//01保留
//10地址域包含16位的短地址
//11地址域包含64位的扩展地址
//Framecontrolfield
//16位短地址模式,数据帧,没有安全保护
#defineBASIC_RF_FCF_NOACK0x8841
#defineBASIC_RF_FCF_ACK0x8861
#defineBASIC_RF_FCF_ACK_BM0x0020
#defineBASIC_RF_FCF_BM(~BASIC_RF_FCF_ACK_BM)
#defineBASIC_RF_SEC_ENABLED_FCF_BM0x0008
//FramecontrolfieldLSB
#defineBASIC_RF_FCF_NOACK_LLO_UINT16(BASIC_RF_FCF_NOACK)
#defineBASIC_RF_FCF_ACK_LLO_UINT16(BASIC_RF_FCF_ACK)
#defineBASIC_RF_FCF_ACK_BM_LLO_UINT16(BASIC_RF_FCF_ACK_BM)
#defineBASIC_RF_FCF_BM_LLO_UINT16(BASIC_RF_FCF_BM)
#defineBASIC_RF_SEC_ENABLED_FCF_BM_LLO_UINT16(BASIC_RF_SEC_ENABLED_FCF_BM)
//AuxiliarySecurityheader
#defineBASIC_RF_AUX_HDR_LENGTH5
#defineBASIC_RF_LEN_AUTHBASIC_RF_PACKET_OVERHEAD_SIZE+\
BASIC_RF_AUX_HDR_LENGTH-BASIC_RF_FOOTER_SIZE
#defineBASIC_RF_SECURITY_M2
#defineBASIC_RF_LEN_MIC8
#ifdefSECURITY_CCM
#undefBASIC_RF_HDR_SIZE
#defineBASIC_RF_HDR_SIZE15
#endif
//Footer
#defineBASIC_RF_CRC_OK_BM0x80
/***********************************************************************************
*TYPEDEFS
*/
//Thereceivestruct
typedefstruct{
uint8seqNumber;
uint16srcAddr;
uint16srcPanId;
int8length;
uint8*pPayload;
uint8ackRequest;
int8rssi;
volatileuint8isReady;
uint8status;
}basicRfRxInfo_t;
//Txstate
typedefstruct{
uint8txSeqNumber;
volatileuint8ackReceived;
uint8receiveOn;
uint32frameCounter;
}basicRfTxState_t;
//兼容IEEE802.15.4的MHR(MAC头)(2字节帧控制+1字节数据序列号+0~20字节地址信息)
//BasicRFpacketheader(IEEE802.15.4)
typedefstruct{
uint8packetLength;
uint8fcf0;//FramecontrolfieldLSB
uint8fcf1;//FramecontrolfieldMSB
uint8seqNumber;
uint16panId;
uint16destAddr;
uint16srcAddr;
#ifdefSECURITY_CCM
uint8securityControl;
uint8frameCounter[4];
#endif
}basicRfPktHdr_t;
/***********************************************************************************
*LOCALVARIABLES
*/
staticbasicRfRxInfo_trxi={0xFF};//Makesuresequencenumbersare
staticbasicRfTxState_ttxState={0x00};//initialisedanddistinct.
staticbasicRfCfg_t*pConfig;
staticuint8txMpdu[BASIC_RF_MAX_PAYLOAD_SIZE+BASIC_RF_PACKET_OVERHEAD_SIZE+1];
staticuint8rxMpdu[128];
/***********************************************************************************
*GLOBALVARIABLES
*/
/***********************************************************************************
*LOCALFUNCTIONS
*/
/***********************************************************************************
*@fnbasicRfBuildHeader
*
*@briefBuildspacketheaderaccordingtoIEEE802.15.4frameformat
*
*@parambuffer-Pointertobuffertowritetheheader
*destAddr-destinationshortaddress
*payloadLength-lengthofhigherlayerpayload
*
*@returnuint8-lengthofheader
*/
//构造兼容IEEE802.15.4的帧头
staticuint8basicRfBuildHeader(uint8*buffer,uint16destAddr,uint8payloadLength)
{
//声明一个指向MAC帧头结构的指针
basicRfPktHdr_t*pHdr;
uint16fcf;
pHdr=(basicRfPktHdr_t*)buffer;
//payloadLength为有效载荷的长度,即要发送的数据的长度
//Populatepacketheader
pHdr->packetLength=payloadLength+BASIC_RF_PACKET_OVERHEAD_SIZE;
//pConfig为基本配置数据结构
/*typedefstruct{
uint16myAddr;
uint16panId;
uint8channel;
uint8ackRequest;
}basicRfCfg_t;
*/
//pHdr->frameControlField=pConfig->ackRequest?
BASIC_RF_FCF_ACK:
BASIC_RF_FCF_NOACK;
fcf=pConfig->ackRequest?
BASIC_RF_FCF_ACK:
BASIC_RF_FCF_NOACK;
//分别得到16位数的低8位和高8位
//#defineHI_UINT16(a)(((uint16)(a)>>8)&0xFF)
//#defineLO_UINT16(a)((uint16)(a)&0xFF)
pHdr->fcf0=LO_UINT16(fcf);
pHdr->fcf1=HI_UINT16(fcf);
//得到数据序列
pHdr->seqNumber=txState.txSeqNumber;
pHdr->panId=pConfig->panId;
pHdr->destAddr=destAddr;
pHdr->srcAddr=pConfig->myAddr;
#ifdefSECURITY_CCM
//AddsecuritytoFCF,lengthandsecurityheader
pHdr->fcf0|=BASIC_RF_SEC_ENABLED_FCF_BM_L;
pHdr->packetLength+=PKT_LEN_MIC;
pHdr->packetLength+=BASIC_RF_AUX_HDR_LENGTH;
pHdr->securityControl=SECURITY_CONTROL;
pHdr->frameCounter[0]=LO_UINT16(LO_UINT32(txState.frameCounter));
pHdr->frameCounter[1]=HI_UINT16(LO_UINT32(txState.frameCounter));
pHdr->frameCounter[2]=LO_UINT16(HI_UINT32(txState.frameCounter));
pHdr->frameCounter[3]=HI_UINT16(HI_UINT32(txState.frameCounter));
#endif
//Makesurebytefieldsarenetworkbyteorder
//这里把大的字节放到了前面,但有不是完全按从大到小的顺序排列字节,不知道为什么?
UINT16_HTON(pHdr->panId);
UINT16_HTON(pHdr->destAddr);
UINT16_HTON(pHdr->srcAddr);
//1字节长度,2字节FCF,1字节序列,2字节PanID,2字节目的地址,2字节源地址=10
returnBASIC_RF_HDR_SIZE;
}
/***********************************************************************************
*@fnbasicRfBuildMpdu
*
*@briefBuildsmpdu(MACheader+payload)accordingtoIEEE802.15.4
*frameformat
*
*@paramdestAddr-Destinationshortaddress
*pPayload-pointertobufferwithpayload
*payloadLength-lengthofpayloadbuffer
*
*@returnuint8-lengthofmpdu
*/
//构造MPDU
staticuint8basicRfBuildMpdu(uint16destAddr,uint8*pPayload,uint8payloadLength)
{
uint8hdrLength,n;
//txMpdu是定义txMpdu[BASIC_RF_MAX_PAYLOAD_SIZE+BASIC_RF_PACKET_OVERHEAD_SIZE+1]
hdrLength=basicRfBuildHeader(txMpdu,destAddr,payloadLength);
//将有效载荷数据放入MPDU单元中
for(n=0;n{
txMpdu[hdrLength+n]=pPayload[n];
}
returnhdrLength+payloadLength;//totalmpdulength
}
/***********************************************************************************
*@fnbasicRfRxFrmDoneIsr
*
*@briefInterruptserviceroutineforreceivedframefromradio
*(eitherdataoracknowlegdement)
*
*@paramrxi-filescopevariableinfoextractedfromthelastincoming
*frame
*txState-filescopevariablethatkeepstxstateinfo
*
*@returnnone
*/
//接收中断服务程序
staticvoidbasicRfRxFrmDoneIsr(void)
{
basicRfPktHdr_t*pHdr;
uint8*pStatusWord;
#ifdefSECURITY_CCM
uint8authStatus="0";
#endif
//Mapheadertopacketbuffer
pHdr=(basicRfPktHdr_t*)rxMpdu;
//IM_FIFOP中断禁止,禁止RF总中断
//ClearinterruptanddisablenewRXframedoneinterrupt
halRfDisableRxInterrupt();
//打开总中断
//Enableallotherinterruptsources(enablesinterruptnesting)
halIntOn();
/*读取接收缓存,length指定要读取的字节数
voidhalRfReadRxBuf(uint8*pData,uint8length)
{
while(length>0){
*pData++=RFD;
length--;
}
}
*/
//读取MPDU的长度
//Readpayloadlength.
halRfReadRxBuf(&pHdr->packetLength,1);
//指定MPDU的长度字节的高位默认固定为0,所以去掉高位,得到长度真实值
pHdr->packetLength&=BASIC_RF_PLD_LEN_MASK;//IgnoreMSB
//Isthisanacknowledgmentpacket?
//Onlyackpacketsmaybe5bytesintotal.
if(pHdr->packetLength==BASIC_RF_ACK_PACKET_SIZE){
//如果只有5个字节长度,则此帧为应答帧
//Readthepacket
halRfReadRxBuf(&rxMpdu[1],pHdr->packetLength);
//Makesurebytefieldsarechangedfromnetworktohostbyteorder
UINT16_NTOH(pHdr->panId);
UINT16_NTOH(pHdr->destAddr);
UINT16_NTOH(pHdr->srcAddr);
#ifdefSECURITY_CCM
UINT32_NTOH(pHdr->frameCounter);
#endif
rxi.ackRequest=!
!
(pHdr->fcf0&BASIC_RF_FCF_ACK_BM_L);
//条过RSSI指到CRC校验
//ReadthestatuswordandcheckforCRCOK
pStatusWord=rxMpdu+4;
//IndicatethesuccessfulACKreceptionifCRCandsequencenumberOK