#include "cc2420.h"
#include "spi.h"
#include "common.h"
#include "uart.h"
/**************************************************
函数功能:写SPI一个字节
输入参数:SPI指令
返回值:对应指令的结果
**************************************************/
unsigned char spi_write(unsigned char data_spi)
{
unsigned char temp,temp1;
SPDR=data_spi;
while(!(SPSR & (1<<SPIF))){;}//等待传输结束
temp1=SPDR;
temp = SPSR;
return temp1;
}
/*******************************************
*函数功能:使能SPI口
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void spi_enable(void)
{
PORTB &= ~CSn; //使能SPI口
}
/*******************************************
*函数功能:禁止SPI口
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void spi_disable(void)
{
PORTB |= CSn; //禁止SPI口
}
/*******************************************
*函数功能:写命令寄存器
*输入参数:命令字
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char write_command(unsigned char command)
{
unsigned char statueval;
spi_enable(); //使能SPI口
statueval=SpiWrite(command);
spi_disable(); //禁止SPI口
return statueval;
}
/*******************************************
*函数功能:读状态寄存器
*输入参数:无
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char read_status(void)
{
unsigned char statuevalue;
statuevalue=write_command(SNOP); //空操作命令,为了读取当前状态寄存器的值
return statuevalue;
}
/*******************************************
*函数功能:写配置字
*输入参数:Addr:配置寄存器的地址;
DataH:配置字的高字节;
DataL:配置字的低字节;
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char write_configure_word(unsigned char Addr,unsigned char DataH,unsigned char DataL)
{
unsigned char statuevalue;
// spi_enable(); //使能SPI口 以具体情况而定使能/禁止SPI口放在何处
statuevalue=spi_write(Addr); //发送配置寄存器的地址,同时返回当前状态寄存器的值
spi_write(DataH); //发送配置字的高字节
spi_write(DataL); //发送配置字的低字节
// spi_disable(); //禁止SPI口
return statuevalue;
}
/*******************************************
*函数功能:读配置字
*输入参数:Addr:配置寄存器的地址;
*输出参数:DataH:配置字的高字节;
DataL:配置字的低字节;
*返 回 值:状态寄存器的值
********************************************/
unsigned char read_configure_word(unsigned char Addr,unsigned char *DataH,unsigned char *DataL)
{
unsigned char statuevalue;
Addr|=0x40; //读标志位为1
spi_enable(); //使能SPI口 以具体情况而定使能/禁止SPI口放在何处
statuevalue=spi_write(Addr); //发送配置寄存器的地址,同时返回当前状态寄存器的值
*DataH=spi_write(0xff); //读配置字的高字节
*DataL=spi_write(0xff); //读配置字的低字节
spi_disable(); //禁止SPI口
return statuevalue;
}
/*******************************************
*函数功能:读RXFIFO
*输入参数:Data_Num:欲读取的字节个数
*输出参数:p_Data:存储数据的缓存首地址;
*返 回 值:状态寄存器的值
********************************************/
unsigned char read_rxfifo(unsigned char Data_Num,unsigned char *p_Data)
{
unsigned char statuevalue,Addr,i;
Addr=RXFIFO|0x40; //读标志位为1
spi_enable(); //使能SPI口
statuevalue=spi_write(Addr);
for(i=0;i<Data_Num;i++)
{
*(p_Data+i)=spi_write(0xff);
}
spi_disable(); //禁止SPI口
return statuevalue;
}
/*******************************************
*函数功能:读一字节RXFIFO
*输入参数:无
*输出参数:无
*返 回 值:读取的数据
********************************************/
unsigned char read_rxfifo_byte(void)
{
unsigned char readvalue,Addr;
Addr=RXFIFO|0x40; //读标志位为1
spi_enable(); //使能SPI口
spi_write(Addr);
readvalue=spi_write(0xff);
spi_disable(); //禁止SPI口
return readvalue;
}
/*******************************************
*函数功能:写TXFIFO
*输入参数:Data_Num:欲写入的字节个数
*输出参数:p_Data:存储数据的缓存首地址;
*返 回 值:状态寄存器的值
********************************************/
unsigned char write_txfifo(unsigned char Data_Num,unsigned char *p_Data)
{
unsigned char statuevalue=0;
unsigned char i;
spi_enable(); //使能SPI口
spi_write(TXFIFO);
for (i=0;i<Data_Num;i++)
{
statuevalue=spi_write(*(p_Data+i));
if ((statuevalue&(1<<TX_UNDERFLOE))!=0x00) //发生下溢
{
write_command(SFLUSHTX);
spi_enable(); //重新使能SPI口
}
}
spi_disable(); //禁止SPI口
return statuevalue;
}
/*******************************************
*函数功能:写一字节TXFIFO
*输入参数:p_Data:要写入的数据
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char write_txfifo_byte(unsigned char p_Data)
{
unsigned char statuevalue;
spi_enable(); //使能SPI口
spi_write(TXFIFO);
statuevalue=spi_write(p_Data);
spi_disable(); //禁止SPI口
return statuevalue;
}
/*******************************************
*函数功能:写RAM
*输入参数:p_Data:存储数据的缓存首地址;
Data_Num:要写入的字节数
AddrH:在选定的RAM存储块中确定RAM地址
AddrL:选择RAM存储块
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char write_ram(unsigned char AddrH,unsigned char AddrL,unsigned char Data_Num,unsigned char *p_Data)
{
unsigned char statuevalue,i;
AddrH|=0X80; //访问RAM位置1
AddrL<<=6;
AddrL&=0XDF; //读写操作位置0,表示写操作
spi_enable(); //使能SPI口
statuevalue=spi_write(AddrH);
spi_write(AddrL);
for (i=0;i<Data_Num;i++)
{
spi_write(*(p_Data+i));
}
spi_disable(); //禁止SPI口
return statuevalue;
}
/*******************************************
*函数功能:写一字节RAM
*输入参数:p_Data:要写入的数据
AddrH:在选定的RAM存储块中确定RAM地址
AddrL:选择RAM存储块
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char write_ram_byte(unsigned char AddrH,unsigned char AddrL,unsigned char p_Data)
{
unsigned char statuevalue;
AddrH|=0X80; //访问RAM位置1
AddrL<<=6;
AddrL&=0XDF; //读写操作位置0,表示写操作
spi_enable(); //使能SPI口
statuevalue=spi_write(AddrH);
spi_write(AddrL);
spi_write(p_Data);
spi_disable(); //禁止SPI口
return statuevalue;
}
/*******************************************
*函数功能:读RAM
*输入参数:p_Data:存储数据的缓存首地址;
Data_Num:要读取的字节数
AddrH:在选定的RAM存储块中确定RAM地址
AddrL:选择RAM存储块
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char read_ram(unsigned char AddrH,unsigned char AddrL,unsigned char Data_Num,unsigned char *p_Data)
{
unsigned char statuevalue,i;
AddrH|=0X80; //访问RAM位置1
AddrL<<=6;
AddrL|=0X20; //读写操作位置1,表示读操作
spi_enable(); //使能SPI口
statuevalue=spi_write(AddrH);
spi_write(AddrL);
for (i=0;i<Data_Num;i++)
{
*(p_Data+i)=spi_write(0xff);
}
spi_disable(); //禁止SPI口
return statuevalue;
}
/*******************************************
*函数功能:读一字节RAM
*输入参数:AddrH:在选定的RAM存储块中确定RAM地址
AddrL:选择RAM存储块
*输出参数:无
*返 回 值:读取的数据值
********************************************/
unsigned char read_ram_byte(unsigned char AddrH,unsigned char AddrL)
{
unsigned char readvalue;
AddrH|=0X80; //访问RAM位置1
AddrL<<=6;
AddrL|=0X20; //读写操作位置1,表示读操作
spi_enable(); //使能SPI口
spi_write(AddrH);
spi_write(AddrL);
readvalue=spi_write(0xff);
spi_disable(); //禁止SPI口
return readvalue;
}
/*******************************************
*函数功能:关闭电压校准器模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void power_off(void)
{
PORTB &= ~VREGEN; //禁止电压校准器
}
/*******************************************
*函数功能:从电压校准器关闭模式转换到掉电模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void pwoff_pwdown(void)
{
PORTB |= VREGEN; //启动电压校准器
delay_nus(600);
spi_enable(); //使能SPI口
write_configure_word(MAIN,0x78,0x00); //先将reset位设置为低
write_configure_word(MAIN,0xf8,0x00); //先将reset位设置为高,完成复位过程
spi_disable(); //禁止SPI口
}
/*******************************************
*函数功能:其他任何模式转换到掉电模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void allstates_pwdown(void)
{
write_command(SXOSCOFF);
}
/*******************************************
*函数功能:从掉电模式转换到空闲模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void pwdown_idle(void)
{
unsigned char statue;
write_command(SXOSCON);
while(1) //等待晶体振荡器稳定运行
{
statue=read_status();
if((statue&(1<<XOSC16M_STABLE))!=0)
{
break;
}
}
}
/*******************************************
*函数功能:从其他任何模式转换到空闲模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void allstates_idle(void)
{
write_command(SRFOFF);
}
/*******************************************
*函数功能:从空闲模式启动发送
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void idle_tx(void)
{
write_command(STXON);
}
/*******************************************
*函数功能:从接收状态转换到发送模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void rx_tx(void)
{
while(1)
{
if((PINB&CCA) != 0) //信道空闲
{
write_command(STXONCCA);
break;
}
}
}
/*******************************************
*函数功能:从空闲模式启动接收模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void idle_rx(void)
{
write_command(SRXON);
}
/*******************************************
*函数功能:设置配置字(用于初始化)
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void set_configure(void)
{
unsigned char RegisterValueH,RegisterValueL;
power_off(); //???????????????????????????????
pwoff_pwdown(); //在power down模式下设置配置寄存器
spi_enable(); //使能SPI口
RegisterValueH=0X0A;
RegisterValueL=0XE2; //地址认证使能,自动应答不使能
write_configure_word(MDMCTRL0,RegisterValueH,RegisterValueL);
RegisterValueH=0X05;
RegisterValueL=0X00;
write_configure_word(MDMCTRL1,RegisterValueH,RegisterValueL);
// RegisterValueH=-50;
// RegisterValueL=0X00;
// write_configure_word(RSSI,RegisterValueH,RegisterValueL); //???????????????????????调试时修改
RegisterValueH=0x41;
RegisterValueL=0X92; //2.45GHz
write_configure_word(FSCTRL,RegisterValueH,RegisterValueL);
RegisterValueH=0x01;
RegisterValueL=0Xe4; //安全模式不使能
write_configure_word(SECCTRL0,RegisterValueH,RegisterValueL);
//RegisterValueH=128;
//RegisterValueL=128;
//write_configure_word(SECCTRL1,RegisterValueH,RegisterValueL); //???????????????????????调试时修改
RegisterValueH=0;
RegisterValueL=TX_length; //RXFIFO的极限值
write_configure_word(IOCFG0,RegisterValueH,RegisterValueL); //???????????????????????调试时修改
spi_disable(); //禁止SPI口
}
/*************************************************
函数功能:初始化CC2420
输入参数:无
返回值:无
**************************************************/
void cc2420_init(void)
{
unsigned char temp;
DDRB |= SPI_MOSI | SPI_CLK | SPI_SS | VREGEN;//设置MOSI、SCK和SS 为输出,其他为输入
DDRD |= RST;
SPCR = (1<<SPE)|(1<<MSTR);//|(1<<SPR0);// 使能SPI,主机模式,设置时钟速率为fck/4
//SPSR = BIT(SPI2X); //SPI时钟加倍
temp = SPSR; //!!! 读一次SPSR为了清除SPIF位和WCOL位
temp = SPDR; //清空SPI,和中断标志,使SPI空闲
PORTB |= CSn; //CSN引脚置位,停止SPI操作,
PORTB |= SCK; // Spi clock line init high
PORTD |= RST; //注意该引脚低电平时,cc2420处于复位状态
set_configure();
pwdown_idle();
}