Tool/software:
Hello TI team!
I am looking into how to send and receive Classic CAN extended format using LP-2434.
I have many questions about classic CAN (e2e) but I don't know how to implement it.
environment:
CCS12.7.0
AM243x MCU+SDK 09.02.01.05
LP-AM2434
R5F Application mcan_loopback_interrupt_am243x-lp_r5fss0-0_nortos_ti-arm-clang
I would like to modify mcan_loopback_interrupt to check the loopback of the classic CAN extended format.
Q1. I would like to have a sample code.
Do you have any sample code?
Q2. MCAN_extTS***() has an ext string in the API name.
I can't find how to use it in the online manual.
Do you have any sample code?
Q3. I don't know which API to use for the definines listed in the online manual.
If you do not have the Classic CAN Extended Format sample code, please let me know the definines and structure names to use.
Q4. I don't know which API to use for the define listed in the online manual.
For example,
MCAN_STD_FILT_ELEM_SET_PRIORITY
Is it set in the MCAN_StdMsgIDFilterElement structure?
Which member variable should it be set to?
I would like to see an addendum to the online manual to see how to use it.
I searched the online documentation for the ext string and found many, many structs, APIs, and defines.
Regards,
Yoshiki Koide
Hi Yoshiki-San,
I am working on your queries, please expect a reply in 1-2 days.
Best Regards.
Meet.
Thanks.
Perform a loopback test using a 3-pin header (J11).
I test with CANFD before the classic CAN loopback test.
I intend to test classic CAN after CANFD is successful.
The sample code used mcan_loopback_interrupt.
App_mcanIntrISR() is executed, but MCAN_INTR_SRC_TRANS_COMPLETE is OFF.
Protocol Error in Data Phase interrupt occurs.
This error occurred during the CANFD loopback test. We believe it also occurs on classic CAN.
We do not use loopback mode.
What is wrong?
Hi Yoshiki-San,
I was able to reproduce this at my end, please allow me some more time to find the root cause.
Best Regards,
Meet.
Hi Yoshiki-San,
Apologies for the delay.
You would need to enable the CAN transceiver to see the data on the bus. What you are using is an internal loopback example so the transceiver is not enabled. You can take mcan_external_loopback_interrupt as a reference on how to enable the transceiver, there a file mcan_transceiver is used to enable the transceiver, you can try to integrate the same in your project. Typically you need to pull the STB pin of MCAN transceiver low to enable it.
Best Regards,
Meet.
Hello, Meat-san.
I have checked mcan_transceiver.c.
file path:
mcu_plus_sdk_am243x_10_01_00_32\examples\drivers\mcan\mcan_external_loopback_interrupt\am243x-evm\mcan_transceiver.c
I want to work sure with LP2434 board.
The mcan_transceiver.c controls the STB.
On LP2434, STB cannot be controlled.
EVM can control STB.
mcan_transceiver.c is not available in LP2434.
How can I do an external loopback with LP2434?
User's Guide "AM64x/AM243x Evaluation Module", p54-55
STB pin of the IC is by default connected to ground to avoid IC entering stand-by mode.
The STB pin is controlled by GPIO to enable Standby mode.
In mcan_transceiver.c, the TCA6424 is controlled via I2C.
User's Guide "AM243x LaunchPad", p44
The STB pin can be directly driven by the AM243x to enable standby mode.
When not directly driven by the AM243x, the 10kΩ pulldown resistor puts the CAN interface IC into normal operation mode.
Regards,
Yoshiki
Hi Yoshiki-San,
There is a FAQ that guides on how to implement this external loopback and verify the functionality, please refer to the same: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1329465/faq-sk-am62x-sk-am62a-lp-testing-mcan-external-loopback-example-using-external-transceiver-tcan1042d
As you are using AM243-lp you don't need to use an external transceiver as it is already available on the board, but you will need to connect your transceiver's CANL and CANH to PCAN module and follow the steps mentioned in the FAQ.
Best Regards,
Meet.
Thanks.
Can communication is serial communication.
I thought I could just connect tx=>rx, rx=>tx like uart.
But this was a mistake.
https://software-dl.ti.com/processor-sdk-linux/esd/AM62AX/09_01_00/exports/docs/linux/How_to_Guides/Target/How_to_test_MCAN_on_AM62x.html#mcan-overview
CAN communication is not possible with a single board.
Two boards are required as shown in the figure.
I will have two LP-2434s.
AM64x /AM243x
Technical Reference Manual
I am transcribing the very first request.
“I would like to modify mcan_loopback_interrupt to check the loopback of the classic CAN extended format.”
"Q1.I would like the sample code, can I download it?”
I studied classic CAN in the online documentation.
mcan_loopback_interrupt.c This sample code is CANFD.
mcan_loopback_polling.c This sample code is Classic Can, CANID is 29bit.
1. I modify mcan_loopback_interrupt.c to ClassicCan.
2. I confirm loopback with CANID 11bit. 3. I modify mcan_loopback_interrupt.c to CANID 29bit.
3. I modify mcan_loopback_interrupt.c to CANID 29bit. mcan_loopback_polling.c confirmed.
4. I confirm loopback with CANID 29bit.
5. I confirm CANID 11bit communication with 2 LP boards.
6. I confirm CANID 29bit communication with 2 LP boards.
Result:.
2: Sending/receiving succeeds
4: Reception fails.
I do not know why CANID 29bit is failing.
I have corrected (*1)-(*5).
Classic CAN 11bit:
(*1)MCAN_InitParams::fdMode FALSE
MCAN_InitParams::brsEnable FALSE
(*2)MCAN_MsgRAMConfigParams::lss APP_MCAN_STD_ID_FILTER_CNT(1)
MCAN_MsgRAMConfigParams::lse APP_MCAN_EXT_ID_FILTER_CNT(0)
(*3)MCAN_MsgRAMConfigParams::rxBufElemSize MCAN_ELEM_SIZE_8BYTES(0)
MCAN_MsgRAMConfigParams::rxFIFO0ElemSize MCAN_ELEM_SIZE_8BYTES(0)
MCAN_MsgRAMConfigParams::rxFIFO1ElemSize MCAN_ELEM_SIZE_8BYTES(0)
MCAN_MsgRAMConfigParams::txBufElemSize MCAN_ELEM_SIZE_8BYTES(0)
(*4)MCAN_StdMsgIDFilterElement::sfid1 0xc0
MCAN_StdMsgIDFilterElement::sfid2 0xc0
MCAN_StdMsgIDFilterElement::sfec MCAN_STD_FILT_ELEM_BUFFER(7)
MCAN_StdMsgIDFilterElement::sft MCAN_STD_FILT_TYPE_CLASSIC(2)
(*5)MCAN_TxBufElement::dlc MCAN_DATA_SIZE_8BYTES(0)
MCAN_TxBufElement::fdf FALSE
Classic CAN 29bit:
(*1)MCAN_InitParams::fdMode FALSE
MCAN_InitParams::brsEnable FALSE
(*2)MCAN_MsgRAMConfigParams::lss APP_MCAN_STD_ID_FILTER_CNT(0)
MCAN_MsgRAMConfigParams::lse APP_MCAN_EXT_ID_FILTER_CNT(1)
(*3)MCAN_MsgRAMConfigParams::rxBufElemSize MCAN_ELEM_SIZE_8BYTES(0)
MCAN_MsgRAMConfigParams::rxFIFO0ElemSize MCAN_ELEM_SIZE_8BYTES(0)
MCAN_MsgRAMConfigParams::rxFIFO1ElemSize MCAN_ELEM_SIZE_8BYTES(0)
MCAN_MsgRAMConfigParams::txBufElemSize MCAN_ELEM_SIZE_8BYTES(0)
(*4)MCAN_ExtMsgIDFilterElement::efid1 0xd0
MCAN_ExtMsgIDFilterElement::efid2 0xd0
MCAN_ExtMsgIDFilterElement::efec MCAN_EXT_FILT_ELEM_BUFFER(7)
MCAN_StdMsgIDFilterElement::eft MCAN_EXT_FILT_TYPE_CLASSIC(2)
(*5)MCAN_TxBufElement::id
MCAN_TxBufElement::xtd FALSE
MCAN_TxBufElement::dlc MCAN_DATA_SIZE_8BYTES
MCAN_TxBufElement::fdf FALSE
What am I doing wrong?
Regards,
Yoshiki.
/// my init { /* Initialize MCAN module initParams */ MCAN_initOperModeParams(&initParams); initParams.fdMode = FALSE; // classic canはFALSE initParams.brsEnable = FALSE; // classic canはFALSE } /// my msgram config static char trial_MCAN_MsgRAMConfigParams(uint32_t mode, MCAN_MsgRAMConfigParams *pConfig) { MCAN_MsgRAMConfigParams wk_cfg; if (pConfig == NULL) { return -1; } /* * Configure the user required msg ram params */ // This API will initialize MCAN message config RAM params to default. MCAN_initMsgRamConfigParams(&wk_cfg); if (mode == MCAN_MODE_STANDARD) { wk_cfg.lss = LLD_MCAN_STD_ID_FILTER_CNT; // List Size: Standard ID wk_cfg.lse = 0; // List Size: Extended ID } else { wk_cfg.lss = 0; // List Size: Standard ID wk_cfg.lse = LLD_MCAN_EXT_ID_FILTER_CNT; // List Size: Extended ID } /* Maximum TX Buffer + TX FIFO, combined can be configured is 32 */ wk_cfg.txBufCnt = LLD_MCAN_TX_BUFF_CNT; // (1) wk_cfg.txFIFOCnt = LLD_MCAN_TX_FIFO_CNT; // (0) /* * Buffer/FIFO mode is selected */ wk_cfg.txBufMode = MCAN_TX_MEM_TYPE_BUF; /* Maximum TX Event FIFO can be configured is 32 */ wk_cfg.txEventFIFOCnt = LLD_MCAN_TX_EVENT_FIFO_CNT; /* Maximum RX FIFO 0 can be configured is 64 */ wk_cfg.rxFIFO0Cnt = LLD_MCAN_FIFO_0_CNT; /* Maximum RX FIFO 1 can be configured is 64 and * rest of the memory is allocated to RX buffer which is again of max size 64 */ wk_cfg.rxFIFO1Cnt = LLD_MCAN_FIFO_1_CNT; /* FIFO blocking mode is selected */ wk_cfg.rxFIFO0OpMode = MCAN_RX_FIFO_OPERATION_MODE_BLOCKING; wk_cfg.rxFIFO1OpMode = MCAN_RX_FIFO_OPERATION_MODE_BLOCKING; wk_cfg.rxBufElemSize = MCAN_ELEM_SIZE_8BYTES; wk_cfg.rxFIFO0ElemSize = MCAN_ELEM_SIZE_8BYTES; wk_cfg.rxFIFO1ElemSize = MCAN_ELEM_SIZE_8BYTES; //This API will calculate start addresses of message RAM params (void)MCAN_calcMsgRamParamsStartAddr(&wk_cfg); (void)memcpy((void*)pConfig, &wk_cfg, sizeof(wk_cfg)); return 0; } /// my std filter static char trial_StdFilterElemParams(MCAN_StdMsgIDFilterElement *pstdFiltElem) { if (pstdFiltElem == NULL) { return -1; } /* sfid1 defines the ID of the standard message to be stored. */ pstdFiltElem->sfid1 = 0; /* As buffer mode is selected, sfid2 should be bufNum[0 - 63] */ pstdFiltElem->sfid2 = 0; /* Store message in buffer */ // Store into Rx Buffer or as debug message, configuration of SFT[1:0] ignored. pstdFiltElem->sfec = MCAN_STD_FILT_ELEM_BUFFER; #if 0 uint32_t sft; /**< Standard Filter Type * 00 = Range filter from SFID1 to SFID2 (SFID2 ≥ SFID1) * 01 = Dual ID filter for SFID1 or SFID2 * 10 = Classic filter: SFID1 = filter, SFID2 = mask * 11 = Filter element disabled */ #endif /* Below configuration is ignored if message is stored in buffer */ pstdFiltElem->sft = MCAN_STD_FILT_TYPE_CLASSIC; return 0; } /// my std filter { (void)trial_StdFilterElemParams(&stdFiltElem[0]); stdFiltElem[0].sfid1 = pTrial->acceptanceCode; // 0x0c stdFiltElem[0].sfid2 = pTrial->acceptanceMask; // 0x0c } /// my ext filter static char trial_ExtFilterElemParams(MCAN_ExtMsgIDFilterElement *pextFiltElem) { if (pextFiltElem == NULL) { return -1; } /* efid1 defines the ID of the standard message to be stored. * Message id configured is 0xD0 to 0xD4 */ pextFiltElem->efid1 = 0; /* As fifo mode is selected, efid2 should be mask */ pextFiltElem->efid2 = 0; /* Store message in buffer */ //pextFiltElem->efec = MCAN_STD_FILT_ELEM_FIFO0; pextFiltElem->efec = MCAN_EXT_FILT_ELEM_BUFFER; #if 0 uint32_t eft; /**< Extended Filter Type * 00 = Range filter from EFID1 to EFID2 (EFID2 ≥ EFID1) * 01 = Dual ID filter for EFID1 or EFID2 * 10 = Classic filter: EFID1 = filter, EFID2 = mask * 11 = Range filter from EFID1 to EFID2 (EFID2 ≥ EFID1), * XIDAM mask not applied */ #endif /* Below configuration is ignored if message is stored in buffer */ pextFiltElem->eft = MCAN_STD_FILT_TYPE_CLASSIC; return 0; } /// my ext filter { (void)trial_ExtFilterElemParams(&extFiltElem[0]); extFiltElem[0].efid1 = pTrial->acceptanceCode; // 0xd0 extFiltElem[0].efid2 = pTrial->acceptanceMask; // 0xd0 } /// my send config char trial_SendConfig( uint32_t baseAddr, uint32_t mode, TRIAL_t* pTrial, MCAN_TxBufElement* plld_tx ) { MCAN_TxBufElement wk_tx; uint8_t ii; /* Initialize message to transmit */ MCAN_initTxBufElement(&wk_tx); /**< Identifier */ wk_tx.id = (uint32_t)pTrial->id; /**< Remote Transmission Reques * 0 = Transmit data frame * 1 = Transmit remote frame */ wk_tx.rtr = pTrial->frame; /**< Extended Identifier * 0 = 11-bit standard identifier * 1 = 29-bit extended identifier */ wk_tx.xtd = TRUE; //if( m_UsrParam[channel].mode == MCAN_MODE_STANDARD ) if( mode == MCAN_MODE_STANDARD ) { wk_tx.xtd = FALSE; } /**< FD Format * 0 = Frame transmitted in Classic CAN format * 1 = Frame transmitted in CAN FD format */ wk_tx.fdf = FALSE; /**< Data Length Code * 0-8 = CAN + CAN FD: transmit frame has 0-8 data bytes * 9-15 = CAN: transmit frame has 8 data bytes * 9-15 = CAN FD: transmit frame has 12/16/20/24/32/48/64 data bytes */ wk_tx.dlc = pTrial->length; for(ii = 0; ii < pTrial->length; ii++) { wk_tx.data[ii] = pTrial->data[ii]; } memcpy((void*)plld_tx, &wk_tx, sizeof(wk_tx)); return 0; }
Hi Yoshki-San,
Please allow me some more time to review the code and get back to you.
Best Regards,
Meet.
mcan_loopback_interrupt.c sets the following structures
MCAN_InitParams
MCAN_ConfigParams
MCAN_MsgRAMConfigParams
MCAN_StdMsgIDFilterElement
MCAN_ExtMsgIDFilterElement
MCAN_BitTimingParams
MCAN_TxBufElement
I believe that by modifying these structures, I can send and receive CANID 11bit and 29bit. Am I right?
Regards,
Yoshiki.
Hi Thaker,
There are a lot of discussion here.
1st of all, could you focus 29bit mode for internal loop back, test it and share the code with Yoshiki-san?
Thank you.
Best Regards,
Kasai
Hi Kasai-San, Yoshiki-San,
mcan_loopback_polling is using 29-bit ID, I understand Yoshiki-San is trying to enable the same for the interrupt example and facing some issue. Please note that interrupt example uses buffer mode and if you are using the buffer mode efid2 has to be set to the buffer number, I see that it is set to 0xD0 here, I am not sure of the reason, but ideally it should be set to buffer number. I will try to run the example at my end and let you know what other changes might be required here.
Best Regards,
Meet.