#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 函数, 和对内核机制, 虚拟地址 物理地址的映射, 一些系统调用函数等不熟悉,有待提高, 继续学习。。