📄 sja1000.c
字号:
#include "upio.h"
#include "sja1000.h"
#include "csp.h"
#define Debug_SJA1000
#ifdef Debug_SJA1000
#define GIC 0xFFFFF000
#define GIC_IECR 0x120
#define GIC_EOICR 0x130
#define INTNUM 28 //sja0对应GIC的28号
#endif
#define SJA1000_ALE_H ALE_H()
#define SJA1000_ALE_L ALE_L()
#define SJA1000_RD_H RD_H()
#define SJA1000_RD_L RD_L()
#define SJA1000_WR_H WR_H()
#define SJA1000_WR_L WR_L()
#define SJA1000_RST_H RST_H()
#define SJA1000_RST_L RST_L()
#define SJA1000_CS0_H CS0_H()
#define SJA1000_CS0_L CS0_L()
#define SJA1000_CS1_H CS1_H()
#define SJA1000_CS1_L CS1_L()
extern void DRIVER_AsmSJAInterruptHandler(void);
static int gnIntError = 0;
static void MyDelay(int _delay){
while(_delay>0)
_delay -= 4;
}
void SJA1000_IO_CS_Init( void )
{
unsigned short k;
InitSJAPio();
SJA1000_ALE_L ; //SI put 0
SJA1000_RD_H; //SCK put 0
SJA1000_WR_H;
SJA1000_RST_H;
SJA1000_CS0_H;
MyDelay(300*NS_Cycle); //延时至少300ns
}
static unsigned char SJA1000Read(unsigned char Address)
{
unsigned short k;
unsigned char data;
SJA1000_ALE_H;
UPIO_SetData(Address);
MyDelay(8*NS_Cycle+1); //延时至少8ns,Add建立到ALE=0,8ns,ALE码冲宽度8ns
SJA1000_ALE_L;
MyDelay(10*NS_Cycle+1); //延时至少10ns,ALE=0到RD=0,10ns,并且AD上地址保持至少2ns
SJA1000_CS0_L;
SJA1000_RD_L;
MyDelay(40*NS_Cycle+1); //延时至少40ns,RD从0到1,40ns
UPIO_GetData(&data);
//MyDelay(10*NS_Cycle+1); //延时至少40ns,RD从0到1,40ns
SJA1000_RD_H;
SJA1000_CS0_H;
return data;
}
//功能:写一个字节,直接寻址
//传递参数:地址,写数据
//返回参数:无
static void SJA1000Write(unsigned char Address,unsigned char value)
{
SJA1000_ALE_H;
UPIO_SetData(Address);
MyDelay(8*NS_Cycle+1); //延时至少8ns,Add建立到ALE=0,8ns,ALE码冲宽度8ns
SJA1000_ALE_L;
MyDelay(10*NS_Cycle+1); //延时至少10ns,ALE=0到WR=0,10ns,并且AD上地址保持至少2ns
SJA1000_CS0_L;
SJA1000_WR_L;
MyDelay(10*NS_Cycle+1); //延时至少20ns,WR从0到1,20ns
UPIO_SetData(value);
MyDelay(20*NS_Cycle+1); //延时至少20ns,WR从0到1,20ns,数据建立到WR=1,8ns
SJA1000_WR_H;
SJA1000_CS0_H;
MyDelay(15*NS_Cycle+1); //延时至少15ns,data保持8ns,WR=1到下一次ALE=1,15ns
}
static void CanSetBaudrate(unsigned int baud)
{
int i;
switch(baud)
{
case 100:
SJA1000Write(REG_BTR0,0x04);
SJA1000Write(REG_BTR1,0x3a);
break;
case 125:
SJA1000Write(REG_BTR0,0x03);
SJA1000Write(REG_BTR1,0x3a);
break;
case 200:
SJA1000Write(REG_BTR0,0x03);
SJA1000Write(REG_BTR1,0x25);
break;
case 250:
SJA1000Write(REG_BTR0,0x01);
SJA1000Write(REG_BTR1,0x3c);
break;
case 400:
SJA1000Write(REG_BTR0,0x01);
SJA1000Write(REG_BTR1,0x25);
break;
case 500:
SJA1000Write(REG_BTR0,0x00);
SJA1000Write(REG_BTR1,0x49);
break;
case 800:
SJA1000Write(REG_BTR0,0x00);
SJA1000Write(REG_BTR1,0x25);
break;
case 1000:
SJA1000Write(REG_BTR0,0x00);
SJA1000Write(REG_BTR1,0x23);
break;
default:
//default baud rate equal 500k bit/s
SJA1000Write(REG_BTR0,0x00);
SJA1000Write(REG_BTR1,0x49);
break;
}
}
int SJA1000_Reset(unsigned int bandrate)
{
unsigned int acr,amr;
//unsigned char tmp;
acr = 0;
amr = 0xffffffff;
//1.复位模式
//tmp = (SJA1000Read(REG_MR);
SJA1000Write(REG_MR, BIT_RM);
if(!(SJA1000Read(REG_MR) & 0x01))
return -1;
//1.1设置时钟分频CDR,pelican模式
SJA1000Write(REG_CDR,SJA1000Read(REG_CDR)|0x80);
//1.3设置AMR,ACR。acr0对应标识符的MSB
SJA1000Write((unsigned char)REG_ACR0,(volatile unsigned char)(acr>>24)); //验收码寄存器0
SJA1000Write((unsigned char)(REG_ACR0+1),(volatile unsigned char)(acr>>16)); //验收码寄存器0
SJA1000Write((unsigned char)(REG_ACR0+2),(volatile unsigned char)(acr>>8)); //验收码寄存器0
SJA1000Write((unsigned char)( REG_ACR0+3),(volatile unsigned char)acr); //验收码寄存器0
SJA1000Write((unsigned char)REG_AMR0,(volatile unsigned char)(amr>>24)); //验收屏蔽寄存器0
SJA1000Write((unsigned char)(REG_AMR0+1),(volatile unsigned char)(amr>>16)); //验收屏蔽寄存器0
SJA1000Write((unsigned char)(REG_AMR0+2),(volatile unsigned char)(amr>>8)); //验收屏蔽寄存器0
SJA1000Write((unsigned char)(REG_AMR0+3),(volatile unsigned char)amr); //验收屏蔽寄存器0
//1.2设置总线时序寄存器
CanSetBaudrate(bandrate); //设置波特率
//1.4设置输出控制寄存器
SJA1000Write(REG_OC,0xfa);//??
//2.使能接收、发送、出错、数据溢出、唤醒中断
SJA1000Write(REG_IER, DIS_IRQ);//先禁止所有中断
//SJA1000Write(REG_IER, BIT_RIE|BIT_TIE|BIT_EIE|BIT_DOIE|BIT_WUIE);
SJA1000Write(REG_IER, BIT_RIE|BIT_EIE|BIT_DOIE|BIT_WUIE);//没有发送中断
SJA1000Read(REG_IER);
//3.正常模式
//SJA1000Write(REG_MR,0x0C);//单滤波,正常,自检测
SJA1000Write(REG_MR,0x00);//双滤波,正常
if(SJA1000Read(REG_MR) & 0x01)
return -1;
else
0;
}
void Init_SJA1000(unsigned int bandrate)
{
unsigned char i,j,a;
SJA1000_IO_CS_Init() ;
SJA1000_Reset(bandrate);
//设置GIC的相关
*(volatile int *)(GIC+4*INTNUM) = 0x01;//模式寄存器,低电平触发,优先级1,最低
*(volatile int *)(GIC+4*32+4*INTNUM) = (int)DRIVER_AsmSJAInterruptHandler;//中断处理函数
*(volatile int *)(GIC+GIC_IECR) = 1<<INTNUM;//中断使能
//CSP_GICConfigInterrupt(INTNUM, 0x61, DRIVER_AsmSJAInterruptHandler);
}
void SJA1000_TX(CanMessageStruct * msg)
{
unsigned char x,i;
unsigned char tmp;
while(!(SJA1000Read(REG_SR)&BIT_TBS));
x = 0;
if(msg->Rtr)
{
x |= 0x40;
}
x |= msg->DataLengthCode;
if(msg->IsExt){
//是扩展桢
x |= 0x80;
SJA1000Write(16,x);
x = (unsigned char)((msg->Identifier) >> 21);
SJA1000Write(17,x); //写标示符1
x = (unsigned char)((msg->Identifier) >> 13);
SJA1000Write(18,x); //写标示符2
x = (unsigned char)((msg->Identifier) >> 5);
SJA1000Write(19,x); //写标示符3
x = (unsigned char)((msg->Identifier) & 0x1F);
x <<= 3;
SJA1000Write(20,x); //写标示符4
for(i = 0; i < msg->DataLengthCode; i++){
SJA1000Write(21+i,msg->Data[i]); //写数据
}
}
else{
//标准桢
SJA1000Write(16,x);
x = (unsigned char)((msg->Identifier) >> 3);
SJA1000Write(17,x); //写标示符1
x = (unsigned char)((msg->Identifier) & 0x07);
x <<= 5;
SJA1000Write(18,x); //写标示符2
for(i = 0; i < msg->DataLengthCode; i++){
SJA1000Write(19+i,msg->Data[i]); //写数据
}
tmp = SJA1000Read(16);
tmp = SJA1000Read(17);
tmp = SJA1000Read(18);
}
SJA1000Write(REG_CMR,BIT_TR); //请求发送
}
void SJA1000_RX(CanMessageStruct * msg)
{
unsigned char x,i;
while(!(SJA1000Read(REG_SR)&BIT_RBS));
//return;//没有报文
x = SJA1000Read(16);
msg->IsExt = (x & 0x80) ? 1:0;//是否扩展桢
msg->Rtr = (x & 0x40) ? 1:0;//是否远程桢
msg->DataLengthCode = x & 0x0f;
if(msg->IsExt){
x = SJA1000Read(17);
msg->Identifier = ((unsigned int)x)<< 21;
x = SJA1000Read(18);
msg->Identifier |= ((unsigned int)x) << 13;
x = SJA1000Read(19);
msg->Identifier |= ((unsigned int)x) << 5;
x = SJA1000Read(20);
msg->Identifier |= ((unsigned int)x) >> 3;
for(i = 0; i < msg->DataLengthCode; i ++)
{
msg->Data[i] = SJA1000Read(21+i); //读数据
}
}
else{
x = SJA1000Read(17);
msg->Identifier = ((unsigned int)x)<< 3;
x = SJA1000Read(18);
msg->Identifier |= ((unsigned int)x) >> 5;
for(i = 0; i < msg->DataLengthCode; i ++)
{
msg->Data[i] = SJA1000Read(19+i); //读数据
}
}
SJA1000Write(REG_CMR,BIT_RR);//释放接收缓冲区,自动清除中断位
}
void SJA_isr(void)
{
unsigned char x = 0, nStatus = 0;
int i = 0;
static int count = 0;
int num = 0;
CanMessageStruct msg1,msg2;
msg1.Identifier = 0x5a5;
msg1.Rtr = 0;
msg1.DataLengthCode = 8;
for(i=0;i<8;i++)
msg1.Data[i] = i+2;
msg1.IsExt = 0;
/*
extern SJABufInfo * RxBuf;
extern const unsigned int RxBuf_Begin;
extern const unsigned int RxBuf_End;
*/
x = SJA1000Read(REG_IR);//get Interrupt source
if(x&BIT_RI){//Receive Interrupt
//SJA1000_RX(&msg2);
//SJA1000_TX(&msg1);
SJA1000_RX(&msg2);
WriteRx(&msg2);
}
if(x&BIT_TI){
if(count ++ <10)
SJA1000_TX(&msg1);
}
if(x&BIT_EI){
;
}
if(x&BIT_DOI){
;
}
if(x&BIT_WUI){
//nWakeNum++;no use now
}
*(volatile int *)(GIC+GIC_EOICR) = 1;//访问这个寄存器通知GIC中断被处理
}
void TsetSJA(void)
{
int i;
CanMessageStruct msg1,msg2;
unsigned char data_write[8]={1,2,3,4,5,6,7,8};
unsigned char data_read[8] ;
Init_SJA1000(500);
__CLI();
msg1.Identifier = 0x5a5;
msg1.Rtr = 0;
msg1.DataLengthCode = 8;
for(i=0;i<8;i++)
msg1.Data[i] = i+1;
msg1.IsExt = 0;
SJA1000_TX(&msg1);
while(1)
{
//SJA1000Read(REG_IR);
//SJA1000_RX(&msg2);
}
}
//测试读写时序
void TestTiming(){
unsigned char i=0;
char tmp[24];
SJA1000_IO_CS_Init() ;
SJA1000Write(0,1);
SJA1000Write(REG_CDR,SJA1000Read(REG_CDR)|0x80);
for(i=1;i<24;i++){
// SJA1000Write(i,i+1);
tmp[i] = SJA1000Read(i);
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -