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.

PROCESSOR-SDK-AM64X: MCAN external loopback issue

Part Number: PROCESSOR-SDK-AM64X


Tool/software:

Hello ,

I'm using mcu_plus_sdk_am64x_10_01_00_32 to try the mcan_external_loopback_interrupt_am64x-evm_r5fss0-0_freertos example, but when I debug the code, the compiler blocks as shown in the screenshot below. I don't shown any debug log .

  • Hi Elbon,

    Could you let me know if the code is getting stuck somewhere or are you encountering any error message while running the code, because from the screenshot I couldn't figure out any issues, could you elaborate the same. Have you connected to UART terminal and seeing any logs of the application there?

    Best Regards,

    Meet.

  • Hello meet,

    The project doesn't have any errors, but it doesn't work. I tried copying the code from mcan_external_loopback_interrupt_am64x to the project mcan_loopback_interrupt_am64x, and when I debug it, I see the debug log as shown in the screenshot. However, it doesn't display the log 'All tests have passed!!'."

    And this is the code :

    #include <stdio.h>
    #include <kernel/dpl/DebugP.h>
    #include <kernel/dpl/TaskP.h>
    #include <kernel/dpl/AddrTranslateP.h>
    #include <drivers/mcan.h>
    #include "ti_dpl_config.h"
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    
    #define APP_MCAN_BASE_ADDR                       (CONFIG_MCAN0_BASE_ADDR)
    #define APP_MCAN_INTR_NUM                        (CONFIG_MCAN0_INTR)
    #define APP_MCAN_MSG_LOOP_COUNT                  (10U)
    
    /* Allocate Message RAM memory section to filter elements, buffers, FIFO */
    /* Maximum STD Filter Element can be configured is 128 */
    #define APP_MCAN_STD_ID_FILTER_CNT               (1U)
    /* Maximum EXT Filter Element can be configured is 64 */
    #define APP_MCAN_EXT_ID_FILTER_CNT               (0U)
    /* Maximum TX Buffer + TX FIFO, combined can be configured is 32 */
    #define APP_MCAN_TX_BUFF_CNT                     (0U)
    #define APP_MCAN_TX_FIFO_CNT                     (0U)
    /* Maximum TX Event FIFO can be configured is 32 */
    #define APP_MCAN_TX_EVENT_FIFO_CNT               (0U)
    /* Maximum RX FIFO 0 can be configured is 64 */
    #define APP_MCAN_FIFO_0_CNT                      (0U)
    /* 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 */
    #define APP_MCAN_FIFO_1_CNT                      (0U)
    
    /* Standard Id configured in TX application.
     * This macro defined to compare with the received message id in this application */
    #define APP_MCAN_STD_ID                          (0xC0U)
    #define APP_MCAN_STD_ID_MASK                     (0x7FFU)
    #define APP_MCAN_STD_ID_SHIFT                    (18U)
    #define APP_MCAN_EXT_ID_MASK                     (0x1FFFFFFFU)
    
    /* In the CAN FD format, the Data length coding differs from the standard CAN.
     * In case of standard CAN it is 8 bytes */
    static const uint8_t gMcanRxDataSize[16U] = {0U,  1U,  2U,  3U,
                                               4U,  5U,  6U,  7U,
                                               8U,  12U, 16U, 20U,
                                               24U, 32U, 48U, 64U};
    /* CAN FD Data */
    uint8_t gMcanRxRecvdData[MCAN_MAX_PAYLOAD_BYTES];
    
    /* Semaphore to indicate transfer completion */
    static SemaphoreP_Object gMcanRxDoneSem;
    static HwiP_Object       gMcanRxHwiObject;
    static uint32_t          gMcanRxBaseAddr;
    
    /* Extern Function Declarations */
    void mcan_enableTransceiver(void);
    
    /* Static Function Declarations */
    static void    App_mcanIntrISR(void *arg);
    static void    App_mcanConfig(void);
    static void    App_mcanInitMsgRamConfigParams(
                   MCAN_MsgRAMConfigParams *msgRAMConfigParams);
    static void    App_mcanEnableIntr(void);
    static void    App_mcanCompareMsg(MCAN_RxBufElement *rxMsg);
    static void    App_mcanInitStdFilterElemParams(
                                      MCAN_StdMsgIDFilterElement *stdFiltElem,
                                      uint32_t bufNum);
    static void    App_mcanInitExpectedRxData(void);
    
    void mcan_loopback_rx_interrupt_main(void *args)
    {
        int32_t                 status = SystemP_SUCCESS;
        HwiP_Params             hwiPrms;
        MCAN_RxBufElement       rxMsg;
        MCAN_RxNewDataStatus    newDataStatus;
        MCAN_ErrCntStatus       errCounter;
        uint32_t                i, bufNum, fifoNum, bitPos = 0U;
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
    
        /* Enabled transceiver in RX application. No need to do in TX application.
         * If user wants to use only TX application then this function need to be
         * called in TX application also. */
        mcan_enableTransceiver();
    
        /* Wait for mcan tx application to be ready */
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
        DebugP_log("[MCAN] RX Application, Interrupt mode started ...\r\n");
    
        /* Construct Rx Semaphore objects */
        status = SemaphoreP_constructBinary(&gMcanRxDoneSem, 0);
        //DebugP_assert(SystemP_SUCCESS == status);
    
        /* Register interrupt */
        HwiP_Params_init(&hwiPrms);
        hwiPrms.intNum      = APP_MCAN_INTR_NUM;
        hwiPrms.callback    = &App_mcanIntrISR;
        status              = HwiP_construct(&gMcanRxHwiObject, &hwiPrms);
        //DebugP_assert(status == SystemP_SUCCESS);
    
        /* Assign MCAN instance address */
        gMcanRxBaseAddr = (uint32_t) AddrTranslateP_getLocalAddr(APP_MCAN_BASE_ADDR);
    
        /* Configure MCAN module, Enable LoopBack Mode */
        App_mcanConfig();
    
        /* Enable Interrupts */
        App_mcanEnableIntr();
    
        /* Transmit And Receive Message */
        for (i = 0U; i < APP_MCAN_MSG_LOOP_COUNT; i++)
        {
    
            /* Wait for mcan tx application to be ready */
            IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
            /* Wait for Rx completion */
            SemaphoreP_pend(&gMcanRxDoneSem, SystemP_WAIT_FOREVER);
    
            /* Checking for Rx Errors */
            MCAN_getErrCounters(gMcanRxBaseAddr, &errCounter);
            DebugP_assert((0U == errCounter.recErrCnt) &&
                          (0U == errCounter.canErrLogCnt));
    
            /* Get the new data staus, indicates buffer num which received message */
            MCAN_getNewDataStatus(gMcanRxBaseAddr, &newDataStatus);
            MCAN_clearNewDataStatus(gMcanRxBaseAddr, &newDataStatus);
    
            /* Select buffer and fifo number, Buffer is used in this app */
            bufNum = 0U;
            fifoNum = MCAN_RX_FIFO_NUM_0;
    
            bitPos = (1U << bufNum);
            if (bitPos == (newDataStatus.statusLow & bitPos))
            {
                MCAN_readMsgRam(gMcanRxBaseAddr, MCAN_MEM_TYPE_BUF, bufNum, fifoNum, &rxMsg);
            }
            else
            {
                DebugP_assert(FALSE);
            }
    
            /* Compare Tx/Rx data */
            App_mcanCompareMsg(&rxMsg);
        }
    
        /* De-Construct Rx Semaphore objects */
        HwiP_destruct(&gMcanRxHwiObject);
        SemaphoreP_destruct(&gMcanRxDoneSem);
    
        /* Wait for mcan tx application to be ready */
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
        DebugP_log("All tests have passed!!\r\n");
    
        Board_driversClose();
        /* We don't close drivers so that the UART driver remains open and flush any
         * pending messages to console */
        /* Drivers_close(); */
    
        return;
    }
    
    static void App_mcanConfig(void)
    {
        MCAN_StdMsgIDFilterElement stdFiltElem[APP_MCAN_STD_ID_FILTER_CNT] = {0U};
        MCAN_InitParams            initParams = {0U};
        MCAN_ConfigParams          configParams = {0U};
        MCAN_MsgRAMConfigParams    msgRAMConfigParams = {0U};
        MCAN_BitTimingParams       bitTimes = {0U};
        uint32_t                   i;
    
        /* Initialize MCAN module initParams */
        MCAN_initOperModeParams(&initParams);
        /* CAN FD Mode and Bit Rate Switch Enabled */
        initParams.fdMode          = TRUE;
        initParams.brsEnable       = TRUE;
    
        /* Initialize MCAN module Global Filter Params */
        MCAN_initGlobalFilterConfigParams(&configParams);
    
        /* Initialize MCAN module Bit Time Params */
        /* Configuring default 1Mbps and 5Mbps as nominal and data bit-rate resp */
        MCAN_initSetBitTimeParams(&bitTimes);
    
        /* Initialize MCAN module Message Ram Params */
        App_mcanInitMsgRamConfigParams(&msgRAMConfigParams);
    
        /* This data initialized here should be same as what TX application sends */
        App_mcanInitExpectedRxData();
    
        /* Initialize Filter element to receive msg, should be same as tx msg id */
        for (i = 0U; i < APP_MCAN_STD_ID_FILTER_CNT; i++)
        {
            App_mcanInitStdFilterElemParams(&stdFiltElem[i], i);
        }
    
        /* wait for memory initialization to happen */
        while (FALSE == MCAN_isMemInitDone(gMcanRxBaseAddr))
        {}
    
        /* Put MCAN in SW initialization mode */
        MCAN_setOpMode(gMcanRxBaseAddr, MCAN_OPERATION_MODE_SW_INIT);
        while (MCAN_OPERATION_MODE_SW_INIT != MCAN_getOpMode(gMcanRxBaseAddr))
        {}
    
        /* Initialize MCAN module */
        MCAN_init(gMcanRxBaseAddr, &initParams);
        /* Configure MCAN module Gloabal Filter */
        MCAN_config(gMcanRxBaseAddr, &configParams);
        /* Configure Bit timings */
        MCAN_setBitTime(gMcanRxBaseAddr, &bitTimes);
        /* Configure Message RAM Sections */
        MCAN_msgRAMConfig(gMcanRxBaseAddr, &msgRAMConfigParams);
        /* Set Extended ID Mask */
        MCAN_setExtIDAndMask(gMcanRxBaseAddr, APP_MCAN_EXT_ID_MASK);
    
        /* Configure Standard ID filter element */
        for (i = 0U; i < APP_MCAN_STD_ID_FILTER_CNT; i++)
        {
            MCAN_addStdMsgIDFilter(gMcanRxBaseAddr, i, &stdFiltElem[i]);
        }
    
        /* Take MCAN out of the SW initialization mode */
        MCAN_setOpMode(gMcanRxBaseAddr, MCAN_OPERATION_MODE_NORMAL);
        while (MCAN_OPERATION_MODE_NORMAL != MCAN_getOpMode(gMcanRxBaseAddr))
        {}
    
        return;
    }
    
    static void App_mcanInitStdFilterElemParams(MCAN_StdMsgIDFilterElement *stdFiltElem,
                                                uint32_t bufNum)
    {
        /* sfid1 defines the ID of the standard message to be stored. */
        stdFiltElem->sfid1 = APP_MCAN_STD_ID;
        /* As buffer mode is selected, sfid2 should be bufNum[0 - 63] */
        stdFiltElem->sfid2 = bufNum;
        /* Store message in buffer */
        stdFiltElem->sfec  = MCAN_STD_FILT_ELEM_BUFFER;
        /* Below configuration is ignored if message is stored in buffer */
        stdFiltElem->sft   = MCAN_STD_FILT_TYPE_RANGE;
    
        return;
    }
    
    static void App_mcanEnableIntr(void)
    {
        MCAN_enableIntr(gMcanRxBaseAddr, MCAN_INTR_MASK_ALL, (uint32_t)TRUE);
        MCAN_enableIntr(gMcanRxBaseAddr,
                        MCAN_INTR_SRC_RES_ADDR_ACCESS, (uint32_t)FALSE);
        /* Select Interrupt Line 0 */
        MCAN_selectIntrLine(gMcanRxBaseAddr, MCAN_INTR_MASK_ALL, MCAN_INTR_LINE_NUM_0);
        /* Enable Interrupt Line */
        MCAN_enableIntrLine(gMcanRxBaseAddr, MCAN_INTR_LINE_NUM_0, (uint32_t)TRUE);
    
        return;
    }
    
    static void App_mcanInitMsgRamConfigParams(MCAN_MsgRAMConfigParams
                                               *msgRAMConfigParams)
    {
        int32_t status;
    
        MCAN_initMsgRamConfigParams(msgRAMConfigParams);
    
        /* Configure the user required msg ram params */
        msgRAMConfigParams->lss = APP_MCAN_STD_ID_FILTER_CNT;
        msgRAMConfigParams->lse = APP_MCAN_EXT_ID_FILTER_CNT;
        msgRAMConfigParams->txBufCnt = APP_MCAN_TX_BUFF_CNT;
        msgRAMConfigParams->txFIFOCnt = APP_MCAN_TX_FIFO_CNT;
        /* Buffer/FIFO mode is selected */
        msgRAMConfigParams->txBufMode = MCAN_TX_MEM_TYPE_BUF;
        msgRAMConfigParams->txEventFIFOCnt = APP_MCAN_TX_EVENT_FIFO_CNT;
        msgRAMConfigParams->rxFIFO0Cnt = APP_MCAN_FIFO_0_CNT;
        msgRAMConfigParams->rxFIFO1Cnt = APP_MCAN_FIFO_1_CNT;
        /* FIFO blocking mode is selected */
        msgRAMConfigParams->rxFIFO0OpMode = MCAN_RX_FIFO_OPERATION_MODE_BLOCKING;
        msgRAMConfigParams->rxFIFO1OpMode = MCAN_RX_FIFO_OPERATION_MODE_BLOCKING;
    
        status = MCAN_calcMsgRamParamsStartAddr(msgRAMConfigParams);
        DebugP_assert(status == CSL_PASS);
    
        return;
    }
    
    static void App_mcanCompareMsg(MCAN_RxBufElement *rxMsg)
    {
        uint32_t i;
    
        if (APP_MCAN_STD_ID == ((rxMsg->id >> APP_MCAN_STD_ID_SHIFT) & APP_MCAN_STD_ID_MASK))
        {
            for (i = 0U; i < gMcanRxDataSize[MCAN_DATA_SIZE_64BYTES]; i++)
            {
                if (gMcanRxRecvdData[i] != rxMsg->data[i])
                {
                    DebugP_logError("Data mismatch !!!\r\n");
                    DebugP_assert(FALSE);
                }
            }
        }
        else
        {
            DebugP_logError("Message ID mismatch !!!\r\n");
            DebugP_assert(FALSE);
        }
    
        return;
    }
    
    /* Data initializated here should be same as TX application */
    static void App_mcanInitExpectedRxData(void)
    {
        uint32_t i;
    
        for (i = 0U; i < gMcanRxDataSize[MCAN_DATA_SIZE_64BYTES]; i++)
        {
            gMcanRxRecvdData[i] = i;
        }
    }
    
    static void App_mcanIntrISR(void *arg)
    {
        uint32_t intrStatus;
    
        intrStatus = MCAN_getIntrStatus(gMcanRxBaseAddr);
        MCAN_clearIntrStatus(gMcanRxBaseAddr, intrStatus);
    
        /* If FIFO0/FIFO1 is used, then MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG macro
         * needs to be replaced by MCAN_INTR_SRC_RX_FIFO0_NEW_MSG/
         * MCAN_INTR_SRC_RX_FIFO1_NEW_MSG respectively */
        if (MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG ==
            (intrStatus & MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG))
        {
            SemaphoreP_post(&gMcanRxDoneSem);
        }
    
        return;
    }
    

  • Hi Elbon,

    This example has a separate Tx and Rx application:

    You are loading the Rx side of the application on core r5f0-0 and observing the corresponding logs, but you are not loading the Tx application which is supposed to be loaded on r5f0-1, that means that there is no data transmitted to MCAN0 hence the test doesn't complete and gets stuck waiting for the data from MCAN1. In the debugger you need to load the binary from both r5fss0-0_freertos and r5fss0-1_nortos on r5f0-0 and r5f0-1 respectively and run both the cores, in that case you will able to run this example. Please also note that you need to connect MCAN0 and MCAN1 externally for this example to work, please refer to this: https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/11_00_00_15/exports/docs/api_guide_am64x/EXAMPLES_DRIVERS_MCAN_EXTERNAL_LOOPBACK_INTERRUPT.html

    I followed these steps and was able to get the expected results:

    Best Regards,

    Meet.

  • Hello ,

    I imported the project 'system_freertos_nortos', which contains two project files: 'r5fss0-1_nortos' and 'r5fss0-0_freertos'. I am loading the binaries from both r5fss0-0_freertos and r5fss0-1_nortos onto r5f0-0 and r5f0-1, respectively. However, I am not seeing any output in the console, as shown in the screenshots below.

  • Hi Elbon,

    Could you confirm if you have made external connections from MCAN0 to MCAN1?

    However, I am not seeing any output in the console, as shown in the screenshots below.

    Do you see any logs in the UART terminal?

    If the proper connections are made, then you should be able to see the logs in the UART terminal which I attached in my previous response, this is working at my end. 

    Best Regards,

    Meet.

  • Hi meet ,

    hope you're doing well.

    As I've mentioned, the current setup isn't working for me. I want to use CAN to receive data from the A53 core and send data using IPC RPMsg from R5 core . Could you please suggest a solution for my setup?

    Currently, I’m testing the example mcan_external_loopback_interrupt_am64x, intending to integrate IPC RPMsg code. However, the example mcan_external_loopback_interrupt_am64x does not work for me.

    If you have any other suggestions to improve my work, I’m open to hearing them.

    Best regards,

    Elbon.

  • Hi Elbon,

    The CCS logs for this application are disabled by default hence you are not observing any logs in CCS. For this reason I suggested to connect the UART terminal and check if you get any logs there. You can enable the CCS log for both r5f0-0 and r5f0-1 from syscfg:

    I am getting the logs in CCS as well after making this change in both examples:

    Best Regards,

    Meet.

  • Hi meet,

    "I have enabled the CCS log as shown in the screens for both the r5f0-0 and the r5f0-1, but I always encounter the same problem: I can't see any logs when I resume the debug.

    I just see this :

    And this is a screen for my project architecture :

    If you have any solution !

    Best Regards,

    Elbon.

  • Hi Elbon,

    If you pause the execution in the debugger, do you see if the program is stuck on a particular instruction or a particular error? Could you try stepping through the code and identify the issue. 

    I still doubt that there is actually any problem with the program itself, as you can see from my responses, I am getting the logs in both UART terminal and CCS console. 

    Could you confirm if you rebuilt both the applications after enabling CCS logs? Please check once with the UART terminal, if you see any logs and attach the same on this thread, you can refer to this link on how you can check the logs on UART terminal: AM64x MCU+ SDK: EVM Setup

    Best Regards,

    Meet.

  • This is the output in uart mode :

  • When I debug the code step by step, it reaches the line vTaskStartScheduler(); where the code halts and stops execution.

  • This is the output in uart mode :

    Are you loading the application from linux or CCS? If the linux and the MCAN example use same UART then you might not be able to see the logs.

    it reaches the line vTaskStartScheduler(); where the code halts and stops execution.

    The execution doesn't stop here, from in the debug window it shows that R5_0_0 is running, so I don't think there is any issue with the application. The debugger is not stopping anywhere as you have not set any breakpoints. Another way of verifying whether the application is working properly is to set a breakpoint here in the mcan_rx_only_interrupt.c file:

    and for the Tx application on r5f0-1 you can set the breakpoint in mcan_tx_only_interrupt.c here:

    If the debugger stops at these instruction then you can verify that the application is working properly and you are just not able to see the logs for some reason.

    Please note that both of these application needs to be running for you to be able to reach here.

    Best Regards,

    Meet.

  • Hi meet,

    Look, I set a breakpoint in mcan_tx_only_interrupt.c and mcan_rx_only_interrupt.c, as you suggested. However, the debugger doesn't enter the code. It stops in main.c at the line vTaskStartScheduler();, as shown in the screen.

    Best Regards,

    Elbon.

  • Please note that both of these application needs to be running for you to be able to reach here.

    From the debugger window it seems that you have not loaded the r5f0-1 application this time, you need to load and run both for application to move forward.

    If you pause the execution could you see at which instruction the program is currently at? I guess it will be at following instruction in mcan_rx_only_interrupt.c, waiting for the Tx data as the Tx application on r5f0-1 is not running:

  • Yes , I think that the debugger stop at this lines :

  • Hi meet ,

    I'm trying another project: the 'mcan_external_read_write' example! However, as you can see, the debugger stops at this line:

  • Yes , I think that the debugger stop at this lines :

    Could you run the r5f0-1 as well and check, the Rx application on r5f0-0 is stuck here as it is waiting to receive messages from r5f0-1 application.

    Please also confirm the external connections are properly done as described here: software-dl.ti.com/.../EXAMPLES_DRIVERS_MCAN_EXTERNAL_LOOPBACK_INTERRUPT.html

  • This is how the flow should be: