我的问题主要是spi口到底是用查询方式还是中断方式。由于水平有限本人用了查询方式。
下面是主要的程序:
/*************************************************
SPI low lever fuctions
**********************************************/
void SPI_INIT()
{ int i;
SPPRE0=0x02;
//Baud rate = PCLK/2/(Prescaler value + 1),pclk=50mhz
//SPCON0=(0<<6)|(0<<5)|(1<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0);
SPCON0=0x18;
//polling,en_sck,master,high,format A,nomal
SPPIN0=0x02;
//Multi Master error detect disable, reserved release
for(i=0;i<10;i++)
SPTDAT0=0xFF;
}
//---------------------------------
void SPI_TX(char data)
{
SPI_dataread()// TX data ready!
SPTDAT0=data;
}
//--------------------------------------
unsigned char SPI_RX()
{
char buf;
//SPTDAT0=0xFF;
SPI_dataread()// RX data ready!
buf=SPRDAT0;
return buf;
}
//--------------------------------------
void SPI_TX_ADDR(char a)
{
SPI_TX(a);
}
//----------------------------------------
void SPI_RX_ADDR(char a)
{
SPI_dataread()// TX data ready!
SPTDAT0=a|0x40;
}
//--------------------------------------------
void SPI_STROBE(char a)
{
SPI_ENABLE;
SPI_TX_ADDR(a);
SPI_DISABLE;
}
//-----------------------------------------------
void SPI_SETREG(char a, int v)
{
SPI_ENABLE;
SPI_TX_ADDR(a);
SPI_TX(v>>8);//high 8 bit
SPI_TX(v); //low 8 bit
SPI_DISABLE;
}
/**********************************************************
CC2420 low lever fuctions
***********************************************************/
//--------------------------------------
void cc2420_power()
{
write_gpio_bit(GPIO_E15,1);
udelay(10);
//write_gpio_bit(GPIO_E15,0);
}
//--------------------------------------
void cc2420_reset()
{
write_gpio_bit(GPIO_E10,0);
udelay(10);
write_gpio_bit(GPIO_E10,1);
}
//--------------------------------------
void cc2420_waitcrystaloscillator()
{
int s=0;
SPI_ENABLE;
SPI_TX_ADDR(CC2420_SNOP);
while(s&0x40==0)//判断状态位第6位是否为1
{
SPI_dataread()// RX data ready!
s=SPRDAT0;
}
SPI_DISABLE;
}
//----------------------------------------------------------------
void cc2420_init()
{ int num;
SPI_INIT();
//s3c2410和cc2420引脚定义
set_gpio_ctrl(GPIO_G2|GPIO_PULLUP_EN | GPIO_MODE_OUT); //nss0---cs
set_gpio_ctrl(GPIO_MODE_SPICLK|GPIO_PULLUP_EN|GPIO_E13); // CLK0
set_gpio_ctrl(GPIO_MODE_SPIMOSI|GPIO_PULLUP_EN|GPIO_E12); //SPIMOSI
set_gpio_ctrl(GPIO_MODE_SPIMISO|GPIO_PULLUP_EN|GPIO_E11); // SPIMISO
set_gpio_ctrl(GPIO_G11|GPIO_PULLUP_DIS|GPIO_MODE_IN); //FIFOP
set_gpio_ctrl(GPIO_E10|GPIO_PULLUP_DIS|GPIO_MODE_OUT); //nRESET
set_gpio_ctrl(GPIO_E14|GPIO_PULLUP_DIS|GPIO_MODE_IN); //FIFO
set_gpio_ctrl(GPIO_E15|GPIO_PULLUP_DIS|GPIO_MODE_OUT); //VREG_EN
cc2420_power();//驱动VREG_EN供给cc2420的1.8V电压
cc2420_reset();//复位时默认为自动CRC、地址识别使能
SPI_STROBE(CC2420_SXOSCON);//开启晶振
udelay(12);
//=========================================
SPI_STROBE(CC2420_SNOP); //发空读状态位
num=SPI_RX();
printk("status1=%d",num);
cc2420_waitcrystaloscillator();//等待晶振稳定,为了让其它选通命令可用
udelay(12);
//==========================================
SPI_STROBE(CC2420_SNOP); //发空读状态位
num=SPI_RX();
printk("status2=%d",num);
//===============================
udelay(12); //CC2420将不会接收任何数据除非它已经处于接收模式12个信号周期
SPI_SETREG(CC2420_MDMCTRL0,0x0AF2); //Turn on automatic packet acknowledgment
SPI_SETREG(CC2420_MDMCTRL1,0x0500); //Set the correlation threshold = 20
SPI_SETREG(CC2420_IOCFG0,0x007F); //Set the FIFOP threshold to maximum 128
SPI_SETREG(CC2420_SECCTRL0,0x01C4); //Turn off "Security enable"
}
//----------------------------------------------------------------
int FIFOP_INT()
{
if(read_gpio_bit(GPIO_G11)==1)//表示收到了一个完整的帧结构
return 1;
}
//------------------------------------
int FIFO_INT()
{
if(read_gpio_bit(GPIO_E14)==1)//在RXFIFO里至少有一个数据
return 1;
}
//------------------------------------------------------------
unsigned char cc2420_read()
{
char buf[2]={0};
char data;
int i;
SPI_STROBE(CC2420_SRXON);//使能接收
SPI_ENABLE;
if ((FIFOP_INT())&(FIFO_INT()) == 1)
SPI_RX_ADDR(CC2420_RXFIFO);//给si上送接收地址(24位数据分别是)
SPI_TX(0xFF);
SPI_TX(0xFF);
for(i=0;i<20;i++)
{
buf=SPI_RX();//读取so上传给SPRDAT的数据
printk(" %d ",buf);
}
printk("/n.........");
if((buf[0]&0x10)==0x10)
{
SPI_STROBE(CC2420_SFLUSHRX);
SPI_STROBE(CC2420_SFLUSHRX);
return -1;
}
else if(!(buf[1]==8))
{
return -1;
}
else{
data=buf[12];
}
SPI_DISABLE;
return data;
}
/******************************************************************************
CC2420_SPI_DRIVER MAIN Fuctions
*******************************************************************************/
static ssize_t CC2420_read (struct file *filp, char *buffer,size_t count, loff_t *ppos)
{
char data;
cc2420_init();
do{
data=cc2420_read();
}while(data == -1);
copy_to_user(buffer, &data, 1);
return 1;
}
问题1、是不知道这样写底层函数可不可以?最后测试连写给cc2420的寄存器的值也读不到。全部返回的是0xff。
问题2、spi查询方式是不是必须先读再写?我是按照2410手册上spi读写说明编的,不知道是否正确。
问题3、我这个驱动主要是要接收无线数据。所以没有用到cca引脚,不知道这样是不是也是程序的不当之处?
问题4、我的晶振稳定方式,不知道可不可以那么编。
希望有高手指点,小弟将不胜感激!
请问你的问题解决了吗?我最近也在搞这个,但是我是要读2420中的RSSI与LQI的数据
请问LZ和1L,你们的问题解决了没有,我也有同样的问题
我来说下
fifop应该是硬件中断
你应该把这个脚和arm的外部中断连接
当这个中断来后进入中断服务程序,读取rxfifo的数据
可以交流么
我qq874490688
谢谢楼上的回答!
现在也没有很好的解决这个问题
有没有高手贴一下程序出来?