📄 can_routine.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 + -