?? can.c~
字號:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/arch-s3c2410/irqs.h>
#include <asm/signal.h>
#include <asm/hardware.h>
#include <asm/uaccess.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-irq.h>
#include <asm/dma.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/cdev.h>
#include <linux/version.h>
#include <linux/vmalloc.h>
#include <linux/ctype.h>
#include <linux/pagemap.h>
#include <linux/poll.h>
#include "demo.h"#define MCP2510_CS_OUT _raw_writel((_raw_readl(S3C2410_GPGCON)&(~(3<<4)))|(1<<4),S3C2410_GPGCON)
#define MCP2510_CS_H _raw_writel(_raw_readl(S3C2410_GPGDAT)|(1<<2),S3C2410_GPGDAT)
#define MCP2510_CS_L _raw_writel(_raw_readl(S3C2410_GPGDAT)&(~(1<<2)),S3C2410_GPGDAT)
#define MCP2510_SI_OUT _raw_writel((_raw_readl(S3C2410_GPECON)&(~(3<<24)))|(1<<24),S3C2410_GPECON)
#define MCP2510_SI_H _raw_writel(_raw_readl(S3C2410_GPEDAT)|(1<<12),S3C2410_GPEDAT)
#define MCP2510_SI_L _raw_writel(_raw_readl(S3C2410_GPEDAT)&(~(1<<12)),S3C2410_GPEDAT)
#define MCP2510_SCK_OUT _raw_writel((_raw_readl(S3C2410_GPECON)&(~(3<<26)))|(1<<26),S3C2410_GPECON)
#define MCP2510_SCK_H _raw_writel(_raw_readl(S3C2410_GPEDAT)|(1<<13),S3C2410_GPEDAT)
#define MCP2510_SCK_L _raw_writel(_raw_readl(S3C2410_GPEDAT)&(~(1<<13)),S3C2410_GPEDAT)
#define MCP2510_SO_IN _raw_writel((_raw_readl(S3C2410_GPECON)&(~(3<<22)))|(0<<22),S3C2410_GPECON)
#define MCP2510_SO_GET (_raw_writel(S3C2410_GPEDAT)&(1<<11))>>11
#define MCP2510_SO_PULLUP _raw_writel(_raw_readl(S3C2410_GPEUP)&(~(1<<11)),S3C2410_GPEUP)
#define MCP2510_SO_DISPULLUP _raw_writel(_raw_readl(S3C2410_GPEUP)|(1<<11),S3C2410_GPEUP)
#define MCP2510_INT_IN _raw_writel((_raw_readl(S3C2410_GPGCON)&(~(3<<0)))|(1<<1),S3C2410_GPGCON)
void MCP2510_RW_Start(viod) //start SPI read and write
{
MCP2510_SI_L;
MCP2510_SCK_L;
ndelay(400);
MCP2510_CS_L;
ndelay(400);
}
void Spi_Write(unsigned char Date) //SPI write data
{
unsigned char m;
for(m=0;m<8;m++)
{
if(Data&0x80)==0x80)
MCP2510_SI_H;
else
MCP2510_SI_L;
ndelay(400);
MCP2510_SCK_H;
Data=Data<<1;
MCP2510_SCK_L;
ndelay(400);
}
}
unsigned char Spi_Read(void)
{
unsigned char m;
unsigned char data=0;
for(m=0;m<8;m++)
{
MCP2510_SCK_H;
ndelay(400);
data=data<<1;
if(MCP2510_SO_GET!=0)
data|=0x01;
else
data&=0xfe;
ndelay(400);
MCP2510_SCK_L;
ndelay(400);
}
return (data);
}
void MCP2510_Write(unsigned char address,unsigned char value)
{
MCP2510_RW_Start();
Spi_Write(MCP2510INSTR_WRITE);
Spi_Write(address);
Spi_Write(value);
MCP2510_CS_H;
}
unsigned char MCP2510_Read(unsigned char address)
{
unsigned char result;
MCP2510_RW_Start();
Spi_Write(MCP2510INSTR_READ);
Spi_Write(address);
result=Spi_Read();
MCP2510_CS_H;
return result;
}
if(request_irq(IRQ_EINT8,&MCPCAN_interrupt,SA_INTERRUPT,"MCPCAN",NULL))
{
printk("request MCPCAN irq failed!\n");
return -1;
}
static irqreturn_t MCPCAN_interrupt(int irq,void *dummy,struct pt_regs *fp)
{
unsigned char byte;
byte=MCP2510_Read(CANINTF);
#if MCP2510_DEBUG
Uart_Printf("mcp2510 enter interrupt!: %d\n",byte);
#endif
if(MCP2510_ReadStatus()&RX0INT)
{
MCP2510_Read_Can(3,&(mcp2510dev->MCP2510_Candata[mcp2510dev->receivePos]));
MCP2510_WriteBits(CANINTF,~RX0INT,RX0INT);
#if MCP2510_DEBUG
Uart_Printf("RX0INT!\n");
#endif
if(MCPCAN_inc==1)
{
NextCanDataPos(mcp2510dev->receivePos);
wake_up_interruptible(&(mcp2510dev->wq));
}
}
if(MCP2510_ReadStatus()&RX0INT)
{
MCP2510_Read_Can(3,&(mcp2510dev->MCP2510_Candata[mcp2510dev->receivePos]));
MCP2510_WriteBits(CANINTF,~RX1INT,RX1INT);
#if MCP2510_DEBUG
Uart_Printf("RX1INT!\n");
#endif
if(MCPCAN_inc==1)
{
NextCanDataPos(mcp2510dev->receivePos);
wake_up_interruptible(&(mcp2510dev->wq));
}
}
return IRQ_HANDLED;
}
struct MCP_Filter
{
unsigned int RXM0SIDH_ID;
unsigned int RXM1SIDH_ID;
unsigned int RXF0SIDH_ID;
unsigned int RXF1SIDH_ID;
unsigned int RXF2SIDH_ID;
unsigned int RXF3SIDH_ID;
unsigned int RXF4SIDH_ID;
unsigned int RXF5SIDH_ID;
unsigned char RXMSIDH_0;
unsigned char RXMSIDH_1;
unsigned char RXFSIDH_0;
unsigned char RXFSIDH_1;
unsigned char RXFSIDH_2;
unsigned char RXFSIDH_3;
unsigned char RXFSIDH_4;
unsigned char RXFSIDH_5;
}
int MCPCAN_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{
unsigned char value=0;
unsigned char ReadBackCNT=0;
void _user*argp=(void _user*)arg;
switch(cmd)
{
case SET_REVEIVEFILTER:
if(copy_from_user(argp,(void _user *)arg,sizeof(struct MCP_Filter)))
{
#if MCP2510_DEBUG
printk("COMMAND_CHANGEFILTER ioctl error\n");
#endif
return -EFAULT;
}
struct MCP_Filter *pfilter=(struct MCP_Filter *)argp;
MCP2510_Write(MCP2510REG_CANCTRL,MODE_CONFIG);
while(ReadBackCNT<8)
{
value=(MCP2510_Read(MCP2510REG_CANSTAT)&0xe0);
if(value==MODE_CONFIG)
{
#if MCP2510_DEBUG
Uart_Printf("ReadBackCNT=0x%x\n",ReadBackCNT);
#endif
break;
}
ReadBackCNT++;
}
if(ReadBackCNT==8)
{
return -EFAULT;
}
MCP2510_Write_ID(RXM0SIDH,pfilter->RXM0SIDH_ID,pfilter->RXMSIDH_0);
MCP2510_Write_ID(RXM1SIDH,pfilter->RXM1SIDH_ID,pfilter->RXMSIDH_1);
MCP2510_Write_ID(RXF0SIDH,pfilter->RXF0SIDH_ID,pfilter->RXFSIDH_0);
MCP2510_Write_ID(RXF1SIDH,pfilter->RXF1SIDH_ID,pfilter->RXFSIDH_1);
MCP2510_Write_ID(RXF2SIDH,pfilter->RXF2SIDH_ID,pfilter->RXFSIDH_2);
MCP2510_Write_ID(RXF3SIDH,pfilter->RXF3SIDH_ID,pfilter->RXFSIDH_3);
MCP2510_Write_ID(RXF4SIDH,pfilter->RXF4SIDH_ID,pfilter->RXFSIDH_4);
MCP2510_Write_ID(RXF5SIDH,pfilter->RXF5SIDH_ID,pfilter->RXFSIDH_5);
MCP2510_Write(CLKCTRL,MODE_NORMAL|CLKEN|CLK8);
MCP2510_WriteBits(RXB0CTRL,(RXB_BUKT+RXB_RX_STDEXT),0XFF);
MCP2510_WriteBits(RXB1CTRL,RXB_RX_STDEXT,0XFF);
#if MCP2510_DEBUG
printk("MCPCAN ioctl successfully\n");
#endif
break;
case SET_CANBAUD:
...
break;
}
return 0;
}
ssize_t MCPCAN_write(struct file *filp,const char _user *buf,size_t count,loff_t *f_pos)
{
char writeBuffer[sizeof(struct Canframe)];
if(count>=sizeof(struct Canframe))
{
copy_from_user(writeBuffer,buf,sizeof(struct Canframe));
if(Mcp2510_Send_Data((struct Canframe *)writeBuffer)==0)
{
return sizeof(struct Canframe);
}
}
return 0;
}/*******************************************************
MODULE ROUTINE
*******************************************************/
void DEMO_cleanup_module(void)
{
dev_t devno = MKDEV(DEMO_MAJOR, DEMO_MINOR);
int i;
for (i = 0; i <4; i++) {
free_irq(irqArray[i],simplekey_interrupt);
}
if (DEMO_devices)
{
cdev_del(&DEMO_devices->cdev);
kfree(DEMO_devices);
}
unregister_chrdev_region(devno,1);
}
int DEMO_init_module(void)
{
int result;
dev_t dev = 0;
int i=0;
initButton();
dev = MKDEV(DEMO_MAJOR, DEMO_MINOR);
result = register_chrdev_region(dev, 1, "DEMO");
if (result < 0)
{
printk(KERN_WARNING "DEMO: can't get major %d\n", DEMO_MAJOR);
return result;
}
DEMO_devices = kmalloc(sizeof(struct DEMO_dev), GFP_KERNEL);
if (!DEMO_devices)
{
result = -ENOMEM;
goto fail;
}
memset(DEMO_devices, 0, sizeof(struct DEMO_dev));
init_MUTEX(&DEMO_devices->sem);
cdev_init(&DEMO_devices->cdev, &DEMO_fops);
DEMO_devices->cdev.owner = THIS_MODULE;
DEMO_devices->cdev.ops = &DEMO_fops;
result = cdev_add (&DEMO_devices->cdev, dev, 1);
if(result)
{
printk(KERN_NOTICE "Error %d adding DEMO\n", result);
goto fail;
}
for (i = 0; i <4; i++) {
if (request_irq(irqArray[i], &simplekey_interrupt, SA_INTERRUPT, "simplekey", NULL)) {
printk("request button irq failed!\n");
return -1;
}
}
init_waitqueue_head(&DEMO_devices->wq);
init_timer(&polling_timer);
polling_timer.data = (unsigned long)0;
polling_timer.function = polling_handler;
return 0;
fail:
DEMO_cleanup_module();
return result;
}
module_init(DEMO_init_module);
module_exit(DEMO_cleanup_module);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -