Chinaunix首页 | 论坛 | 博客
  • 博客访问: 21995
  • 博文数量: 8
  • 博客积分: 186
  • 博客等级: 入伍新兵
  • 技术积分: 80
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-14 15:05
文章分类
文章存档

2011年(8)

我的朋友
最近访客

分类: LINUX

2011-06-20 10:08:28

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define TRX_CE S3C2410_GPF(0)
#define AM  S3C2410_GPF(4)
#define MISO S3C2410_GPF(6)
#define SCK  S3C2410_GPG(1)
#define CSN  S3C2410_GPG(5)
#define MOSI S3C2410_GPG(7)
#define TX_EN S3C2410_GPE(14)
#define PWR_UP S3C2410_GPE(13)
#define CD S3C2410_GPE(11)
#define DR S3C2410_GPG(10)
#define WC 0x00  // 写配置寄存器(RF-Configuration Register)
#define RC 0x10  // 读配置寄存器(RF-Configuration Register)
#define WTP 0x20  // 向 TX-Payload 寄存器写入发送有效数据
#define RTP 0x21  // 从 TX-Payload 寄存器读取发送有效数据
#define WTA 0x22  // 向 TX-Address 寄存器写入发送地址
#define RTA 0x23  //  从 TX-Address 寄存器读取发送地址
#define RRP 0x24  //  从 RX-Payload 寄存器读取接收到的有效数据
#define uchar unsigned char
#define uint unsigned int
#define DEVICE_NAME "rf905s"
 uchar TxBuf[32];
 uchar RxBuf[32];
//struct RFConfig    //rf905里的配置信息
//{
 //  uchar buf[10];
//} RxTxConf = {{0x3b, 0x0c, 0x44, 0x20, 0x20, 0xcc, 0xcc, 0xcc,0xcc, 0x58}};
static uchar RxTxConf[10] = {0x3b, 0x0c, 0x44, 0x20, 0x20, 0xcc, 0xcc, 0xcc,0xcc, 0x58};
//#define DEVICE_NAME "rf905s"

static void define_io(void )
{
/* s3c2410_gpio_cfgpin(AM, S3C2410_GPIO_SFN2);
 s3c2410_gpio_cfgpin(CD, S3C2410_GPIO_SFN2);
 s3c2410_gpio_cfgpin(MISO, S3C2410_GPIO_SFN2);
 s3c2410_gpio_cfgpin(DR, S3C2410_GPIO_SFN2);
*/
 s3c2410_gpio_cfgpin(MISO, S3C2410_GPIO_INPUT);
 s3c2410_gpio_cfgpin(DR, S3C2410_GPIO_INPUT);
 s3c2410_gpio_cfgpin(AM, S3C2410_GPIO_INPUT);
 s3c2410_gpio_cfgpin(CD, S3C2410_GPIO_INPUT);
 s3c2410_gpio_cfgpin(TRX_CE, S3C2410_GPIO_OUTPUT);
 s3c2410_gpio_cfgpin(TX_EN, S3C2410_GPIO_OUTPUT);
 s3c2410_gpio_cfgpin(PWR_UP, S3C2410_GPIO_OUTPUT);
 s3c2410_gpio_cfgpin(MOSI, S3C2410_GPIO_OUTPUT);
 s3c2410_gpio_cfgpin(SCK, S3C2410_GPIO_OUTPUT);
 s3c2410_gpio_cfgpin(CSN, S3C2410_GPIO_OUTPUT);
 //set_gpio_ctrl(GPIO_MODE_IN | GPIO_PULLUP_DIS | DR);
 
 //s3c2410_gpio_cfgpin(DR, S3C2410_GPIO_INPUT);
 s3c2410_gpio_pullup(DR, 0);
 s3c2410_gpio_pullup(AM, 0);
 s3c2410_gpio_pullup(CD, 0);
 s3c2410_gpio_pullup(MISO, 0);
 s3c2410_gpio_pullup(MOSI, 0);
 s3c2410_gpio_pullup(SCK, 0);
 s3c2410_gpio_pullup(TRX_CE, 0);
 s3c2410_gpio_pullup(TX_EN, 0);
 s3c2410_gpio_pullup(PWR_UP, 0);
 s3c2410_gpio_pullup(CSN, 0);

 printk (DEVICE_NAME"\t define_io\n");
}
static void SpiWrite( uchar byte )    //SPI 写一个字节
{
 uchar i, DATA_BUF;
 DATA_BUF = byte;          // 将需要发送的数据写入缓存
 for (i=0; i<8; i++)
 {
   if (DATA_BUF & 0x80)
   {
   s3c2410_gpio_setpin(MOSI, 1);
   }
   else
   {
   s3c2410_gpio_setpin(MOSI, 0);
   }
  s3c2410_gpio_setpin(SCK, 1);
  udelay(5);
   DATA_BUF = DATA_BUF<<1;   // 左移一位,为下一位的发送做准备
  s3c2410_gpio_setpin(SCK, 0);
  udelay(5);
 }
}
static uchar SpiRead( void )
{
 uchar i;
 uchar DATA_BUF = 0;
 mdelay(1);
 for (i=0; i<8; i++)
 {
  s3c2410_gpio_setpin(SCK, 1);
   if (s3c2410_gpio_getpin(MISO))
       DATA_BUF = ( DATA_BUF<<1 ) | 1;
   else
       DATA_BUF = ( DATA_BUF<<1 ) | 0;
  udelay(5);
  s3c2410_gpio_setpin(SCK, 0);
  udelay(5);
 }
 return DATA_BUF;        // DATA_BUF 为接收到的完整数据
}
static void Config905( void )
{
 uchar i;
 s3c2410_gpio_setpin(CSN, 0); // CSN 片选信号,SPI 使能
 udelay(5);
 SpiWrite(WC);  // 向 905 芯片写配置命令
 udelay(5);
 for (i=0; i<10; i++)    // 循环写入配置信息
 {
   SpiWrite(RxTxConf[i]); //RxTxConf 保存预先设置好
  udelay(5);
 }
 s3c2410_gpio_setpin(CSN, 1); // CSN 片选信号,SPI 禁止 udelay(100);
 udelay(5);
 printk (DEVICE_NAME"\t configure\n");
}
static  void nRF905Init ( void ) //RF905初始化
{
 s3c2410_gpio_setpin(PWR_UP, 1);
 udelay(500);
 s3c2410_gpio_setpin(TRX_CE, 0);
 udelay(60);
 s3c2410_gpio_setpin(CSN, 1);
 udelay(60);
 s3c2410_gpio_setpin(SCK, 0); 
 s3c2410_gpio_setpin(AM, 0); 
 s3c2410_gpio_setpin(CD, 0); 
 s3c2410_gpio_setpin(DR, 0); 
 s3c2410_gpio_setpin(TX_EN, 0); 
 udelay(60);
 mdelay(1);
 printk (DEVICE_NAME"\t init_rf905\n");
}
static void SetTxMode( void )   //设置发射模式
{
 s3c2410_gpio_setpin(TRX_CE, 0);
 s3c2410_gpio_setpin(TX_EN, 1);
 mdelay(2);
}
static void SetRxMode( void )
{
 mdelay(2);
 s3c2410_gpio_setpin(TRX_CE, 1);
 s3c2410_gpio_setpin(TX_EN, 0);
 mdelay(2);
}
 
static void TxPacket( void )
{
 uchar i;
 s3c2410_gpio_setpin(CSN, 0); // CSN 片选信号,SPI 使能
 mdelay(1);
 SpiWrite(WTP);          // Write payload command
 mdelay(1);
 for (i=0; i<32; i++)
 {
  SpiWrite(TxBuf[i]);     // 写入 32 直接发送数据
  udelay(5);
 }
 s3c2410_gpio_setpin(CSN, 1); // CSN 片选信号,SPI 禁止
 mdelay(1);
 s3c2410_gpio_setpin(CSN, 0); // CSN 片选信号,SPI 使能
 mdelay(1);
 SpiWrite(WTA);          // 写数据至地址寄存器
 mdelay(1);
 for (i=0; i<4; i++)       // 写入 4 字节地址
 {
  SpiWrite( RxTxConf[i+5] );
  udelay(5);
 }
 s3c2410_gpio_setpin(CSN, 1); // CSN 片选信号,SPI 禁止
 mdelay(1);
 s3c2410_gpio_setpin(TRX_CE, 1);  // 进入发送模式,启动射频发送
 printk (DEVICE_NAME " DR is\t%d\n",s3c2410_gpio_getpin(DR));
 mdelay(1);
 s3c2410_gpio_setpin(TRX_CE, 0); //发完数据后,返回空闲状态
 mdelay(1);
 printk (DEVICE_NAME " DR is\t%d\n",s3c2410_gpio_getpin(DR));
 mdelay(1);
}
static void RxPacket( void )
{
 uint i;
 mdelay(10);
 s3c2410_gpio_setpin(TRX_CE, 0); //发完数据后,返回空闲状态
 udelay(1);
 s3c2410_gpio_setpin(CSN, 0); // CSN 片选信号,SPI 使能
 mdelay(1);
 SpiWrite(RRP);          // 准备读取接收到的数据
 mdelay(1);
 for (i=0; i<32; i++)
 {
   RxBuf[i]=SpiRead();     // 通过 SPI 接口从 905 芯片读取数据  
  mdelay(1);
 }
 s3c2410_gpio_setpin(CSN, 1); // CSN 片选信号,SPI 禁止
 mdelay(3);
 s3c2410_gpio_setpin(TRX_CE, 1);  // 进入发送模式,启动射频发送
 mdelay(1);
}
static int sbc2440_rf905s_ioctl(
 struct inode *inode,
 struct file *file,
 unsigned int cmd,
 unsigned long arg)
{
 switch(cmd) {
 case 1:
  define_io();
   nRF905Init (); //RF905初始化
  mdelay(1);
  Config905();
  mdelay(1);
 
   SetTxMode( ); //设置发送模式
  mdelay(1);
  printk (DEVICE_NAME"\tset txmode\n");
  return -EINVAL;
 case 5:
  TxBuf[2] = (uchar)arg;
  TxPacket( );
  TxPacket( );
  return -EINVAL;
 case 3:
  TxBuf[0] = (uchar)arg;
  TxPacket( );
  TxPacket( );
  return -EINVAL;
 case 4:
  TxBuf[1] = (uchar)arg;
  TxPacket( );
  TxPacket( );
  return -EINVAL;
 case 6:
  SetRxMode();
  mdelay(5);
  if (s3c2410_gpio_getpin(DR)){
   printk (DEVICE_NAME"\t recerive sucessed! \n");
   RxPacket();
  }
  mdelay(1);
  if (s3c2410_gpio_getpin(DR)){
   printk (DEVICE_NAME"\t recerive sucessed! \n");
   RxPacket();
  }
  mdelay(1);
  printk (DEVICE_NAME"\tget the wendu:  %d %d . %d C\n", RxBuf[6], RxBuf[7], RxBuf[8]);
 default:
  return -EINVAL;
 }
 return -EINVAL;
}
static struct file_operations dev_fops = {
 .owner = THIS_MODULE,
 .ioctl = sbc2440_rf905s_ioctl,
};
static struct miscdevice misc = {
 .minor = MISC_DYNAMIC_MINOR,
 .name = DEVICE_NAME,
 .fops = &dev_fops,
};
static int __init dev_init(void)
{
 int ret;
 memset(TxBuf, 0, 32);
 memset(RxBuf, 0, 32);
 ret = misc_register(&misc);
 printk (DEVICE_NAME"\tinitialized\n");
 return ret;
}
static void __exit dev_exit(void)
{
 misc_deregister(&misc);
 printk (DEVICE_NAME"\t rf905 exits! \n");
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");
该程序只是单纯实现IOCTL 填充函数而已,在调试过程中, 注意结构体变量的定义(查看下内核变量的定义) 能简单实现无线的简单驱动
2.注意调用系统的延迟函数, 实现器件的延迟
3.还无有补充read write 函数, 和对内核机制, 虚拟地址 物理地址的映射, 一些系统调用函数等不熟悉,有待提高, 继续学习。。
 
阅读(950) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~