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.
Hello Nadia,
Recommend first recommend the CAN demo under SDK for lpcpxresso55s16 board.
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
@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)
> 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).
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).