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

📄 can_sja1000_dev.c

📁 这是Pxa270下的can驱动程序
💻 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:        Chenxibing
** Modified date:      2007-03-05
** Version:            V1.1        
** Descriptions:       For MagicARM270 Linux 2.6.18
**
**------------------------------------------------------------------------------------------------------
** Modified by: 
** Modified date:
** Version:     
** Descriptions: 
**
********************************************************************************************************/
#include "config.h"
#include "print_DEBUG.h"

#define SJA_ALE_PADR 0x14000008		//SJA1000锁存器端口物理地址
#define SJA_DAT_PADR 0x14000004		//SJA1000数据端口物理地址
#define SJA_SRC_LEN  0x04		//SJA1000数据长度,4字节

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_DESCRIPTION("Guangzhou Zhiyuan Electronic Co.,LTD.\ngraduate school\nhttp://www.embedtools.com");
MODULE_SUPPORTED_DEVICE("Linux 2.6.18 & MagicARM270");
MODULE_AUTHOR("Chenxibing");

#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)
{
	if(TRUE != SJA1000Init(PELI_CAN,BTR_1000K,0x00000000,0xFFFFFFFF))
	{
		printk("<0>SJA1000 Init Error!\n");
		return -ENODEV;
	}
	try_module_get(THIS_MODULE);
	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)
{
	module_put(THIS_MODULE);
	printk("MagicARM270 SJA1000_CAN released!\n");
	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("Copy to usr Error!\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 Error!\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;
	int bak,tmp;

	PDEBUG("CAll init_module.\n");
	MSC2 = 0xFFFF7FF8; //BANK5 NOR Flash
	bak = MSC2;

	//映射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++)
	{
		iowrite8(0x09,sja1000_ale);
		iowrite8(1<<i,sja1000_dat);
		iowrite8(0x09,sja1000_ale);

		if(ioread8(sja1000_dat) != 1<<i)
		{
			printk("Abing : read tmp = %d\n", ioread8(sja1000_dat));

			iounmap(sja1000_ale);
			iounmap(sja1000_dat);
			printk("SJA1000 Hardware Connection Error!!");
			return -ENODEV;
		}
	}

	//中断初始化
	pxa_gpio_mode(1 | GPIO_IN);
	if (request_irq(IRQ_GPIO(1), can_interrupt, IRQF_DISABLED|IRQF_TRIGGER_FALLING,	"MagicARM270 Can", NULL))
		printk(KERN_WARNING "mgc270can: Can't get SJA1000_CAN IRQ: %d!\n", IRQ_GPIO(1));

	//注册设备
	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("Unloading MagicARM270 CAN Device Controller Driver\n");

	//关闭CAN设备控制器     
	if(TRUE != SJA_SoftRst(TRUE))
	{
		printk("<0>" "SJA_SoftRst Failed!.\n");
	}   

	//取消IO映射
	iounmap(sja1000_ale);
	iounmap(sja1000_dat);
	
	free_irq(IRQ_GPIO(1),NULL);

	//注销设备
	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 + -