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

📄 sja1000.c

📁 调试9200处理器板卡的一个调试实例
💻 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 + -