📄 can_sja1000_dev.c
字号:
/*
****************************************Copyright (c)**************************************************
** 广州致远电子有限公司
** CAN开发组
** http://www.zyinside.com
**
**
**--------------File Info-------------------------------------------------------------------------------
** File name: can_sja1000-dev.c
** Last modified Date: 2006-02-16
** Last Version: V1.0
** Descriptions: can_sja1000-dev.c, S3C2410 SJA1000 CAN 控制器设备驱动程序
** can_sja1000-dev.c, S3C2410 SJA1000 CAN-bus controller driver
**------------------------------------------------------------------------------------------------------
** Created by: 滕欣欣 Xingxing Teng
** Created date: 2006-02-16
** Version: V1.0
** Descriptions: 初始版本 The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#include "config.h"
#include "Print_DEBUG.h"
#define SJA_ALE_PADR 0x20000008 //SJA1000锁存器端口物理地址
#define SJA_DAT_PADR 0x20000004 //SJA1000数据端口物理地址
#define SJA_SRC_LEN 0x01 //SJA1000数据长度,1字节
static int major = CAN_MAJOR_NR;
stcSJA1000_BufInfo SJA1000_RxBuf;
void *sja1000_ale;
void *sja1000_dat;
static DECLARE_WAIT_QUEUE_HEAD(can_wait);
EXPORT_SYMBOL(sja1000_ale);
EXPORT_SYMBOL(sja1000_dat);
static int can_init(void);
static void can_cleanup(void);
static int can_open(struct inode *p_inode, struct file *p_file);
static int can_release(struct inode *p_inode, struct file *p_flie);
static ssize_t can_read(struct file *p_flie, char *p_buf, size_t count, loff_t *f_pos);
static ssize_t can_write(struct file *p_flie, const char *p_buf, size_t count, loff_t *f_pos);
static int can_ioctl(struct inode *p_inode, struct file *p_flie, unsigned int cmd, unsigned long param);
static void can_interrupt(int irq , void* dev_id, struct pt_regs *regs);
MODULE_PARM(major, "i");
MODULE_DESCRIPTION("Guangzhou Zhiyuan Electronic Co.,LTD.\ngraduate school\nhttp://www.zyinside.com");
MODULE_SUPPORTED_DEVICE("Linux 2.4.18 & MagicARM2410");
MODULE_AUTHOR("Xinxin Teng");
#define MAJOR_NR major
struct file_operations sja1000_can_fops =
{
owner: THIS_MODULE,
ioctl: can_ioctl,
open : can_open,
write: can_write,
read: can_read,
release : can_release,
};
/*
********************************************************************************************************************
**函数原型 : int can_open(struct inode *p_inode, struct file *p_file)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
int can_open(struct inode *p_inode, struct file *p_file)
{
uint8 num;
int result;
/* get the device minor and save into filp structure */
num = MINOR(p_inode->i_rdev);
//p_file->private_data = (void *)num; /* 取得次设备号并保存在filp结构中 */
//设备初始化
if(TRUE != SJA1000Init(PELI_CAN,BTR_1000K,0x00000000,0xFFFFFFFF))
{
printk("<0>SJA1000Init Err!!.\n");
return -ENODEV;
}
//申请中断
set_external_irq(IRQ_EINT5,EXT_FALLING_EDGE,GPIO_PULLUP_DIS);
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);
return result;
}
MOD_INC_USE_COUNT;
printk("<0>" DEVICE_NAME " Opened!.\n");
return(0);
}
/*
********************************************************************************************************************
**函数原型 : int can_release(struct inode *p_inode, struct file *p_flie)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
int can_release(struct inode *p_inode, struct file *p_flie)
{
MOD_DEC_USE_COUNT;
free_irq(IRQ_EINT5,NULL);
return(0);
}
/*
********************************************************************************************************************
**函数原型 : ssize_t can_read(struct file *p_flie, char *p_buf, size_t count, loff_t *f_pos)
**参数说明 :
**返回值 :
**说 明 : CAN驱动的
********************************************************************************************************************
*/
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驱动的
********************************************************************************************************************
*/
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驱动的
********************************************************************************************************************
*/
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);
}
/*
********************************************************************************************************************
**函数原型 : int can_init(void)
**参数说明 : NULL
**返回值 : 返回赋值表示调用出错
**说 明 : CAN驱动的初始化函数函数
********************************************************************************************************************
*/
int can_init(void)
{
int i,result;
PDEBUG("CAll init_module.\n");
//映射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;
}
}
//注册设备
result = register_chrdev(MAJOR_NR, DEVICE_NAME, &sja1000_can_fops);
if (result < 0)
{
printk("<0>" DEVICE_NAME ": Unable to get major %d\n", MAJOR_NR );
return(result);
}
//注册中断
//中断初始化
if (MAJOR_NR == 0)
{
MAJOR_NR = result; /* dynamic */
}
printk(KERN_INFO DEVICE_NAME ": init OK\n");
return(0);
}
/*
********************************************************************************************************************
**函数原型 : void can_cleanup(void)
**参数说明 : NULL
**返回值 : NULL
**说 明 : CAN驱动的清除函数
********************************************************************************************************************
*/
void can_cleanup(void)
{
PDEBUG("CAll cleanup_module.\n");
printk("\tUnloading S3C2410 CAN Device Controller Driver\n");
//关闭CAN设备控制器
if(TRUE != SJA_SoftRst(TRUE))
{
printk("<0>" "SJA_SoftRst False!.\n");
}
//取消IO映射
iounmap(sja1000_ale);
iounmap(sja1000_dat);
//注销设备
unregister_chrdev(MAJOR_NR, DEVICE_NAME);
}
void can_interrupt(int irq , void* dev_id, struct pt_regs *regs)
{
IntEnty();
wake_up_interruptible(&can_wait);
}
module_init(can_init);
module_exit(can_cleanup);
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -