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

📄 can_sja1000_dev.c

📁 uccos2的的源码文件
💻 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 + -