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

📄 sja1000p.cpp

📁 windows ce 下 can总线驱动源码
💻 CPP
字号:
/* sja1000.c * Linux CAN-bus device driver. * Written by Arnaud Westenberg email:arnaud@wanadoo.nl * This software is released under the GPL-License. * Version 0.6 18 Sept 2000 * Changed for PeliCan mode SJA1000 by Tomasz Motylewski (BFAD GmbH) * T.Motylewski@bfad.de */#include <windows.h>#include <windef.h>#include <types.h>#include <excpt.h>#include <tchar.h>#include <cardserv.h>#include <cardapi.h>#include <tuple.h>#include <devload.h>#include <diskio.h>#include <nkintr.h>#include <oalintr.h>#include <windev.h>#include <memory.h>#include <linklist.h>#include <pegdser.h>#include <pm.h>#include "sja1000p.h" int baudrate=0;int CLOCK = 24000000; // Chip CLOCK in Hzstatic volatile CAN_ADDR*			m_pCanAddr = NULL;static void Delay(DWORD dwMSecs) {	#define MSEC_DELAY_SCALER	0x2	volatile DWORD dwScaledSecs = (dwMSecs * MSEC_DELAY_SCALER);	while (dwScaledSecs)	{		dwScaledSecs--;	}}int CanP_VirtualAlloc(){	RETAILMSG(1, (TEXT("CAN:: CanVirtualAlloc++ \r\n") ));	m_pCanAddr = ( volatile CAN_ADDR *)VirtualAlloc(0, sizeof(CAN_ADDR), MEM_RESERVE, PAGE_NOACCESS);	if(m_pCanAddr == NULL) 	{		RETAILMSG (1,(TEXT("CAN:: CanVirtualAlloc m_pCanAddr : VirtualAlloc failed!\r\n")));		goto error_return;	}	else 	{		if(!VirtualCopy((PVOID)m_pCanAddr, (PVOID)(SJA1000_BASE), sizeof(CAN_ADDR), PAGE_READWRITE|PAGE_NOCACHE )) 		{			RETAILMSG(1,(TEXT("CAN:: CanVirtualAlloc m_pCanAddr : VirtualCopy failed!\r\n")));			goto error_return;		}	}	RETAILMSG(1, (TEXT("CAN::  m_pCanAddr  %x\r\n"), m_pCanAddr));		RETAILMSG(1,(TEXT("CAN:: CanVirtualAlloc-- \r\n")));		return TRUE;error_return:	if ( m_pCanAddr )		VirtualFree((PVOID)m_pCanAddr, 0, MEM_RELEASE);		m_pCanAddr		= NULL;	return 0;	} unsigned can_read_reg( unsigned short reg ){    m_pCanAddr->byteAddr  = reg;                   //访问地址指向控制寄存器    return  m_pCanAddr->byteData;                      //保存原始值   }; void can_write_reg(unsigned char data, unsigned short reg ){	m_pCanAddr->byteAddr  = reg;                   //访问地址指向控制寄存器    m_pCanAddr->byteData  = data;                      //保存原始值};// Enter reset mode.int sja1000p_enable_configuration( ){	int i=0;	unsigned int  flags;	flags=can_read_reg( SJAMOD);	while ((!(flags & MOD_RM)) && (i<=10)) {		can_write_reg( MOD_RM, SJAMOD);// TODO: chinfigurable MOD_AFM (32/16 bit acceptance filter)// config MOD_LOM (listen only)		Delay(10);		i++;		flags=can_read_reg( SJAMOD);	}	if (i>=10) {		RETAILMSG(1,(TEXT("Reset error\n")));				return -1;	}	return 0;}// Quit reset mode.int sja1000p_disable_configuration( ){	int i=0;	unsigned int  flags;	flags=can_read_reg( SJAMOD);	while ( (flags & MOD_RM) && (i<=10) ) {		can_write_reg(  0, SJAMOD);// TODO: chinfigurable MOD_AFM (32/16 bit acceptance filter)// config MOD_LOM (listen only)		Delay(10);		i++;		flags=can_read_reg(  SJAMOD);	}	if (i>=10) {		RETAILMSG(1,(TEXT("Error leaving reset status\n")));		return -1;	}	return 0;}/************************************  ACR==0AAH,AMR==00H  BTR0==C2H,BTR1==3aH  OC : 0xd9 为测试模式。 0xda 为正常工作模式  CDR=48H  ************************************************/int sja1000p_chip_config( unsigned int uCDR, unsigned int  uOCR,			  unsigned int uBTR0, unsigned int  uBTR1, 			  unsigned int uACR,  unsigned int  uAMR ){	if (sja1000p_enable_configuration())		return -1;		can_write_reg( uCDR, SJACDR); 	can_write_reg( uOCR,SJAOCR); 	sja1000p_set_btregs( uBTR0, uBTR1 );	if (sja1000p_extended_mask( uACR, uAMR))		return -1;		/* Enable hardware interrupts */	can_write_reg(  ENABLE_INTERRUPTS, SJAIER); 	sja1000p_disable_configuration();		return 0;}int sja1000p_set_cdr_ocrregs( unsigned int uCDR, unsigned int  uOCR){     if (sja1000p_enable_configuration())		return -1;	can_write_reg( uCDR, SJACDR); 	can_write_reg( uOCR,SJAOCR);       sja1000p_disable_configuration();  	}	// Config  ACR, AMR registor.int sja1000p_extended_mask(  unsigned long code, unsigned  long mask){	int i;	if (sja1000p_enable_configuration())		return -1;// LSB to +3, MSB to +0		for(i=SJA_PeliCAN_AC_LEN; --i>=0;) {		can_write_reg( code&0xff,SJAACR0+i);		can_write_reg( mask&0xff,SJAAMR0+i);		code >>= 8;		mask >>= 8;	}	sja1000p_disable_configuration();	return 0;}/* Set communication parameters. * param rate baud rate in Hz * param CLOCK frequency of sja1000 CLOCK in Hz (ISA osc is 14318000) * param sjw synchronization jump width (0-3) prescaled CLOCK cycles * param sampl_pt sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio * param flags fields BTR1_SAM, OCMODE, OCPOL, OCTP, OCTN, CLK_OFF, CBP */int sja1000p_baud_rate( int rate, int sjw, int sampl_pt, int flags){	int best_error = 1000000000, error;	int best_tseg=0, best_brp=0, best_rate=0, brp=0;	int tseg=0, tseg1=0, tseg2=0;		if (sja1000p_enable_configuration())		return -1;	CLOCK /=2;	/* tseg even = round down, odd = round up */	for (tseg=(0+0+2)*2; tseg<=(MAX_TSEG2+MAX_TSEG1+2)*2+1; tseg++) {		brp = CLOCK/((1+tseg/2)*rate)+tseg%2;		if (brp == 0 || brp > 64)			continue;		error = rate - CLOCK/(brp*(1+tseg/2));		if (error < 0)			error = -error;		if (error <= best_error) {			best_error = error;			best_tseg = tseg/2;			best_brp = brp-1;			best_rate = CLOCK/(brp*(1+tseg/2));		}	}	if (best_error && (rate/best_error < 10)) {		RETAILMSG(1,(TEXT("baud rate %d is not possible with %XHz CLOCK\n")),								rate, 2*CLOCK);		RETAILMSG(1,(TEXT("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n")),				best_rate, best_brp, best_tseg, tseg1, tseg2);		return -1;	}	tseg2 = best_tseg-(sampl_pt*(best_tseg+1))/100;	if (tseg2 < 0)		tseg2 = 0;	if (tseg2 > MAX_TSEG2)		tseg2 = MAX_TSEG2;	tseg1 = best_tseg-tseg2-2;	if (tseg1>MAX_TSEG1) {		tseg1 = MAX_TSEG1;		tseg2 = best_tseg-tseg1-2;	}	RETAILMSG(1,(TEXT("Setting %d bps.\n")), best_rate);	RETAILMSG(1,(TEXT("brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d, sampl_pt=%d\n")),					best_brp, best_tseg, tseg1, tseg2,					(100*(best_tseg-tseg2)/(best_tseg+1)));	can_write_reg(  sjw<<6 | best_brp, SJABTR0);	can_write_reg(  ((flags & BTR1_SAM) != 0)<<7 | (tseg2<<4) 					| tseg1, SJABTR1);	sja1000p_disable_configuration();	return 0;}int sja1000p_set_btregs( unsigned int btr0,  unsigned int btr1){	if (sja1000p_enable_configuration())		return -1;	can_write_reg( btr0, SJABTR0);	can_write_reg( btr1, SJABTR1);	sja1000p_disable_configuration();	return 0;}int sja1000p_start_chip( ){	unsigned int  flags;	flags = can_read_reg(  SJAMOD) & (MOD_LOM|MOD_STM|MOD_AFM|MOD_SM);	can_write_reg( flags, SJAMOD);	return 0;}int sja1000p_stop_chip( ){	unsigned int  flags;	flags = can_read_reg(  SJAMOD) & (MOD_LOM|MOD_STM|MOD_AFM|MOD_SM);	can_write_reg( flags|MOD_RM, SJAMOD);	return 0;} int    peli_DATA_RECEIVE( RXFIFO& rxfifo)// 读写函数都有问题,应该判断是standard帧还是extended帧才能知道数据真正的长度 { 	   int i = 0; 	   BYTE byReg1 = 0; 	      unsigned  char  TempCount;                                                //访问地址指向状态寄存器   if((can_read_reg(SJASR)&0x01)==0)               //判断报文是否有效  这个应该是判断接受缓冲区是否为空 by黎科峰   {   	RETAILMSG(1,(TEXT("SJA1K:: BCAN_DATA_RECEIVE-- no data error \r\n")));        return 1;   }      	for( i = 0; i <= 12; i++)	{	     rxfifo.reg[i] = can_read_reg( 16+ i );		     RETAILMSG(1, (TEXT(" TX buffer reg%x = %x\r\n"), i+16, rxfifo.reg[i] ));	     	}       //    can_write_reg( CMR_RRB,SJACMR );	        RETAILMSG(1,(TEXT("SJA1K:: BCAN_DATA_RECEIVE-- ok \r\n")));   return  0; }  int  peli_DATA_WRITE(unsigned int *SendDataBuf) {   unsigned  char  TempCount;   int i = 0;   	   /* and leave Reset Mode */ 		   sja1000p_disable_configuration();    if(( can_read_reg(SJASR)&0x08) == 0)         //判断上次发送是否完成   {   	RETAILMSG(1,(TEXT("SJA1K:: BCAN_DATA_WRITE-- not complete error \r\n")));    return	1;   }     if((can_read_reg(SJASR)&0x04)==0)          //判断发送缓冲区是否锁定   {   	RETAILMSG(1,(TEXT("SJA1K:: BCAN_DATA_WRITE--lock error \r\n")));     return	1;   }         if((SendDataBuf[0]&0x40)==0)         //判断RTR,从而得出是数据帧还是远程帧   {      TempCount =(SendDataBuf[0]&0x0f) + 5; //输入数据帧   }   else   {     TempCount =5;                     //远程帧   }     //  memcpy(m_pCanAddr->byteData,SendDataBuf,TempCount);    for ( i = 0; i < TempCount; i++)   {   	can_write_reg(  SendDataBuf[i],SJAFRM + i);    }       RETAILMSG(1, (TEXT("CAN::  SendDatacount  %x\r\n"), TempCount));        can_write_reg( CMR_TR,SJACMR );	      	  RETAILMSG(1,(TEXT("SJA1K:: BCAN_DATA_WRITE-- ok \r\n")));   return 0;}void TestReadAllRegs(  ){	int i = 0;	unsigned int ireg = 0;	RETAILMSG(1,(TEXT(" TestReadAllRegs++ \r\n")));			for( i = 0; i <= 0x1f; i++)	{	    ireg = can_read_reg ( i );	    RETAILMSG(1, (TEXT(" Reg%x = %x\r\n"),i, ireg ));	}	RETAILMSG(1,(TEXT(" TestReadAllRegs-- \r\n")));}void initcan(  ){		BYTE byCDR,byOCR,byBTR0,byBTR1,byMOD,byCMR;	unsigned regtmp = 0, RegInt = 0, Reg1 = 0, Reg2 = 0;				RETAILMSG(1,(TEXT(" SlefTest ++ \r\n"))); 	RETAILMSG(1, (TEXT(" Hardware reset status \r\n")));	TestReadAllRegs();  	//	byCDR = 0xC8,byOCR= 0xda,byBTR0 = 0xc2, byBTR1 = 0x3a,byMOD = MOD_STM,byCMR = CMR_SRR;	        				if (sja1000p_enable_configuration())		return  ;	 	// PeliCAN Mode 	can_write_reg(  0xC8, SJACDR); 				can_write_reg(  0x1a, SJAOCR);	can_write_reg(  0x18, SJABTR0);  			can_write_reg(  0xef, SJABTR1);				Delay(10);		can_write_reg( 0x00, 16); 	can_write_reg( 0x00, 17); 	can_write_reg( 0x00, 18); 	can_write_reg( 0x00, 19); 		can_write_reg( 0xff, 20); 	can_write_reg( 0xff, 21); 		can_write_reg( 0xff, 22); 	can_write_reg( 0xff, 23); 			Sleep(5);	RETAILMSG(1, (TEXT(" reset status After Setting \r\n")));	TestReadAllRegs();		  		 		sja1000p_disable_configuration();					 	 //Enter Self Test Mode  	can_write_reg( MOD_AFM, SJAMOD);				can_write_reg(  ENABLE_INTERRUPTS, SJAIER);			can_read_reg ( SJAIR );   	RETAILMSG(1, (TEXT(" Operate status init \r\n"))); 	TestReadAllRegs();   				for( regtmp = 0; regtmp <= 12; regtmp++)	{	     Reg2 = can_read_reg( 96+ regtmp );		     RETAILMSG(1, (TEXT(" TX buffer reg%x = %x\r\n"), regtmp+96, Reg2));	     	}		RETAILMSG(1,(TEXT(" SlefTest-- \r\n")));		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -