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

📄 obcan_pxa.c

📁 arm-linux 下小键盘驱动程序源码
💻 C
字号:
/* *	General Char Device for linux * */ #include <linux/module.h>#include <linux/config.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/mm.h>#include <linux/miscdevice.h>#include <linux/reboot.h>#include <linux/smp_lock.h>#include <linux/init.h>#include <asm/uaccess.h>#include <asm/io.h> #include <asm-arm/arch-pxa/irqs.h>#include "can_pxa.h"#define	mdprintk	printk#define	DEVICE_MINOR	100#define	DEVICE_NAME		"g_chdrv"#define cana_addr 0xeb300000#define canb_addr 0xeb308000//static int g_param1 , g_param2 , g_param3;//MODULE_PARM(g_param1,"i");//MODULE_PARM(g_param2,"i");//MODULE_PARM(g_param3,"i");MODULE_LICENSE("GPL");static DECLARE_WAIT_QUEUE_HEAD( g_w_queue1 );#define	g_chdrv_waitdone( q , tf )	\{	\		if ( !(tf) ) {	\			if (file->f_flags & O_NONBLOCK)\				return -EAGAIN;\			if (wait_event_interruptible( q ,  (tf) ))\				return -ERESTARTSYS;\		}\}/***************************  can控制器   ***************************///#include "can.h"//1.错误代码定义#define    EVerify          12     // 写入回读不同#define    RESET_CAN_OK     13     // 复位成功#define    RESET_CAN_ERROR  14     // 复位错误#define    CAN_RESET        15     //#define    CAN_DEBUG        16     //0XFF#define    CAN_DEBUG_ERROR  17#define    CAN_OK           11#define    CAN_READ_NO_DATA  9     //无数据#define    CAN_WRITE_BUSY   10     //写数据忙      //2.控制寄存器#define    FlagRR          0x01   // 复位请求// 命令寄存器#define    FlagCOS         0x08   // 清除超载#define    FlagRRB         (0x04)   // 清除接收缓冲,允许接收#define    FlagAT          0x02   // 中止发送#define    FlagTR          0x01   // 发送请求//3.状态寄存器#define    FlagBS          0x80   // 总线脱离#define    FlagES          0x40   // 错误#define    FlagTS          0x20   // 正在发送#define    FlagRS          0x10   // 正在接收#define    FlagTCS         0x08   // 发送完成#define    FlagTBS         0x04   // 发送缓冲可用#define    FlagDO          0x02   // 数据超载#define    FlagRBS         0x01   // 接收缓冲有效//4.中断寄存器#define    FlagWUI         0x10   // 唤醒中断#define    FlagOI          0x08   // 超载中断#define    FlagEI          0x04   // 错误中断#define    FlagTI          0x02   // 发送中断#define    FlagRI          0x01   // 接收中断//5.速度#define    BTR0_125K       0x03   // 波特率=125Kbps(16MHZ),(3+1)*2=8#define    BTR1_125K       0x1C   // TSEG1=0x0C=>13,TSEG2=0x01=>2,1+13+2=16#define    BTR0_500K       0x01   // 波特率=500Kbps(16MHZ),(1+1)*2=4#define    BTR1_500K       0x14   // TSEG1=0x04=>5,TSEG2=0x01=>2,1+5+2=8#define    BTR0_1M         0x00   // 波特率=1Mbps(16MHZ),(1)*2=2#define    BTR1_1M         0x14   // TSEG1=0x04=>5,TSEG2=0x01=>2,1+5+2=8//6.其他#define    DLCMask         0x0F   // DLC屏蔽#define    IDLMask         0xE0   // D低字节高3位屏蔽#define    IDLShift        5      // ID低字节高3位右对齐移位计数#define    TimeReset       100    // 复位时间,毫秒struct CanControl {   unsigned short CR; //控制寄存器   unsigned short CMR;//命令寄存器   unsigned short SR; //状态寄存器    unsigned short IR;//中断寄存器   unsigned short ACR;//验收寄存器   unsigned short AMR;//屏蔽寄存器   unsigned short BTR0;   unsigned short BTR1;   unsigned short OCR;   unsigned short TR; // 寄存器00..09   unsigned short TxDSCR[2],TxData[8];//发送ID,数据 10..19   unsigned short RxDSCR[2],RxData[8];//接收ID,数据 20..29   unsigned short XX30,CDR;//31 时钟驱动 30..31   // unsigned char XX32[0x0100-32],RST;   //复位控制 0x0100} volatile *pcan=0;static int can_irq=14;static int canid=0;static int canspeed=0;static int get_sp0(){	switch( canspeed )	{		case	1:	return BTR0_1M;		case	0:	return BTR0_500K;//		case	B125:	return BTR0_125K;	}	return 0;}static int get_sp1(){	switch( canspeed )	{		case	1:	return BTR1_1M;		case	0:	return BTR1_500K;//		case	B125:	return BTR1_125K;	}	return 0;}#define    BTR0_Data       get_sp0()#define    BTR1_Data       get_sp1()#define	CAN_IN_BUF_SIZE	100static struct canmsg_t	can_in_buffer[CAN_IN_BUF_SIZE];static int can_in_buf_head=0; //接受缓冲区头指针static int can_in_buf_tail=0; //接受缓冲区尾指针static char can_write_busy=0;//初始时置0,write后置1,发送中断产生时置0static DECLARE_WAIT_QUEUE_HEAD(r_queue);static DECLARE_WAIT_QUEUE_HEAD(w_queue);static int irqt_tx=0 , irqt_rx=0 ;void interrupt_interrupt_can(int irq, void *dev_id, struct pt_regs *regs){  unsigned char ir;	unsigned short t,t1;	struct canmsg_t *pct = &can_in_buffer[can_in_buf_tail];  ir=(pcan->IR)&0xff;	printk("IR=%x,CR=%x\n",ir,pcan->CR);	  if((ir&FlagRI))  {//接受中断        		t  	= (pcan->RxDSCR[0])&0xff;		t1	= (pcan->RxDSCR[1])&0xff;		pct->id = (t<<3) | (t1>>5);    pct->length = t1&0xf;				pct->data[0] = pcan->RxData[0];		pct->data[1] = pcan->RxData[1];		pct->data[2] = pcan->RxData[2];		pct->data[3] = pcan->RxData[3];		pct->data[4] = pcan->RxData[4];		pct->data[5] = pcan->RxData[5];		pct->data[6] = pcan->RxData[6];		pct->data[7] = pcan->RxData[7];					pcan->CMR=FlagRRB;//清除接受缓冲区		can_in_buf_tail++;		can_in_buf_tail%=CAN_IN_BUF_SIZE;		wake_up_interruptible(&r_queue);					irqt_rx++;	}  else   if(ir&FlagTI||ir==0xe0)//发送中断  {    can_write_busy=0;		wake_up_interruptible(&w_queue);		irqt_tx++;    }  else  {		reset_interrupt_can();		printk("can reset , SR=%x\n",pcan->SR);		wake_up_interruptible(&r_queue);		wake_up_interruptible(&w_queue);	}	return;}int reset_interrupt_can(void){//复为can控制器   short b;   int i;      pcan->CR=0x0f;   pcan->CMR=0;   pcan->BTR0=BTR0_Data;   pcan->BTR1=BTR1_Data;   printk(" 8bit read on 8bit device:%x,%x\n",pcan->BTR0,pcan->BTR1);   printk("16bit read on 8bit device:%x\n",*((unsigned int *)&pcan->BTR0));     if((pcan->BTR0!=BTR0_Data)|(pcan->BTR1!=BTR1_Data))   {   		printk("error\n");      return RESET_CAN_ERROR;   }   pcan->ACR=0x07;   pcan->AMR=0xff;   pcan->OCR=0xfa;      b=pcan->CR;   pcan->CR=b&0xfe;      can_in_buf_head = 0;   can_in_buf_tail = 0;   can_write_busy=0;      return RESET_CAN_OK;}/* *	Allow only one person to hold it open */static int g_chdrv_open(struct inode *inode, struct file *file){	mdprintk("g_chdrv device %s opened\n",DEVICE_NAME);	reset_interrupt_can();		return 0;}static int g_chdrv_release(struct inode *inode, struct file *file){	mdprintk("g_chdrv device %s released\n",DEVICE_NAME);	return 0;}static ssize_t g_chdrv_read(struct file *file, char *data, size_t len, loff_t *ppose){	struct canmsg_t	t;	int i;		mdprintk("g_chdrv device %s read %d bytes\n",DEVICE_NAME,len);	g_chdrv_waitdone( r_queue , (can_in_buf_head!=can_in_buf_tail) );	copy_to_user( data , &can_in_buffer[can_in_buf_head] , sizeof(t) );  printk("RxDsCR is %x,%x\n",pcan->RxDSCR[0],pcan->RxDSCR[1]);  for(i=0;i<8;i++) printk("the data %x is %x\n",i,pcan->RxData[i]);	can_in_buf_head++;	can_in_buf_head%=CAN_IN_BUF_SIZE;	return 1;}static ssize_t g_chdrv_write(struct file *file, const char *data, size_t len, loff_t *ppos){	struct canmsg_t	t;	int i;	mdprintk("g_chdrv device %s write %d bytes\n",DEVICE_NAME,len);		g_chdrv_waitdone( w_queue , !can_write_busy );	  if(can_write_busy)      return 0;		copy_from_user( &t , data , sizeof(t) );	if( t.length>8 )t.length=8;		pcan->TxDSCR[0] = t.id>>3 ;	pcan->TxDSCR[1] = ((t.id&7)<<5) | (t.length&0xf);	for(i=0;i<t.length;i++)pcan->TxData[i] = t.data[i];	pcan->CMR=FlagTR;  can_write_busy=1;	return 1;}static int g_chdrv_ioctl(struct inode *inode, struct file *file,	unsigned int cmd, unsigned long arg){	return 0;}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////static struct file_operations g_chdrv_fops = {	owner:		THIS_MODULE,	read:		g_chdrv_read,	write:		g_chdrv_write,	ioctl:		g_chdrv_ioctl,	open:		g_chdrv_open,	release:	g_chdrv_release,};static struct miscdevice g_chdrv_miscdev = {	minor:		DEVICE_MINOR,	name:		DEVICE_NAME,	fops:		&g_chdrv_fops,};MODULE_PARM(canid,"i");MODULE_PARM(canspeed,"i");static int __init g_chdrv_init(void){	int ret;	if( canid==0 )	{		can_irq = 14;		pcan = cana_addr;		g_chdrv_miscdev.minor = 100;		g_chdrv_miscdev.name = "cana";	}else	{		can_irq = 13;		pcan = canb_addr;		g_chdrv_miscdev.minor = 101;		g_chdrv_miscdev.name = "canb";	}	set_GPIO_IRQ_edge(can_irq,GPIO_FALLING_EDGE);	/*if( request_irq(IRQ_GPIO(can_irq), interrupt_interrupt_can,SA_INTERRUPT, g_chdrv_miscdev.name,NULL) )	{		printk("Get Interrupt %d Error\n" , can_irq );		return -1;	}*/	ret = misc_register(&g_chdrv_miscdev);	mdprintk("g_chdrv device %s init\n",DEVICE_NAME);	if (ret)	{		//free_irq(IRQ_GPIO(can_irq),NULL);		printk("error\n");		return ret;	}	reset_interrupt_can();	return 0;}static void __exit g_chdrv_exit(void){	//free_irq(IRQ_GPIO(can_irq),NULL);	misc_deregister(&g_chdrv_miscdev);	mdprintk("g_chdrv device %s exit\n",DEVICE_NAME);}module_init(g_chdrv_init);module_exit(g_chdrv_exit);

⌨️ 快捷键说明

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