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

📄 can012read.c

📁 很明显了
💻 C
字号:
//*******************************************************/
//*File name	:can0.c
//*Writer			:Simon Liu
//*Data				:20050106
//*Reversion	:0.1
//*copywright	:KeyWay
//*******************************************************/
//*									Description
//*This file is for the can0 driver of the linux and init
//*the can0 device SJA1000
//*can0_init():init the can0 device
//*can0_open():open the can0 device
//*can0_release():release the can0 device
//*can0_write():write to the can0 
//*can0_read():read from the can0 
//*******************************************************/
#define PeliCANMode
#define KERNEL 
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/init.h>

#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/module.h>

#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/irq.h>
#include "can0.h"
#include <asm/arch/AT91RM9200.h>
#include <asm/arch/hardware.h>

static int can0_trace;
static int write_busy;
static int read_busy;
//static unsigned long can0_address;
static unsigned long can0_add;
static unsigned long can0_data;

static ssize_t can0_read(struct file*, char*, size_t, loff_t* );
static ssize_t can0_write(struct file*, const char*, size_t, loff_t* );
static int can0_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
static int can0_open(struct inode*,struct file*);
static int can0_release(struct inode*,struct file*);

AT91PS_SYS AT91_SYS1 = (AT91PS_SYS) AT91C_VA_BASE_SYS;

/***********SJA1000 base address**************/
#define BASEADD_can0				0x40000000					//cs3
#define WORK_MODE	AFM_Bit
#define PeliCANMode
//#define can_debug
struct file_operations can0_fops=
{
	write:		can0_write,
	read:		can0_read,
  	ioctl:		can0_ioctl,
	open:		can0_open,
	release:	can0_release,
};

/////////////////////////////////////////////////////////////////////////////////
void can0_reg_write(unsigned char address, unsigned char data)
{
	outb(address,can0_add);
	outb(data,can0_data);
	return;
}

unsigned char can0_reg_read(unsigned char address)
{
	unsigned char can_temp;
	outb(address,can0_add);
	can_temp	= 	inb(can0_data);
	return(can_temp);
}

//init the SJA1000 just work in PeliCan mod 
void can0_int(void)
{
	unsigned char temp;
	printk("\nSJA100 init Begin,and go to reset mode\n");
	
	AT91_SYS1->EBI_SMC2_CSR[2] = (AT91C_SMC2_NWS & 0x8) | AT91C_SMC2_WSEN
					| (AT91C_SMC2_TDF & 0xf00) | AT91C_SMC2_BAT | AT91C_SMC2_DBW_8;	do
	{
	    	can0_reg_write(ModeControlReg,RM_RR_Bit);
	     	temp	=	can0_reg_read(ModeControlReg);
	}while ((temp&RM_RR_Bit) !=RM_RR_Bit);
  	
  	do
  	{
   		can0_reg_write(ClockDivideReg,CBP_Bit|CLKOff_Bit|CANMode_Bit);
   		temp	=	can0_reg_read(ClockDivideReg);
	}while ((temp&CANMode_Bit) !=CANMode_Bit);			//begine,and enter the reset mode
	
	can0_reg_write(AcceptCode0Reg,0);
	can0_reg_write(AcceptCode1Reg,0);
	can0_reg_write(AcceptCode2Reg,0);
	can0_reg_write(AcceptCode3Reg,0);
	can0_reg_write(AccepMask0Reg,0xff);
	can0_reg_write(AccepMask1Reg,0xff);
	can0_reg_write(AccepMask2Reg,0xff);
	can0_reg_write(AccepMask3Reg,0xff);
			
	do{
		can0_reg_write(BusTiming0Reg,Presc_500KB|SJW_500KB);
    		temp=can0_reg_read(BusTiming0Reg);
	}while (temp !=(Presc_500KB|SJW_500KB));				//set the baud rate to 1M by default//
	
	do{
    		can0_reg_write(BusTiming1Reg,TSEG1_500KB|TSEG2_500KB);
    		temp=can0_reg_read(BusTiming1Reg);
    	}while(temp != (TSEG1_500KB|TSEG2_500KB));
    	
    	can0_reg_write(OutControlReg,0x1a);				//out put control
  	
  	can0_reg_write(ModeControlReg,WORK_MODE);
  	temp = can0_reg_read(ModeControlReg);
   	printk("\nThe ModeControlReg is %d\n",temp);
  	can0_reg_write(InterruptEnReg,DISABLE);//disable the interrupt 
	//reset mode
	printk("\nEnd of init the SJA1000\n");
	return;
}

////////////////////////////////////////////////////////////////////////////////
//****************init the can0 *******************************************//
static int __init can0_init(void)
{
	unsigned long ioaddress;
	ioaddress = BASEADD_can0;
	can0_trace = YES;
	
	if(register_chrdev(32,"can0",&can0_fops))
	{
		printk("Can not register can0 driver as major device 30\n");
		return 1;
	}
	else
	{
		printk("\nTiny device SJA1000 driver registered as major device 30 successfully\n");
	}
	
	printk("\nSJA1000 driver success\n \nDriver version 0.1 by Simon Liu \n");
	printk("\nCan0 Physical address is %x\n",(unsigned int)ioaddress);
	can0_data = (unsigned long)(ioremap(ioaddress, 0x1024));
	can0_add = can0_data + 4;
	ioaddress = can0_data;
	printk("\nCan0 virtual address is %x\n",(unsigned int)ioaddress);
	
	if (check_region(ioaddress, 0x1024)<0) 
	{
		printk("Can0:memory already in use\n"); return 1; 
	}
	printk("Can0 will request this memory space \n");
	request_region(ioaddress, 0x1024,"can0");
	printk("Can0 request memory successful\n");
	can0_int();																							//init the SJA1000;
	write_busy = NO;
	read_busy = NO;
	return 0;	
} 

static void __exit  can0_exit(void)
{
	printk("CAN0: can0_exit has been called\n");	unregister_chrdev(32,"can0");	return;
}

///////////////////////////////////////////////////////////////////////////////
//***********open the can0*****************************************//
int can0_open(struct inode * inode,struct file *file)
{
	unsigned char temp;
	temp = can0_reg_read(StatusReg);
	if((temp&0xc0)==0xc0)
	{
	    	can0_reg_write(ModeControlReg,RM_RR_Bit);
	    	can0_reg_write(RxErrCountReg,DISABLE);
	    	can0_reg_write(TxErrCountReg,DISABLE);
	    	can0_reg_write(ModeControlReg,WORK_MODE);
    	}
	MOD_INC_USE_COUNT;
	return 0;

}
//**************release the can0 *********************************//
int can0_release(struct inode * inode ,struct file * file)
{
	MOD_DEC_USE_COUNT;
	return 0;
}
//end of release the can0

static int can0_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)
{
	unsigned int arg_data;
	switch (cmd)
	{
	case 800:
		printk("Will set the can baud rate to 800K\n");
		can0_reg_write(ModeControlReg,RM_RR_Bit);
		can0_reg_write(ClockDivideReg,DivBy1|CANMode_Bit);
		can0_reg_write(BusTiming0Reg,Presc_800KB|SJW_800KB);
		can0_reg_write(BusTiming1Reg,TSEG1_800KB|TSEG2_800KB);
		can0_reg_write(ModeControlReg,WORK_MODE);
		break; 
	
	case 500:
		printk("Will set the can baud rate to 800K\n");
		can0_reg_write(ModeControlReg,RM_RR_Bit);
		can0_reg_write(ClockDivideReg,DivBy1|CANMode_Bit);
		can0_reg_write(BusTiming0Reg,Presc_500KB|SJW_500KB);
		can0_reg_write(BusTiming1Reg,TSEG1_500KB|TSEG2_500KB);
		can0_reg_write(ModeControlReg,WORK_MODE);
		break; 	
						
	case 400:		
		printk("Will set the can baud rate to 400K\n");
		can0_reg_write(ModeControlReg,RM_RR_Bit);
		can0_reg_write(ClockDivideReg,DivBy1|CANMode_Bit);
		can0_reg_write(BusTiming0Reg,Presc_400KB|SJW_400KB);
		can0_reg_write(BusTiming1Reg,TSEG1_400KB|TSEG2_400KB);
		can0_reg_write(ModeControlReg,WORK_MODE);							
		break; 
						
	case 100:					
		printk("will set the can baud rate to 100K\n");
		can0_reg_write(ModeControlReg,RM_RR_Bit);
		can0_reg_write(ClockDivideReg,DivBy1|CANMode_Bit);
		can0_reg_write(BusTiming0Reg,Presc_100KB|SJW_100KB);
		can0_reg_write(BusTiming1Reg,TSEG1_100KB|TSEG2_100KB);
		can0_reg_write(ModeControlReg,WORK_MODE);
		break; 				
	case 202:	//set id
		copy_from_user(&arg_data,(unsigned int *)arg,sizeof(unsigned int));
		can0_reg_write(ModeControlReg,RM_RR_Bit);
		arg_data = arg_data << 3;
		can0_reg_write(AcceptCode0Reg, (arg_data >> 24) & 0xff);
		can0_reg_write(AcceptCode1Reg, (arg_data >> 16) & 0xff);
		can0_reg_write(AcceptCode2Reg, (arg_data >> 8) & 0xff);
		can0_reg_write(AcceptCode3Reg, arg_data  & 0xff);
		can0_reg_write(AccepMask0Reg,0x0);
		can0_reg_write(AccepMask1Reg,0x0);
		can0_reg_write(AccepMask2Reg,0x0);
		can0_reg_write(AccepMask3Reg,0x7);
		
		/*printk("Set AcceptCode0Reg as %X.%X.%X.%X\n",can0_reg_read(AcceptCode0Reg),
			can0_reg_read(AcceptCode1Reg),can0_reg_read(AcceptCode2Reg),can0_reg_read(AcceptCode3Reg));*/
		can0_reg_write(ModeControlReg,WORK_MODE);	
	default: 
		break;
	}
	return (0);	
}		


static  ssize_t can0_read(struct file * file ,char * buff,size_t count,loff_t * offp)
{
	//unsigned char fram_info;
	unsigned char temp;
	unsigned char data_buff[12],i=0;
	temp=can0_reg_read(StatusReg);
	
	if ((temp & RBS_Bit)==RBS_Bit)   												//check the receive state
 	{
    		//printk("state:%d\n",temp);
    		data_buff[i++]=can0_reg_read(RxBuffer1);
    		data_buff[i++]=can0_reg_read(RxBuffer2);
    		data_buff[i++]=can0_reg_read(RxBuffer3);
    		data_buff[i++]=can0_reg_read(RxBuffer4);
     		data_buff[i++]=can0_reg_read(RxBuffer5);
    		data_buff[i++]=can0_reg_read(RxBuffer6);
    		data_buff[i++]=can0_reg_read(RxBuffer7);
    		data_buff[i++]=can0_reg_read(RxBuffer8);
    		data_buff[i++]=can0_reg_read(RxBuffer9);
    		data_buff[i++]=can0_reg_read(RxBuffer10);
    		data_buff[i++]=can0_reg_read(RxBuffer11);
    		data_buff[i++]=can0_reg_read(RxBuffer12);
    		can0_reg_write(CommandReg,RRB_Bit);		//release receive buf
    		copy_to_user(buff,data_buff,12);
				/*temp = can0_reg_read(RxErrCountReg);
    		printk("err count:%d\n",temp);
				temp = can0_reg_read(ErrCodeCapReg);
    		printk("err code:%d\n",temp);*/
    		return 12;
   }
	return 0;
}

ssize_t can0_write(struct file* file, const char* ch, size_t count, loff_t* offp )
{
	unsigned char temp;
	unsigned int ID;
	unsigned char data_buff[12];
	copy_from_user(data_buff,ch,12);
	do
	{
		temp = can0_reg_read(StatusReg);
		temp = temp & TBS_Bit;
	}while (temp !=0x04);
	
	ID = (data_buff[0] << 24) | (data_buff[1] << 16) | (data_buff[2] << 8) | (data_buff[3]);
	ID = ID << 3;
	can0_reg_write(TxFramInFo,0x88);		//framinfo, for EFF format!!!
	can0_reg_write(TxBuffer1,(ID >> 24) & 0xff);
    	can0_reg_write(TxBuffer2,(ID >> 16) & 0xff);			//fram ID28--ID0
 	can0_reg_write(TxBuffer3,(ID >> 8 ) & 0xff);
	can0_reg_write(TxBuffer4,(ID ) & 0xff);

	can0_reg_write(TxBuffer5,data_buff[4]);
	can0_reg_write(TxBuffer6,data_buff[5]);
	can0_reg_write(TxBuffer7,data_buff[6]);
	can0_reg_write(TxBuffer8,data_buff[7]);
	can0_reg_write(TxBuffer9,data_buff[8]);
	can0_reg_write(TxBuffer10,data_buff[9]);	
	can0_reg_write(TxBuffer11,data_buff[10]);
	can0_reg_write(TxBuffer12,data_buff[11]);
		
  can0_reg_write(CommandReg,TR_Bit);		//begin to send
	return 8;
}

module_init(can0_init);module_exit(can0_exit);

⌨️ 快捷键说明

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