📄 can_sja1000_dev.c
字号:
/*************************************************************
* *
**************************************************************/
#include "config.h"
#include "Print_DEBUG.h"
stcSJA1000_BufInfo SJA1000_RxBuf; //used by other file
void *sja1000_ale;
void *sja1000_dat;
static DECLARE_WAIT_QUEUE_HEAD(can_wait);
/*
********************************************************************************************************************
**函数原型 : int can_open(struct inode *p_inode, struct file *p_file)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
static int can_open(struct inode *p_inode, struct file *p_file)
{
//设备初始化
if(TRUE != SJA1000Init(PELI_CAN,BTR_500K,0x00000000,0xFFFFFFFF)) {
printk("<0>SJA1000Init Err!!.\n");
return -ENODEV;
}
//MOD_INC_USE_COUNT;
printk("<0>" DEVICE_NAME " Opened!.\n");
return(0);
}
/*
********************************************************************************************************************
**函数原型 : int can_release(struct inode *p_inode, struct file *p_flie)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
static int can_release(struct inode *p_inode, struct file *p_flie)
{
//MOD_DEC_USE_COUNT;
return(0);
}
/*
********************************************************************************************************************
**函数原型 : ssize_t can_read(struct file *p_flie, char *p_buf, size_t count, loff_t *f_pos)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
static ssize_t can_read(struct file *p_flie, char *p_buf, size_t count, loff_t *f_pos)
{
interruptible_sleep_on(&can_wait);
if(count != sizeof(stcSJA1000_BufInfo)) {
return (-EINVAL);
}
if(copy_to_user(p_buf, (void*)(&SJA1000_RxBuf), sizeof(stcSJA1000_BufInfo))) {
printk("Coyp to usr Err!.\n");
return -EFAULT;
}
return(sizeof(SJA1000_RxBuf));
}
/*
********************************************************************************************************************
**函数原型 : ssize_t can_write(struct file *p_flie, const char *p_buf, size_t count, loff_t *f_pos)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
static ssize_t can_write(struct file *p_flie, const char *p_buf, size_t count, loff_t *f_pos)
{
stcSJA1000_BufInfo TxBuf;
if(count != sizeof(stcSJA1000_BufInfo)) {
printk("count = %d not %d\n",count,sizeof(stcSJA1000_BufInfo));
return (-EINVAL);
}
if(copy_from_user((void*)&TxBuf,(void*)p_buf,sizeof(stcSJA1000_BufInfo))) {
printk("copy_from_user Err.\n");
return -EFAULT;
}
SetTxBuf(&TxBuf);
SetCommand(CMR_NOM_SD);
return(sizeof(SJA1000_RxBuf));
}
/*
********************************************************************************************************************
**函数原型 : int can_ioctl(struct inode *p_inode, struct file *p_flie, unsigned int cmd, unsigned long param)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
static int can_ioctl(struct inode *p_inode, struct file *p_flie, unsigned int cmd, unsigned long param)
{
int val = 0;
switch(cmd) {
case IOCTL_BAUD:
SJA_SoftRst(TRUE);
if(TRUE != SetBaudRate((uint16)param)) {
val = -ENOTTY;
}
SJA_SoftRst(FALSE);
break;
case IOCTL_ACR:
SJA_SoftRst(TRUE);
if(TRUE != ACRCode(param)) {
val = -ENOTTY;
}
SJA_SoftRst(FALSE);
break;
case IOCTL_AMR:
SJA_SoftRst(TRUE);
if(TRUE != AMRCode(param)) {
val = -ENOTTY;
}
SJA_SoftRst(FALSE);
break;
default:
val = -ENOTTY;
break;
}
return(val);
}
static irqreturn_t can_interrupt(int irq, void *dev_id, struct pt_regs *reg)
{
IntEnty();
wake_up_interruptible(&can_wait);
return IRQ_HANDLED;
}
static struct file_operations sja1000_can_fops =
{
owner: THIS_MODULE,
ioctl: can_ioctl,
open : can_open,
write: can_write,
read: can_read,
release : can_release,
};
static struct miscdevice can_dev=
{
MISC_DYNAMIC_MINOR, //dynamically
"can_bus",
&sja1000_can_fops
};
/*
********************************************************************************************************************
**函数原型 : int can_init(void)
**参数说明 : NULL
**返回值 : 返回赋值表示调用出错
**说 明 : CAN驱动的初始化函数函数
********************************************************************************************************************
*/
#define SJA_ALE_PADR 0x20000008 //SJA1000锁存器端口物理地址
#define SJA_DAT_PADR 0x20000004 //SJA1000数据端口物理地址
#define SJA_SRC_LEN 0x01 //SJA1000数据长度,1字节
static int can_init(void)
{
int i,result;
PDEBUG("CAll init_module.\n");
misc_register(&can_dev);
//映射IO
sja1000_dat = ioremap(SJA_DAT_PADR, SJA_SRC_LEN);
sja1000_ale = ioremap(SJA_ALE_PADR, SJA_SRC_LEN);
//测试硬件连接
for (i=0 ; i<0x8; i++) {
writeb(0x09,sja1000_ale);
writeb(1<<i,sja1000_dat);
writeb(0x09,sja1000_ale);
if(readb(sja1000_dat) != 1<<i) {
iounmap(sja1000_ale);
iounmap(sja1000_dat);
printk("SJA_1000 Hare Ware Connected Err!!");
return -ENODEV;
}
}
//申请中断
__raw_writel((__raw_readl(S3C2410_GPFCON) & (~(0x03<<10))) | (0x02<<10), S3C2410_GPFCON); //Pin function
__raw_writel(__raw_readl(S3C2410_EXTINT0) | (0x02<<20), S3C2410_EXTINT0); //EINT5--falling edge triger
result = request_irq(IRQ_EINT5, can_interrupt, SA_INTERRUPT, "SJA1000", NULL);
if(result == 0)
printk("<0> Interrupt Set OK!.\n");
else {
printk("<0> Interrupt Set Err! ErrCose = %d.\n", result);
goto failed_request_irq;
}
//enable_irq(IRQ_EINT5);
printk(KERN_INFO DEVICE_NAME ": init OK\n");
return(0);
failed_request_irq:
misc_deregister(&can_dev);
return -1;
}
/*
********************************************************************************************************************
**函数原型 : void can_cleanup(void)
**参数说明 : NULL
**返回值 : NULL
**说 明 : CAN驱动的清除函数
********************************************************************************************************************
*/
static void can_cleanup(void)
{
PDEBUG("CAll cleanup_module.\n");
printk("\tUnloading S3C2410 CAN Device Controller Driver\n");
//disable_irq(IRQ_EINT5);
free_irq(IRQ_EINT5,NULL);
//关闭CAN设备控制器
if(TRUE != SJA_SoftRst(TRUE)) {
printk("<0>" "SJA_SoftRst False!.\n");
}
//取消IO映射
iounmap(sja1000_ale);
iounmap(sja1000_dat);
//注销设备
misc_deregister(&can_dev);
}
module_init(can_init);
module_exit(can_cleanup);
EXPORT_SYMBOL(sja1000_ale);
EXPORT_SYMBOL(sja1000_dat);
MODULE_SUPPORTED_DEVICE("Linux 2.6.8 & GEC2410-BOX");
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -