MCAN communication

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCAN communication

2,045 Views
Nadia
Contributor III

Hello to all,
I'm using a LPC55S14 to communicate with the CAN bus of the car, but I can't get it. I am also using the MCP2551 to get the CAN L and CAN H lines.

Can anyone tell me if I need to know any specific data from the car bus to establish the communication?

Best regards.

0 Kudos
10 Replies

1,963 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Nadia,

Recommend first recommend the CAN demo under SDK for lpcpxresso55s16 board.

 

0 Kudos

2,038 Views
frank_m
Senior Contributor III

At least the baud rate of the system you want to attach it to. The CAN bus ist static, i.e. there is no configuration/reconfiguration at runtime. It must be properly planned and configured beforehand.

I would assume the MCAN peripheral is the same IP block as on other NXP MCUs, and thus very similar.

Not really a tutorial, but a good starting point: https://en.wikipedia.org/wiki/CAN_bus

0 Kudos

2,032 Views
Nadia
Contributor III

@frank_m Thanks for your help.
Yes, I'm taking that into account, but it still doesn't work, I'm attaching the code part. The transmission seems to go through, but when I read the response, it doesn't match the id.

/******************************************************//**
** Definición de macros
*********************************************************/
#define TAM_BUFF 26
#define QUEUE_LENGTH 50
#define CAN_DATASIZE 26U
#define DATA_MCAN CAN0
//#define MCAN_CLK_FREQ CLOCK_GetMCanClkFreq(0)
#define USE_CANFD (0U)
//#define MCAN_CLK_FREQ 8000000U
#define MCAN_CLK_FREQ CLOCK_GetMCanClkFreq()

#define TX_BUFFER_OFS 0x20U
#define MSG_RAM_BASE 0x04000000U
#define msgRam MSG_RAM_BASE
#define MSG_RAM_SIZE (TX_BUFFER_OFS + 8 + CAN_DATASIZE)
#define BOARD_DEBUG_UART_CLK_ATTACH kFRO12M_to_FLEXCOMM0
#define STD_FILTER_OFS 0x0
#define RX_FIFO0_OFS 0x20U
/**********************************************************
** Variables privados
**********************************************************/
static TaskHandle_t _tskHandleSendCAN;
static QueueHandle_t _queueHandleBuff;
/// Variables para CAN
static TaskHandle_t _tskHandleCAN;
volatile bool rxComplete = false;
mcan_rx_buffer_frame_t rxFrame;
mcan_tx_buffer_frame_t txFrame;
uint8_t tx_data[CAN_DATASIZE];
uint8_t rx_data[CAN_DATASIZE];
//#ifndef MSG_RAM_BASE


mcan_handle_t mcanHandle;
//mcan_tx_buffer_frame_t mcanHandle;
mcan_buffer_transfer_t txXfer;
volatile bool txComplete = false;

void CAN0_IRQ0_IRQHandler(void)
{
MCAN_ClearStatusFlag(DATA_MCAN, CAN_IR_RF0N_MASK);
MCAN_ReadRxFifo(DATA_MCAN, 0, &rxFrame);
rxComplete = true;
SDK_ISR_EXIT_BARRIER;
}

static void _CANInit(void)
{
/* set BOD VBAT level to 1.65V */
POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false);
// POWER_SetBodVbatLevel(kPOWER_BodVbatLevel3300mv, kPOWER_BodHystLevel25mv, false);
// /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

/* Set MCAN clock 100Mhz/5=20MHz. */
CLOCK_SetClkDiv(kCLOCK_DivCanClk, 5U, true);
CLOCK_AttachClk(kMCAN_DIV_to_MCAN);
} //static void _CANInit(void)

///*! \fn static void _TskSendCAN (void)
// * \brief Envío de datos por el bus can.
// * \return Nada.
// */
static void _TskSendCAN(void)
{
// uint32_t *CANBuff;
mcan_frame_filter_config_t rxFilter;
mcan_std_filter_element_config_t stdFilter;
mcan_rx_fifo_config_t rxFifo0;
uint8_t *CANBuff[26];
mcan_config_t mcanConfig;
mcan_tx_buffer_config_t txBuffer;
uint8_t numMessage = 0;
// LecDRACallBack(_RecDatCAN);
while (true)
{
// ulTaskNotifyTake(pdFALSE, portMAX_DELAY);!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// if (xQueueReceive(_queueHandleBuff, &CANBuff, portMAX_DELAY) != 0)
// {
// if (CANBuff != NULL)
// {
_CANInit();
MCAN_GetDefaultConfig(&mcanConfig);
mcanConfig.enableLoopBackExt = true;
// mcanConfig.enableLoopBackInt = false;
MCAN_Init(DATA_MCAN, &mcanConfig, MCAN_CLK_FREQ);
// MCAN_TransferCreateHandle(DATA_MCAN, &mcanHandle, mcan_callback, NULL);
MCAN_SetMsgRAMBase(DATA_MCAN, (uint32_t)msgRam);
memset((void *)msgRam, 0, MSG_RAM_SIZE * sizeof(uint8_t));

/* STD filter config. */
rxFilter.address = STD_FILTER_OFS;
rxFilter.idFormat = kMCAN_FrameIDStandard;
rxFilter.listSize = 1U;
rxFilter.nmFrame = kMCAN_reject0;
rxFilter.remFrame = kMCAN_rejectFrame;
MCAN_SetFilterConfig(DATA_MCAN, &rxFilter);

stdFilter.sfec = kMCAN_storeinFifo0;
/* Classic filter mode, only filter matching ID. */
stdFilter.sft = kMCAN_classic;
stdFilter.sfid1 = 0x123U;
stdFilter.sfid2 = 0x7FFU;
MCAN_SetSTDFilterElement(DATA_MCAN, &rxFilter, &stdFilter, 0);


/* RX fifo0 config. */
rxFifo0.address = RX_FIFO0_OFS;
rxFifo0.elementSize = 1U;
rxFifo0.watermark = 0;
rxFifo0.opmode = kMCAN_FifoBlocking;
rxFifo0.datafieldSize = kMCAN_8ByteDatafield;
#if (defined(USE_CANFD) && USE_CANFD)
rxFifo0.datafieldSize = BYTES_IN_MB;
#endif
MCAN_SetRxFifo0Config(DATA_MCAN, &rxFifo0);


/* TX buffer config. */
memset(&txBuffer, 0, sizeof(txBuffer));
txBuffer.address = TX_BUFFER_OFS; //Dirección trama CAN 0X20
txBuffer.dedicatedSize = 1U;
txBuffer.fqSize = 0;
txBuffer.datafieldSize = kMCAN_8ByteDatafield;

MCAN_SetTxBufferConfig(DATA_MCAN, &txBuffer);

/* Enter normal mode. */
MCAN_EnterNormalMode(DATA_MCAN);

/* Config TX frame data. */
uint8_t cnt = 0;
memset(tx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
tx_data[0] = 58;
for (cnt = 1; cnt < CAN_DATASIZE; cnt++)
{
// tx_data[cnt] = *CANBuff[cnt]; //Aquí se almacenan los datos del Buffer
// tx_data[cnt] = _anlBuffer[cnt];
tx_data[cnt] = cnt;
}
//** Valores de configuración del CAN**//
txFrame.xtd = kMCAN_FrameIDStandard;
txFrame.rtr = kMCAN_FrameTypeData;
txFrame.fdf = 0;
txFrame.brs = 0;
txFrame.dlc = 8U;
txFrame.id = 31;
txFrame.data = tx_data;
txFrame.size = CAN_DATASIZE;
#if (defined(USE_CANFD) && USE_CANFD)
txFrame.fdf = 1;
txFrame.brs = 1;
txFrame.dlc = DLC;
#endif
// txXfer.frame = &txFrame;
// txXfer.bufferIdx = 0;
// MCAN_TransferSendNonBlocking(DATA_MCAN, &mcanHandle, &txXfer);
MCAN_TransferSendBlocking(DATA_MCAN, 0, &txFrame);
// vTaskDelay(1000);
// while (!txComplete)
// {
// }
// txComplete = false;
// }
// vPortFree(CANBuff);
// }
//////////////////////////////////////////////////////////
MCAN_ReadRxBuffer(DATA_MCAN,0,&rxFrame);

//////////////////////////////////////////////////////////
} // while (true)

} // void _TskSendCAN(void)

/**********************************************************
** Métodos públicos
**********************************************************/
/*! \fn void ModCANInit(void)
* \brief Inicializa el módulo CAN.
* \return Nada.
*/
void ModCANInit(void)
{
BaseType_t xReturned;
if(!ModoConfig())
{
xReturned = xTaskCreate((TaskFunction_t)_TskSendCAN,"TskSendCAN",4*configMINIMAL_STACK_SIZE,NULL,APP_TSK_LOW_PRIORITY,&_tskHandleSendCAN);
configASSERT(xReturned);
// _queueHandleBuff = xQueueCreate(QUEUE_LENGTH, TAM_BUFF);
// configASSERT(_queueHandleBuff);
}


} // void ModCANInit(void)

0 Kudos

2,028 Views
frank_m
Senior Contributor III

> The transmission seems to go through, but when I read the response, it doesn't match the id.

Not sure what that means, and what you expect.

As mentioned in earlier threads, CAN is not based on a request-response mechanism.

There are only nodes that send messages, and bus arbitration is based on IDs (CAN identifier). On CAN level, everything is broadcast, i.e. every node receives every message.

What happens internally (i.e. interpreting one message as a response to another) is solely a firmware functionality of the node(s).

0 Kudos

2,024 Views
Nadia
Contributor III

@frank_m The function MCAN_ReadRxBuffer(), returns a 1 in the parameter esi. This indicates an error.

0 Kudos

2,015 Views
frank_m
Senior Contributor III

Do you see both transmissions on the bus ?

Try a scope and/or CAN monitoring software. If you (your company) develops CAN related devices, you will definitely need those. I could recommend Vector (https://www.vector.com/int/en/) or PEAK products (https://www.peak-system.com/?&L=1).

> The function MCAN_ReadRxBuffer(), returns a 1 in the parameter esi. This indicates an error.

Can you step into the call, or check the sources to see why it fails, and what the raturn value exactly means ?

Perhaps the bus is physically not set up correctly (no termination, CANH/CANL swapped, shifting GND potentials).

0 Kudos

2,010 Views
Nadia
Contributor III

@frank_m The transmission seems to have been carried out. With an oscilloscope I can see that data is being sent on both channels.

0 Kudos

2,006 Views
frank_m
Senior Contributor III

You will need to look into your setup and source code.

Checking a CAN example for the LPC546xx, the function MCAN_ReadRxBuffer() of said SDK returns the fixed value kStatus_Success (0).

 

0 Kudos

2,001 Views
Nadia
Contributor III

Yes, the function returns a kStatus_Success

0 Kudos

2,000 Views
Nadia
Contributor III

@frank_m Yes, the function returns a kStatus_Success

0 Kudos