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

📄 can_routine.c

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

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

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

//extern rb_obj_t * fifo_RX;	// buffer RX from CAN 
//extern rb_obj_t * fifo_TX;  // buffer TX to CAN

extern volatile int can_WasSent_remote;
extern volatile int can_WasSent_tx;

static const uint32  can_start_time_wait = (CAN_START_TIMEOUT / TIMER_PERIOD); 

/************************************************************************
* NAME: can_unit_Run
*
* DESCRIPTION Function enables Rx/Tx interrupts 
*			  and makes possible Tx procedure.
************************************************************************/
uint8 can_unit_Run()
{
	uint32 time;
	
	// Initialize all operating modes 
	MCF5282_FLEXCAN_CANCTRL0 = (0
	    | MCF5282_FLEXCAN_CANCTRL0_BOFFMSK			// bus off interrupt enabled
	    | MCF5282_FLEXCAN_CANCTRL0_ERRMSK			// error interrupt enabled
	    | MCF5282_FLEXCAN_CANCTRL0_TXMODE_CMOSPOS);  // due to documentation (Texas Instrument)
	
	MCF5282_FLEXCAN_IMASK = (0
	    | MCF5282_FLEXCAN_IMASK_BUF0M
	    | MCF5282_FLEXCAN_IMASK_BUF1M
	    | MCF5282_FLEXCAN_IMASK_BUF2M
	    | MCF5282_FLEXCAN_IMASK_BUF3M
	    | MCF5282_FLEXCAN_IMASK_BUF4M
	    | MCF5282_FLEXCAN_IMASK_BUF5M
	    | MCF5282_FLEXCAN_IMASK_BUF6M
	    | MCF5282_FLEXCAN_IMASK_BUF7M
	    | MCF5282_FLEXCAN_IMASK_BUF8M
	    | MCF5282_FLEXCAN_IMASK_BUF9M
	    | MCF5282_FLEXCAN_IMASK_BUF10M
	    | MCF5282_FLEXCAN_IMASK_BUF11M
	    | MCF5282_FLEXCAN_IMASK_BUF12M
	    | MCF5282_FLEXCAN_IMASK_BUF13M
	    | MCF5282_FLEXCAN_IMASK_BUF14M
	    | MCF5282_FLEXCAN_IMASK_BUF15M);   
	 
	MCF5282_FLEXCAN_CANMCR = (MCF5282_FLEXCAN_CANMCR & 0xAF7F);

	can_unit_Mode = can_ModeRunFull;
	
	// make 1 sec pause (to detect messages on CAN bus)
	time = current_time;
	while( timer_get_interval(time, current_time) < can_start_time_wait ) ;
	
	return (can_unit_Mode);
}

/************************************************************************
* NAME: can_unit_Stop
*
* DESCRIPTION Function disables Rx/Tx interrupts 
*			  and makes Tx procedure impossible. 
************************************************************************/
void can_unit_Stop(void)
{

	MCF5282_FLEXCAN_IMASK = 0;
	MCF5282_FLEXCAN_CANCTRL0 = 0;

	MCF5282_FLEXCAN_CANMCR = MCF5282_FLEXCAN_CANMCR & 0xEFFF;

	can_unit_Mode = can_ModeStop;
	can_unit_IntegrationState = can_Waiting;
}

/************************************************************************
* NAME: can_get_unitMode
*
* DESCRIPTION Return unit mode from 
*			  can_unitMode parameters list.
************************************************************************/
uint8 can_unit_getMode()
{
	return (can_unit_Mode);
}

/************************************************************************
* NAME: can_getUnitStatus
*
* DESCRIPTION Return unit mode from 
*			  can_unitCurrentOperation parameters list.
************************************************************************/
vuint8 can_unit_getStatus()
{
	return (can_unit_CurrentOperation);
}


/************************************************************************
* NAME: can_data_CopyRxToFIFO
*
* DESCRIPTION Return number of messages were copied to FIFO buffer.  
************************************************************************/
uint32 can_data_CopyRxToFIFO()
{
	uint32	nMsgToCopy; 
	uint32	nMsgWereCopied = 0;
	uint32	temp_data;

	can_unit_CurrentOperation = can_StatusFIFOCopingTo;

	nMsgToCopy = rb_get_DataToReadSize(can_RX);
	
	if (nMsgToCopy == 0)
	{
		can_unit_CurrentOperation = can_StatusIdle;
		return (0);
	}
	
	
	if (can_RX->pRD + nMsgToCopy < can_RX->nBufSize)
	{
		// easy case, no wrapping
		rx_buffer_Write(rx_buffer, &(can_RX->pBuf[can_RX->pRD]), nMsgToCopy);
		can_RX->pRD += nMsgToCopy;
		nMsgWereCopied = nMsgToCopy;
	}
	else // harder case, buffer wraps around
	{
		temp_data = can_RX->nBufSize - can_RX->pRD;	  // First Part size

		rx_buffer_Write(rx_buffer, &(can_RX->pBuf[can_RX->pRD]), temp_data);

		can_RX->pRD = 0;

		rx_buffer_Write(rx_buffer, &(can_RX->pBuf[can_RX->pRD]), (nMsgToCopy - temp_data));

		can_RX->pRD = (nMsgToCopy - temp_data);
		nMsgWereCopied = nMsgToCopy;
	}

	if (nMsgWereCopied == 0)
		can_err_SendError(&can_err_ErrorTable[5], current_time, can_data_CopyRxToFIFO_Id);

	can_unit_CurrentOperation = can_StatusIdle;
	
	return (nMsgWereCopied);
}

/************************************************************************
* NAME: can_data_CopyTxFromFIFO
*
* DESCRIPTION Return number of messages were copied from FIFO buffer.  
************************************************************************/
uint32 can_data_CopyTxFromFIFO()
{
	uint32	nMsgToCopy,	nFreeSpace; 
	uint32	nMsgWereCopied = 0;
	
	can_unit_CurrentOperation = can_StatusFIFOCopingFrom;

	nFreeSpace = rb_get_FreeSpace(can_TX);
	if (nFreeSpace)
	{ 
		nMsgToCopy = tx_buffers_get_DataToRead();
		if (nMsgToCopy == 0)
		{
			can_unit_CurrentOperation = can_StatusIdle;
			return (0);
		}
		
		if (nFreeSpace <= nMsgToCopy)	
			nMsgToCopy = nFreeSpace - 1;
		while (nMsgToCopy>0)
		{
			if (current_client_tx_buffer->busy && (current_client_tx_buffer->can_from_client_read_ptr != current_client_tx_buffer->client_to_can_write_ptr))
			{
				memcpy(&(can_TX->pBuf[can_TX->pWR]), &(current_client_tx_buffer->client_tx_buf[current_client_tx_buffer->can_from_client_read_ptr]), CAN_MSG_LEN);
				if (++can_TX->pWR == (can_TX->nBufSize-1))
					can_TX->pWR = 0;
				if (++current_client_tx_buffer->can_from_client_read_ptr==(TX_FIFO_BUFFER_SIZE-1))
					current_client_tx_buffer->can_from_client_read_ptr = 0;
				nMsgToCopy--;
				nMsgWereCopied++;
			}
			current_client_tx_buffer = current_client_tx_buffer->next;
		}
	}
	return nMsgWereCopied;
}

/************************************************************************
* NAME: can_data_SendDataToCANbus
*
* DESCRIPTION Return number of messages were sent to CAN from 
*			  local buffer.  
************************************************************************/
uint32 can_data_SendDataToCANbus()
{
	uint32 i, j;
	uint16 nBuf;
	uint32 nMsgInTx;
	uint32 nMsgWereSent = 0;
	can_Message_t * msgToSend; 
	
	can_unit_CurrentOperation = can_StatusCanTransmittingData;
	
	nMsgInTx = rb_get_DataToReadSize(can_TX);
	for (i = 0; i < nMsgInTx; i++)
	{
		// get element to send
		msgToSend = rb_data_ReadOneVirtual(can_TX);

		if (msgToSend)
		{
		if ( ((msgToSend->IDH & MCF5282_FLEXCAN_IDH_IDE) == 0) && 
		     ((msgToSend->IDH & MCF5282_FLEXCAN_IDH_RTR) == 1))
		{
		/* REMOTE msg */
			// wait for free remote buffer (could be commented)
			//while (can_WasSent_remote == 0) ;
			//can_WasSent_remote = 0;
				
			if (MCF5282_FLEXCAN_MBUF_CTRL(TX_BUFFER_REMOTE_1) == 0)
			{
				nBuf = TX_BUFFER_REMOTE_1;
			}
			else if ((MCF5282_FLEXCAN_MBUF_CTRL(TX_BUFFER_REMOTE_1) != 0) && 
			   		 (MCF5282_FLEXCAN_MBUF_CTRL(TX_BUFFER_REMOTE_2) == 0) )
			{
				nBuf = TX_BUFFER_REMOTE_2;
			}
			else if ((MCF5282_FLEXCAN_MBUF_CTRL(TX_BUFFER_REMOTE_1) != 0) && 
			   		 (MCF5282_FLEXCAN_MBUF_CTRL(TX_BUFFER_REMOTE_2) != 0) )
			{
				#ifdef CAN_DEBUG_MSG
					printf ("%s %u ERR CAN: <sendData> remote frame couldn't be sent due to both Tx RemoteFrame buffers are busy\n", DBG_MSG_PROMPT, current_time);
				#endif
				can_err_SendError( &can_err_ErrorTable[20], current_time, can_data_SendDataToCANbus_Id );
				continue;
			}
				
			MCF5282_FLEXCAN_MBUF_CTRL(nBuf) = BUFFER_TX_CODE_REMOTE;
		}
		else
		{	
		/* TX msg */
			
			nBuf = TX_BUFFER_DATA;
			MCF5282_FLEXCAN_MBUF_CTRL(nBuf) = BUFFER_TX_CODE_DATA;
		}
		
			MCF5282_FLEXCAN_MBUF_IDH(nBuf) = msgToSend->IDH;
			MCF5282_FLEXCAN_MBUF_IDL(nBuf) = msgToSend->IDL;
		
			if (nBuf == TX_BUFFER_DATA)
			{
				#ifdef CAN_DEBUG_MSG
					printf ("%s %u msg CAN: <sendData> sending Data frame...\n", DBG_MSG_PROMPT, current_time);
				#endif
				for (j=0; j < CAN_UNIT_MESSAGE_DATA_LENGTH; j++) 
        			MCF5282_FLEXCAN_MBUF_BYTE(nBuf, j) = msgToSend->data[j];  
				
				// wait for free tx buffer
				can_WasSent_tx = 0;
	 			
	 			MCF5282_FLEXCAN_MBUF_CTRL(nBuf) = 0xC0 | CAN_UNIT_MESSAGE_DATA_LENGTH;// | msgToSend->Ctrl;
				
				while (can_WasSent_tx == 0) ;
			}
			else
			{
				#ifdef CAN_DEBUG_MSG
					printf ("%s %u msg CAN: <sendData> sending remote frame...\n", DBG_MSG_PROMPT, current_time);
				#endif
			}
		}


		nMsgWereSent++; 
	}
	
	can_unit_CurrentOperation = can_StatusIdle;
	
	return (nMsgWereSent);
}


⌨️ 快捷键说明

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