那位高手能帮忙解决一下s3c2410的spi口读写无线模块cc2420的问题??

jumpbear   2009-3-11 11:36 楼主
我的问题主要是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、我的晶振稳定方式,不知道可不可以那么编。
希望有高手指点,小弟将不胜感激!

回复评论 (5)

请问你的问题解决了吗?我最近也在搞这个,但是我是要读2420中的RSSI与LQI的数据
点赞  2009-7-27 15:50
请问LZ和1L,你们的问题解决了没有,我也有同样的问题
点赞  2009-10-20 14:29
请问一楼2楼3楼你们的问题解决了没有啊
点赞  2009-11-29 21:22
我来说下
fifop应该是硬件中断
你应该把这个脚和arm的外部中断连接
当这个中断来后进入中断服务程序,读取rxfifo的数据

可以交流么
我qq874490688
点赞  2009-11-30 13:41
谢谢楼上的回答!
现在也没有很好的解决这个问题
有没有高手贴一下程序出来?
点赞  2010-4-24 11:38
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复