www.pudn.com > CANdrv.rar > CANDrv.c


/* CANDrv.c - MC523x Flexcan communication driver */ 
 
/*  Copyright 2005 ZHUHAI UNITECH POWER TECHNOLOGY CO.,LTD  */ 
 
/* 
modification history 
-------------------- 
*/ 
 
/* 
DESCRIPTION 
This is the driver for the Flexcan contained in the 523X. 
*/ 
#include "vxWorks.h" 
#include "iosLib.h" 
#include "intLib.h" 
#include "errno.h" 
#include "CANDrv.h" 
#include "string.h" 
 
int Tx_count; 
int Rx_count; 
 
int CanDrvNum  = 0;  
 
Tx_count=0; 
Rx_count=0; 
 
Can_DEV can_chan_dev[NUM_CAN]; 
 
LOCAL STATUS InitCan(Can_DEV *); 
LOCAL STATUS WriteByte(Can_DEV *,UCHAR ,int ); 
LOCAL STATUS CanBaudSet (Can_DEV *, UINT); 
LOCAL STATUS CanTxIDSet (Can_DEV *,UINT); 
LOCAL STATUS CanRxIDSet (Can_DEV *,UINT); 
LOCAL STATUS CheckBusStatus(Can_DEV *); 
LOCAL void CanTxInterrupt (Can_DEV *); 
LOCAL void CanRxInterrupt (Can_DEV *); 
 
/****************************************************************************** 
*CanDrv  --  CAN驱动安装程序 
*返回 - 安装成功返回OK,否则返回ERROR 
*参数:无 
******************************************************************************/ 
STATUS CanDrv(void) 
{ 
	if(CanDrvNum > 0) 
	{ 
		printf("Can driver has been installed!\n"); 
		return OK;//已经安装驱动 
	} 
 
	if((CanDrvNum = iosDrvInstall(0,0,CanOpen,CanClose,CanRead,CanWrite,CanIoctl)) == ERROR) 
	{ 
		printf("Can driver install ERROR!\n"); 
		return ERROR; 
	} 
#if NUM_CAN == 2 
	intConnect(INUM_TO_IVEC(CAN0_MB0_INTVEC),Can0TxInterrupt,0); 
	intConnect(INUM_TO_IVEC(CAN0_MB1_INTVEC),Can0RxInterrupt,0); 
	intConnect(INUM_TO_IVEC(CAN1_MB0_INTVEC),Can1TxInterrupt,0); 
	intConnect(INUM_TO_IVEC(CAN1_MB1_INTVEC),Can1RxInterrupt,0); 
	 
#else 
	intConnect(INUM_TO_IVEC(CAN0_MB0_INTVEC),Can0TxInterrupt,0); 
	intConnect(INUM_TO_IVEC(CAN0_MB1_INTVEC),Can0RxInterrupt,0);	 
#endif 
 
	printf("Can driver has been installed successfully !\n"); 
	return OK; 
} 
 
/****************************************************************************** 
*itos  --  将一个整数转换为字符 
*返回 - 转换后的字符串指针 
*参数:val -- 要转换的整数 
******************************************************************************/ 
 
static char * itos (int val) 
{ 
    static char str [20]; 
    char strtmp [20]; 
    str [0] = '\0'; 
 
    if (val == 0) 
	return "0"; 
 
    while (val != 0) 
	{ 
	strcpy (strtmp, str); 
	str[0] = '0' + (val % 10); 
	str[1] = '\0'; 
	strcat (str, strtmp); 
	val = val - (val %= 10); 
	} 
 
    return str; 
} 
 
/****************************************************************************** 
*CanDevCreate  --  CAN设备创建函数 
*返回 - 创建成功返回OK,否则返回ERROR 
*参数:无 
* 
******************************************************************************/ 
 
STATUS CanDevCreate() 
{ 
	char canName[20]; 
	int i; 
	if(CanDrvNum == 0) 
	{ 
		return ERROR; 
	} 
 
	for(i=0;iFlag_canOpen = CAN_YES; /*打开CAN设备*/ 
 
	/*使MB0和MB1不参与仲裁与配匹*/ 
    CANDEV_WRITE(pCan_Dev->txcode, 
		TX_NOTENABLE | DEFAULT_LENGTH); 
	CANDEV_WRITE(pCan_Dev->rxcode, 
		RX_NOTENABLE | DEFAULT_LENGTH); 
	/*清除发送缓冲区数据*/ 
	CANDEV_WRITE(pCan_Dev->txdata0,0x00); 
	CANDEV_WRITE(pCan_Dev->txdata1,0x00); 
	CANDEV_WRITE(pCan_Dev->txdata2,0x00); 
	CANDEV_WRITE(pCan_Dev->txdata3,0x00); 
	CANDEV_WRITE(pCan_Dev->txdata4,0x00); 
	CANDEV_WRITE(pCan_Dev->txdata5,0x00); 
	CANDEV_WRITE(pCan_Dev->txdata6,0x00); 
	CANDEV_WRITE(pCan_Dev->txdata7,0x00); 
 
	/*清除接收缓冲区数据*/ 
	CANDEV_WRITE(pCan_Dev->rxdata0,0x00); 
	CANDEV_WRITE(pCan_Dev->rxdata1,0x00); 
	CANDEV_WRITE(pCan_Dev->rxdata2,0x00); 
	CANDEV_WRITE(pCan_Dev->rxdata3,0x00); 
	CANDEV_WRITE(pCan_Dev->rxdata4,0x00); 
	CANDEV_WRITE(pCan_Dev->rxdata5,0x00); 
	CANDEV_WRITE(pCan_Dev->rxdata6,0x00); 
	CANDEV_WRITE(pCan_Dev->rxdata7,0x00); 
 
	/*接收使能*/ 
	CANDEV_WRITE(pCan_Dev->rxcode, 
		RX_ENABLE | DEFAULT_LENGTH); 
 
	printf("Can device has been opened !\n"); 
	return((int)pCan_Dev); 
 
 
} 
 
/****************************************************************************** 
*CanOpen  --  关闭CAN设备 
*返回 - 无 
*参数:pCan_Dev   --  要关闭的CAN设备 
* 
******************************************************************************/ 
 
int CanClose(Can_DEV *pCan_Dev) 
{ 
	if(pCan_Dev->Flag_canOpen == CAN_NO) 
	{ 
		printf("Can device has been closed !\n"); 
		return OK; 
	} 
	 
	pCan_Dev->Flag_canOpen = CAN_NO; /*关闭CAN设备*/ 
 
	CANDEV_WRITE(pCan_Dev->txcode, 
		TX_NOTENABLE | DEFAULT_LENGTH); 
	CANDEV_WRITE(pCan_Dev->rxcode, 
		RX_NOTENABLE | DEFAULT_LENGTH); 
	/*初始化发送缓冲区指针及发送计数器*/ 
	pCan_Dev->ptx = pCan_Dev->tx_Buff; 
	pCan_Dev->tx_number = 0; 
	pCan_Dev->tx_length =0; 
 
		/*初始化接收缓冲区指针及接收计数器*/ 
	pCan_Dev->prx_write = pCan_Dev->rx_Buff; 
	pCan_Dev->prx_read = pCan_Dev->rx_Buff; 
	pCan_Dev->rx_number = 0; 
	pCan_Dev->rx_length = 0; 
 
		 
	printf("Can device has been closed !\n"); 
	return OK; 
 
} 
/****************************************************************************** 
* 
* CanWrite  --   CAN发送函数 
* 返回: 成功返回已写入的字节数, 否则返回0 
*参数说明: 
         pChan    --   需要控制的设备 
         buffer   --   写缓冲区 
         someArg  --   写字节数 
******************************************************************************/ 
 
int CanWrite(Can_DEV *pCan_Dev,UCHAR *buffer,UINT16 nBytes) 
{ 
	int i; 
	int j; 
	UCHAR *txbuf; 
	txbuf = buffer; 
	if(pCan_Dev->Flag_canOpen == CAN_NO)  
	{ 
		printf("Can device hasn't been opened !\n"); 
		return 0;/*如果设备没有打开返回0*/ 
	} 
	if(nBytes > MAX_TX_BUFFER) 
	{ 
		printf("要发送的字节数大于发送缓冲区长度 !\n"); 
		return 0; /*要发送的字节数大于发送缓冲区*/ 
	} 
 
	/* 
	if( ERROR == semTake(pCan_Dev->tx_semSync, 50) ) 
	{ 
		printf("Cann't Take The TX Sem.\n\r"); 
		return 0; 
	} 
    */ 
 
	//semTake(pCan_Dev->tx_semSync,WAIT_FOREVER);/*等待发送中断释放信号量*/ 
	/*如果需发送的字节数小于或等于8,不用复制到设备的发送缓冲区中,直接发送 
	否则将所有数据复制到设备缓冲区中,先发送前8个字节,剩余的在设备的缓冲区中用中断发送*/ 
	if(nBytes <= 8) 
	{ 
		j = 0; 
		while(CheckBusStatus(pCan_Dev) != OK) //检查CAN总线是否在空闲状态 
		{ 
			j++; 
			if(j >= 40000) break; 
		} 
		if(j >= 40000)  
		{ 
 
			printf("Can bus is always busy !\n"); 
			return 0;//总线一直忙 
		} 
 
		CANDEV_WRITE(pCan_Dev->txcode,   /*INACTIVE发送*/ 
			TX_NOTENABLE); 
		for(i=0;itx_number = 0; 
		pCan_Dev->tx_length = nBytes; 
		pCan_Dev->ptx = pCan_Dev->tx_Buff; 
		CANDEV_WRITE(pCan_Dev->txcode,   /*ACTIVE发送*/ 
			TX_ENABLE | pCan_Dev->tx_length); 
		printf("Has been transmitted!\n"); 
 
	} 
	else 
	{ 
		/*复制数据到设备的发送缓冲区中*/ 
		for(i = 0;i < nBytes;i++,txbuf++) 
		{ 
			pCan_Dev->tx_Buff[i] = *txbuf; 
		} 
 
		pCan_Dev->ptx = pCan_Dev->tx_Buff; 
		pCan_Dev->ptx += 8;/*发送指针往后移8个字节*/ 
		pCan_Dev->tx_number = nBytes -8; 
		pCan_Dev->tx_length = 8; 
 
		j = 0; 
		while(CheckBusStatus(pCan_Dev) != OK) //检查CAN总线是否在空闲状态 
		{ 
			j++; 
			if(j >= 40000) break; 
		} 
		if(j >= 40000) 
		{ 
			pCan_Dev->ptx = pCan_Dev->tx_Buff; 
			pCan_Dev->tx_number = 0; 
			pCan_Dev->tx_length = 0; 
			printf("Can bus is always busy !\n"); 
			return 0;//总线一直忙 
		} 
 
		CANDEV_WRITE(pCan_Dev->txcode,   /*INACTIVE发送*/ 
			TX_NOTENABLE); 
		txbuf = buffer; 
		for(i=0;i<8;i++) 
		{ 
			WriteByte(pCan_Dev,*txbuf,i); 
			txbuf++; 
		} 
		CANDEV_WRITE(pCan_Dev->txcode,   /*ACTIVE发送*/ 
			TX_ENABLE | pCan_Dev->tx_length); 
		printf("Has been transmitted!\n"); 
	} 
	return nBytes; 
 
 
} 
/****************************************************************************** 
* 
* CanRead  --   CAN接收函数 
* 返回: 成功返回已读的字节数, 否则返回0 
*参数说明: 
         pChan    --   需要控制的设备 
         buffer   --   读缓冲区 
         someArg  --   读字节数 
******************************************************************************/ 
int CanRead(Can_DEV *pCan_Dev,UCHAR *buffer,UINT16 nBytes) 
{ 
	UINT16 i; 
	UCHAR *rx_buff; 
	rx_buff = buffer; 
	i = 0; 
	if(pCan_Dev->Flag_canOpen == CAN_NO)  
	{ 
		printf("Can device is not been opened !\n"); 
		return 0; 
	} 
	if( ERROR == semTake(pCan_Dev->rx_semSync, 50) ) 
	{ 
		//printf("Cann't Take The RX Sem.\n"); 
		return 0; 
	} 
 
	//semTake(pCan_Dev->rx_semSync,WAIT_FOREVER);/*等待接收中断释放信号量*/ 
 
	while((pCan_Dev->prx_read != pCan_Dev->prx_write)&&(i < nBytes)) 
	{ 
	     *rx_buff = *pCan_Dev->prx_read; 
		 rx_buff++; 
		 pCan_Dev->prx_read++; 
		 i++; 
		 if((pCan_Dev->prx_read - pCan_Dev->rx_Buff) == MAX_RX_BUFFER ) 
		 { 
			pCan_Dev->prx_read = pCan_Dev->rx_Buff; 
		 } 
	} 
 
	return(i); 
 
} 
/****************************************************************************** 
* 
* CAN控制函数 
* 
* 返回: 
* 成功返回OK, 设备错误返回ERROR, 不支持返回ERROR 
*  
*参数说明: 
*  pChan    --   需要控制的设备 
*  request  --   请求的功能 
*  someArg  --   控制参数 
******************************************************************************/ 
 
int CanIoctl 
    ( 
    Can_DEV *	pChan,		/* device to control */ 
    int		request,		/* request code */ 
    void *	someArg			/* some argument */ 
    ) 
{ 
    STATUS result = OK; 
    int     arg = (int)someArg; 
 
	if(pChan->Flag_canOpen != CAN_YES) return ERROR;/*如果设备没有打开返回0*/ 
 
    switch (request) 
	{ 
	case CAN_BAUD_SET: 
	    if (CanBaudSet(pChan, arg) != OK) 
		result = ERROR; 
	    break; 
 
	case CAN_BAUD_GET: 
	    *(int *)arg = pChan->baudRate; 
	    return (OK); 
 
	case CAN_TXID_SET: 
	    if (CanTxIDSet(pChan, arg) != OK) 
			result = ERROR; 
	    break; 
 
	case CAN_TXID_GET: 
	    *(int *)arg = pChan->TxID; 
	    return (OK); 
 
	case CAN_RXID_SET: 
	    if (CanRxIDSet(pChan, arg) != OK) 
			result = ERROR; 
	    break; 
 
	case CAN_RXID_GET: 
	    *(int *)arg = pChan->RxID; 
	    return (OK); 
 
	default: 
	    return (ERROR); 
	} 
	printf("CanIoctl funtion has been set \n"); 
    return (result); 
} 
/****************************************************************************** 
* 
* CanBaudSet - 改变can设备的波特率 
*设置can的波特率,设置时不使能中断 
*波特率只能为1M 500K 250K 125K 100K 75K 50K  
* 
* 返回:OK或者ERROR 
*  
******************************************************************************/ 
 
LOCAL STATUS CanBaudSet 
    ( 
    Can_DEV *	pcan_chan, 
    UINT32		baud 
    ) 
{ 
	register int i; 
	i = 0; 
    if (!baud) 
	return (ERROR); 
    if (baud != pcan_chan->baudRate) 
	{ 
		UINT32 val; 
		int oldlevel; 
		 
		switch(baud) 
		{ 
		case 1000000: 
			val = 0x045B2005; 
			break; 
		case 500000: 
			val = ((PRESDIV1(baud)) << 24)| CTRL_RJW | CTRL_PSEG1 | CTRL_PSEG2 | CTRL_CLK_SRC | CTRL_SMP | CTRL_PROPSEG; 
			break; 
		case 125000: 
			val = ((PRESDIV1(baud)) << 24)| CTRL_RJW | CTRL_PSEG1 | CTRL_PSEG2 | CTRL_CLK_SRC | CTRL_SMP | CTRL_PROPSEG; 
			break; 
		case 100000: 
			val = ((PRESDIV1(baud)) << 24)| CTRL_RJW | CTRL_PSEG1 | CTRL_PSEG2 | CTRL_CLK_SRC | CTRL_SMP | CTRL_PROPSEG; 
			break; 
		case 75000: 
			val = ((PRESDIV1(baud)) << 24)| CTRL_RJW | CTRL_PSEG1 | CTRL_PSEG2 | CTRL_CLK_SRC | CTRL_SMP | CTRL_PROPSEG; 
			break; 
		case 50000: 
			val = ((PRESDIV1(baud)) << 24)| CTRL_RJW | CTRL_PSEG1 | CTRL_PSEG2 | CTRL_CLK_SRC | CTRL_SMP | CTRL_PROPSEG; 
			break; 
		default: 
			return ERROR; 
		} 
		 
		oldlevel = intLock (); 
		 
		/*设置FRZ和HALT位,使CAN进入Freeze模式,进入管理模式*/ 
		CANDEV_WRITE(pcan_chan->mcr, 
			MCR_MENE | MCR_FRZ | MCR_HALT | MCR_SUPV | MCR_MAXMB); 
		 
		while((CANDEV_READ(pcan_chan->mcr) & 0x01000000) == 0x00000000) //等待can进入Freeze模式 
		{ 
			i++; 
			if(i >= 40000) 
			{ 
				return ERROR; 
			} 
		} 
		 
		CANDEV_WRITE(pcan_chan->ctrl,val); 
		 
		/*退出FREEZE模式,退出管理模式*/ 
		CANDEV_WRITE(pcan_chan->mcr, 
			MCR_MENE | MCR_MAXMB); 
		 
		pcan_chan->baudRate = baud; 
		intUnlock (oldlevel); 
	} 
    return (OK); 
} 
/****************************************************************************** 
* 
* CanIDTxSet - 改变can信息缓冲区MB0的ID 
*设置信息缓冲区ID,设置时理论上可以不用使该CAN进入FREEZE模式 
*但为了安全起见,还是考虑进入FREEZE模式并且不使能中断 
* 
* 返回:OK或者ERROR 
*  
******************************************************************************/ 
LOCAL STATUS CanTxIDSet  
( 
 Can_DEV *pcan_chan, 
 UINT32 Id 
 ) 
{ 
	register int i; 
	UINT32 MbufId; 
	int oldlevel; 
	i = 0; 
	if((Id ==0) || (Id > 2047)) 
	{ 
		printf("The TXID number is too large!\n"); 
		return ERROR; 
	} 
	if(Id != pcan_chan->TxID) 
	{ 
		 
		MbufId = Id << 18; 
 
		oldlevel = intLock (); 
		 
		/*设置FRZ和HALT位,使CAN进入Freeze模式,进入管理模式*/ 
		CANDEV_WRITE(pcan_chan->mcr, 
			MCR_MENE | MCR_FRZ | MCR_HALT | MCR_SUPV | MCR_MAXMB); 
		 
		while((CANDEV_READ(pcan_chan->mcr) & 0x01000000) == 0x00000000) //等待can进入Freeze模式 
		{ 
			i++; 
			if(i >= 40000) 
			{ 
				printf("CAN didn't enter into freeze mode!"); 
				return ERROR; 
			} 
		} 
		 
		CANDEV_WRITE(pcan_chan->txcode, 
		TX_NOTENABLE | DEFAULT_LENGTH); 
		CANDEV_WRITE(pcan_chan->txID,MbufId); //写发送缓冲区ID 
		 
 
 
		/*退出FREEZE模式,退出管理模式*/ 
		CANDEV_WRITE(pcan_chan->mcr, 
			MCR_MENE | MCR_MAXMB); 
 
		pcan_chan->TxID = Id; 
		intUnlock (oldlevel); 
	} 
	 
	return OK; 
} 
 
/****************************************************************************** 
* 
* CanIDRxSet - 改变can信息缓冲区MB1的ID 
*设置信息缓冲区ID,设置时理论上可以不用使该CAN进入FREEZE模式 
*但为了安全起见,还是考虑进入FREEZE模式并且不使能中断 
* 
* 返回:OK或者ERROR 
*  
******************************************************************************/ 
LOCAL STATUS CanRxIDSet  
( 
 Can_DEV *pcan_chan, 
 UINT32 Id 
 ) 
{ 
	register int i; 
	i = 0; 
	if((Id ==0) || (Id > 2047)) 
	{ 
		printf("The RXID number is too large!\n"); 
		return ERROR; 
	} 
	if(Id != pcan_chan->RxID) 
	{ 
		UINT32 MbufId; 
		int oldlevel; 
		MbufId = Id << 18; 
 
		oldlevel = intLock (); 
		 
		/*设置FRZ和HALT位,使CAN进入Freeze模式,进入管理模式*/ 
		CANDEV_WRITE(pcan_chan->mcr, 
			MCR_MENE | MCR_FRZ | MCR_HALT | MCR_SUPV | MCR_MAXMB); 
		 
		while((CANDEV_READ(pcan_chan->mcr) & 0x01000000) == 0x00000000) //等待can进入Freeze模式 
		{ 
			i++; 
			if(i >= 40000) 
			{ 
				printf("CAN didn't enter into freeze mode!"); 
				return ERROR; 
			} 
		} 
 
		CANDEV_WRITE(pcan_chan->rxcode, 
		RX_NOTENABLE | DEFAULT_LENGTH); 
		CANDEV_WRITE(pcan_chan->rxID,MbufId);//写接收缓冲区ID 
 
		CANDEV_WRITE(pcan_chan->rxcode, 
		RX_ENABLE | DEFAULT_LENGTH); 
		/*退出FREEZE模式,退出管理模式*/ 
		CANDEV_WRITE(pcan_chan->mcr, 
			MCR_MENE | MCR_MAXMB); 
 
		pcan_chan->RxID = Id; 
		intUnlock (oldlevel); 
	} 
	return OK; 
} 
/****************************************************************************** 
* 
* CanDevInit - can设备初始化程序 
*初始化CAN设备结构寄存器地址,并调用Initcan函数对CAN寄存器进行初始化 
* 
*返回:无 
*  
*参数:无 
******************************************************************************/ 
void CanDevInit (void) 
{ 
	int i; 
	for(i=0;imcr, 
		MCR_MENE | MCR_FRZ | MCR_HALT | MCR_SUPV | MCR_MAXMB); 
 
	while((CANDEV_READ(pcan_chan->mcr) & MCR_FRZACK) == 0x00000000) //等待can进入Freeze模式 
	{ 
		i++; 
		if(i >= 40000) 
		{ 
			return ERROR; 
		} 
	} 
 
	/*配置S_CLK的预除因子,时钟源及时间分额数量*/ 
	CANDEV_WRITE(pcan_chan->ctrl, 
		CTRL_PRESDIV | CTRL_RJW | CTRL_PSEG1 | CTRL_PSEG2 | CTRL_CLK_SRC | CTRL_SMP | CTRL_PROPSEG); 
     
	/*初始化MB0作为发送缓冲区,MB1作为接收缓冲区*/ 
    CANDEV_WRITE(pcan_chan->txcode, 
		TX_NOTENABLE | DEFAULT_LENGTH); 
	CANDEV_WRITE(pcan_chan->rxcode, 
		RX_NOTENABLE | DEFAULT_LENGTH); 
 
	/*初始化发送缓冲区及接收缓冲区ID*/ 
	CANDEV_WRITE(pcan_chan->txID,(pcan_chan->TxID)<<18); 
	CANDEV_WRITE(pcan_chan->rxID,(pcan_chan->RxID)<<18); 
 
	/*清除发送缓冲区数据*/ 
	CANDEV_WRITE(pcan_chan->txdata0,0x00); 
	CANDEV_WRITE(pcan_chan->txdata1,0x00); 
	CANDEV_WRITE(pcan_chan->txdata2,0x00); 
	CANDEV_WRITE(pcan_chan->txdata3,0x00); 
	CANDEV_WRITE(pcan_chan->txdata4,0x00); 
	CANDEV_WRITE(pcan_chan->txdata5,0x00); 
	CANDEV_WRITE(pcan_chan->txdata6,0x00); 
	CANDEV_WRITE(pcan_chan->txdata7,0x00); 
 
	/*清除接收缓冲区数据*/ 
	CANDEV_WRITE(pcan_chan->rxdata0,0x00); 
	CANDEV_WRITE(pcan_chan->rxdata1,0x00); 
	CANDEV_WRITE(pcan_chan->rxdata2,0x00); 
	CANDEV_WRITE(pcan_chan->rxdata3,0x00); 
	CANDEV_WRITE(pcan_chan->rxdata4,0x00); 
	CANDEV_WRITE(pcan_chan->rxdata5,0x00); 
	CANDEV_WRITE(pcan_chan->rxdata6,0x00); 
	CANDEV_WRITE(pcan_chan->rxdata7,0x00); 
 
	/*不用的缓冲区2~15全部作为接受缓冲区,并且不使能和清零缓冲区的数据*/ 
	/*MB2*/ 
	CANDEV_WRITE(pcan_chan->mb2code, 
		TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb2ID,0); 
	CANDEV_WRITE(pcan_chan->mb2data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb2data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb2data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb2data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb2data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb2data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb2data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb2data7,0x00); 
 
	/*MB3*/ 
	CANDEV_WRITE(pcan_chan->mb3code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb3ID,0); 
	CANDEV_WRITE(pcan_chan->mb3data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb3data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb3data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb3data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb3data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb3data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb3data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb3data7,0x00); 
 
	/*MB4*/ 
	CANDEV_WRITE(pcan_chan->mb4code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb4ID,0); 
	CANDEV_WRITE(pcan_chan->mb4data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb4data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb4data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb4data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb4data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb4data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb4data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb4data7,0x00); 
 
	/*MB5*/ 
	CANDEV_WRITE(pcan_chan->mb5code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb5ID,0); 
	CANDEV_WRITE(pcan_chan->mb5data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb5data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb5data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb5data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb5data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb5data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb5data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb5data7,0x00); 
 
	/*MB8*/ 
	CANDEV_WRITE(pcan_chan->mb6code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb6ID,0); 
	CANDEV_WRITE(pcan_chan->mb6data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb6data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb6data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb6data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb6data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb6data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb6data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb6data7,0x00); 
 
	/*MB7*/ 
	CANDEV_WRITE(pcan_chan->mb7code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb7ID,0); 
	CANDEV_WRITE(pcan_chan->mb7data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb7data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb7data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb7data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb7data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb7data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb7data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb7data7,0x00); 
 
	/*MB8*/ 
	CANDEV_WRITE(pcan_chan->mb8code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb8ID,0); 
	CANDEV_WRITE(pcan_chan->mb8data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb8data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb8data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb8data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb8data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb8data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb8data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb8data7,0x00); 
 
	/*MB9*/ 
	CANDEV_WRITE(pcan_chan->mb9code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb9ID,0); 
	CANDEV_WRITE(pcan_chan->mb9data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb9data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb9data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb9data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb9data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb9data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb9data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb9data7,0x00); 
 
	/*MB10*/ 
	CANDEV_WRITE(pcan_chan->mb10code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb10ID,0); 
	CANDEV_WRITE(pcan_chan->mb10data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb10data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb10data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb10data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb10data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb10data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb10data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb10data7,0x00); 
 
	/*MB11*/ 
	CANDEV_WRITE(pcan_chan->mb11code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb11ID,0); 
	CANDEV_WRITE(pcan_chan->mb11data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb11data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb11data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb11data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb11data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb11data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb11data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb11data7,0x00); 
 
	/*MB12*/ 
	CANDEV_WRITE(pcan_chan->mb12code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb12ID,0); 
	CANDEV_WRITE(pcan_chan->mb12data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb12data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb12data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb12data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb12data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb12data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb12data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb12data7,0x00); 
 
	/*MB13*/ 
	CANDEV_WRITE(pcan_chan->mb13code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb13ID,0); 
	CANDEV_WRITE(pcan_chan->mb13data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb13data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb13data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb13data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb13data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb13data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb13data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb13data7,0x00); 
 
	/*MB14*/ 
	CANDEV_WRITE(pcan_chan->mb14code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb14ID,0); 
	CANDEV_WRITE(pcan_chan->mb14data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb14data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb14data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb14data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb14data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb14data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb14data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb14data7,0x00); 
 
	/*MB15*/ 
	CANDEV_WRITE(pcan_chan->mb15code,TX_NOTENABLE | 0); 
	CANDEV_WRITE(pcan_chan->mb15ID,0); 
	CANDEV_WRITE(pcan_chan->mb15data0,0x00); 
	CANDEV_WRITE(pcan_chan->mb15data1,0x00); 
	CANDEV_WRITE(pcan_chan->mb15data2,0x00); 
	CANDEV_WRITE(pcan_chan->mb15data3,0x00); 
	CANDEV_WRITE(pcan_chan->mb15data4,0x00); 
	CANDEV_WRITE(pcan_chan->mb15data5,0x00); 
	CANDEV_WRITE(pcan_chan->mb15data6,0x00); 
	CANDEV_WRITE(pcan_chan->mb15data7,0x00); 
 
	/*设置ID屏蔽寄存器,检查所有的标准格式的ID位*/ 
	CANDEV_WRITE(pcan_chan->rxgmask,0x1FFFFFFF); 
 
	/*屏蔽除MBO和MB1外的所有中断*/ 
	CANDEV_WRITE(pcan_chan->imask,0x0003); 
 
	/*清除中断标志*/ 
	CANDEV_WRITE(pcan_chan->iflag,0xFFFF); 
 
	/*退出FREEZE模式,退出管理模式*/ 
	CANDEV_WRITE(pcan_chan->mcr, 
		MCR_MENE | MCR_MAXMB); 
   intUnlock (oldlevel); 
 
   /*创建发送接收信号量*/ 
   printf("Create Sem...\n\r"); 
   pcan_chan->tx_semSync = semBCreate(SEM_Q_FIFO,SEM_FULL); /*发送信号量初始状态为满*/ 
    
   if(pcan_chan->tx_semSync == NULL) 
   { 
	   printf("tx_semSync creat error\n"); 
	   return ERROR; 
   } 
   pcan_chan->rx_semSync = semBCreate(SEM_Q_FIFO,SEM_EMPTY);/*接收信号量初始状态为空*/ 
   if(pcan_chan->rx_semSync == NULL) 
   { 
	   printf("rx_semSync creat error\n"); 
	   return ERROR; 
   } 
    
   printf("Done.\n\r"); 
 
   return OK; 
 
} 
 
/****************************************************************************** 
* 
* WriteByte - 写字节到Flex_can的信息缓冲区中 
* 
*返回:成功返回OK,否则返回ERROR 
*  
*参数: 
      pcan_chan  --  要写入字节的can设备 
	  byte       --  要写入的字节 
	  num        --  该字节在信息缓冲区中的位置 
******************************************************************************/ 
 
LOCAL STATUS WriteByte(Can_DEV *pcan_chan,UCHAR byte,int num) 
{ 
	if(num >= 8) return ERROR; 
	switch (num) 
	{ 
	case 0: 
		CANDEV_WRITE(pcan_chan->txdata0,byte); 
		break; 
	case 1: 
		CANDEV_WRITE(pcan_chan->txdata1,byte); 
		break; 
	case 2: 
		CANDEV_WRITE(pcan_chan->txdata2,byte); 
		break; 
	case 3: 
		CANDEV_WRITE(pcan_chan->txdata3,byte); 
		break; 
	case 4: 
		CANDEV_WRITE(pcan_chan->txdata4,byte); 
		break; 
	case 5: 
		CANDEV_WRITE(pcan_chan->txdata5,byte); 
		break; 
	case 6: 
		CANDEV_WRITE(pcan_chan->txdata6,byte); 
		break; 
	case 7: 
		CANDEV_WRITE(pcan_chan->txdata7,byte); 
		break; 
	default: 
		return ERROR; 
	} 
	return OK; 
 
 
} 
 
/****************************************************************************** 
* 
* Can0TxInterrupt - Flex_can0模块发送中断函数,调用相应的中断例程 
* 
*返回:无 
*  
*参数:无 
******************************************************************************/ 
void Can0TxInterrupt (void) 
{ 
	UINT16        intStatus; 
    //logMsg("#can0 Tx Int!T#", 1, 2, 3, 4, 5, 6); 
 
	intStatus = CANDEV_READ(can_chan_dev[0].iflag);/*读中断状态标志*/ 
	if((intStatus & 0x0001) == 0x0001) 
	{ 
		CanTxInterrupt(&can_chan_dev[0]); 
	} 
	else 
	{		 
		logMsg("#can0 Tx vacant Int!T#", 1, 2, 3, 4, 5, 6); 
	} 
	/* 
	if(intStatus & CAN0_TX_INT_STATUS) 
	{ 
		CanTxInterrupt(&can_chan_dev[0]); 
	} 
	if(intStatus & CAN0_RX_INT_STATUS) 
	{ 
		CanRxInterrupt(&can_chan_dev[0]); 
	} 
	*/ 
    CANDEV_WRITE(can_chan_dev[0].iflag,0x0001);/*清除中断状态标志*/ 
} 
/****************************************************************************** 
* 
* Can0RxInterrupt - Flex_can0模块接收中断函数,调用相应的中断例程 
* 
*返回:无 
*  
*参数:无 
******************************************************************************/ 
void Can0RxInterrupt (void) 
{ 
	UINT16        intStatus; 
	Rx_count++; 
    ///logMsg("#can0 Rx Int!T#", 1, 2, 3, 4, 5, 6); 
	intStatus = CANDEV_READ(can_chan_dev[0].iflag);/*读中断状态标志*/ 
	if((intStatus & 0x0002) == 0x0002) 
	{ 
		CanRxInterrupt(&can_chan_dev[0]); 
 
	} 
	else 
	{ 
		//logMsg("#can0 Rx vacant Int!T#", 1, 2, 3, 4, 5, 6); 
	} 
	/* 
	if(intStatus & CAN0_TX_INT_STATUS) 
	{ 
		CanTxInterrupt(&can_chan_dev[0]); 
	} 
	if(intStatus & CAN0_RX_INT_STATUS) 
	{ 
		CanRxInterrupt(&can_chan_dev[0]); 
	} 
	*/ 
    CANDEV_WRITE(can_chan_dev[0].iflag,0x0002);/*清除中断状态标志*/ 
} 
 
/****************************************************************************** 
* 
* Can1TxInterrupt - Flex_can1模块发送中断函数,调用相应的中断例程 
* 
*返回:无 
*  
*参数:无 
******************************************************************************/ 
 
void Can1TxInterrupt (void) 
{ 
	UINT16        intStatus; 
 
	Tx_count++; 
	//logMsg("#can1 Tx Int!T#", 1, 2, 3, 4, 5, 6); 
	intStatus = CANDEV_READ(can_chan_dev[1].iflag);/*读中断状态标志*/ 
	if((intStatus & 0x0001) == 0x0001) 
	{ 
		CanTxInterrupt(&can_chan_dev[1]); 
	} 
	else 
	{ 
		//logMsg("#can1 Tx vacant Int!T#", 1, 2, 3, 4, 5, 6); 
	} 
	/* 
	if(intStatus & CAN1_TX_INT_STATUS) 
	{ 
 
		CanTxInterrupt(&can_chan_dev[1]); 
	} 
	if(intStatus & CAN1_RX_INT_STATUS) 
	{ 
 
		logMsg("#T****T#", 1, 2, 3, 4, 5, 6); 
		CanRxInterrupt(&can_chan_dev[1]); 
	} 
	*/ 
    CANDEV_WRITE(can_chan_dev[1].iflag,0x0001);/*清除中断状态标志*/ 
} 
 
/****************************************************************************** 
* 
* Can1RxInterrupt - Flex_can1模块接收中断函数,调用相应的中断例程 
* 
*返回:无 
*  
*参数:无 
******************************************************************************/ 
 
void Can1RxInterrupt (void) 
{ 
	UINT16        intStatus; 
 
	//logMsg("#can1 Rx Int!T#", 1, 2, 3, 4, 5, 6); 
	intStatus = CANDEV_READ(can_chan_dev[1].iflag);/*读中断状态标志*/ 
 
	if((intStatus & 0x0002) == 0x0002) 
	{ 
		CanRxInterrupt(&can_chan_dev[1]); 
	} 
	else 
	{ 
		//logMsg("#can1 Rx vacant Int!T#", 1, 2, 3, 4, 5, 6); 
	} 
	/* 
	if(intStatus & CAN1_TX_INT_STATUS) 
	{ 
 
		CanTxInterrupt(&can_chan_dev[1]); 
	} 
	if(intStatus & CAN1_RX_INT_STATUS) 
	{ 
 
		logMsg("#T****T#", 1, 2, 3, 4, 5, 6); 
		CanRxInterrupt(&can_chan_dev[1]); 
	} 
	*/ 
    CANDEV_WRITE(can_chan_dev[1].iflag,0x0002);/*清除中断状态标志*/ 
} 
/****************************************************************************** 
* 
* CanTxInterrupt - Flex_can模块发送中断服务函数 
* 
*返回:无 
*  
*参数: 
      pcan_chan  --  需要发送服务的CAN设备 
******************************************************************************/ 
LOCAL void CanTxInterrupt (Can_DEV *pcan_chan) 
{ 
	UINT16 i; 
	UINT16 j; 
	UINT32 count; 
	UCHAR ch; 
	if(pcan_chan->tx_number == 0) 
	{ 
		pcan_chan->ptx = pcan_chan->tx_Buff;/*重新定位发送指针,为下一次发送做准备*/ 
		CANDEV_WRITE(pcan_chan->txcode, 
			TX_NOTENABLE | DEFAULT_LENGTH); 
		semGive(pcan_chan->tx_semSync);      /*释放信号量*/ 
		return; 
	} 
	if(( pcan_chan->tx_number > 0) && ( pcan_chan->tx_number <= 8)) 
	{ 
		count = 0; 
		while(CheckBusStatus(pcan_chan) != OK) //检查CAN总线是否在空闲状态 
		{ 
			count++; 
			if(count >= 40000) break; 
		} 
		if(count >= 40000) /*如果总线一直忙,则清发送缓冲区,由上层协议决定是否重发*/ 
		{ 
 
			//logMsg("#bus is busy!T#", 1, 2, 3, 4, 5, 6); 
			pcan_chan->ptx = pcan_chan->tx_Buff;/*重新定位发送指针,为下一次发送做准备*/ 
			pcan_chan->tx_number = 0; 
		    CANDEV_WRITE(pcan_chan->txcode, 
			TX_NOTENABLE | DEFAULT_LENGTH); 
		    semGive(pcan_chan->tx_semSync);      /*释放信号量*/ 
			return; 
		} 
		CANDEV_WRITE(pcan_chan->txcode, 
			TX_NOTENABLE | DEFAULT_LENGTH);/*INACTIVE发送*/ 
		j = pcan_chan->tx_number; 
		for(i = 0;i < j;i++) 
		{ 
			ch = *pcan_chan->ptx; 
		    WriteByte(pcan_chan,ch,i); 
			pcan_chan->ptx++; 
		} 
		pcan_chan->tx_length = j; 
		pcan_chan->tx_number = 0; 
		CANDEV_WRITE(pcan_chan->txcode,   /*ACTIVE发送*/ 
			TX_ENABLE | pcan_chan->tx_length); 
		return; 
 
	} 
 
	if( pcan_chan->tx_number > 8)  
	{ 
		count = 0; 
		while(CheckBusStatus(pcan_chan) != OK) //检查CAN总线是否在空闲状态 
		{ 
			count++; 
			if(count >= 40000) break; 
		} 
		if(count >= 40000) /*如果总线一直忙,则清发送缓冲区,由上层协议决定是否重发*/ 
		{ 
 
			//logMsg("#bus is busy!T#", 1, 2, 3, 4, 5, 6); 
			pcan_chan->ptx = pcan_chan->tx_Buff;/*重新定位发送指针,为下一次发送做准备*/ 
			pcan_chan->tx_number = 0; 
		    CANDEV_WRITE(pcan_chan->txcode, 
			TX_NOTENABLE | DEFAULT_LENGTH); 
		    semGive(pcan_chan->tx_semSync);      /*释放信号量*/ 
			return; 
		} 
		CANDEV_WRITE(pcan_chan->txcode, 
			TX_NOTENABLE | DEFAULT_LENGTH);/*INACTIVE发送*/ 
		j = 8; 
		for(i = 0;i < j;i++) 
		{ 
			ch = *pcan_chan->ptx; 
		    WriteByte(pcan_chan,ch,i); 
			pcan_chan->ptx++; 
		} 
		pcan_chan->tx_length = j; 
		pcan_chan->tx_number -= j; 
		CANDEV_WRITE(pcan_chan->txcode,   /*ACTIVE发送*/ 
			TX_ENABLE | pcan_chan->tx_length); 
		return; 
 
	} 
 
} 
 
/****************************************************************************** 
* 
* CanRxInterrupt - Flex_can模块接收中断服务函数 
* 
*返回:无 
*  
*参数: 
      pcan_chan  --  需要发送服务的CAN设备 
******************************************************************************/ 
 
LOCAL void CanRxInterrupt (Can_DEV *pcan_chan) 
{ 
	UINT16 c_s_word;                       /*控制/状态信息字*/ 
	UINT32 freeRunTimer;                   /*控制/状态信息字*/ 
	//UINT32 id;                             /*ID*/ 
	UINT16 i,j; 
 
 
	c_s_word = CANDEV_READ(pcan_chan->rxcode); /*读控制/状态字 锁定该信息缓冲区*/ 
	//id   = CANDEV_READ(pcan_chan->rxID); /*信息ID*/ 
	j = c_s_word & 0x000F; /*获取接收数据长度*/ 
	 
	/*写数据到接收缓冲区中*/ 
	for(i = 0;i < j;i++) 
	{ 
		switch (i) 
		{ 
		case 0: 
			if((pcan_chan->prx_write+1) != pcan_chan->prx_read) 
			{ 
			    *pcan_chan->prx_write = CANDEV_READ(pcan_chan->rxdata0); 
				pcan_chan->prx_write++; 
				if((pcan_chan->prx_write - pcan_chan->rx_Buff) == MAX_RX_BUFFER) 
		        {//接收指针回绕 
		            if(pcan_chan->prx_read == pcan_chan->rx_Buff) 
		            { 
		                pcan_chan->prx_write = pcan_chan->prx_write-1; 
		            } 
					else 
					{ 
					    pcan_chan->prx_write = pcan_chan->rx_Buff; 
					} 
		        } 
				 
			} 
			break; 
		case 1: 
			if((pcan_chan->prx_write+1) != pcan_chan->prx_read) 
			{ 
			    *pcan_chan->prx_write = CANDEV_READ(pcan_chan->rxdata1); 
				pcan_chan->prx_write++; 
				if((pcan_chan->prx_write - pcan_chan->rx_Buff) == MAX_RX_BUFFER) 
		        {//接收指针回绕 
		            if(pcan_chan->prx_read == pcan_chan->rx_Buff) 
		            { 
		                pcan_chan->prx_write = pcan_chan->prx_write-1; 
		            } 
					else 
					{ 
					    pcan_chan->prx_write = pcan_chan->rx_Buff; 
					} 
		        } 
				 
			} 
			break; 
		case 2: 
			if((pcan_chan->prx_write+1) != pcan_chan->prx_read) 
			{ 
			    *pcan_chan->prx_write = CANDEV_READ(pcan_chan->rxdata2); 
				pcan_chan->prx_write++; 
				if((pcan_chan->prx_write - pcan_chan->rx_Buff) == MAX_RX_BUFFER) 
		        {//接收指针回绕 
		            if(pcan_chan->prx_read == pcan_chan->rx_Buff) 
		            { 
		                pcan_chan->prx_write = pcan_chan->prx_write-1; 
		            } 
					else 
					{ 
					    pcan_chan->prx_write = pcan_chan->rx_Buff; 
					} 
		        } 
				 
			} 
			break; 
		case 3: 
			if((pcan_chan->prx_write+1) != pcan_chan->prx_read) 
			{ 
			    *pcan_chan->prx_write = CANDEV_READ(pcan_chan->rxdata3); 
				pcan_chan->prx_write++; 
				if((pcan_chan->prx_write - pcan_chan->rx_Buff) == MAX_RX_BUFFER) 
		        {//接收指针回绕 
		            if(pcan_chan->prx_read == pcan_chan->rx_Buff) 
		            { 
		                pcan_chan->prx_write = pcan_chan->prx_write-1; 
		            } 
					else 
					{ 
					    pcan_chan->prx_write = pcan_chan->rx_Buff; 
					} 
		        } 
				 
			} 
			break; 
		case 4: 
			if((pcan_chan->prx_write+1) != pcan_chan->prx_read) 
			{ 
			    *pcan_chan->prx_write = CANDEV_READ(pcan_chan->rxdata4); 
				pcan_chan->prx_write++; 
				if((pcan_chan->prx_write - pcan_chan->rx_Buff) == MAX_RX_BUFFER) 
		        {//接收指针回绕 
		            if(pcan_chan->prx_read == pcan_chan->rx_Buff) 
		            { 
		                pcan_chan->prx_write = pcan_chan->prx_write-1; 
		            } 
					else 
					{ 
					    pcan_chan->prx_write = pcan_chan->rx_Buff; 
					} 
		        } 
				 
			} 
			break; 
		case 5: 
			if((pcan_chan->prx_write+1) != pcan_chan->prx_read) 
			{ 
			    *pcan_chan->prx_write = CANDEV_READ(pcan_chan->rxdata5); 
				pcan_chan->prx_write++; 
				if((pcan_chan->prx_write - pcan_chan->rx_Buff) == MAX_RX_BUFFER) 
		        {//接收指针回绕 
		            if(pcan_chan->prx_read == pcan_chan->rx_Buff) 
		            { 
		                pcan_chan->prx_write = pcan_chan->prx_write-1; 
		            } 
					else 
					{ 
					    pcan_chan->prx_write = pcan_chan->rx_Buff; 
					} 
		        } 
				 
			} 
			break; 
		case 6: 
			if((pcan_chan->prx_write+1) != pcan_chan->prx_read) 
			{ 
			    *pcan_chan->prx_write = CANDEV_READ(pcan_chan->rxdata6); 
				pcan_chan->prx_write++; 
				if((pcan_chan->prx_write - pcan_chan->rx_Buff) == MAX_RX_BUFFER) 
		        {//接收指针回绕 
		            if(pcan_chan->prx_read == pcan_chan->rx_Buff) 
		            { 
		                pcan_chan->prx_write = pcan_chan->prx_write-1; 
		            } 
					else 
					{ 
					    pcan_chan->prx_write = pcan_chan->rx_Buff; 
					} 
		        } 
				 
			} 
			break; 
		case 7: 
			if((pcan_chan->prx_write+1) != pcan_chan->prx_read) 
			{ 
			    *pcan_chan->prx_write = CANDEV_READ(pcan_chan->rxdata7); 
				pcan_chan->prx_write++; 
				if((pcan_chan->prx_write - pcan_chan->rx_Buff) == MAX_RX_BUFFER) 
		        {//接收指针回绕 
		            if(pcan_chan->prx_read == pcan_chan->rx_Buff) 
		            { 
		                pcan_chan->prx_write = pcan_chan->prx_write-1; 
		            } 
					else 
					{ 
					    pcan_chan->prx_write = pcan_chan->rx_Buff; 
					} 
		        } 
				 
			} 
			break; 
		default: 
			break; 
		} 
		 
		 
 
	} 
	pcan_chan->rx_number += j; 
	pcan_chan->rx_length =j; 
	freeRunTimer = CANDEV_READ(pcan_chan->timer);/*读自由运行时间,释放该信息缓冲区*/ 
	CANDEV_WRITE(pcan_chan->rxcode, 
		RX_ENABLE | DEFAULT_LENGTH);/*使能接收,为下一次接收做准备*/ 
	semGive(pcan_chan->rx_semSync);      /*释放信号量*/ 
 
} 
/****************************************************************************** 
* 
* CheckBusStatus - 检查can总线状态 
*读can的ERRSTAT寄存器,IDLE位是否为1 
* 
* 返回:总线空闲返回OK,否则返回ERROR 
*  
******************************************************************************/ 
LOCAL STATUS CheckBusStatus(Can_DEV *pcan_chan) 
{ 
	UINT32 Status; 
	Status = CANDEV_READ(pcan_chan->errstat); 
	if((Status & 0x00000080) == 0x00000080) 
	{ 
		return OK; 
	} 
	else 
	{ 
		return ERROR; 
	} 
 
}