📄 can_init.c
字号:
/************************************************************************
*
* 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 + -