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

📄 sja1000.c

📁 嵌入式开发板EDB9315的CAN测试程序
💻 C
字号:
#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <asm/io.h>#include <asm/uaccess.h>#include <linux/ioport.h>#include <linux/poll.h>#include <linux/delay.h>#include "sja1000.h"#define DEVICE_NAME "SJACAN"unsigned char Receive(unsigned char *RCdata);void Transmit(unsigned char *TXdata);unsigned SJA1000_READ(unsigned sja_reg_addr);void SJA1000_WRITE(unsigned sja_reg_addr, unsigned value);unsigned long SJA1000_DATA_VBASE=0;unsigned long SJA1000_ADDR_VBASE=0;int log_flag = 1; // 0 -- stop buffer CAN frames. 1 -- start buffer CAN frames.#define MAX_NR_FRAMES	100struct rec{	unsigned char databuf[11 * MAX_NR_FRAMES];	int start,end;	/*0,1,2,...9*/} rd_buf;void init_rd_buf(){	rd_buf.start = 0;	rd_buf.end = 0;}int is_empty_rd_buf(){	return (rd_buf.start == rd_buf.end);}int is_full_rd_buf(){	return (rd_buf.start == (rd_buf.end+1) % MAX_NR_FRAMES);}void out_rd_buf(unsigned char *buf){	if(is_empty_rd_buf())		return;	memcpy(buf, &rd_buf.databuf[rd_buf.start*11],11);	rd_buf.start = ++rd_buf.start % MAX_NR_FRAMES;}void in_rd_buf(unsigned char *buf){	if(is_full_rd_buf())		return;	memcpy(&rd_buf.databuf[rd_buf.end*11],buf,11);	rd_buf.end = ++rd_buf.end % MAX_NR_FRAMES;}void sja1000_can_irq(int irq, void *dev_id, struct pt_regs *regs){	unsigned char buf[11];	int intrkind;	intrkind=SJA1000_READ(SJA1000_IR);//read the interrupt status		if(intrkind & 0x01 == 0)/*not receive interrupt*/        {		goto out;	}	Receive(buf);	//printk("int1 : %d %d %d %d %d %d %d %d %d %d %d\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10]);	if(log_flag)		in_rd_buf(buf);	//buffer this frameout:	SJA1000_WRITE(SJA1000_CMR,4); //clear sja receive buffer in order to clear it's INT signal	//*(volatile unsigned long*)(MCF_MBAR + 0x20) |= 0x80000000;//clear pending bit	//clear EPP interrupt}/*-------------------------------------------------------------------*/unsigned SJA1000_READ(unsigned sja_reg_addr){    unsigned value;    SJA1000_SET_AEN;    writeb(sja_reg_addr,SJA1000_ADDR_VBASE);    SJA1000_CLR_AEN;    value=readb(SJA1000_DATA_VBASE);    return value;}void SJA1000_WRITE(unsigned sja_reg_addr, unsigned value){        SJA1000_SET_AEN;        writeb(sja_reg_addr,SJA1000_ADDR_VBASE);        SJA1000_CLR_AEN;        writeb(value,SJA1000_DATA_VBASE);	}/*------------------------------------------------------------*/unsigned char Receive(unsigned char *RCdata){	int i=16;	int j=0;	unsigned char sr = SJA1000_READ(SJA1000_SR);		for(;j<11;i++,j++){		RCdata[j] = SJA1000_READ(i);	}	SJA1000_WRITE(SJA1000_CMR,0x04);   		return sr;	}void Transmit(unsigned char *TXdata){	int i=16;	int j=0;	do{            printk("xxxxxxxxxxxx\n");	}while( !(SJA1000_READ(SJA1000_SR)&0x04) );	for(;j<11;i++,j++){		SJA1000_WRITE(i,TXdata[j]);                printk("TXdata[%d]=%d ",j,TXdata[j]);	}	SJA1000_WRITE(SJA1000_CMR,0x01);//0x01);		}/*------------------------------------------------------------------*/static int can_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	int error, n, rc = 0;	struct sja_reg sja_reg_data;// = 0;	switch (cmd) {//		case QSPIIOCS_LOGCANFRAMES://			log_flag = arg;//			break;		case SJA_IOCTL_WRITE:				copy_from_user(&sja_reg_data,(void *)arg,sizeof(struct sja_reg));			//sja_reg_data = (struct sja_reg*)arg;			//error = verify_area(VERIFY_READ, sja_reg_data,			//				sizeof(struct sja_reg));			//if (error)			//	return error;                        printk("write_sja_reg_addr=%x\n",sja_reg_data.sja_reg_addr);                        printk("write_sja_reg_value=%x\n",sja_reg_data.sja_reg_value);			SJA1000_WRITE(sja_reg_data.sja_reg_addr, sja_reg_data.sja_reg_value);			break;		case SJA_IOCTL_READ:                        printk("enter read\n");				copy_from_user(&sja_reg_data,(void *)arg,sizeof(struct sja_reg));			//sja_reg_data = (struct sja_reg*)arg;                        printk("sja_reg_addr=%x\n",sja_reg_data.sja_reg_addr);			//error = verify_area(VERIFY_READ, sja_reg_data,			//				sizeof(struct sja_reg));			//if (error)				//return error;			sja_reg_data.sja_reg_value = SJA1000_READ(sja_reg_data.sja_reg_addr);                        printk("sja_reg_value=%x\n",sja_reg_data.sja_reg_value);			copy_to_user((void *)arg,&sja_reg_data,sizeof(struct sja_reg));			break;		default:			rc = -EINVAL;			break;				}	return rc;}static int can_open(struct inode *inode, struct file *file){	MOD_INC_USE_COUNT;	return 0;}static int can_release(struct inode *inode, struct file *file){	MOD_DEC_USE_COUNT;	return 0;}static loff_t can_llseek(struct file *filep, loff_t off, int mod){	return off;}/*---------------------------------------------------*/static ssize_t can_read(struct file *filep,char *buffer,size_t length,loff_t *ppos){	int total = 0;//	down(&sem);	be careful!					while(1){		if(total >= length)			break;					if(is_empty_rd_buf())			break;					out_rd_buf(buffer+total);				total+=11;	}//	up(&sem);	return total;}static ssize_t can_write(struct file *filep,const char *buffer,size_t length, loff_t *ppos){	int total = 0,i;	unsigned char TXdata[11];//	down(&sem);/*	memcpy(dbuf, buffer, length);*/        for(i=0;i<11;i++){                printk("[%d]=%d ",i,buffer[i]);	}        printk("\n");	while(total+11 <= length){		memcpy(TXdata,buffer+total,11);		Transmit(TXdata);		total += 11;	}	//	up(&sem);	return total;}unsigned int can_poll(struct file *filep, struct poll_table_struct *table){	unsigned int mask = 0;		if(! is_empty_rd_buf() )		mask = POLLIN;	return mask;	}struct file_operations fops = {	owner:		THIS_MODULE,	read:		can_read, 	poll:		can_poll,	llseek:		can_llseek,	write:		can_write,	ioctl:		can_ioctl,	open:		can_open,	release:	can_release,  /* a.k.a. close */};void Egpio_Init(void){        unsigned int uiPADDR, uiPADR,config;	uiPADDR = inl(GPIO_PADDR) | 0x10;//egpio4	outl( uiPADDR, GPIO_PADDR );	uiPADR = inl(GPIO_PADR) | 0x10;//outdata is 1:  4	outl( uiPADR, GPIO_PADR );	uiPADDR = inl(GPIO_PADDR) & 0xdf;//egpio5 is input	outl( uiPADDR, GPIO_PADDR );        config=inl(GPIO_AINTEN) & 0xdf;        outl(config,GPIO_AINTEN);        config=inl(GPIO_AINTTYPE1) & 0xdf;        outl(config,GPIO_AINTTYPE1);        config=inl(GPIO_AINTTYPE2) & 0xdf;        outl(config,GPIO_AINTTYPE2);        config=inl(GPIO_AEOI) | 0x20;        outl(config,GPIO_AEOI);        config=inl(GPIO_AINTEN) | 0x20;        outl(config,GPIO_AINTEN);           config = inl(SMCBCR2);        printk ("SMCBCR2=0X%X\n",config);        config &=0xcfffffff;        outl(config,SMCBCR2);        config = inl(SMCBCR2);        printk ("SMCBCR2=0X%X\n",config);}#define MAXWAIT 2000int InitializeSJA(void){        int i,j,status=0;        unsigned char txbuffer[11]={0,0,0,0,8,255,255,4,255,4},rxbuffer[11]={0};        txbuffer[0]=0x08;        txbuffer[1]=30;        txbuffer[2]=70;        txbuffer[3]=5;	for(i=0;i<MAXWAIT;i++)        {                       j=SJA1000_READ(SJA1000_MOD);                printk ("SJA1000_MOD_00 0X%X\n",j);		SJA1000_WRITE(SJA1000_MOD,0x01);	//reset mode                j=SJA1000_READ(SJA1000_MOD);                printk ("SJA1000_MOD_01 0X%X\n",j);		if(j&0x01)//(SJA1000_READ(SJA1000_MOD)&0x01)             			break;	}	if(i==MAXWAIT)        {                printk ("time out\n");		return -1;          	}        SJA1000_WRITE(SJA1000_BTR0,0X0d);   	SJA1000_WRITE(SJA1000_BTR1,0X22);   //125KHz	SJA1000_WRITE(SJA1000_OCR,0xdA);   //output control 1a	SJA1000_WRITE(SJA1000_CDR,0XCf);   //PeliCAN mode,bypass the input comparator	                                   //disable clkout out	SJA1000_WRITE(SJA1000_ACR0,0xff);	SJA1000_WRITE(SJA1000_ACR1,0xff);	SJA1000_WRITE(SJA1000_ACR2,0xff);	SJA1000_WRITE(SJA1000_ACR3,0xff);	SJA1000_WRITE(SJA1000_AMR0,0xff);	SJA1000_WRITE(SJA1000_AMR1,0xff);	SJA1000_WRITE(SJA1000_AMR2,0xff);	SJA1000_WRITE(SJA1000_AMR3,0xff);	SJA1000_WRITE(SJA1000_INT_IER,0XFF);	//0X00 disable interrupt 0x01 enable receive interrupt	SJA1000_READ(SJA1000_IR);  //clear the interrupt register(except receive interrupt bit)	SJA1000_WRITE(SJA1000_CMR,0x04);//clear receive buffer. if no other message then                                         //clear receive interrupt bit        printk ("--------------------------------------\n");	for(i=0;i<MAXWAIT;i++)        {		SJA1000_WRITE(SJA1000_MOD,0x00);		if( ! (SJA1000_READ(SJA1000_MOD)&0x01) )			break;	}	if(i==MAXWAIT) return -1;        /*        status=SJA1000_READ(SJA1000_SR);        printk("pre_status=0X%X\n",status);                printk("pre_rxbuffer:");        for(i=0;i<11;i++){        printk(" %d",rxbuffer[i]);}        printk("\n");        while(1)        {           status=SJA1000_READ(SJA1000_SR);           if(status & 0x01)          {                 status=SJA1000_READ(SJA1000_IR);                 printk("SJA1000_IR=0X%X\n",status);                    status=Receive(rxbuffer);                 printk("status=0X%X\n",status);                 for(i=0;i<11;i++)                 {                    printk(" %d",rxbuffer[i]);                 }                 printk("\n");                Transmit(txbuffer);           }                      }       */	return 0;}/*----------------init for module driver-----------------*/int __init sja1000_init(void){	int ret;       Egpio_Init();       ret=request_irq(IRQ_GPIO,sja1000_can_irq,SA_INTERRUPT,"can_irq",NULL);       if(ret < 0)        {	 printk ("%s device failed with %d\n","Sorry, registering the IRQ", ret);         return ret;        }                ret = register_chrdev(CAN_MAJOR, DEVICE_NAME, &fops);	if (ret < 0)         {	  printk ("%s device failed with %d\n","Sorry, registering the character", ret);	  return ret;	}        SJA1000_DATA_VBASE =ioremap(nCS2_PHYBASE,4);        SJA1000_ADDR_VBASE =ioremap(nCS7_PHYBASE,4);                InitializeSJA();	init_rd_buf();	//init read buffer	printk("sja1000 driver init ok.\n");	return 0;} /* Cleanup - undid whatever init_module did */void __exit sja1000_exit(void){	int ret;	free_irq(IRQ_GPIO, NULL);        iounmap(SJA1000_DATA_VBASE);        iounmap(SJA1000_ADDR_VBASE);        ret = unregister_chrdev(CAN_MAJOR, DEVICE_NAME);	if (ret < 0)		printk("Error in unregister_chrdev: %d\n", ret);}module_init(sja1000_init);module_exit(sja1000_exit); 

⌨️ 快捷键说明

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