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.

IWR6843AOP: CAN-FD interface implementation issues

Part Number: IWR6843AOP
Other Parts Discussed in Thread: AWR1642, , MMWAVEICBOOST

Hi, 

Following the previous discussion regarding UART to CAN-FD migration, I'm opening this thread to hopefully resolve issues during code compilation. I tried to follow the recommendations mentioned in the discussion; however, I find these not sufficient.

To recall, I started modifing the OOB demo for IWR6843AOP according to Data Over CAN provided only for the AWR1642 platform in order to use the CAN-FD interface for data transmission. Up to now, I'm able to compile modified code, including CAN interface initialization. Now, I'm trying to identify what is necessary to implement in order to send data over a CAN interface. Several questions have emerged:

 

1. OOB and Data Over CAN differ in their usage of MBOX. Is it necessary to implement MBOX in OOB? OOB sends data over UART through MmwDemo_transmitProcessedOutput and UART_writePolling, Data over CAN using MmwDemo_mboxReadTask and Can_Transmit_Schedule. I wonder if replacing UART_writePolling with Can_Transmit_Schedule would be sufficient.

 

Thank you,

Adam

  • Hi Adam,

    Sorry for the delay here. We are looking into your query and will get back to you soon.

    Best Regards,

    Josh

  • Hey Adam,

    You should not need to use the mailbox for the OOB demo. The mailbox is used to communicate with the C674x DSP and is used almost exclusively to send unprocessed data to the DSP to be processed and sent back. Some of the older projects, such as the Data over CAN demo and other AWR1642 demos, directly called the mailbox API to retrieve detected objects and other data points from the DSP. For the OOB demo and other newer projects, this is all handled through the DPM_execute function and other DPM functions. 

    If you've followed the app note on integrating CAN to a project, you can replace the UART_writePolling functions with Can_Transmit_Schedule functions. However, you will have to keep in mind what exactly you are trying to send over CAN. If you go about replacing the functions as is, you will be outputting TLV data which works for UART, but you might want to pack the data in a different way for CAN. If that is your intention, you will also need to set the message ID which you can reuse the Get_CanMessageIdentifier from the Data Over CAN demo to create message IDs; remember to also copy over the MmwDemo_output_message_type typedef enumeration.

    Let me know if you have any other questions.

    Regards,

    Kristien

    EDIT: The mailbox read task should not need to be used for the OOB demo, but the mailbox still needs to be initialized to for the demos to work, even for newer projects. The mailbox is also leveraged by the mmWaveLink framework to communicate with the radar front-end from the application.

  • Hi Kristien,

    I removed mailbox, build image successfully. However, communication over CAN still not working. 

    1) Regarding TLV data, I do not really understand what you mean by packing the data in a different way. I use a part of code from ODOC:

            txMsgObjectParams.msgIdentifier = Get_CanMessageIdentifier((MmwDemo_output_message_type)&tl[tlvIdx].type);
            Can_Transmit_Schedule(txMsgObjectParams.msgIdentifier,
                                  (uint8_t *)&tl[tlvIdx],
                                  sizeof(MmwDemo_output_message_tl));

    Is there something I need to pack differently?

    2) As my build is based on OOB, I assume it is waiting to configure and start sensor. Then it should send data. Is there any reference doc how to configure and start sensor over CAN? Or should I implement Hard Coded Config instead?

    Thank you,

    Adam

  • ad 2) I followed step described in radar_toolbox_1_20_00_11/source/ti/examples/Fundamentals/Hard_Coded_Config/docs/hard_coded_config_user_guide.html, specifically Method A.2 - I should be able to use HCC to ensure starting the sensor. Later, I would like to modify UART part to CAN-FD in order to send config file over CAN. I added those two files (cli_mmwave.c and cli.c) and remove those in File Search Path. There is also file mmw_cli.c which comes from original OOB demo. I'm not sure if hard coded config part is properly called. Still do not see any output on CAN-FD. 

  • I used image creator to get binary file using xer4f for MSS (modified in order to implement CAN-FD) and original OOB xe674 file for DSS. Creation passed off without error. Hopefully this is correct process. 

    No data on CAN interface. Not sure sensor is running (now using HCC).

    Even if I enable UART configuration, I'm not able to connect to device using mmwave visualizer.

    Is it possible to share my modified code to check whether there is everything ok.

    Thank you.

  • Hey Adam,

    I'll go over each of your questions/replies individually.

    1. Sorry for the confusion on this point for TLVs. The code used in the ODOC demo is enough to pack the data into a TLV format. I was not sure whether or not you wanted to pack data into TLVs or wanted to use a different communication format. We've had customers in the past that use CAN to transmit raw ADC data or error messages, so I wanted to highlight that you are free to send other data formats as well.
    2. We don't have any documentation on sending configs over CAN. While it is possible to send a config over CAN, using the HCC method is generally faster and simpler to setup. 
    3. If you are using CCS to build your project, you should not need to directly call the image creator tools to generate the flashable binary files as the files should be automatically generated from the makefile when building a project. If you would like to verify if the sensor is running, you can connect to the device's Enhanced COM Port using TeraTerm or the CCS terminal - baud rate set to 115200 - before resetting the device to see if the CLI commands are being sent to the device. You can also check the to see if TLV data is being sent using the Standard COM Port - baud rate set to 921600.

    If you are still having problems sending CAN data, there are a few things you can check. First, for IWR6843AOP, S2.1 needs to be set to ON to select the CAN bus for output - CAN0 is J8 and CAN1 is J10. If you are using the MMWAVEICBOOST, you need to flip S1.1 ON to use the CAN buses on the ICBOOST board separately from the AOP board. The topmost screw terminal - closest to CAN_FD indicator LED - is CAN0 and the bottom is CAN1. Second, I would add a conditional statement inside the Can_Transmit_Schedule function to check for an error after any CANFD_transmitData and print out the error code. Error codes are documented near the top of the canfd.h file and are offset by 3500 - e.g., error code 3502 corresponds to CANFD_EINUSE.

    if (retVal < 0)
    {
    System_printf ("Error: CANFD instance 0 transmit data retry failed [Error code %d]\n", errCode); // if using ICBOOST
    CLI_write("Error: CANFD instance 0 transmit data retry failed [Error code %d]\n", errCode);
    }

    You may share your modified code, but I would recommend only sharing your CAN initialization function, any functions that call CAN transmit functions, and any other functions or code snippets that may be relevant to your CAN implementation.

    Regards,

    Kristien

  • Hi Kristien,

    thank you for these answers. It seems I'm stucked in CLI initialization, I'm not able to see any output using Tera Term as you descibed above. 

    I think I have implemented all necessary parts, however, it seems there is some problem opening CLI communication. I tried both HCC and configuration over UART. 

    Note:

    - EVM works using OOB you provided in SDK (uart communication) - tested using mmwave visualizer as well as custom code

    - user led on EVM not turns on when using modified code (sensor does not start) - it turns on using OOB from SDK 

    Do you have any suggestions? 

    Thank you,

    Adam

  • Hey Adam,

    Are you still running the mmWave visualizer in the background when attempting to run your program with HCC? If so, close out of it. When building the project, do you see the compiler building the cli.c file added into your project? If not, verify that you have removed the CLI library from the search path under the linker file search path. Have you made any modifications to the MmwDemo_initTask, particularly the UART initializations? You should have only needed to add the Can_Initialize function. If you aren't able to determine what could be causing this issue, it may be best for you to share your MmwDemo_initTask function and everything you've added to incorporate HCC.

    Regards,

    Kristien

  • Hi Kristien,

    mmWave visualizer is not running in the background, I just tried it to ensure EVM is working correctly using OOB from SDK. Both cli.c and cli_mmwave.c is compiled during build and I verified that I removed CLI lib from the path. In order to use HCC, I copied cli_mmwave.c and hcc_cli.c to the project folder and rename hcc_cli.c to cli.c. 

    Strange thing is that I do not see anything on cli even if I write a message just after MmwDemo_CLIInit(MMWDEMO_CLI_TASK_PRIORITY); call. 

    Do I understand correct that IWR6843AOP, S2.1 ON is not affecting UART CLI functionality?

    Unfortunately, I do not have debug probe to be able to see where is a problem.

    Attaching MmwDemo_initTask, started from main() as gMmwMCB.taskHandles.initTask = Task_create(MmwDemo_initTask, &taskParams, NULL); 

    Thank you for you help,

    Adam

    void MmwDemo_initTask(UArg arg0, UArg arg1)
    {
        int32_t             errCode;
        MMWave_InitCfg      initCfg;
        UART_Params         uartParams;
        Task_Params         taskParams;
        Semaphore_Params    semParams;
        DPM_InitCfg         dpmInitCfg;
        DPC_ObjectDetection_InitParams      objDetInitParams;
        uint32_t            edmaCCIdx;
        int32_t             i;
        //int32_t             retVal;
    
        /* Debug Message: */
        System_printf("Debug: Launched the Initialization Task\n");
    
        /*****************************************************************************
         * Initialize the mmWave SDK components:
         *****************************************************************************/
    
        /* Init CAN */
        Can_Initialize();
    
        /* Initialize the UART */
        UART_init();
    
        /* Initialize the GPIO */
        GPIO_init();
    
        /* Platform specific configuration */
        MmwDemo_platformInit(&gMmwMCB.cfg.platformCfg);
    
        /* Initialize the Data Path: */
        MmwDemo_dataPathInit(&gMmwMCB.dataPathObj);
    
        /* Setup the default UART Parameters */
        UART_Params_init(&uartParams);
        uartParams.clockFrequency = gMmwMCB.cfg.platformCfg.sysClockFrequency;
        uartParams.baudRate       = gMmwMCB.cfg.platformCfg.commandBaudRate;
        uartParams.isPinMuxDone   = 1;
    
        /* Open the UART Instance */
        gMmwMCB.commandUartHandle = UART_open(0, &uartParams);
        if (gMmwMCB.commandUartHandle == NULL)
        {
            //System_printf("Error: Unable to open the Command UART Instance\n");
            MmwDemo_debugAssert (0);
            return;
        }
        System_printf("Debug: UART Instance %p has been opened successfully\n", gMmwMCB.commandUartHandle);
    
        /* Setup the default UART Parameters */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.readDataMode = UART_DATA_BINARY;
        uartParams.clockFrequency = gMmwMCB.cfg.platformCfg.sysClockFrequency;
        uartParams.baudRate       = gMmwMCB.cfg.platformCfg.loggingBaudRate;
        uartParams.isPinMuxDone   = 1U;
    
        /* Open the Logging UART Instance: */
        gMmwMCB.loggingUartHandle = UART_open(1, &uartParams);
        if (gMmwMCB.loggingUartHandle == NULL)
        {
            //System_printf("Error: Unable to open the Logging UART Instance\n");
            MmwDemo_debugAssert (0);
            return;
        }
        System_printf("Debug: UART Instance %p has been opened successfully\n", gMmwMCB.loggingUartHandle);
    
        /* Create a binary semaphores which are used to signal DPM_start/DPM_stop are done.
         * The signaling (Semaphore_post) will be done from DPM registered report function
         * (which will execute in the DPM execute task context). */
        Semaphore_Params_init(&semParams);
        semParams.mode = Semaphore_Mode_BINARY;
        gMmwMCB.DPMstartSemHandle = Semaphore_create(0, &semParams, NULL);
        gMmwMCB.DPMstopSemHandle  = Semaphore_create(0, &semParams, NULL);
    
        /*****************************************************************************
         * mmWave: Initialization of the high level module
         *****************************************************************************/
    
        /* Initialize the mmWave control init configuration */
        memset ((void*)&initCfg, 0 , sizeof(MMWave_InitCfg));
    
        /* Populate the init configuration: */
        initCfg.domain                  = MMWave_Domain_MSS;
        initCfg.socHandle               = gMmwMCB.socHandle;
        initCfg.eventFxn                = MmwDemo_eventCallbackFxn;
        initCfg.linkCRCCfg.useCRCDriver = 1U;
        initCfg.linkCRCCfg.crcChannel   = CRC_Channel_CH1;
        initCfg.cfgMode                 = MMWave_ConfigurationMode_FULL;
        initCfg.executionMode           = MMWave_ExecutionMode_ISOLATION;
    
        /* Initialize and setup the mmWave Control module */
        gMmwMCB.ctrlHandle = MMWave_init (&initCfg, &errCode);
        if (gMmwMCB.ctrlHandle == NULL)
        {
            /* Error: Unable to initialize the mmWave control module */
            //System_printf ("Error: mmWave Control Initialization failed [Error code %d]\n", errCode);
            MmwDemo_debugAssert (0);
            return;
        }
        System_printf ("Debug: mmWave Control Initialization was successful\n");
    
        /* Synchronization: This will synchronize the execution of the control module
         * between the domains. This is a prerequisite and always needs to be invoked. */
        if (MMWave_sync (gMmwMCB.ctrlHandle, &errCode) < 0)
        {
            /* Error: Unable to synchronize the mmWave control module */
            System_printf ("Error: mmWave Control Synchronization failed [Error code %d]\n", errCode);
            MmwDemo_debugAssert (0);
            return;
        }
        System_printf ("Debug: mmWave Control Synchronization was successful\n");
    
        MmwDemo_dataPathOpen(&gMmwMCB.dataPathObj);
    
        /* Initialize LVDS streaming components */
        if ((errCode = MmwDemo_LVDSStreamInit()) < 0 )
        {
            System_printf ("Error: MMWDemoDSS LVDS stream init failed with Error[%d]\n",errCode);
            return;
        }
    
        /* initialize cq configs to invalid profile index to be able to detect
         * unconfigured state of these when monitors for them are enabled.
         */
        for(i = 0; i < RL_MAX_PROFILES_CNT; i++)
        {
            gMmwMCB.cqSatMonCfg[i].profileIndx    = (RL_MAX_PROFILES_CNT + 1);
            gMmwMCB.cqSigImgMonCfg[i].profileIndx = (RL_MAX_PROFILES_CNT + 1);
        }
    
        /* Configure banchmark counter */
        Cycleprofiler_init();
    
        /*****************************************************************************
         * Launch the mmWave control execution task
         * - This should have a higher priroity than any other task which uses the
         *   mmWave control API
         *****************************************************************************/
        Task_Params_init(&taskParams);
        taskParams.priority  = MMWDEMO_MMWAVE_CTRL_TASK_PRIORITY;
        taskParams.stackSize = 3*1024;
        gMmwMCB.taskHandles.mmwaveCtrl = Task_create(MmwDemo_mmWaveCtrlTask, &taskParams, NULL);
    
        /*****************************************************************************
         * Initialization of the DPM Module:
         *****************************************************************************/
        memset ((void *)&objDetInitParams, 0, sizeof(DPC_ObjectDetection_InitParams));
    
        /* Note this must be after MmwDemo_dataPathOpen() above which opens the hwa
         * and edma drivers */
        objDetInitParams.hwaHandle = gMmwMCB.dataPathObj.hwaHandle;
        for (edmaCCIdx = 0; edmaCCIdx < EDMA_NUM_CC; edmaCCIdx++)
        {
            objDetInitParams.edmaHandle[edmaCCIdx] = gMmwMCB.dataPathObj.edmaHandle[edmaCCIdx];
        }
    
        /* Memory related config */
        objDetInitParams.L3ramCfg.addr = (void *)&gMmwL3[0];
        objDetInitParams.L3ramCfg.size = sizeof(gMmwL3);
        objDetInitParams.CoreLocalRamCfg.addr = &gDPC_ObjDetTCM[0];
        objDetInitParams.CoreLocalRamCfg.size = sizeof(gDPC_ObjDetTCM);
    
        /* Call-back config */
        objDetInitParams.processCallBackCfg.processFrameBeginCallBackFxn =
            MmwDemo_DPC_ObjectDetection_processFrameBeginCallBackFxn;
        objDetInitParams.processCallBackCfg.processInterFrameBeginCallBackFxn =
            MmwDemo_DPC_ObjectDetection_processInterFrameBeginCallBackFxn;
    
        memset ((void *)&dpmInitCfg, 0, sizeof(DPM_InitCfg));
    
        /* Setup the configuration: */
        dpmInitCfg.socHandle        = gMmwMCB.socHandle;
        dpmInitCfg.ptrProcChainCfg  = &gDPC_ObjectDetectionCfg;
        dpmInitCfg.instanceId       = 0xFEEDFEED;
        dpmInitCfg.domain           = DPM_Domain_LOCALIZED;
        dpmInitCfg.reportFxn        = MmwDemo_DPC_ObjectDetection_reportFxn;
        dpmInitCfg.arg              = &objDetInitParams;
        dpmInitCfg.argSize          = sizeof(DPC_ObjectDetection_InitParams);
    
        /* Initialize the DPM Module: */
        gMmwMCB.dataPathObj.objDetDpmHandle = DPM_init (&dpmInitCfg, &errCode);
        if (gMmwMCB.dataPathObj.objDetDpmHandle == NULL)
        {
            System_printf ("Error: Unable to initialize the DPM Module [Error: %d]\n", errCode);
            MmwDemo_debugAssert (0);
            return;
        }
    
        /* Launch the DPM Task */
        Task_Params_init(&taskParams);
        taskParams.priority  = MMWDEMO_DPC_OBJDET_DPM_TASK_PRIORITY;
        taskParams.stackSize = 4*1024;
        gMmwMCB.taskHandles.objDetDpmTask = Task_create(MmwDemo_DPC_ObjectDetection_dpmTask, &taskParams, NULL);
    
        /* Calibration save/restore initialization */
        if(MmwDemo_calibInit()<0)
        {
            System_printf("Error: Calibration data initialization failed \n");
            MmwDemo_debugAssert (0);
        }
    
        /*****************************************************************************
         * Initialize the CLI Module:
         *      User can choose to create their own task here with the same priority
         *      instead that does hard coded config instead of interactive CLI
         *****************************************************************************/
        MmwDemo_CLIInit(MMWDEMO_CLI_TASK_PRIORITY);
    
        return;
    }

  • Hey Adam,

    I apologize for the confusion, but the mailbox needs to be initialized for the demos to work, particularly the mmWaveLink framework. I should've clarified that you don't need the mailbox read task that's defined in the object detection over CAN demo, but the mailbox is still needed to communicate with the C674x DSP and control the radar front-end from the application using the mmWaveLink. I will edit my previous reply to make that more apparent and avoid confusion for others that may look at this post. I tested your initialization function after adding back in Mailbox_init(MAILBOX_TYPE_MSS) after GPIO_init and was able to confirm that CLI commands we're working after the addition.

    Let me know if you have any other questions.

    Regards,

    Kristien

  • Hi Kristien,

    this resolved my issue. Now I'm able to receive data on CLI while using HCC. It is now possible for me to use CLI for debugging.

    Also, it seems some data is sent over CAN, however, I need to analyze (parse) it more to confirm functionality. In case of some problems, I open new question in order to keep this quite clear. 

    Thank you very much for your constructive responses, I owe you a beer! Beers

    Regards,

    Adam

  • Hey Adam,

    I'm glad I was able to help, and feel free to open up a new thread if you have any other questions! 

    Regards,

    Kristien