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

📄 obcanb_r.c

📁 CAN在S3C2440下的驱动代码
💻 C
字号:
//中断设备程序的编写//1.编译开关://gcc -O2 -D__KERNEL__ -DMODULE -I/usr/src/linux/include -c example.c -o example.o//2.加载模快:// insmod  example.o//3.卸载模快://  rmmod /*************************  cana中断处理程序  *************************///设备名:cana,地址:D0000-D01FF//#define _debug  //编译调试代码开关#include <asm/io.h>#define cana_ADDR        0xfa000000#define cana_MEM_LEN     0X200  #define INTERRUPT        IRQ_EINT3     //使用5号中断#define MODULE_VERSION   "1.0"#define MODULE_NAME      "can_b_for_arm_f"#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/proc_fs.h>#include <linux/string.h>#include <asm/io.h> #include <asm/arch/irqs.h>static void Sx(int a){  unsigned long volatile *pp = (unsigned long volatile *)0xfe000064;    if(a)*pp|=1;  else *pp&=0xfffffffe;  }//#define	EnCanW	Sx(0)//#define 	DisCanW	Sx(1)#define	EnCanW#define 	DisCanW/***************************  can控制器   ***************************///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#define    BTR0_Data       BTR0_500K#define    BTR1_Data       BTR1_500K//6.其他#define    DLCMask         0x0F   // DLC屏蔽#define    IDLMask         0xE0   // D低字节高3位屏蔽#define    IDLShift        5      // ID低字节高3位右对齐移位计数#define    TimeReset       100    // 复位时间,毫秒char volatile *OUTP;#define outb(X,Y)   OUTP=(char *)(0xfb000000+Y); *OUTP=X;struct CanControl {   unsigned char CR; //控制寄存器   unsigned char CMR;//命令寄存器   unsigned char SR; //状态寄存器    unsigned char IR;//中断寄存器   unsigned char ACR;//验收寄存器   unsigned char AMR;//屏蔽寄存器   unsigned char BTR0;   unsigned char BTR1;   unsigned char OCR;   unsigned char TR; // 寄存器00..09   unsigned char TxDSCR[2],TxData[8];//发送ID,数据 10..19   unsigned char RxDSCR[2],RxData[8];//接收ID,数据 20..29   unsigned char XX30,CDR;//31 时钟驱动 30..31   // unsigned char XX32[0x0100-32],RST;   //复位控制 0x0100} volatile *pcana;#define FRAME_DATA_SIZE   10   //每帧大小(包括TxDSCR[2]、TxData[8]或RxDSCR[2]、RxData[8])#define IN_BUFFER_LEN     FRAME_DATA_SIZE*200  //接受缓冲区大小:100帧static unsigned char cana_in_buffer[IN_BUFFER_LEN];   //接受缓冲区:指通过CAN接受的数据临时存放处,用户通过read函数读取该缓冲区static int cana_in_buf_head=0; //接受缓冲区头指针static int cana_in_buf_tail=0; //接受缓冲区尾指针static char cana_write_busy=0;//初始时置0,write后置1,发送中断产生时置0static struct proc_dir_entry *interrupt_cana_file;int cana_interruptcount = 0;char cana_flag=0;#include "filter.h"//中断处理函数static unsigned long irqt_tx=0,irqt_rx=0;static unsigned char rgbuf[20][12];static int prgb=0,btrig=0,btrigcount;void interrupt_interrupt_cana(int irq, void *dev_id, struct pt_regs *regs){    unsigned char ir;    static char  into_flag=0;    static int first=1,errcount=0;    static unsigned char rcount = 0;	static int gua = 0;	int i,ccc;    if(into_flag) return;    into_flag=1;    ir=pcana->IR;if(ir!=0xe2)printk("IR=%x,CR=%x\n",ir,pcana->CR);	    if((ir&FlagRI))    {//接受中断        		//pcana->RxData[1] = 0x44;	cana_in_buffer[cana_in_buf_tail]=pcana->RxDSCR[0];        cana_in_buffer[cana_in_buf_tail+1]=pcana->RxDSCR[1];			//	if(IsOk(cana_in_buffer[cana_in_buf_tail])&&//	   ((cana_in_buffer[cana_in_buf_tail+1]&0x1f)<=8))	{//           cana_in_buffer[cana_in_buf_tail+1]=pcana->RxDSCR[1];           cana_in_buffer[cana_in_buf_tail+2]=pcana->RxData[0];           cana_in_buffer[cana_in_buf_tail+3]=pcana->RxData[1];           cana_in_buffer[cana_in_buf_tail+4]=pcana->RxData[2];           cana_in_buffer[cana_in_buf_tail+5]=pcana->RxData[3];           cana_in_buffer[cana_in_buf_tail+6]=pcana->RxData[4];           cana_in_buffer[cana_in_buf_tail+7]=pcana->RxData[5];           cana_in_buffer[cana_in_buf_tail+8]=pcana->RxData[6];           cana_in_buffer[cana_in_buf_tail+9]=pcana->RxData[7];           if(cana_in_buf_tail+FRAME_DATA_SIZE<IN_BUFFER_LEN)              cana_in_buf_tail=cana_in_buf_tail+FRAME_DATA_SIZE;	   else	      cana_in_buf_tail=0;	}{static int flagin = 0;EnCanW;//if(flagin==1)//	for(flagin=0;flagin<1000;flagin++);		pcana->CMR=FlagRRB;//清除接受缓冲区//i = pcana->CMR;DisCanW;flagin=1;irqt_rx++;}     }     else      if(ir&FlagTI||ir==0xe0)//发送中断     {        cana_write_busy=0;//	printk("send a");	irqt_tx++;     }     else     {       reset_interrupt_cana();	printk("reset a , SR=%x\n",pcana->SR);     }     into_flag=0;		return;}static unsigned char scount=0;//read响应函数//page和count分别对应调用函数read传递的参数buf和count//而且一次只返回一帧数据,故count和其他参数忽略//返回值为0表示无数据,否则page返回一帧数据static int proc_read_interrupt_cana(char *page, char **start, off_t off,                                       int count, int *eof, void *data){	printk("IRQ Times tx:%d,rx:%d , lastvalue tx:%x\n",irqt_tx,irqt_rx,scount);	return 0;}int __init reset_interrupt_cana(void){//复为can控制器   unsigned char b;   int i;      EnCanW;   pcana->CR=0x0f;//开放中断   pcana->CMR=0;   pcana->BTR0=BTR0_Data;   pcana->BTR1=BTR1_Data;//置波特率   if((pcana->BTR0!=BTR0_Data)|(pcana->BTR1!=BTR1_Data))//写入回读不同      return RESET_CAN_ERROR;   pcana->ACR=0x07;   pcana->AMR=0xff;   pcana->OCR=0xfa;      b=pcana->CR;   pcana->CR=b&0xfe;   cana_write_busy=0;   DisCanW;   return RESET_CAN_OK;}static char can_a_counts=0;//for debugstatic int proc_write_interrupt_cana(struct file *file,			const char *buffer,unsigned long count,void *data){	static int loop=0,wif=1;	int i,c=0,k;    if(cana_write_busy)         return 0;		pcana->TxDSCR[0]=scount;	pcana->TxDSCR[1]=(wif&1)?0xe8:0xe2;	for(i=0;i<8;i++)	{		pcana->TxData[i] = scount+i;	}	for(i=0;i<8;i++)	{		while( pcana->TxData[i]!=scount+i )		{			printk("error on write TxData[%d] now %x, should be %x\n",i,pcana->TxData[i],scount);			pcana->TxData[i]=scount+i;		}	}		scount++;	scount&=0xf;			pcana->CMR=FlagTR;    cana_write_busy=1;    return CAN_OK;}//初始化函数static int __init init_interrupt_cana(void){  int rv = 0;  unsigned char b;// we use bank5 for can access   unsigned long volatile *pp = (unsigned long volatile *)0xfc000000;  *pp&=0xff0fffff;  *pp|=0x00c00000;  pp  =0xfc000018;  *pp =0x7ff0;EnCanW;  pcana = cana_ADDR;  pcana = (struct CanControl *)ioremap_nocache(0x29000000,cana_MEM_LEN);  pcana->CR=0x0f;    // BUG---BUG  //return EVerify;    pcana->CMR=0x0;  //printk("IR=%x,SR=%x\n",pcana->IR,pcana->SR);  pcana->BTR1=BTR1_Data;//置波特率  pcana->BTR0=BTR0_Data;  //printk(" 8bit read on 8bit device:%x,%x\n",&pcana->BTR0,&pcana->BTR1);  printk(" 8bit read on 8bit device:%x,%x\n",pcana->BTR0,pcana->BTR1);  printk("16bit read on 8bit device:%x\n",*((unsigned short *)&pcana->BTR0));  if((pcana->BTR0!=BTR0_Data)|(pcana->BTR1!=BTR1_Data))  {//写入回读不同      printk("What read is not what written  when cana initialize\n");      iounmap((void *)pcana);      return EVerify;  }  pcana->ACR=0x07;  pcana->AMR=0xff;  pcana->OCR=0xfa;  b=pcana->IR;  interrupt_cana_file = create_proc_entry("canb", 0444, NULL);  if(interrupt_cana_file == NULL)  {      printk("create_proc_entry error....\n");      iounmap((void *)pcana);        return -ENOMEM;  }  interrupt_cana_file->data = NULL;  interrupt_cana_file->read_proc = &proc_read_interrupt_cana;  interrupt_cana_file->write_proc = &proc_write_interrupt_cana;  interrupt_cana_file->owner = THIS_MODULE;  set_external_irq(INTERRUPT, EXT_FALLING_EDGE , 0 );  rv=request_irq(INTERRUPT, interrupt_interrupt_cana,SA_INTERRUPT,                 "canb",NULL);  if(rv)   {    printk("Can't get interrupt %d\n", INTERRUPT);    iounmap((void *)pcana);    remove_proc_entry("canb", NULL);    return -1;  }    b=pcana->CR;  pcana->CR=b&0xfe;  printk("%s %s initialized \n",MODULE_NAME, MODULE_VERSION);  DisCanW;    Sx(1);    return 0;}static void __exit cleanup_interrupt_cana(void){  free_irq(INTERRUPT,NULL);//释放所占用中断号  iounmap((void *)pcana);  remove_proc_entry("canb", NULL);   printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERSION);}module_init(init_interrupt_cana);module_exit(cleanup_interrupt_cana);MODULE_AUTHOR("yh");MODULE_DESCRIPTION("interrupt_cana proc module");EXPORT_NO_SYMBOLS;

⌨️ 快捷键说明

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