📄 mcp2510.h
字号:
#ifndef _LINUX_MCP2510_H#define _LINUX_MCP2510_H#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/vmalloc.h>#include <linux/ioctl.h>#include <linux/Def.h>#include <linux/2410.h>
#include <linux/spi.h>#include <asm/hardware.h>
#include <asm/arch/cpu_s3c2410.h>
/********************** MCP2510 Regrister *********************************/
// Register offsets into the transmit buffers.
#define MCP2510REG_TXBnCTRL 0
#define MCP2510REG_TXBnSIDH 1
#define MCP2510REG_TXBnSIDL 2
#define MCP2510REG_TXBnEID8 3
#define MCP2510REG_TXBnEID0 4
#define MCP2510REG_TXBnDLC 5
#define MCP2510REG_TXBnD0 6
#define MCP2510REG_TXBnD1 7
#define MCP2510REG_TXBnD2 8
#define MCP2510REG_TXBnD3 9
#define MCP2510REG_TXBnD4 10
#define MCP2510REG_TXBnD5 11
#define MCP2510REG_TXBnD6 12
#define MCP2510REG_TXBnD7 13
#define MCP2510REG_CANSTAT 14
#define MCP2510REG_CANCTRL 15
#define MCP2510LREG_SIDH 0
#define MCP2510LREG_SIDL 1
#define MCP2510LREG_EID8 2
#define MCP2510LREG_EID0 3
/******************* Bits in the TXBnCTRL registers.***************************/
#define TXB_TXBUFE_M 0x80
#define TXB_ABTF_M 0x40
#define TXB_MLOA_M 0x20
#define TXB_TXERR_M 0x10
#define TXB_TXREQ_M 0x08
#define TXB_TXIE_M 0x04
#define TXB_TXP10_M 0x03
#define DLC_MASK 0x0F
#define RTR_MASK 0x40
#define TXB0CTRL 0x30
#define TXB0SIDH 0x31
#define TXB1CTRL 0x40
#define TXB1SIDH 0x41
#define TXB2CTRL 0x50
#define TXB2SIDH 0x51
#define TXPRIOHIGH 0x03
#define TXPRIOHIGHLOW 0x02
#define TXPRIOLOWHIGH 0x01
#define TXPRIOLOW 0x00
#define TXB_EXIDE_M 0x0800 // In TXBnSIDL
#define TXB_RTR_M 0x40 // In TXBnDLC
#define RXB_IDE_M 0x08 // In RXBnSIDL
#define RXB_RTR_M 0x40 // In RXBnDLC
#define BFPCTRL 0x0C
#define B2RTS 0x20
#define B1RTS 0x10
#define B0RTS 0x08
#define B2RTSM 0x04
#define B1RTSM 0x02
#define B0RTSM 0x01
#define TEC 0x1C
#define REC 0x1D
#define CLKCTRL MCP2510REG_CANCTRL
#define RXF0SIDH 0
#define RXF0SIDL 1
#define RXF0EID8 2
#define RXF0EID0 3
#define RXF1SIDH 4
#define RXF1SIDL 5
#define RXF1EID8 6
#define RXF1EID0 7
#define RXF2SIDH 8
#define RXF2SIDL 9
#define RXF2EID8 10
#define RXF2EID0 11
#define RXF3SIDH 16
#define RXF3SIDL 17
#define RXF3EID8 18
#define RXF3EID0 19
#define RXF4SIDH 20
#define RXF4SIDL 21
#define RXF4EID8 22
#define RXF4EID0 23
#define RXF5SIDH 24
#define RXF5SIDL 25
#define RXF5EID8 26
#define RXF5EID0 27
#define RXF_EXIDE_M 0x08
#define RXM0SIDH 0x20
#define RXM0SIDL 0x21
#define RXM0EID8 0x22
#define RXM0EID0 0x23
#define RXM1SIDH 0x24
#define RXM1SIDL 0x25
#define RXM1EID8 0x26
#define RXM1EID0 0x27
#define CNF3 0x28
#define CNF2 0x29
#define CNF1 0x2A
#define CANINTE 0x2B
#define CANINTF 0x2C
#define EFLG 0x2D
#define TXRTSCTRL 0x0D
#define EFLG_RX1OVR 0x80
#define EFLG_RX0OVR 0x40
#define EFLG_TXBO 0x20
#define EFLG_TXEP 0x10
#define EFLG_RXEP 0x08
#define EFLG_TXWAR 0x04
#define EFLG_RXWAR 0x02
#define EFLG_EWARN 0x01
//CNF1 同步跳转宽度
#define SJW1 0x00
#define SJW2 0x40
#define SJW3 0x80
#define SJW4 0xC0
#define BTLMODE_CNF3 0x80
#define SAMP1 0x00 //对采样点采样1次
#define SAMP3 0x40 //对采样点采样3次
#define SEG1 0x00
#define SEG2 0x01
#define SEG3 0x02
#define SEG4 0x03
#define SEG5 0x04
#define SEG6 0x05
#define SEG7 0x06
#define SEG8 0x07
#define BRP1 0x00
#define BRP2 0x01
#define BRP3 0x02
#define BRP4 0x03
#define BRP5 0x04
#define BRP6 0x05
#define BRP7 0x06
#define BRP8 0x07
//CANINTE - 中断使能寄存器
#define IVRIE 0x80
#define WAKIE 0x40
#define ERRIE 0x20
#define TX2IE 0x10
#define TX1IE 0x08
#define TX0IE 0x04
#define RX1IE 0x02
#define RX0IE 0x01
#define NO_IE 0x00
#define IVRINT 0x80
#define WAKINT 0x40
#define ERRINT 0x20
#define TX2INT 0x10
#define TX1INT 0x08
#define TX0INT 0x04
#define RX1INT 0x02
#define RX0INT 0x01
#define NO_INT 0x00
#define RXB0CTRL 0x60
#define RXB1CTRL 0x70
#define RXB_RXRDY 0x80
#define RXB_RXM1 0x40
#define RXB_RXM0 0x20
#define RXB_RX_ANY 0x60
#define RXB_RX_EXT 0x40
#define RXB_RX_STD 0x20
#define RXB_RX_STDEXT 0x00
#define RXB_RXMx_M 0x60
// #define RXB_RXIE_M 0x10
#define RXB_RXRTR 0x08 // In RXBnCTRL
#define RXB_BUKT 0x04
#define RXB_BUKT_RO 0x02
#define RXB_FILHIT 0x01
#define RXB_FILHIT2 0x04
#define RXB_FILHIT1 0x02
#define RXB_FILHIT_M 0x07
#define RXB_RXF5 0x05
#define RXB_RXF4 0x04
#define RXB_RXF3 0x03
#define RXB_RXF2 0x02
#define RXB_RXF1 0x01
#define RXB_RXF0 0x00
//CANCTRL can控制器的模式选择
#define CLKEN 0x04
#define CLK1 0x00
#define CLK2 0x01
#define CLK4 0x02
#define CLK8 0x03
#define MODE_NORMAL 0x00
#define MODE_SLEEP 0x20
#define MODE_LOOPBACK 0x40
#define MODE_LISTENONLY 0x60
#define MODE_CONFIG 0x80
#define ABORT 0x10
typedef enum{
BandRate_10kbps,
BandRate_125kbps,
BandRate_250kbps,
BandRate_500kbps,
BandRate_1Mbps
}CanBandRate;typedef struct{ unsigned int id; unsigned char data[8]; unsigned char dlc; int IsExt; int rxRTR;}CanData, *PCanData;
// Start the transmission from one of the tx buffers.
/*#define MCP2510_transmit(address) do{MCP2510_WriteBits(address, TXB_TXREQ_M, TXB_TXREQ_M);}while(0)*/
unsigned int uiErr = 0 , brk = 0;
U32 watch , watch1;
U8 WriteCanData1 [8]={0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55} , WriteCanData2 [8] , WriteCanData3 [8] , WriteCanData4 [8];
U8 ReadCanData1 [8] , ReadCanData2 [8] , ReadCanData3 [8] , ReadCanData4 [8];
U32 id1 , id2 , id3 , id4;
U8 pdata1 , pdata2 , pdata3 , pdata4;
U8 dlc1 , dlc2 , dlc3 , dlc4;
int rxRTR1 , rxRTR2 , rxRTR3 , rxRTR4;
int isExt1 , isExt2 , isExt3 , isExt4;int rwflag = 0;
// MCP2510 Instruction
#define MCP2510INSTR_RESET 0xc0 //复位为缺省状态,并设定为配置模式
#define MCP2510INSTR_READ 0x03 //从寄存器中读出数据
#define MCP2510INSTR_WRITE 0x02 //向寄存器写入数据
#define MCP2510INSTR_RTS 0x80 //启动一个或多个发送缓冲器的报文发送
#define MCP2510INSTR_RDSTAT 0xa0 //读取状态
#define MCP2510INSTR_BITMDFY 0x05 //位修改
void MCP2510_RW1_Start(void){ GPGDAT &=0xfffb;
}void MCP2510_RW1_Close(void){ GPGDAT |=0x0004;}void MCP2510_RW2_Start(void){ GPCDAT &=0xffbf;
}void MCP2510_RW2_Close(void){ GPCDAT |=0x0040;}
void MCP2510_RW3_Start(void){ GPCDAT &=0xff7f;
}void MCP2510_RW3_Close(void){ GPCDAT |=0x0080;}
/****************************************************************************
【功能说明】软件复位MCP2510
****************************************************************************/
void MCP2510_Reset( void )
{ if (rwflag == 1)
MCP2510_RW1_Start() ; if (rwflag == 2) MCP2510_RW2_Start() ; if (rwflag == 3) MCP2510_RW3_Start() ;
SPI_SendByte( MCP2510INSTR_RESET ); if (rwflag == 1)
MCP2510_RW1_Close() ; if (rwflag == 2)
MCP2510_RW2_Close() ; if (rwflag == 3)
MCP2510_RW3_Close() ;
}
/****************************************************************************
【功能说明】向MCP2510指定地址写入一个字节
****************************************************************************/
void MCP2510_Write( U8 address, U8 value)
{ if (rwflag == 1)
MCP2510_RW1_Start() ; if (rwflag == 2) MCP2510_RW2_Start() ; if (rwflag == 3) MCP2510_RW3_Start() ;
SPI_SendByte(MCP2510INSTR_WRITE);
SPI_SendByte( address );
SPI_SendByte( value );
if (rwflag == 1)
MCP2510_RW1_Close() ; if (rwflag == 2)
MCP2510_RW2_Close() ; if (rwflag == 3)
MCP2510_RW3_Close() ;
}
/****************************************************************************
【功能说明】从MCP2510指定地址中读出一个字节
****************************************************************************/
unsigned char MCP2510_Read( U8 address )
{
unsigned char result;
if (rwflag == 1)
MCP2510_RW1_Start() ; if (rwflag == 2) MCP2510_RW2_Start() ; if (rwflag == 3) MCP2510_RW3_Start() ;
SPI_SendByte(MCP2510INSTR_READ) ; //0x03
SPI_SendByte( address ) ;
result = SPI_ReadByte() ;
if (rwflag == 1)
MCP2510_RW1_Close() ; if (rwflag == 2)
MCP2510_RW2_Close() ; if (rwflag == 3)
MCP2510_RW3_Close() ;
return result ;
}
/****************************************************************************
【功能说明】序列读取MCP2510数据
****************************************************************************/
void MCP2510_SRead( U8 address, unsigned char* pdata, U8 nlength )
{
int i;
if (rwflag == 1)
MCP2510_RW1_Start() ; if (rwflag == 2) MCP2510_RW2_Start() ; if (rwflag == 3) MCP2510_RW3_Start() ;
SPI_SendByte(MCP2510INSTR_READ);
SPI_SendByte( address );
for (i=0; i<nlength; i++)
{
*pdata=SPI_ReadByte();
//if( MCP2510_DEBUG ) printf( " 0x%x\n", (unsigned char)*pdata ) ;
pdata++;
} if (rwflag == 1)
MCP2510_RW1_Close() ; if (rwflag == 2)
MCP2510_RW2_Close() ; if (rwflag == 3)
MCP2510_RW3_Close() ;
}
/****************************************************************************
【功能说明】读取MCP2510 CAN总线ID
参数: address为MCP2510寄存器地址
can_id为返回的ID值
返回值
TRUE,表示是扩展ID(29位)
FALSE,表示非扩展ID(11位)
****************************************************************************/
int MCP2510_Read_Can_ID( U8 address, U32* can_id)
{
U32 tbufdata;
unsigned char* p=(unsigned char*)&tbufdata;
MCP2510_SRead(address, p, 4);
*can_id = (tbufdata<<3)|((tbufdata>>13)&0x7);
*can_id &= 0x7ff;
if ( (p[MCP2510LREG_SIDL] & RXB_IDE_M) == RXB_IDE_M )
{
*can_id = (*can_id<<2) | (p[MCP2510LREG_SIDL] & 0x03);
*can_id <<= 8;
*can_id |= ((tbufdata>>16)&0xff);
*can_id <<= 8;
*can_id |= tbufdata>>24;
return TRUE;
}
return FALSE;
}/****************************************************************************
【功能说明】修改指定地址寄存器的某些位
****************************************************************************/
void MCP2510_WriteBits( U8 address, U8 mask, U8 data )
{
if (rwflag == 1)
MCP2510_RW1_Start() ; if (rwflag == 2) MCP2510_RW2_Start() ; if (rwflag == 3) MCP2510_RW3_Start() ;
SPI_SendByte( MCP2510INSTR_BITMDFY );
SPI_SendByte( address);
SPI_SendByte( mask);
SPI_SendByte( data); if (rwflag == 1)
MCP2510_RW1_Close() ; if (rwflag == 2)
MCP2510_RW2_Close() ; if (rwflag == 3)
MCP2510_RW3_Close() ;
}
/***********************************************************\
* 读取MCP2510 接收的数据 *
* 参数: nbuffer为第几个缓冲区 其值可以为3或者4 *
* can_id为返回的ID值 *
* rxRTR表示是否是RXRTR *
* data表示读取的数据 *
* dlc表示data length code *
* 返回值 *
* TRUE,表示是扩展总线 *
* FALSE,表示非扩展总线 *
\***********************************************************/
int MCP2510_Read_Can(U8 nbuffer, int* rxRTR, U32* can_id, U8* data , U8* dlc)
{
U8 mcp_addr = (nbuffer<<4) + 0x31, ctrl;
int IsExt;
IsExt=MCP2510_Read_Can_ID( mcp_addr, can_id);
ctrl=MCP2510_Read(mcp_addr-1);
*dlc=MCP2510_Read( mcp_addr+4);
if ((ctrl & 0x08)) {
*rxRTR = TRUE;
}
else{
*rxRTR = FALSE;
}
*dlc &= DLC_MASK;
//MCP2510_SRead(mcp_addr+5, data, *dlc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -