⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nnrf2401.c

📁 组网协议设计中
💻 C
字号:
#include<linux/module.h>#include<linux/init.h>#include<linux/kernel.h>#include<linux/config.h>#include<linux/fs.h>#include<asm/uaccess.h>#include<linux/version.h>#include<linux/irq.h>#include<linux/poll.h>#include<linux/delay.h>#include<asm/arch/irq.h>#include<asm/hardware.h>#include<linux/spinlock.h>#include<asm/arch/S3C2440.h>   //为了使用GPIO端口定义#include<linux/devfs_fs_kernel.h> //为了使用devfs_register和devfs_unregister函数MODULE_LICENSE("GPL");

#define DEVICE_NAME "nRF2401"
#define MAJOR_NUM 233#define MINOR_NUM 0
static devfs_handle_t devfs_handle=NULL;static devfs_handle_t devfs_nRF2401_dir=NULL; //在/dev下建立相应的目录#define DEV_DIR "nRF2401" static DECLARE_WAIT_QUEUE_HEAD(nRF2401_wait); static int ready=0;                            
#define DR1     GPIO_G9                  //定义GPIO口与NRF2440的接口#define PWR_UP  GPIO_B6#define CLK1    GPIO_G7#define MISO    GPIO_G5#define MOSI    GPIO_G6#define CE      GPIO_E13#define CS      GPIO_E12#define LED     GPIO_F4
#define PACKETLEN 22
unsigned char RData[PACKETLEN];  //指向驱动程序申请的用于存放接收数据的内存区域
static struct nRF2401Config{	unsigned char n; //配置字长度	unsigned char buf[15];//配置字数组}config={15,        {	  0x00,			//接收通道2有效数据长度          0xB0,			//接收通道1有效数据长度		          0x00,0x00,0x00,0x00,0x00,  //接收通道2地址,最长5字节,缺少位用0填          0x00,0xcc,0xcc,0xcc,0xcc,	//接收通道1地址,最长5字节,缺少位用0填          0x83,                //32位地址长度(bit7-bit2);16bit CRC(bit1);CRC enable          0x4f,//单通道接收(bit7);ShockBrust(bit6);速率(bit5);晶振频率(bit4-bit2);功率(bit2-bit0)          0x01		//频道(bit7-bit1);发送/接收(bit0:0/1)	}       };static void SPI_init(void){	//IO initial	set_gpio_ctrl(DR1|GPIO_MODE_ALT0);//设置为DR1为中断模式	set_gpio_ctrl(CE|GPIO_MODE_OUT|GPIO_PULLUP_EN);	set_gpio_ctrl(CS|GPIO_MODE_OUT|GPIO_PULLUP_EN);	set_gpio_ctrl(PWR_UP|GPIO_MODE_OUT|GPIO_PULLUP_EN);	set_gpio_ctrl(CLK1|GPIO_MODE_ALT1|GPIO_PULLUP_EN);//设置引脚为SPI	set_gpio_ctrl(MISO|GPIO_MODE_ALT1|GPIO_PULLUP_EN);	set_gpio_ctrl(MOSI|GPIO_MODE_ALT1|GPIO_PULLUP_EN);		set_gpio_ctrl(LED|GPIO_MODE_OUT|GPIO_PULLUP_EN);//设置LED引脚	write_gpio_bit(PWR_UP,0);//初始化nFR2401引脚
	write_gpio_bit(CE,0);
	write_gpio_bit(CS,0);	write_gpio_bit(LED,1);//关LED
		//REGISTER initial	SPPRE1=0xff; //设置波特率为132,300bps	SPCON1=0x18;//设置为查询方式	printk("SPI configured\n");	}	static void SPI_poll_done(void){	int ncount=0;	while(!(SPSTA1&0x01)){    //判断SPI发送寄存器是否已经准备好		ncount++;		if(ncount>=5000){			printk("SPI state poll failed\n");
		//	return -1;			break;			}			}
		//return 0;		}static void SPI_tx_data(unsigned char data){                //通过SPI发送数据	SPI_poll_done();	SPTDAT1=data;	SPI_poll_done();	}	
void RX_Packet(void)						
{					//读取数据包
	unsigned char i;
	for(i=0;i<PACKETLEN;i++)
	{
		SPI_tx_data(0xff);
		RData[i]=SPRDAT1;
		}	printk("recevie RX_Packet\n");
}		
static void nRF2401_ON(void) {	                                //nRF2401上电	write_gpio_bit(CE,0);
	write_gpio_bit(CS,0);
	write_gpio_bit(PWR_UP,1);
	mdelay(3);//延时3ms,nrf2401进入待机模式
	printk("nRF2401 on\n");
}
static void nRF2401_Config(void)
{                                   //nRF2401配置
	unsigned char i;
	write_gpio_bit(CE,0);
	write_gpio_bit(CS,1);
	udelay(10);   //延时10us
	for(i=0;i<config.n;i++){
		SPI_tx_data(config.buf[i]);
		}
	write_gpio_bit(CS,0);
	write_gpio_bit(CE,1);//激活接收模式,经过202us内部延时后进入接收模式
	printk("nRF2401 configed\n");
}

static void nRF2401_Close(void)//关闭nRF2401
{
	write_gpio_bit(CE,0);
	write_gpio_bit(CS,0);
	write_gpio_bit(PWR_UP,0);
	printk("nRF2401 close\n");
}	
static void nRF2401_irq(int irq,void *dev_id,struct pt_regs *reg)
{       
	unsigned int flags;	write_gpio_bit(LED,0);//开LED,表示接收到数据
	save_flags(flags); //中断处理时禁止再次中断
	cli();
	//printk("nRF2401have prepared the datas!\n");     //中断处理函数	//mdelay(1000);
	RX_Packet();	
	restore_flags(flags);		write_gpio_bit(LED,1);//关LED,表示读完数据	ready=1;
	wake_up_interruptible(&nRF2401_wait); //通知应用程序有数据可读
	
}

static int requestb_irq(void)   //中断申请函数
{ 
	set_external_irq(IRQ_EINT17,EXT_RISING_EDGE,GPIO_PULLUP_DIS);//DR1上升沿触发
	if(request_irq(IRQ_EINT17,&nRF2401_irq,SA_INTERRUPT,DEVICE_NAME,&nRF2401_irq)){
		printk(DEVICE_NAME" request_irq failed!\n");
		return -1;
		}	printk("irq succes!\n");
	return 0;
}
static void freeb_irq(void)
{
	free_irq(IRQ_EINT17,nRF2401_irq);	
}
static int nRF2401_open(struct inode *inode,struct file *file){
	ready=0;
	nRF2401_ON();
	nRF2401_Config();   printk(DEVICE_NAME" open\n");   MOD_INC_USE_COUNT;   return 1;   }static int nRF2401_release(struct inode *inode,struct file *file){	nRF2401_Close();   printk(DEVICE_NAME" release\n");
      MOD_DEC_USE_COUNT;   return 1;   }static ssize_t nRF2401_read(struct file *file,char *buf,size_t len,loff_t *off){   	  	__copy_to_user(buf,RData,sizeof(RData));
  	ready=0;   	return sizeof(RData);}/*static ssize_t nRF2401_write(struct file *file,const char *buf,size_t len,loff_t *off){	__copy_from_user(&,buf,sizeof());	return sizeof();}*/static  unsigned int nRF2401_select(struct file *file,struct poll_table_struct *wait){	//printk("poll ready is%d\n",ready);		if(ready)return 1;	poll_wait(file,&nRF2401_wait,wait);//使外部应用程序阻塞,等待数据准备好	return 0;}
static struct file_operations nRF2401_fops={ owner: THIS_MODULE, open:nRF2401_open, release:nRF2401_release, //ioctl:nRF2401_ioctl, read:nRF2401_read,// write:nRF2401_write, poll:nRF2401_select, };
 static int nRF2401_init(void){    int ret;    ret=register_chrdev(MAJOR_NUM,DEVICE_NAME,&nRF2401_fops);    if(ret)    {    printk(DEVICE_NAME" register failure\n");    return ret;    }    else    printk(DEVICE_NAME" register success\n");     ret=requestb_irq();    if(ret){    	ret=unregister_chrdev(MAJOR_NUM,DEVICE_NAME);    	 if(ret)   		 {    		printk(DEVICE_NAME" unregister failure\n");   		 }   	 else printk(DEVICE_NAME" unregister success\n");    	return ret;    	}    devfs_nRF2401_dir=devfs_mk_dir(NULL,DEV_DIR,NULL);    devfs_handle=devfs_register(devfs_nRF2401_dir,DEVICE_NAME,DEVFS_FL_DEFAULT,MAJOR_NUM,MINOR_NUM,S_IFCHR|S_IRUSR|S_IWUSR,&nRF2401_fops,NULL);    SPI_init();    return ret;}static void nRF2401_exit(void){       int ret;    devfs_unregister(devfs_handle);    freeb_irq();    ret=unregister_chrdev(MAJOR_NUM,DEVICE_NAME);    if(ret)    {    printk(DEVICE_NAME" unregister failure\n");    }    else    printk(DEVICE_NAME" unregister success\n");        }  module_init(nRF2401_init);module_exit(nRF2401_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -