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

📄 can_init.c

📁 can initialization for coldfire microcontorllers
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************
*
*  Freescale Semicondactor
*  ALL RIGHTS RESERVED
*  (c) Copyright 2004Freescale Semiconductor
*
*************************************************************************
*
*  FILE NAME: can_init.c
* 
*  PURPOSE:
*
*  AUTHOR(s): Igor Byeda
*************************************************************************/

#include "can_unit.h"
#include "can_buffer.h"

can_SpeedParam_t can_CurrentSettings;

can_SpeedParam_t can_SpeedParam[] = {

	{125000,	15,	16,	3,	8,	4,	2,	0,  1},
	{250000,	7,	16,	3,	8,	4,	2,	0,  1},
	{500000,	3,	16,	8,	5,	2,	2,	0,  1},
	{800000,	3,	10,	4,	3,	2,	2,	0,  1},
	{1000000,	3,	8,	2,	3,	2,	2,	0,  1}
	
};
#define CAN_SPEED_PARAM_NUM (sizeof(can_SpeedParam)/sizeof(can_SpeedParam_t))

can_HWBufferParam_t can_HWBufferParam[] = {

//	IsRx, 		Id_H,	Id_L,			BufferNumber 

	{RX,		0x0000, 0x0000, 0x0001, "Buffer0"},
	{RX,		0x0000, 0x0000, 0x0002, "Buffer1"},
	{RX,		0x0000, 0x0000, 0x0004, "Buffer2"},
	{RX,		0x0000, 0x0000, 0x0008, "Buffer3"},
	{RX,		0x0000, 0x0000, 0x0010, "Buffer4"},
	{RX,		0x0000, 0x0000, 0x0020, "Buffer5"},
	{RX,		0x0000, 0x0000, 0x0040, "Buffer6"},
	{RX,		0x0000, 0x0000, 0x0080, "Buffer7"},
	{RX,		0x0000, 0x0000, 0x0100, "Buffer8"},
	{RX,		0x0000, 0x0000, 0x0200, "Buffer9"},
	{RX,		0x0000, 0x0000, 0x0400, "Buffer10"},
	{TX,		0x0000, 0x0000, 0x0800, "Buffer11"},
	{REMOTE,	0x0000, 0x0000, 0x1000, "Buffer12"},
	{REMOTE,	0x0000, 0x0000, 0x2000, "Buffer13"},
	{RX,		0x0000, 0x0000, 0x4000, "Buffer14"},
	{RX,		0x0000, 0x0000, 0x8000, "Buffer15"},

};

can_err_ErrorTable_t can_err_ErrorTable[] = {

{0, "CAN unit can't connect to the CAN bus."},
{1, "Parameter to set isn't correspond to allowable value."},
{2, "The value of can_unit_Mode doesn't equal allowable value."},
{3, "The value of can_unit_CurrentOperation doesn't equal allowable value."},
{4, "Invalid value of free space in internal Tx buffer."},
{5, "No messages were copied from internal Rx buffer into FIFO."},
{6, "No messages were copied from FIFO into internal Tx buffer."},
{7, "Number of messages to send is greater than in internal Tx buffer."},
{8, "The message from CAN bus cann't be copied. Internal Rx buffer is full."},
{9, "Rx interrupt handler was called for empty buffer."},
{10, "Rx buffer is in overrun state."},
{11, "Illegal Rx code in the HW buffer."},
{12, "The number of time quanta isn't equal allowable value."},
{13, "The sum of all time quanta in segments doesn't correspond general number of time quanta."},
{14, "Propagation segment isn't equal allowable value."},
{15, "Phase segment 1 isn't equal allowable value."},
{16, "Phase segment 2 isn't equal allowable value."},
{17, "Resynchronization jump width isn't equal allowable value."},
{18, "SAMP bit isn't equal allowable value."},
{19, "Selected speed doesn't correspond to standart speed array."},
{20, "The remote frame couldn't be sent because of both Tx Remote Frames' buffers are busy."}
};

rb_obj_t * can_RX; // can unit RX buffer (receive from CAN bus)
rb_obj_t * can_TX; // can unit TX buffer (transmit to CAN bus)

static can_err_ErrorDescript_t can_err_ErrorDescript[CAN_UNIT_ERROR_DESCRIP_BUFFER_SIZE];
static can_err_ErrorPointer_t can_err_ErrorPointer;

uint8 can_unit_IsSpeedAutodetected;

volatile int can_WasSent_remote;
volatile int can_WasSent_tx;

enum can_unit_IntegrationState_t can_unit_IntegrationState;
enum can_unit_PlugInState_t can_unit_PlugInState;

uint8 can_unit_Mode;
volatile uint8 can_unit_CurrentOperation;

/************************************************************************
* NAME: can_data_IsSelfMsgWasRecv
*
* DESCRIPTION Compares received message with sent message 
*			  to clarify alien or own message was received.
*			  Return 1, if own message was received.  
************************************************************************/
inline uint8 can_data_IsSelfMsgWasRecv (can_Message_t* m, uint8 i)
{
	uint8 j;
    
 	if (m->IDH != MCF5282_FLEXCAN_MBUF_IDH(i))
    		return (FALSE); 
	if (m->IDL != MCF5282_FLEXCAN_MBUF_IDL(i))
		return (FALSE); 
     	 	
	for (j=0; j<(m->Ctrl & 0x7); j++) 
		if (m->data[j] != MCF5282_FLEXCAN_MBUF_BYTE(i, j)) 
			return (FALSE);
	    	
	return (TRUE);
}

/************************************************************************
* NAME: can_Tx
*
* DESCRIPTION Interrupt handler for CAN 
*			    transmit buffer.
************************************************************************/
__interrupt__
void can_Tx (void) 
{
	isr_lock();
		cpu_iord_16(MCF5282_FLEXCAN_IFLAG);
		MCF5282_FLEXCAN_IFLAG = can_HWBufferParam[TX_BUFFER_DATA].IFlag;
	
		#ifdef CAN_DEBUG_MSG
			printf ("%s %u msg CAN: <_int_ Tx> message sent\n", DBG_MSG_PROMPT, current_time);
		#endif
	isr_unlock();
	can_WasSent_tx=1;
}

/************************************************************************
* NAME: can_Remote
*
* DESCRIPTION Interrupt handler for CAN remote frame Tx/Rx buffer.
************************************************************************/
__interrupt__
void can_Remote (void) 
{
	uint8  nBuf = 0;
	can_Message_t* msgWrInto;
	
	isr_lock();
	
	if (MCF5282_FLEXCAN_IFLAG & can_HWBufferParam[TX_BUFFER_REMOTE_1].IFlag)
		nBuf = TX_BUFFER_REMOTE_1;
	else if(MCF5282_FLEXCAN_IFLAG & can_HWBufferParam[TX_BUFFER_REMOTE_2].IFlag)
		nBuf = TX_BUFFER_REMOTE_2;
	
	switch ( MCF5282_FLEXCAN_MBUF_CTRL_CODE(nBuf) )
	{
	case BUFFER_TX_CODE_REMOTE:
		{
			cpu_iord_16(MCF5282_FLEXCAN_IFLAG);
			can_WasSent_remote++;
			#ifdef CAN_DEBUG_MSG
				printf ("%s %u msg CAN: <_int_ Remote> remote message sent\n", DBG_MSG_PROMPT, current_time);
			#endif
		}
		break;
	case BUFFER_RX_CODE_FULL:
		{	
			msgWrInto = rb_data_WriteOneVirtual(can_RX);
			if ( msgWrInto ) 
			{
				memcpy16 ( (uint16 *)msgWrInto, 
						   (uint16 *)MCF5282_FLEXCAN_MBUF_CTRL_ADDR(nBuf), 
						   NUMBER_OF_BYTES_IN_HW_BUFFER);
				msgWrInto->absTime = current_time;
				
				#ifdef RECEIVE_ALIEN_MESSAGES_ONLY
					// if we receive our own message - do not place the msg in stack
					if (can_data_IsSelfMsgWasRecv(msgWrInto, TX_BUFFER_DATA))
						rb_data_WriteOneBack(can_RX);
					else
						can_unit_IntegrationState = can_MessageSuccesfullyReceived;
				#else		
					can_unit_IntegrationState = can_MessageSuccesfullyReceived;
				#endif		
				MCF5282_FLEXCAN_MBUF_CTRL(nBuf) = 0;
				
				#ifdef CAN_DEBUG_MSG
					printf ("%s %u msg CAN: <_int_ Remote> RemoteFrame response (has been sent from buffer %d) received\n", DBG_MSG_PROMPT, current_time, nBuf);
				#endif
			}
			else
				can_err_SendError(&can_err_ErrorTable[8], current_time, can_Remote_Id);
		}
		break;
	case BUFFER_RX_CODE_EMPTY:
		can_err_SendError(&can_err_ErrorTable[9], current_time, can_Remote_Id);
		break;
	case BUFFER_RX_CODE_OVERRUN:
		can_err_SendError(&can_err_ErrorTable[10], current_time, can_Remote_Id);
		break;
	default:
		can_err_SendError(&can_err_ErrorTable[11], current_time, can_Remote_Id);
		break;
	}           
		
	MCF5282_FLEXCAN_IFLAG = can_HWBufferParam[nBuf].IFlag;  // clear buffer flag
	cpu_iord_16(MCF5282_FLEXCAN_TIMER); 					// globally release a locked message buffer

	can_unit_CurrentOperation = can_StatusIdle;
	
	isr_unlock();
}


/************************************************************************
* NAME: can_Rx
*
* DESCRIPTION Interrupt handler for CAN  
*			    receive buffer.
************************************************************************/
__interrupt__
void can_Rx (void) 
{
	uint8 nBuf = 0;
	can_Message_t* msgWrInto;
	uint16 IFlag;
	
	// definition Rx buffer number, which Interrupt Flag is set
	IFlag = MCF5282_FLEXCAN_IFLAG >> 1;
	while (IFlag >> nBuf) 	nBuf++;
	if ( nBuf == TX_BUFFER_DATA || nBuf == TX_BUFFER_REMOTE_1 || nBuf == TX_BUFFER_REMOTE_2)
	{
		nBuf = TX_BUFFER_REMOTE_2+1;
		while (IFlag >> nBuf) 	nBuf++;
	}
	if (nBuf>(CAN_UNIT_HW_BUFFER_NUMBER-1))
		return;

	isr_lock();
	
	can_unit_CurrentOperation = can_StatusCanReceivingData;
	cpu_iord_16(MCF5282_FLEXCAN_IFLAG);

	// do we have correct message?
	switch ( MCF5282_FLEXCAN_MBUF_CTRL_CODE(nBuf) )        
	{
	case BUFFER_RX_CODE_FULL:	
		{
			msgWrInto = rb_data_WriteOneVirtual(can_RX);
			if ( msgWrInto ) 
			{
				memcpy16 ( (uint16 *)msgWrInto, 
						   (uint16 *)MCF5282_FLEXCAN_MBUF_CTRL_ADDR(nBuf), 
						   NUMBER_OF_BYTES_IN_HW_BUFFER );
				msgWrInto->absTime = current_time;
				
				#ifdef RECEIVE_ALIEN_MESSAGES_ONLY
					// if we receive our own message - do not place the msg in stack
					if (can_data_IsSelfMsgWasRecv(msgWrInto, TX_BUFFER_DATA)) 
						rb_data_WriteOneBack(can_RX);
					else
						can_unit_IntegrationState = can_MessageSuccesfullyReceived;
				#else
					can_unit_IntegrationState = can_MessageSuccesfullyReceived;
				#endif			
				
				if (((msgWrInto->IDH)>>5)== 0x20a || ((msgWrInto->IDH)>>5)== 0x24a || ((msgWrInto->IDH)>>5)== 0x10a)				
				{
					rb_data_WriteOneBack(can_RX);
				}
				#ifdef CAN_DEBUG_MSG
					printf ("%s %u msg CAN: <_int_ Rx>\n", DBG_MSG_PROMPT, current_time);
				#endif
			}
			else
				can_err_SendError(&can_err_ErrorTable[8], current_time, can_Rx_Id);
		}	
	    break;
	case BUFFER_RX_CODE_EMPTY:
		can_err_SendError(&can_err_ErrorTable[9], current_time, can_Rx_Id);
		break;
	case BUFFER_RX_CODE_OVERRUN:
		can_err_SendError(&can_err_ErrorTable[10], current_time, can_Rx_Id);
		break;
	default:
		can_err_SendError(&can_err_ErrorTable[11], current_time, can_Rx_Id);
		break;
    }           

	MCF5282_FLEXCAN_IFLAG = can_HWBufferParam[nBuf].IFlag;  // clear buffer flag
	cpu_iord_16(MCF5282_FLEXCAN_TIMER); 					// globally release a locked message buffer
	
	can_unit_CurrentOperation = can_StatusIdle;
	
	isr_unlock();
}

/************************************************************************
* NAME: can_Error
*
* DESCRIPTION Interrupt handler for CAN Errors.
************************************************************************/
__interrupt__
void can_Error (void) 
{
	uint32 i;
	
	isr_lock();
	
	cpu_iord_16(MCF5282_FLEXCAN_ESTAT);
	MCF5282_FLEXCAN_CANCTRL0 = MCF5282_FLEXCAN_CANCTRL0 & 0xBF;
	if (MCF5282_FLEXCAN_ESTAT & 0x0002) 
	{
		if (can_unit_Mode != can_ModeIntegration)
		{	
			#ifdef CAN_DEBUG_MSG
				printf("%s %u msg CAN: <_int_ Err> can_mode: %d\n", DBG_MSG_PROMPT, current_time, can_unit_Mode);
			#endif
		}
	}
	can_unit_IntegrationState = can_ErrorOccured;
	MCF5282_FLEXCAN_ESTAT = MCF5282_FLEXCAN_ESTAT & 0xFFFF; // clear buffer flag
	if (can_unit_Mode != can_ModeIntegration)
		MCF5282_FLEXCAN_CANCTRL0 = MCF5282_FLEXCAN_CANCTRL0 | MCF5282_FLEXCAN_CANCTRL0_ERRMSK;
	
	isr_unlock();
}

/************************************************************************
* NAME: can_Bus_Off
*
* DESCRIPTION CAN bus off interrupt handler.
************************************************************************/
__interrupt__
void can_Bus_Off (void) 
{
	isr_lock();
	
	if (MCF5282_FLEXCAN_ESTAT & 0x0004)
	{
		#ifdef CAN_DEBUG_MSG
			printf("%s %u msg CAN: <_int_ BusOff>\n", DBG_MSG_PROMPT, current_time);
		#endif
	}
	// clear buffer flag
	MCF5282_FLEXCAN_ESTAT = MCF5282_FLEXCAN_ESTAT & 0xFFFF; 
	
	isr_unlock();
}

/************************************************************************
* NAME: can_Wake_Up
*
* DESCRIPTION CAN wake up interrupt handler.
************************************************************************/
__interrupt__
void can_Wake_Up (void) 
{
	isr_lock();
	
	if (MCF5282_FLEXCAN_ESTAT & 0x0001)
	{
		#ifdef CAN_DEBUG_MSG
			printf("%s %u msg CAN: <_int_ WakeUp>\n", DBG_MSG_PROMPT, current_time);
		#endif
	}
	// clear buffer flag
	MCF5282_FLEXCAN_ESTAT = MCF5282_FLEXCAN_ESTAT & 0xFFFF; 
	
	isr_unlock();
}

/************************************************************************
* NAME: CAN_unit_init
*
* DESCRIPTION CAN unit initialization
************************************************************************/
uint8 
can_unitInit(void)
{
	uint16 i, k;

	can_RX = NULL;	
	can_TX = NULL;	
	
	can_RX = rb_Create(CAN_UNIT_TX_RX_BUFFER_SIZE);
	if (can_RX == NULL)
	{
		#ifdef CAN_DEBUG_MSG
			printf("! can_unitInit: ERROR RX buffer creation\n");
		#endif
		return (ERR);
	}
	
	can_TX = rb_Create(CAN_UNIT_TX_RX_BUFFER_SIZE);

⌨️ 快捷键说明

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