📄 sja1000-driver.c
字号:
/*****************************************************************************/
/*
* linux/deriver/char/sja1000.c
* sja1000 CAN Controller for Samsung s3c4510B-uclinux
* Copyright (C) 2004年3月, Yin Yedan,Post-graduate of Wuhan university of Technology <yinyedan@163.net>
*/
/*****************************************************************************/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kernel.h> // printk()
#include <linux/slab.h> // kmalloc()
#include <linux/errno.h> // error codes
#include <linux/types.h> // size_t
#include <linux/interrupt.h> // mark_bh
#include <linux/ioport.h>
#include <linux/fcntl.h>
#include <linux/unistd.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/delay.h>
/*****************************************************************************/
#undef DEBUG
#ifdef DEBUG
#define TRACE(str, args...) printk("S3C4510 sja1000: " str, ## args)
#else
#define TRACE(str, args...)
#endif
#define openflag 0
#define IO_PMOD (*(volatile unsigned *)0x3ff5000)
#define IO_PDATA (*(volatile unsigned *)0x3ff5008)
#define IO_PCON (*(volatile unsigned *)0x3ff5004)
#define SJA_MOD (0x2700000)
#define SJA_CMR (0x2700004)
#define SJA_SR (0x2700008)
#define SJA_IR (0x270000c)
#define SJA_IER (0x2700010)
#define SJA_BTR0 (0x2700018)
#define SJA_BTR1 (0x270001c)
#define SJA_EWLR (0x2700034)
#define SJA_OCR (0x2700020)
#define SJA_ACR0 (0x2700040)
#define SJA_ACR1 (0x2700044)
#define SJA_ACR2 (0x2700048)
#define SJA_ACR3 (0x270004c)
#define SJA_AMR0 (0x2700050)
#define SJA_AMR1 (0x2700054)
#define SJA_AMR2 (0x2700058)
#define SJA_AMR3 (0x270005c)
#define SJA_CDR (0x270007c)
#define SJA_ID0 (0x2700040)
#define SJA_ID1 (0x2700044)
#define SJA_ID2 (0x2700048)
#define SJA_ID3 (0x270004c)
#define SJA_ID4 (0x2700050)
#define SJA_CANRXB (0x2700054)
#define SJA_CANRXB1 (0x2700054)
#define SJA_CANRXB2 (0x2700058)
#define SJA_CANRXB3 (0x270005c)
#define SJA_CANRXB4 (0x2700060)
#define SJA_CANRXB5 (0x2700064)
#define SJA_CANRXB6 (0x2700068)
#define SJA_CANRXB7 (0x270006c)
#define SJA_CANRXB8 (0x2700070)
#define SJA_RBSA (0x2700078)
#define SJA_BUF1 (0x2700080)
#define SJA_BUF2 (0x2700084)
#define INT_sja1000 0
struct wait_queue *sja_readQ = NULL;
/*****************************************************************************/
void sja_write(unsigned int data,unsigned int addr)
{
unsigned char tmp;
tmp=(addr)>>2;
outl(tmp,addr);
IO_PDATA=0x32; //ALE=0
outl(data,addr);
IO_PDATA=0x33;
}
/*****************************************************************************/
unsigned char sja_read(unsigned int addr)
{
unsigned char data;
volatile unsigned int data1;
unsigned char tmp;
tmp=(addr)>>2;
outl(tmp,addr);
IO_PDATA=0x32; //p0-ALE=0
IO_PDATA=0x12; //p5-245dir=0
data1=inl(addr);
IO_PDATA=0x33;
data=data1;
return(data);
}
/*****************************************************************************/
static int sja1000_read(struct file *filp, char *buf, size_t size, loff_t *offp)
{
int num=0,i=0;
unsigned char CANdata[13];
unsigned long int pdata;
printk("read0\n");
if((sja_read(SJA_SR)&0x0c3)!=0)
{
if((sja_read(SJA_SR)&0x80)==0)//
{
if((sja_read(SJA_IR) & 0x80)==0x80)//
sja_write(0x0c,SJA_CMR);
else if((sja_read(SJA_IR) & 0x01)==0x01)//
{
pdata=SJA_ID0; //register 21. data start address
for(i=0;i<13;i++)
{
*buf=sja_read(pdata);
pdata=pdata+4;
buf++;
}
sja_write(0x04,SJA_CMR);
num++;
}
}
}
return num;
}
/*****************************************************************************/
static int sja1000_write(struct file *filp, const char *buf, size_t size, loff_t *offp)
{
unsigned char temp2,i;
unsigned int pdata;
sja_write(0x04,SJA_CMR);
temp2=(sja_read(SJA_SR))&0x10;
if(temp2==0x10) //
temp2=(sja_read(SJA_SR))&0x10;
temp2=(sja_read(SJA_SR))&0x08;
if(temp2==0x08) //
temp2=(sja_read(SJA_SR))&0x08;
temp2=(sja_read(SJA_SR))&0x04;
if(temp2==0x04) //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -