This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM2634: CAN-FD Rx FIFO always crashes on second frame (null pointer in rxMapping[])

Part Number: AM2634
Other Parts Discussed in Thread: TMDSCNCD263, TCA6416, , SYSCONFIG

Tool/software:

Hi!

I am trying to run TI’s canfd_external_read_write.c example found here:

https://github.com/TexasInstruments/mcupsdk-core/blob/next/examples/drivers/mcan/canfd_external_read_write/canfd_external_read_write.c

https://dev.ti.com/tirex/content/mcu_plus_sdk_am263x_10_01_00_31/docs/api_guide_am263x/EXAMPLES_DRIVERS_MCAN_CANFD_EXTERNAL_READ_WRITE.html

I have a TMDSCNCD263 control card dev kit set up per the description in the example to a Windows computer running PCAN VIEW.

I am importing the `canfd_external_read_write_am263x-cc_r5fss0-0_nortos_ti-arm-clang` to my CCS Version 20.1.1 (20.1.1.466), compiling and running the code with the debugger available.

I am having 2 issues. 

1)

I have found I'm required to comment out L97 `mcanEnableTransceiver()`, for the program to run. https://github.com/TexasInstruments/mcupsdk-core/blob/next/examples/drivers/mcan/canfd_external_read_write/canfd_external_read_write.c#L97 

If I do not, I receive the error `Cortex_R5_0: ASSERT: 0.181s: ../canfd_transceiver.c:SetupI2CTransfer:103: SystemP_SUCCESS == status failed !!!` on the terminal.

Is this okay to comment out? Why is this happening?

2)

After commenting out canfd_external_read_write.c L97 `mcanEnableTransceiver()`.

When I run the code, I can confirm that the TX is working as my PCAN VIEW shows incoming CAN FD messages. If I send multiple messages from PCAN VIEW with a CAN ID of 0x0, the program receives the messages without issue. Through the debug tool, I see a interrupt status of `MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG` and `CANFD_receiveBufferInterrupt` is called. https://github.com/TexasInstruments/mcupsdk-core/blob/next/source/drivers/mcan/v0/canfd.c#L319

However, when I send a message with CAN ID that is not 0x0, I see an interrupt status of `MCAN_INTR_SRC_RX_FIFO0_NEW_MSG` and `CANFD_processFIFOElements` is called. This works successfully for the first non-0 CAN ID message. However the second non-0 CAN ID message receives causes a hard fault. 

ptrCanMsgObj = ptrCanFdObj->rxMapping[fifoStatus.getIdx]; has getIdx return 1, ptrCanMsgObj is given a value of 0 as rxMapping[1] is still NULL, and dereferencing ptrCanMsgObj causes a crash. https://github.com/TexasInstruments/mcupsdk-core/blob/next/source/drivers/mcan/v0/canfd.c#L198 

How can I configure / setup the CAN FIFO differently so it can successfully receive multiple can messages from any extended CAN ID? (I still want 64B canfd messages). I tried playing around with configuration settings to make things specific for supporting CAN FD - FIFO without success.

Thank you!

  • Hi Justin,

    Thanks for reaching out and providing a detailed description of your current test results.

    I am looking into this issue and will provide a response before the end of the week. Thank you for your patience.

    Best Regards,

    Zackary Fleenor

  • Great thank you. Please let me know if I can provide additional context. This is quite urgent for our needs.

  • Hey Justin,

    1) The mcanEnableTransciever() function differs depending on the EVM (LaunchPad vs ControlCard). In the launchpad is simply used to pull GPIO51 low which is conntected to the STB (Standby) pin of the TCAN1044 transciever. When the STB pin is High, the transciever is in Standby/Low-power mode, when it is Low, the transciever is in active/normal mode. In the ControlCard, it is configures I2C0 to communicate with the TCA6416 I/O Expander to implement the same STB pull down function for normal mode (hence function name "EnableTransciever"). There is an external pull down resistor that will cause the transcivever to default into normal mode. Due to this, it is probably okay to comment out this line. However, it would be valuable if you could single step through that function to determine which I2C Transfer causes the failure.

    2)

    Have you configured the RX_FIFO0 to receive elements? If so how have you configured it? Can you also share you configuration for the RX Buffer?

    You will want to setup your RX_FIFO acceptence filter to recieve the specific ID's being sent.

    TI provides the following suggestion when debugging the CAN implementation (https://www.ti.com/lit/an/spracu9/spracu9.pdf)

    "When attempting to initiate communication on the bus for the very first time, ensure that the mailbox in the transmitting node and the receiving node are programmed with the same MSGID. Do not use Acceptance Mask Filtering initially. Filtering could be added later once it is confirmed there are no hardware issues."

    Hope this helps get you started in the debug process, and we're glad to help further where we can.

    Best Regards,

    Zackary Fleenor

  • Hi Zackary, thanks for getting back to me.

    1) I've stepped through the function, running the `canfd_external_read_write_am263x-cc_r5fss0-0_nortos_ti-arm-clang` imported example unchanged. Looks like even the first call to `SetupI2CTransfer` from `mcanEnableTransceiver` is causing the failure, receiving the error `Cortex_R5_0: ASSERT: 0.181s: ../canfd_transceiver.c:SetupI2CTransfer:103: SystemP_SUCCESS == status failed !!!` on the terminal.

    https://github.com/TexasInstruments/mcupsdk-core/blob/next/examples/drivers/mcan/canfd_external_read_write/am263x-cc/canfd_transceiver.c#L71

    2) Initially I have not modified the example from its original state (besides commenting out mcanEnableTransceiver). So the syscfg can be found here

    https://github.com/TexasInstruments/mcupsdk-core/blob/next/examples/drivers/mcan/canfd_external_read_write/am263x-cc/r5fss0-0_nortos/example.syscfg

    However, when I try to change the syscfg with the following, it still halts and fails when the interrupt status `MCAN_INTR_SRC_RX_FIFO0_NEW_MSG` is found (instead of the `MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG` for a buffer interrupt).

    That being said, I can configure this example program to successfully send TX messages from whatever CAN ID, and still receive RX messages with CAN ID 0x0, just not accepting any RX with a different CAN ID.

    From modifying the `canfd_external_read_write_am263x-cc_r5fss0-0_nortos_ti-arm-clang` imported example, here is my configuration in syscfg when I try to disable the filter and enable the rx fifo. This has the same failure in which it will receive one message in the RX FIFO, and hard fault the program upon the second received message in the RX FIFO (due to the null pointer deref).

    mcan1.$name = "CONFIG_MCAN0";
    mcan1.sdkInfra = "HLD";
    mcan1.transferMode = "CALLBACK";
    mcan1.transferCallbackFxn = "App_CANFDTransferCallback";
    mcan1.errorCallbackFxn = "App_CANFDErrorCallback";
    mcan1.darEnable = true;
    mcan1.autoWkupEnable = true;
    mcan1.wkupReqEnable = true;
    mcan1.additionalCoreConfig = true;
    mcan1.enableLoopback = false;
    mcan1.loopbackMode = "EXTERNAL";
    mcan1.nomPseg1 = 8;
    mcan1.nomPseg2 = 2;
    mcan1.tdcEnable = true;
    mcan1.rxMemType = "FIFO";
    mcan1.extendedFilterEleConfig = "MCAN_EXT_FILT_ELEM_DISABLE";
    mcan1.standardFilterEleConfig = "MCAN_STD_FILT_ELEM_DISABLE";
    mcan1.MCAN.$assign = "MCAN1";

    And here is a modified `canfd_external_read_write_main`

    #include <string.h>
    #include <kernel/dpl/SemaphoreP.h>
    #include <kernel/dpl/ClockP.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"

    /** \brief Maximum data size for CAN FD frames */
    #define MCAN_APP_MAX_DATA_SIZE 64U

    CANFD_MessageObject rxMsgObject;
    static SemaphoreP_Object gMcanRxDoneSem;
    uint8_t rxData[MCAN_APP_MAX_DATA_SIZE] = {0};
    volatile uint32_t totalMessagesReceived = 0U;

    void mcanEnableTransceiver(void);

    void canfd_external_read_write_main(void *args)
    {
    CANFD_MsgObjHandle rxMsgObjHandle;
    int32_t status = SystemP_SUCCESS;

    /* Open drivers to open the UART driver for console */
    Drivers_open();
    Board_driversOpen();

    // mcanEnableTransceiver();

    status = SemaphoreP_constructBinary(&gMcanRxDoneSem, 0);
    DebugP_assert(SystemP_SUCCESS == status);

    DebugP_log("\r\n[MCAN] CAN RX FIFO Monitor Started...\r\n");
    DebugP_log("Waiting for CAN messages (press CTRL+C to stop)...\r\n\r\n");

    /* Setup the receive message object for FIFO operation */
    rxMsgObject.direction = CANFD_Direction_RX;
    rxMsgObject.msgIdType = CANFD_MCANXidType_29_BIT; /* Accept both 11-bit and 29-bit IDs */
    rxMsgObject.startMsgId = 0x0; /* Start ID (not used for FIFO) */
    rxMsgObject.endMsgId = 0x1FFFFFFF; /* End ID (accept all) */
    rxMsgObject.args = (uint8_t *)rxData;
    rxMsgObject.dataLength = MCAN_APP_MAX_DATA_SIZE;
    status = CANFD_createMsgObject(gCanfdHandle[CONFIG_MCAN0], &rxMsgObject);
    if (status != SystemP_SUCCESS)
    {
    DebugP_log("Error: CANFD create Rx message object failed\r\n");
    return;
    }
    rxMsgObjHandle = &rxMsgObject;

    /* Main reception loop */
    while (1)
    {
    /* Read from FIFO (non-blocking) */
    status = CANFD_read(rxMsgObjHandle, 1, &rxData[0]);
    if (status == SystemP_SUCCESS)
    {
    /* Wait for RX completion */
    SemaphoreP_pend(&gMcanRxDoneSem, SystemP_WAIT_FOREVER);

    totalMessagesReceived++;

    /* Print first 8 bytes of data */
    DebugP_log("MSG #%u: Data: ", totalMessagesReceived);
    uint32_t bytesToPrint = (rxMsgObject.dataLength > 8) ? 8 : rxMsgObject.dataLength;
    for (uint32_t i = 0; i < bytesToPrint; i++)
    {
    DebugP_log("%02X ", rxData[i]);
    }
    if (rxMsgObject.dataLength > 8)
    {
    DebugP_log("... (+%u more)", rxMsgObject.dataLength - 8);
    }
    DebugP_log("\r\n");
    }
    else
    {
    /* Small delay to prevent busy waiting */
    ClockP_usleep(1000); /* 1ms delay */
    }
    }

    /* Cleanup (this code will never be reached in the infinite loop) */
    SemaphoreP_destruct(&gMcanRxDoneSem);
    status = CANFD_deleteMsgObject(rxMsgObjHandle);

    Board_driversClose();
    Drivers_close();

    return;
    }

    void App_CANFDTransferCallback(void *args, CANFD_Reason reason)
    {
    if (reason == CANFD_Reason_RX)
    {
    SemaphoreP_post((SemaphoreP_Object *)&gMcanRxDoneSem);
    }
    }

    void App_CANFDErrorCallback(void *args, CANFD_Reason reason)
    {
    DebugP_log("CAN Error: Reason code 0x%x\r\n", reason);
    }

    Please let me know if I should be doing anything differently.

    Is there an example that will run on the AM2634 dev board that has CAN FD rx FIFO enabled I can use as a reference? This would be the most helpful. 

  • Hey Justin,

    I am assigning this thread to our SW expert to provide additional guidance and possible timeline for CAN-FD RX FIFO example.

    Please allow some time for review and additional feedback.

    Best Regards,

    Zackary Fleenor

  • Great thanks Zackary. Just bumping this thread.

  • Hey Justin,

    I have received this thread, please give me some time, probably until mid of next week to replicate it on my end and check further. It will be helpful if you could attach your modified project as a zip file here.

    Meantime you can refer to this example "mcan_loopback_polling" that demonstrates Tx and Rx used in FIFO mode, although it is an HLD example and not LLD one like the canfd example you're referring to. So in this case the configurations will be found within the source code itself, instead of in sysconfig.

    Best Regards,
    Aswathi 

  • Hi Aswathi,

    Here is a zipped file of my modified code. I attempted to view the mcan_loopback_polling example but could not correlate it to using fdcan FIFO mode. Again, every time the board receives not a message with CAN ID 0x0, the fifo pointer is nullified and the second message causes a hard crash.

    Is there anything you have been able to test for this? A working FIFO with CAN FD example, that would be able to send messages on any can id and receive messages on any can id would be ideal.

    Thank you.

    canfd_external_read_write_am263x-cc_r5fss0-0_nortos_ti-arm-clang.zip

  • Hi Justin,

    Thanks for sharing the program. 

    1. Paste the below file in this path: {SDK}/source/drivers/mcan/v0/

    canfd.c

    2. Import this project to CCS

    2604.canfd_external_read_write_am263x-cc_r5fss0-0_nortos_ti-arm-clang.zip

    It should fix the transceiver issue and the crashing issue. But both Tx and Rx is in Buffer mode. I do not have the hardware to test for FIFO mode currently. Let me know if FIFO selection via sysconfig is still not working with this updated project. I will try it on my end on Tuesday. 

    Best Regards,
    Aswathi

  • Hi Aswathi, I'm having trouble running your package with MCU_PLUS_SDK_AMXXX v7.3.0.01. Could you please provide me with details about what should be changed in my syscfg and the main function as provided in my previous zip file.

    There also seems to be a massive diff between the `canfd.c` you send and the one I have in mcu_plus_sdk_am263x_10_01_00_31.

    Can this not be supported on a more recent version of the sdk like v10.01.00.31 I am using?

    Thanks for looking into the fifo option, this is ultimately what we need working.

  • Hi Aswathi, any update here? Thanks

  • Hi Justin,
    Apologies for the delay, I am not keeping well. I will get someone in the team to help you with the migration of the files I sent. Thanks for your patience.

    Thanks,
    Aswathi

  • Hi Justin,

    Sorry for the delay.

    Below is the application on SDK 10.1. Could you please try the same?

    /cfs-file/__key/communityserver-discussions-components-files/908/6765.canfd_5F00_external_5F00_read_5F00_write_5F00_am263x_2D00_cc_5F00_r5fss0_2D00_0_5F00_nortos_5F00_ti_2D00_arm_2D00_clang.zip

    and the only change in the canfd.c file is replacing the ifcondition with switch case in CANFD_isDataSizeValid() as shown below

    current implementation
    
    int32_t CANFD_isDataSizeValid(uint32_t dataSize)
    {
        uint32_t canfdDataSize[CANFD_MAX_DLC_MAPPING] = 
                        {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U,
                         12U, 16U, 20U, 24U, 32U, 48U, 64U};
    
        if((canfdDataSize[dataSize] == 0U) || 
           (canfdDataSize[dataSize] == 1U) ||
           (canfdDataSize[dataSize] == 2U) ||
           (canfdDataSize[dataSize] == 3U) ||
           (canfdDataSize[dataSize] == 4U) ||
           (canfdDataSize[dataSize] == 5U) ||
           (canfdDataSize[dataSize] == 6U) ||
           (canfdDataSize[dataSize] == 7U) ||
           (canfdDataSize[dataSize] == 8U) ||
           (canfdDataSize[dataSize] == 12U) ||
           (canfdDataSize[dataSize] == 16U) ||
           (canfdDataSize[dataSize] == 20U) ||
           (canfdDataSize[dataSize] == 24U) ||
           (canfdDataSize[dataSize] == 32U) ||
           (canfdDataSize[dataSize] == 48U) ||
           (canfdDataSize[dataSize] == 64U))
        {
            return SystemP_SUCCESS;
        }
    
        return SystemP_FAILURE;
    }
    
    
    fixed implementation
    int32_t CANFD_isDataSizeValid(uint32_t dataSize)
    {
        switch (dataSize)
        {
            case 0U:
            case 1U:
            case 2U:
            case 3U:
            case 4U:
            case 5U:
            case 6U:
            case 7U:
            case 8U:
            case 12U:
            case 16U:
            case 20U:
            case 24U:
            case 32U:
            case 48U:
            case 64U:
                return SystemP_SUCCESS;
            
            default:
                return SystemP_FAILURE;
        }
    }

    Could you please try this and let me know if it works at your end?

    Thanks and Regards,

    Nikhil Dasan

  • Hi Nikhil, 

    I attempted to use your zip file example but it would still not accept any different CAN ID's other than 0x0.

    It did fix the `mcanEnableTransceiver()`, thank you.


    Instead, I ported the LLD mcan loopback polling example to use canfd for my use case. I do have this working now.

     

    Thanks!