📄 can012read.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 + -