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.

AM62A7-Q1: How to Configure MCAN to Receive Extended Frame

Part Number: AM62A7-Q1

Hi TI Experts,

Customer is working on AM62A SDK9.1.

Now they can use MCU MCAN to receive & transmit standard frame successfully.

However, they could not receive extended frame.

Their purpose is to allow MCU MCAN receive & transmit standard & extended frame at the same time.

The rxFIFO shows there is no extended frame received.

The txFIFO shows transmitting extended frame is okay.

In summary, there is no problem for customer to transmit standard frame & extended frame. There is no problem for customer to receive standard frame.

However, they just could not receive the extended frame.

Hence, may I know is there any guide or suggested configurations to receive the extended frame?

Thanks a lot,

Kevin

  • Hello Kevin,

    Is the customer using MCU+ SDK RTOS example or the Linux Processor SDK?

    Now they can use MCU MCAN to receive & transmit standard frame successfully.

    Could you also help me with more information regarding the hardware setup being used by the customer? Internal loopback or external loopback?

    Regards,
    Aparna

  • Hi Kevin,

    Please share your code.

    Regards,

    Veerapandiyan V

  • Hi TI Experts,

    We are using MCU+ SDK RTOS.

    The InintFunction is following:

    void CanDpl_InitFunction(void)
    {
        CanDpl_mcanInitMsgDataBufferInfo();

        for (size_t i = 0; i < CONFIG_MCAN_NUM_INSTANCES; i++)
        {
            uint8_t                    status = 0x00;
            MCAN_InitParams            initParams = {0U};
            MCAN_ConfigParams          configParams = {0U};
            MCAN_MsgRAMConfigParams    msgRAMConfigParams = {0U};
            MCAN_BitTimingParams       bitTimes = {0U};

            /* Assign MCAN Tx and Rx Data Buffer */
            status = CanDpl_mcanInitTxMsgDataBuffer(i);
            DebugP_assert(status == CSL_PASS);
            status = CanDpl_mcanInitRxMsgDataBuffer(i);
            DebugP_assert(status == CSL_PASS);

            /* Assign MCAN instance address */
            CanDpl_mcanStatusInfo[i].mcanRegisterBaseAddr = (uint32_t) AddrTranslateP_getLocalAddr(CanDpl_mcanCfgInfo[i].mcanBaseAddr);

            /* get the default value for InitParams:  */
            MCAN_initOperModeParams(&initParams);
            /* according the user configuration,update the InitParams */
            CanDpl_mcanInitCanModuleModeParams(i, &initParams);
            CanDpl_mcanInitBrsEnableParams(i, &initParams);
            /* get the default value for ConfigParams */
            MCAN_initGlobalFilterConfigParams(&configParams);
            /* get the bit timing params */
            CanDpl_mcanInitBitTimingParams(i, &bitTimes);
            /* get the message ram default value for msgRAMConfigParams */
            MCAN_initMsgRamConfigParams(&msgRAMConfigParams);

            /* update message ram configuration parameters */
            CanDpl_mcanInitMsgRamConfigParams(i, &msgRAMConfigParams);
            /* calc msg ram params */
            status = MCAN_calcMsgRamParamsStartAddr(&msgRAMConfigParams);
            DebugP_assert(status == CSL_PASS);

            /* MCAN Rx Filter Element Configuration parameters */
            CanDpl_mcanInitRxMsgFilterParams(i);

            /* wait for memory initialization to happen */
            while (FALSE == MCAN_isMemInitDone(CanDpl_mcanStatusInfo[i].mcanRegisterBaseAddr))
            {
                // TODO : SHALL BE IMPLEMENT TIMEOUT STRATEGY
            }

            DebugP_log("[CanDpl] MCAN Chanel : %d  has been MemInit Done and the register base address is 0x%lx\r\n",i,CanDpl_mcanStatusInfo[i].mcanRegisterBaseAddr);
       
                /* Put MCAN in SW initialization mode */
            MCAN_setOpMode(CanDpl_mcanStatusInfo[i].mcanRegisterBaseAddr, MCAN_OPERATION_MODE_SW_INIT);
            while (MCAN_OPERATION_MODE_SW_INIT != MCAN_getOpMode(CanDpl_mcanStatusInfo[i].mcanRegisterBaseAddr))
            {
                // TODO : SHALL BE IMPLEMENT TIMEOUT STRATEGY
            }

            DebugP_log("[CanDpl] MCAN Chanel : %d  has been setting opMode to MCAN_OPERATION_MODE_SW_INIT Done\r\n",i);

            /* Initialize MCAN module */
            MCAN_init(CanDpl_mcanStatusInfo[i].mcanRegisterBaseAddr, &initParams);
            /* Configure MCAN module Gloabal Filter */
            MCAN_config(CanDpl_mcanStatusInfo[i].mcanRegisterBaseAddr, &configParams);
            /* Configure Bit timings */
            MCAN_setBitTime(CanDpl_mcanStatusInfo[i].mcanRegisterBaseAddr, &bitTimes);
            /* Configure Message RAM Sections */
            MCAN_msgRAMConfig(CanDpl_mcanStatusInfo[i].mcanRegisterBaseAddr, &msgRAMConfigParams);

            /* Configure Standard ID filter element */
            CanDpl_mcanAddRxRxMsgFilterParamsRequest(i);

            // MCAN_lpbkModeEnable(CanDpl_mcanStatusInfo[i].mcanRegisterBaseAddr, MCAN_LPBK_MODE_INTERNAL, TRUE);

            /* Take MCAN out of the SW initialization mode */
            MCAN_setOpMode(CanDpl_mcanStatusInfo[i].mcanRegisterBaseAddr, MCAN_OPERATION_MODE_NORMAL);
            while (MCAN_OPERATION_MODE_NORMAL != MCAN_getOpMode(CanDpl_mcanStatusInfo[i].mcanRegisterBaseAddr))
            {
                // TODO : SHALL BE IMPLEMENT TIMEOUT STRATEGY
            }

            DebugP_log("[CanDpl] MCAN Chanel : %d  has been setting opMode to MCAN_OPERATION_MODE_NORMAL Done\r\n",i);
        }
        CanDpl_InitState = CANDPL_INIT_STATE_INITED;
        DebugP_log("[CanDpl] Init Function Perform Finished\r\n");
    }
    and the Rx Process function floowing :
    static uint8_t CanDpl_mcanRxProcess(uint8_t index)
    {
        uint8_t                 ret = 0x00;
        MCAN_RxFIFOStatus       fifoStatus;
        MCAN_ErrCntStatus       errCounter;
        MCAN_RxBufElement       rxBuff;

        /* Poll for Rx Process */
        if ( CANDPL_MCAN_PROCESS_MODE_POLLING == CanDpl_mcanCfgInfo[index].mcanRxProcessMode)
        {
            /* Get the FIFO0 Msg */
            if (0x00 != CanDpl_mcanStatusInfo[index].mcanRxFifo0MsgNum)
            {
                fifoStatus.num = MCAN_RX_FIFO_NUM_0;
                MCAN_getRxFIFOStatus(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, &fifoStatus);
                for (size_t i = 0; i < fifoStatus.fillLvl; i++)
                {
                    MCAN_getErrCounters(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, &errCounter);
                    DebugP_assert((0U == errCounter.recErrCnt) &&  (0U == errCounter.canErrLogCnt));

                    MCAN_getRxFIFOStatus(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, &fifoStatus);
                    MCAN_readMsgRam(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, MCAN_MEM_TYPE_FIFO, fifoStatus.getIdx, fifoStatus.num, &rxBuff);
                    // DebugP_log("[CanDpl] mcan Polling RxMsg : MCAN_readMsgRam Done.. Channel is %d, FIFO Index is %d, RxBuffId is 0x%x\r\n",index, i, rxBuff.id);

                    (void) MCAN_writeRxFIFOAck(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, fifoStatus.num, fifoStatus.getIdx);

                    //Load the rxMsg to RxMsg Buffer
                    CanDpl_mcanUnpackRxMsgParams(index, rxBuff);
                }
            }
            else
            {
                /* Doing Nothing */
            }

            /* Get the FIFO1 Msg */
            if (0x00 != CanDpl_mcanStatusInfo[index].mcanRxFifo1MsgNum)
            {
                fifoStatus.num = MCAN_RX_FIFO_NUM_1;
                MCAN_getRxFIFOStatus(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, &fifoStatus);

                for (size_t i = 0; i < fifoStatus.fillLvl; i++)
                {
                    MCAN_getErrCounters(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, &errCounter);
                    DebugP_assert((0U == errCounter.recErrCnt) &&  (0U == errCounter.canErrLogCnt));

                    MCAN_getRxFIFOStatus(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, &fifoStatus);
                    MCAN_readMsgRam(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, MCAN_MEM_TYPE_FIFO, fifoStatus.getIdx, fifoStatus.num, &rxBuff);
                    // DebugP_log("[CanDpl] mcan Polling RxMsg : MCAN_readMsgRam Done.. Channel is %d, FIFO Index is %d, RxMsgId is 0x%x\r\n",index, i, rxBuff.id);

                    (void) MCAN_writeRxFIFOAck(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, fifoStatus.num, fifoStatus.getIdx);

                    //Load the rxMsg to RxMsg Buffer
                    CanDpl_mcanUnpackRxMsgParams(index, rxBuff);
                }
            }
            else
            {
                /* Doing Nothing */
            }
           
        }
        return ret;
    }
    Thanks,
    Tom
  • Hello Tom,

    I could notice from the above shared code that you are not using the MCAN APIs from MCU+ SDK. It is hard to understand the use of custom APIs without their code.

    For instance: CanDpl_mcanAddRxRxMsgFilterParamsRequest(i); should be assigning the standard ID filter element. Can you disable this API or assign the extended ID filter element?

    Regards,
    Aparna

  • Hi Aparma

    I implemented function CanDpl_mcanAddRxMsgFilterParamsRequest has been use the MCAN APIs.

    refer following code,initMsgFilter and RxMsgFilterRequest

    static uint8_t CanDpl_mcanInitRxMsgFilterParams(uint8_t index)
    {
        uint8_t ret = 0x00;
        uint8_t rxMsgCnt = 0x00;

        for (size_t i = 0; i < CanDpl_mcanCfgInfo[index].mcanRxStdMsgNum; i++)
        {
            rxMsgCnt++;
            if (rxMsgCnt <= 64)  
            {
                CanDpl_mcanCfgInfo[index].mcanRxStdIdFilter[i].sfec = MCAN_STD_FILT_ELEM_FIFO0;
            }
            else if ( (rxMsgCnt > 64) && (rxMsgCnt <= 128) )
            {
                CanDpl_mcanCfgInfo[index].mcanRxStdIdFilter[i].sfec = MCAN_STD_FILT_ELEM_FIFO1;
            }
            else
            {
                ret = 0x01;
                break;
            }
            CanDpl_mcanCfgInfo[index].mcanRxStdIdFilter[i].sft = MCAN_STD_FILT_TYPE_CLASSIC;
            CanDpl_mcanCfgInfo[index].mcanRxStdIdFilter[i].sfid1 = CanDpl_mcanCfgInfo[index].mcanRxStdMsgCfgStatusInfoTab[i].frameId & 0x7FFU;
            CanDpl_mcanCfgInfo[index].mcanRxStdIdFilter[i].sfid2 = 0xFFFFFFFFU;
        }

        for (size_t i = 0; i < CanDpl_mcanCfgInfo[index].mcanRxExtMsgNum; i++)
        {
            rxMsgCnt++;
            if (rxMsgCnt <= 64)  
            {
                CanDpl_mcanCfgInfo[index].mcanRxExtIdFilter[i].efec = MCAN_STD_FILT_ELEM_FIFO0;
            }
            else if ( (rxMsgCnt > 64) && (rxMsgCnt <= 128) )
            {
                CanDpl_mcanCfgInfo[index].mcanRxExtIdFilter[i].efec = MCAN_STD_FILT_ELEM_FIFO1;
            }
            else
            {
                ret = 0x01;
                break;
            }        
            CanDpl_mcanCfgInfo[index].mcanRxExtIdFilter[i].eft = MCAN_STD_FILT_TYPE_CLASSIC;
            CanDpl_mcanCfgInfo[index].mcanRxExtIdFilter[i].efid1 = CanDpl_mcanCfgInfo[index].mcanRxExtMsgCfgStatusInfoTab[i].frameId & 0x1FFFFFFFU;
            CanDpl_mcanCfgInfo[index].mcanRxExtIdFilter[i].efid2 = 0x1FFFFFFFU;
        }

        return ret;
    }
    and the function of 
    static uint8_t CanDpl_mcanAddRxRxMsgFilterParamsRequest(uint8_t index)
    {
        uint8_t ret = 0x00;
        uint8_t rxMsgCnt = 0x00;

        for (size_t i = 0; i < CanDpl_mcanCfgInfo[index].mcanRxStdMsgNum; i++)
        {
            rxMsgCnt++;
            if (rxMsgCnt <= 64)  
            {
                MCAN_addStdMsgIDFilter(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, (rxMsgCnt-1), &CanDpl_mcanCfgInfo[index].mcanRxStdIdFilter[i]);
            }
            else if ( (rxMsgCnt > 64) && (rxMsgCnt <= 128) )
            {
                MCAN_addStdMsgIDFilter(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, (rxMsgCnt-65), &CanDpl_mcanCfgInfo[index].mcanRxStdIdFilter[i]);
            }
            else
            {
                ret = 0x01;
                break;
            }            
        }

        /* Set Extended ID Mask */
        MCAN_setExtIDAndMask(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, 0x1FFFFFFFU);
        for (size_t i = 0; i < CanDpl_mcanCfgInfo[index].mcanRxExtMsgNum; i++)
        {
            rxMsgCnt++;
            if (rxMsgCnt <= 64)  
            {
                MCAN_addExtMsgIDFilter(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, (rxMsgCnt-1), &CanDpl_mcanCfgInfo[index].mcanRxExtIdFilter[i]);
            }
            else if ( (rxMsgCnt > 64) && (rxMsgCnt <= 128) )
            {
                MCAN_addExtMsgIDFilter(CanDpl_mcanStatusInfo[index].mcanRegisterBaseAddr, (rxMsgCnt-65), &CanDpl_mcanCfgInfo[index].mcanRxExtIdFilter[i]);
            }
            else
            {
                ret = 0x01;
                break;
            }        
        }

        return ret;
    }
    and the configuration params following:
  • Hi Tom,

    Could you set the following to disable the filter element and try again:

    Fullscreen
    1
    2
    #define MCAN_STD_FILT_TYPE_DISABLE (3U)
    CanDpl_mcanCfgInfo[index].mcanRxExtIdFilter[i].eft = MCAN_STD_FILT_TYPE_DISABLE;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Regards,
    Aparna

  • Hi Aparna

    I try for disable of eft,but is not received ext message also

    BR

    Tom

  • Hi Tom, have you tried using the TI example code?

    Could you help me with the hardware connections:
    What is the transceiver being used?
    Which MCU MCAN instance is being used?
    Is this an external loopback setup or you are using an additional CAN tool?

    Regards,
    Aparna

  • The transceiver is Tja1043 and the MCU MCAN instance is MCU_MCAN0

  • Could you explain the data flow?

  • Hello Tom,

    I was able to send and receive data both extended and standard frames, by using the MCAN polling example in sdk. Please use it and you may add further modifications as required.

    Regards,
    Aparna