📄 mcp2510.c
字号:
#include "spi.h"
#include "dbgu.h"
#include "MCP2510.h"
void DelayX(unsigned x){
unsigned i;
while(--x) {
for(i=0;i<1000;i++);
}
}
/*芯片复位*/
void McpReset(uint num)
{
SPI_CE(num,0);
OutByte(RESET);
SPI_CE(num,1);
}
/*读寄存器数据*/
uchar McpRdByte(uchar Raddr,uint num)
{
unsigned char val;
SPI_CE(num,0);
OutByte(READ);
OutByte(Raddr);
val=InByte();
SPI_CE(num,1);
return val;
}
/*写寄存器数据*/
void McpWrByte(uchar Raddr,uchar Rdata,uint num)
{
SPI_CE(num,0);
OutByte(WRITE);
OutByte(Raddr);
OutByte(Rdata);
SPI_CE(num,1);
}
/*读当前状态*/
uchar ReadStatus(uint num)
{
unsigned char i,j;
SPI_CE(num,0);
OutByte(RD_STAT);
i=InByte();
j=InByte();
SPI_CE(num,1);
return i;
}
/*请求发送*/
void WriteRTS(uchar cmd,uint num)
{
SPI_CE(num,0);
OutByte(cmd);
SPI_CE(num,1);
}
/*寄存器位改写*/
void BitModify(uchar Raddr,uchar Rmask,uchar Rdata,uint num)
{
SPI_CE(num,0);
OutByte(BIT_MOD);
OutByte(Raddr);
OutByte(Rdata);
OutByte(Rmask);
SPI_CE(num,1);
}
void InitPorts(uint num)
{
BitModify( TXRTSCTRL, 0, 0xFF,num );
// The two pins RX0BF and RX1BF are used to control two LEDs; set them as outputs and
// set them as 00.
BitModify( BFPCTRL, 0x3C, 0xFF,num );
}
uchar GetPort(uint num)
{
uchar port;
port=McpRdByte(TXRTSCTRL,num);
// Bits 3..5 are used.
return ((~port) >> 3) & 0x07;
}
void SetLED(int v,uint num)
{
BitModify(BFPCTRL, ~v << 4, 0x30,num);
}
void McpWriteCanId( uchar mcp_addr,uchar ext,ulong can_id,uint num)
{
int i;
uint canid;
uchar tbufdata[4];
canid = (uint)(can_id & 0x0FFFF);
if (ext) {
tbufdata[EID0] = (uchar) (canid & 0xFF);
tbufdata[EID8] = (uchar) (canid / 0x100);
canid = (uint)( can_id / 0x10000L );
tbufdata[SIDL] = (uchar) (canid & 0x03);
tbufdata[SIDL] += (uchar) ((canid & 0x1C)<<3);
tbufdata[SIDL] |= TXB_EXIDE_M;
tbufdata[SIDH] = (uchar) (canid / 32 );
}
else {
tbufdata[SIDH] = (uchar) (canid / 8 );
tbufdata[SIDL] = (uchar) ((canid & 0x07 )<<5); //*32
tbufdata[EID0] = 0;
tbufdata[EID8] = 0;
}
SPI_CE(num,0);
OutByte(WRITE);
OutByte(mcp_addr);
for(i=0;i<4;i++)
OutByte(tbufdata[i]);
SPI_CE(num,1);
}
// Buffer can be 1..2..3
void McpWriteCan( uchar row, uchar ext, ulong can_id,
uchar dlc, uchar rtr, uchar* data,uint num)
{
int i;
uchar mcp_addr = row*16 + 0x21;
McpWriteCanId(mcp_addr,ext,can_id,num); // write CAN id
// write n bytes data in the Mcp2510
SPI_CE(num,0);
OutByte(WRITE);
OutByte(mcp_addr+5);
for(i=0;i<dlc;i++)
OutByte(data[i]);
SPI_CE(num,1);
if (rtr == 1) dlc |= RTR_MASK; // if RTR set bit in byte
// write the RTR and DLC
McpWrByte((mcp_addr+4),dlc,num);
}
//*----------------------------------------------------------------------------
//* \fn McpReadCanId
//* \brief Write to one or more registers in the MCP2510, starting at address writedata
//*----------------------------------------------------------------------------
void McpReadCanId( uchar mcp_addr,uchar* ext,ulong* can_id,uint num)
{
int i;
uchar tbufdata[4];
*ext = 0;
*can_id = 0;
SPI_CE(num,0);
OutByte(READ);
OutByte(mcp_addr);
for(i=0;i<4;i++)
tbufdata[i]=InByte();
SPI_CE(num,1);
*can_id = (tbufdata[SIDH]<<3) + (tbufdata[SIDL]>>5);
if ( (tbufdata[SIDL] & TXB_EXIDE_M) == TXB_EXIDE_M )
{
*can_id = (*can_id<<2) + (tbufdata[SIDL] & 0x03);
*can_id <<= 16;
*can_id = *can_id +(tbufdata[EID8]<<8) + tbufdata[EID0];
*ext = 1;
}
}
// Buffer can be 4..5
void McpReadCan( uchar buffer, uchar* ext, ulong* can_id,
uchar* dlc, uchar* rtr, uchar* data,uint num )
{
int i;
uchar mcp_addr = buffer*16 + 0x21, ctrl,data_size;
McpReadCanId( mcp_addr, ext, can_id,num );
//read RXBnCTRL
ctrl=McpRdByte(mcp_addr-1,num);
//read RXBnDLC
data_size=McpRdByte(mcp_addr+4,num);
if (ctrl & 0x08) {
*rtr = 1;
}
else {
*rtr = 0;
}
*dlc =(data_size & DLC_MASK);
SPI_CE(num,0);
OutByte(READ);
OutByte(mcp_addr+5);
for(i=0;i<(*dlc);i++)
data[i]=InByte();
SPI_CE(num,1);
}
/*CAN控制器初始化函数*/
//void CanInit(unsigned char BroadCast,unsigned char OriginType,unsigned char OriginNum,unsigned char TargetType,unsigned char TargetNum)
void MCP2510Init(uint num)
//unsigned char TargetType,unsigned char TargetNum)
{
uchar data,a;
unsigned char i,j; //暂不关心数据源只是目标是自己即可
McpReset(num);
DelayX(70);
/*1.设置操作模式*/
McpWrByte(CANCTRL,MODE_CONFIG,num);
/*2.确认操作模式*/
do
{
i=McpRdByte(CANSTAT,num);
i=i&(0xE0);
}while(i!=MODE_CONFIG);
/*3.设置位定时:125K波特率*/
McpWrByte(CNF1,(SJW1 + BRP3),num);
McpWrByte(CNF2,(BTLMODE_CNF3+SEG4*8+SEG7),num);
McpWrByte(CNF3,SEG4,num);
/*4.设置中断使能*/
McpWrByte(CANINTE,RX0IE,num);
//CanWrByte(CANINTE,0xbf);
/*5.设置TXn引脚功能*/
// Mark all filter bits as don't care:
McpWriteCanId(RXM0SIDH, 0, 0, num);//add,ext,id,cs
McpWriteCanId(RXM1SIDH, 0, 0, num);
// Anyway, set all filters to 0:
McpWriteCanId(RXF0SIDH, 0, 0, num);
McpWriteCanId(RXF1SIDH, 0, 0, num);
McpWriteCanId(RXF2SIDH, 0, 0, num);
McpWriteCanId(RXF3SIDH, 0, 0, num);
McpWriteCanId(RXF4SIDH, 0, 0, num);
McpWriteCanId(RXF5SIDH, 0, 0, num);
/*7.设置操作模式*/
McpWrByte(CANCTRL,MODE_NORMAL +CLKEN+CLK4,num);
/*8.确认操作模式*/
do
{
i=McpRdByte(CANSTAT,num);
i=i&(0xE0);
}while(i!=MODE_NORMAL);
// Clear, deactivate the three transmit buffers
data = 0;
a = TXB0CTRL;
for (i = 0; i < 3; i++) {
for (j = 0; j < 14; j++) {
McpWrByte(a,data,num);
a++;
}
a += 2; // We did not clear CANSTAT or CANCTRL
}
/*9.设置接收控制寄存器*/
data=0x00;
McpWrByte(RXB0CTRL,data,num);
//屏蔽掉接收滤波寄存器和接收屏蔽滤波器
McpWrByte(RXB1CTRL,data,num);
AT91F_DBGU_Printk("\n\rMCP2510 Init Completed\n\r");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -