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

📄 cc2420rf.c

📁 射频芯片cc2420的使用例程
💻 C
字号:
/*******************************************************************************************************
 *******************************************************************************************************/
#include "include.h"

// RF 设置结构声明, since we'll always need halRfInit()
BASIC_RF_SETTINGS rfSettings;

//h10a58869d74be5a374cf867cfb473859000000000000000000000000000000006d251e6944b051e04eaa6fb4dbf78465
//y security RAM content
UINT8 SEC_KEY0[16] = {0x59,0x38,0x47,0xfb,0x7c,0x86,0xcf,0x74,0xa3,0xe5,0x4b,0x69,0xfb,0x88,0xa5,0x10};
UINT8 SEC_KEY1[16] = {0x59,0x38,0x47,0xfb,0x7c,0x86,0xcf,0x74,0xa3,0xe5,0x4b,0x69,0xfb,0x88,0xa5,0x10};
UINT8 SEC_RXNONCE[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
UINT8 SEC_TXNONCE[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};

UINT16 temp_rf;
/*
UINT8 temp1[16];
UINT8 temp2[16];
UINT8 temp3[16];
UINT8 temp4[16];
UINT8 temp5[16];
UINT8 temp6[16];
UINT8 temp7[16];
UINT8 temp8[16];
*/
void basicRfInit(BASIC_RF_RX_INFO *pRRI, UINT8 channel, WORD panId, WORD myAddr)
{
	UINT8 n;

	//确保电压调节器打开,重启引脚是非活动的
	DISABLE_GLOBAL_INT(); //当访问CC2420的寄存器时,关闭全局中断
/*
       for(n = 0; n < 3; n++)
        {
            	SET_YLED();
               	halWait(10000);halWait(50000);halWait(50000);halWait(50000);
               	CLR_YLED();
               	halWait(10000);halWait(50000);halWait(50000);halWait(50000);

        }
*/
	SET_VREG_ACTIVE(); //打开内部电源供电
	halWait(1000);
//	halWait(250);halWait(250);halWait(250);
//	halWait(250);halWait(250);halWait(250);
//	halWait(50000);halWait(50000);halWait(50000);
	SET_RESET_ACTIVE(); //复位2420
	halWait(1);
	SET_RESET_INACTIVE();
	halWait(5);
	
	FIFOP_INT_INIT(); //初始化FIFOP外部中断
	ENABLE_FIFOP_INT();

    	// 修改寄存器
    	FASTSPI_STROBE(CC2420_SXOSCON); //打开晶体振荡器
    	FASTSPI_SETREG(CC2420_MDMCTRL0, 0x0AF2); // 开启自动包确认 和 自动CRC 和 ADR_DECODE

//    	FASTSPI_GETREG(CC2420_MDMCTRL0,temp_rf);
//    	if(temp_rf == 0x0AF2) SET_GLED();
//    	else SET_YLED();
//    	while(1);

    	FASTSPI_SETREG(CC2420_MDMCTRL1, 0x0500); // 设置解调器相关器的域值为20
    	FASTSPI_SETREG(CC2420_IOCFG0, 0x007F);   // 设置FIFOP域值为最大

	FASTSPI_SETREG(CC2420_SECCTRL0, 0x01C4); // 关闭”安全性使能“
//    	FASTSPI_SETREG(CC2420_SECCTRL0, 0x01C6); //y SECCTRL0 打开安全使能,发送用KEY1,接收用KEY0
    	FASTSPI_SETREG(CC2420_SECCTRL1, 0x0909); //y SECCTRL1 <=0x7F7F 什么时候设置?
    	FASTSPI_SETREG(CC2420_TXCTRL, 0xA0FF); 	 //y power control 0xA0FF ~ 0xA0E0
    	
    	// current
    	//FASTSPI_SETREG(CC2420_TXCTRL, 0xE7FF);
    	//FASTSPI_SETREG(CC2420_RXCTRL0,0x3EC5);
    	//FASTSPI_SETREG(CC2420_RXCTRL1,0x2A7F);
    	//FASTSPI_SETREG(CC2420_AGCCTRL,0x0FF0);
/*
        for(n = 0; n < 3; n++)
        {
            FASTSPI_SETREG(CC2420_TXCTRL, 0xA0FF);
            FASTSPI_GETREG(CC2420_TXCTRL, temp_rf);
            if(temp_rf == 0xA0FF)
            {
               	SET_GLED();
               	halWait(10000);halWait(50000);halWait(50000);halWait(50000);
               	CLR_GLED();
               	halWait(10000);halWait(50000);halWait(50000);halWait(50000);
            }
        }
*/
    	halRfSetChannel(channel); // 设置RF通道

	ENABLE_GLOBAL_INT(); // 重新打开全局中断

	// 设置协议配置
	rfSettings.pRxInfo = pRRI;
	rfSettings.panId = panId;
	rfSettings.myAddr = myAddr;
	rfSettings.txSeqNumber = 0;
    	rfSettings.receiveOn = FALSE;
    	
    	halRfWaitForCrystalOscillator(); //等待晶体振荡器变得稳定

	// 向CC2420 RAM里写入短地址和PAN ID(需要XOSC打开并稳定)
   	DISABLE_GLOBAL_INT();
    	FASTSPI_WRITE_RAM_LE(&myAddr, CC2420RAM_SHORTADDR, 2, n);
    	FASTSPI_WRITE_RAM_LE(&panId, CC2420RAM_PANID, 2, n);

    	//y security settings
    	//  RAM
    	FASTSPI_WRITE_RAM_LE(SEC_KEY0,CC2420RAM_KEY0,16,n); // key0
    	FASTSPI_WRITE_RAM_LE(SEC_RXNONCE,CC2420RAM_RXNONCE,16,n); // RX_NONCE
    	FASTSPI_WRITE_RAM_LE(SEC_KEY1,CC2420RAM_KEY1,16,n); // key1
    	FASTSPI_WRITE_RAM_LE(SEC_TXNONCE,CC2420RAM_TXNONCE,16,n); // TX_NONCE
/*//y     
	FASTSPI_READ_RAM_LE(temp1,CC2420RAM_KEY0,16,n);
    	FASTSPI_READ_RAM_LE(temp2,CC2420RAM_RXNONCE,16,n);
    	FASTSPI_READ_RAM_LE(temp3,CC2420RAM_KEY1,16,n);
    	FASTSPI_READ_RAM_LE(temp4,CC2420RAM_TXNONCE,16,n);
//y */
  	ENABLE_GLOBAL_INT(); // 重新打开全局中断
}

BOOL basicRfSendPacket(BASIC_RF_TX_INFO *pRTI) 
{
    	WORD frameControlField;
    	UINT8 packetLength;//y
    	UINT16 number_TXONCCA = 0;
	//UINT8 n;//y
    	BOOL success;
    	BYTE spiStatusByte;
    
    	// 等待,直到收发器空闲
    
    	DISABLE_GLOBAL_INT(); // 关闭全局中断避免SPI接口上的干扰 
	
	FASTSPI_STROBE(CC2420_SFLUSHTX); // 为了以防万一,Flush the TX FIFO
    
    	if (!rfSettings.receiveOn) FASTSPI_STROBE(CC2420_SRXON); // 如果需要,打开RX

    	//y
    	// 将包写入TX FIFO(当使能AUTOCRC时,FCS自动添加上)
    	packetLength = pRTI->length + BASIC_RF_PACKET_OVERHEAD_SIZE;
    	FASTSPI_WRITE_FIFO((BYTE*)&packetLength, 1);               //包长度
    	frameControlField = pRTI->ackRequest ? BASIC_RF_FCF_ACK : BASIC_RF_FCF_NOACK;
    	FASTSPI_WRITE_FIFO((BYTE*) &frameControlField, 2);         // 帧控制域
    	FASTSPI_WRITE_FIFO((BYTE*) &rfSettings.txSeqNumber, 1);    // 序列号
    	FASTSPI_WRITE_FIFO((BYTE*) &rfSettings.panId, 2);          // 目的地 PAN ID
    	FASTSPI_WRITE_FIFO((BYTE*) &pRTI->destAddr, 2);            // 目的地地址
    	FASTSPI_WRITE_FIFO((BYTE*) &rfSettings.myAddr, 2);         // 源地址
	FASTSPI_WRITE_FIFO((BYTE*) pRTI->pPayload, pRTI->length);  // 载荷
/*
	FASTSPI_READ_RAM_LE(temp1,CC2420RAM_TXFIFO,16,n);
	FASTSPI_READ_RAM_LE(temp2,CC2420RAM_TXFIFO+16,16,n);
	FASTSPI_READ_RAM_LE(temp3,CC2420RAM_TXFIFO+32,16,n);
	FASTSPI_READ_RAM_LE(temp4,CC2420RAM_TXFIFO+48,16,n);
	FASTSPI_READ_RAM_LE(temp5,CC2420RAM_TXFIFO+64,16,n);
	FASTSPI_READ_RAM_LE(temp6,CC2420RAM_TXFIFO+80,16,n);
	FASTSPI_READ_RAM_LE(temp7,CC2420RAM_TXFIFO+96,16,n);
	FASTSPI_READ_RAM_LE(temp8,CC2420RAM_TXFIFO+112,16,n);
*/

	//y security encryption
/*	FASTSPI_STROBE(CC2420_STXENC);
    	do 
		{
        	FASTSPI_UPD_STATUS(spiStatusByte);
    	} while (!!(spiStatusByte & BV(CC2420_ENC_BUSY)));
    	*/
/*
	FASTSPI_READ_RAM_LE(temp1,CC2420RAM_TXFIFO,16,n);
	FASTSPI_READ_RAM_LE(temp2,CC2420RAM_TXFIFO+16,16,n);
	FASTSPI_READ_RAM_LE(temp3,CC2420RAM_TXFIFO+32,16,n);
	FASTSPI_READ_RAM_LE(temp4,CC2420RAM_TXFIFO+48,16,n);
	FASTSPI_READ_RAM_LE(temp5,CC2420RAM_TXFIFO+64,16,n);
	FASTSPI_READ_RAM_LE(temp6,CC2420RAM_TXFIFO+80,16,n);
	FASTSPI_READ_RAM_LE(temp7,CC2420RAM_TXFIFO+96,16,n);
	FASTSPI_READ_RAM_LE(temp8,CC2420RAM_TXFIFO+112,16,n);
*/

    	// 等待RSSI值变得有效
    	do 
		{
        	FASTSPI_UPD_STATUS(spiStatusByte);
    	} while (!(spiStatusByte & BV(CC2420_RSSI_VALID)));
 //y051228
	// TX在CCA检查通过以后开始
	FASTSPI_STROBE(CC2420_STXONCCA);
    	do 
		{
		halWait(100);
		FASTSPI_UPD_STATUS(spiStatusByte);
		number_TXONCCA++;
		if(number_TXONCCA > 0x0F00) return(0); // or "如果没有修改过 rfTxInfo 内容的话,调用 basicRfSendPacket(&rfTxInfo);"
    	} while (!(spiStatusByte & BV(CC2420_TX_ACTIVE)));

/*
    	FASTSPI_STROBE(CC2420_STXON);
*/    	
	while (!SFD_IS_1); // 等待传输开始(确信此函数不能调用两次)
	success = TRUE;

	ENABLE_GLOBAL_INT(); // 打开全局中断

    	if (pRTI->ackRequest) // 等待接收到确认包
	{
		rfSettings.ackReceived = FALSE;

		while (SFD_IS_1); // 等待SFD重新变低
		
		// 将自动进入RX,所以只要等待直到可以确信确认包接收过程完成
        	// 超时由一个12-symbol turnaround time, the ack packet duration, 和一个small margin组成
        	halWait((12 * BASIC_RF_SYMBOL_DURATION) + (BASIC_RF_ACK_DURATION) + 
        		(2 * BASIC_RF_SYMBOL_DURATION) + 100);

		success = rfSettings.ackReceived; // 如果收到确认包(通过FIFOP中断), 设置ackReceived标志
    	}

	if (!rfSettings.receiveOn) // 如果接收器不应该继续使能,关闭接收器
	{
		DISABLE_GLOBAL_INT();
		FASTSPI_STROBE(CC2420_SRFOFF);
		ENABLE_GLOBAL_INT();
	} 

    	rfSettings.txSeqNumber++; // 增加序列号
    	return success; // 返回结果
}

void CC2420_FIFOP_ISP()
{
	WORD frameControlField;
	INT8 length;
//	INT8 spiStatusByte;
	BYTE pFooter[2];

    	// 万一FIFO溢出,清除并退出。FIFO是否溢出,由FIFOP=1或FIFO=0来指示
	if ((FIFOP_IS_1) && (!(FIFO_IS_1)))
	{
		FASTSPI_STROBE(CC2420_SFLUSHRX);
		FASTSPI_STROBE(CC2420_SFLUSHRX);
		return;
	}

	FASTSPI_READ_FIFO_BYTE(length); // 载荷长度
	length &= BASIC_RF_LENGTH_MASK; // 忽略 MSB

    	if (length < BASIC_RF_ACK_PACKET_SIZE)  // 如果长度过小,忽略这个包
	{
    		FASTSPI_READ_FIFO_GARBAGE(length);
    	}
	else //或者,如果长度是合法的,继续进行包的剩余部分
	{
        	rfSettings.pRxInfo->length = length - BASIC_RF_PACKET_OVERHEAD_SIZE;  // 登记载荷长度

        	FASTSPI_READ_FIFO_NO_WAIT((BYTE*) &frameControlField, 2); // 读取帧控制域和数据序列号
        	rfSettings.pRxInfo->ackRequest = !!(frameControlField & BASIC_RF_FCF_ACK_BM);
    		FASTSPI_READ_FIFO_BYTE(rfSettings.pRxInfo->seqNumber);

    		if ((length == BASIC_RF_ACK_PACKET_SIZE) 
			&& (frameControlField == BASIC_RF_ACK_FCF) 
			&& (rfSettings.pRxInfo->seqNumber == rfSettings.txSeqNumber)) // 这是一个确认包?
    		{
			FASTSPI_READ_FIFO_NO_WAIT((BYTE*) pFooter, 2); // 读取footer

			// 检查CRC是否OK ? 指示成功接收ack(这个标志通过传输例程得到)
			if (pFooter[1] & BASIC_RF_CRC_OK_BM) rfSettings.ackReceived = TRUE;
		}
		else if (length < BASIC_RF_PACKET_OVERHEAD_SIZE) //太小了,不是一个有效包
		{
			FASTSPI_READ_FIFO_GARBAGE(length - 3);
			return;
		}
		else //接收包的余下部分
		{
			FASTSPI_READ_FIFO_GARBAGE(4); // 忽略目的PAN和地址(其由硬件地址识别来关注)

			FASTSPI_READ_FIFO_NO_WAIT((BYTE*) &rfSettings.pRxInfo->srcAddr, 2); // 读取源地址
/*
// security	///////////////////////////////////		
                        //y security decryption
                   //     DISABLE_GLOBAL_INT();
                        FASTSPI_STROBE(CC2420_SRXDEC);
                        do 
                                {
                   //           halWait(100);
                                FASTSPI_UPD_STATUS(spiStatusByte);
                        } while (!!(spiStatusByte & BV(CC2420_ENC_BUSY)));
                   //     ENABLE_GLOBAL_INT();
// security    ///////////////////////////////////
//y
*/			// 读取包载荷
			FASTSPI_READ_FIFO_NO_WAIT(rfSettings.pRxInfo->pPayload, rfSettings.pRxInfo->length);

			// 读取footer以获得RSSI值
			FASTSPI_READ_FIFO_NO_WAIT((BYTE*) pFooter, 2);
			rfSettings.pRxInfo->rssi = pFooter[0];

			// 如果CRC是OK的,通知应用程序接收到的数据包
			if (((frameControlField & (BASIC_RF_FCF_BM)) == BASIC_RF_FCF_NOACK) 
				&& (pFooter[1] & BASIC_RF_CRC_OK_BM))
				rfSettings.pRxInfo = basicRfReceivePacket(rfSettings.pRxInfo);
			else 
			{ //y051227
			    SET_YLED();
                            halWait(50000);halWait(50000);halWait(50000);halWait(50000);
                            CLR_YLED();
                            halWait(50000);halWait(50000);halWait(50000);halWait(50000);
			}
		}
    	}
    //	ENABLE_GLOBAL_INT();
}

void halRfSetChannel(UINT8 channel)
{
	UINT16 f;

	//从给定的通道值得到频率值
	f = (UINT16) (channel - 11); // Subtract the base channel 
	f = f + (f << 2);    		 // Multiply with 5, which is the channel spacing
	f = f + 357 + 0x4000;		 // 357 is 2405-2048, 0x4000 is LOCK_THR = 1

    	//将频率值写入CC2420
	DISABLE_GLOBAL_INT();
	FASTSPI_SETREG(CC2420_FSCTRL, f);
	ENABLE_GLOBAL_INT();
}

void halRfWaitForCrystalOscillator(void) 
{
    	BYTE spiStatusByte;
    	// 不断得到SPI状态字节,直到晶体振荡器变得稳定下来
    	do {
	    DISABLE_GLOBAL_INT();
	    FASTSPI_UPD_STATUS(spiStatusByte);
	    ENABLE_GLOBAL_INT();
    	} while (!(spiStatusByte & (BV(CC2420_XOSC16M_STABLE))));
}

void basicRfReceiveOn(void) 
{
    	rfSettings.receiveOn = TRUE;
	FASTSPI_STROBE(CC2420_SRXON);
	FASTSPI_STROBE(CC2420_SFLUSHRX);
   	 ENABLE_FIFOP_INT();
}

void basicRfReceiveOff(void) 
{
    	rfSettings.receiveOn = FALSE;
	FASTSPI_STROBE(CC2420_SRFOFF);
    	DISABLE_FIFOP_INT();
}
void halWait(UINT16 timeout)
{
	do
	{
		NOP();
		NOP();
		NOP();
		NOP();
	}
	while (--timeout);
}

⌨️ 快捷键说明

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