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.

AWR2243BOOST: AWR2243Boost+AM2732 Building Demo问题

Part Number: AWR2243BOOST
Other Parts Discussed in Thread: AWR2243, AM2732

您好,

按照mmwave_mcuplus_sdk_user_guide.pdf   4.8.3中Building Demo的方法以及

%MMWAVE_SDK_INSTALL_PATH%/ti/demo/%MMWAVE_SDK_DEVICE%/mmw路径下makefile里面的配置说明,当前Build 'mssDemo'是一起的、Build 'dssDemo'及Build 'bin'各个模式都是一起的(比如am273x_mmw_demoDDM.appimage和am273x_mmw_demoTDM.appimage),如果想单独编译其中某一个image文件(比如am273x_mmw_demoTDM.appimage)或者mssDemo(比如am273x_mmw_demo_mssTDM.xer5f等)需要如何去做配置呢,相关的配置文件需要做怎样的修改实现呢?

此外,当前编译的image文件刷录之后需要重新单独通过mmWave_Demo_Visualizer  Load  profiles参数配置文件,对于用户的产品来说可不可以直接编译完整的image文件(包括参数配置)刷录之后雷达就可以直接运行了?如果可以的话,该如何去实现呢?

谢谢。

  • 你好,

    编译单独一个demo,例如:gmake mmwDemoTDMEnet

    只编译这个demo里的mss,例如需要编译TDMEnet的mss,并且要编译出可烧写的bin,需要在makefile里添加类似下面的代码,然后运行gmake mmwDemoTDMEnet_mss

    mmwDemoTDMEnet_mss:
    $(MAKE) PROC_CHAIN=TDM objClean syscfg mssDemoEnet bin enetBin

    此外,当前编译的image文件刷录之后需要重新单独通过mmWave_Demo_Visualizer  Load  profiles参数配置文件,对于用户的产品来说可不可以直接编译完整的image文件(包括参数配置)刷录之后雷达就可以直接运行了?如果可以的话,该如何去实现呢?

    目前的demo手动加载配置文件。你也可以修改代码,把配置文件固化在代码里。下面blog介绍的是如何单芯片毫米波的代码里固化配置,可以参考看看:

    (+) 适用于TI mmWave sensor平台的配置随启动加载的方式 - 汽车 - 技术文章 - E2ETm 设计支持

  • 您好,

    针对这个配置文件固化CLI参数以实现芯片上电后自动加载配置里还有些疑问想请教下:

    1)帖子中提到的.c文件是否为E:\ti\mmwave_mcuplus_sdk_04_02_00_02\mmwave_mcuplus_sdk_04_02_00_02\ti\utils\cli\src\cli.c文件(同路径下还有cli_mmwave.c,对比了下内容和帖子中提到的函数,我认为应该是cli.c文件

    2)针对帖子中提到的.c文件需要增加的头文件、外部函数和结构体定义、参数命令配置等,在mmwave_mcuplus_sdk_04_02_00_02\ti\utils\cli\src\cli.c文件中基本都有了,除了文中提到的如下MmwDemo_initTask是没有的(但是需要在此函数调用” MmwDemo_Bypass_CLI”函数),可能文中提到的主要针对1443、1642、1843,AWR2243+AM2732是不是有些区别?AWR2243+AM2732的cli.c文件需要按照帖子中提到的去做更改吗,还是可以直接用呢?

    3)此外这个.c文件修改之后如何编译生成完整的固化参数的bin文件做刷录呢,跟mmwave_mcuplus_sdk_user_guide.pdf里面Building demo的方法有啥异同吗?

    谢谢。

  • Kun,

    我提供的blog基于的是sdk3.5,你现在使用的是sdk4.2,应该还是有些区别的,但是修改的思路是可以参考的,你需要尝试一下。

    修改后重新编译demo代码就可以了。

  • Kun,

    由于需要修改cli.c,修改后在编译demo前,先要编译更新cli lib,然后再先clean一下demo,再编译demo。

  • 好的,谢谢,这个编译更新cli lib哪里有命令说明吗,更新之后完整的编译跟mmwave_mcuplus_sdk_user_guide.pdf里面Building demo的方法一样是吧,先gmake clean,然后再gmake  xxxDemo或者gmake all?

  • 这个编译更新cli lib哪里有命令说明吗,

    请参考sdk user guide里4.8.4.1. Building datapath/control/utils components章节的内容。

  • 您好,

    按照上述Blog 第三部分固化CLI参数的方法修改了E:\ti\mmwave_mcuplus_sdk_04_02_00_02\mmwave_mcuplus_sdk_04_02_00_02\ti\utils\cli\src\cli.c文件相关函数配置定义,如下(由于文件有乱码,下面代码为有修改的部分):

    /**************************************************************************
    *************************** Include Files ********************************
    **************************************************************************/

    /* Standard Include Files. */
    #include <stdint.h>
    #include <stdlib.h>
    #include <stddef.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdbool.h>

    #include <drivers/uart.h>

    /* mmWave SDK Include Files: */
    #include <ti/utils/cli/cli.h>
    #include <ti/utils/cli/include/cli_internal.h>

    #define CLI_TASK_STACK_SIZE (4 *1024U)

    /**************************************************************************
    *************************** Global Variables *****************************
    **************************************************************************/
    TaskHandle_t gCliTask;
    StaticTask_t gCliTaskObj;

    StackType_t gCliTskStack[CLI_TASK_STACK_SIZE] __attribute__((aligned(32)));

    /**
    * @brief Global variable which tracks the CLI MCB
    */
    CLI_MCB gCLI;

    extern CLI_MCB gCLI; /*wang*/
    extern void MmwDemo_Bypass_CLI (void); /*wang*/

    // #define CLI_BYPASS
    #define CLI_BYPASS 1 /*wang*/
    //#define MAX_RADAR_CMD 34
    #define MAX_RADAR_CMD 34 /*wang*/
    char* radarCmdString[MAX_RADAR_CMD] =
    {
    "sensorStop \n\r",
    "flushCfg \n\r",
    "dfeDataOutputMode 1 \n\r",
    "channelCfg 15 5 0 \n\r",
    "adcCfg 2 1 \n\r",
    "adcbufCfg -1 0 1 1 1 \n\r",
    "lowPower 0 1 \n\r",
    "profileCfg 0 77 7 3 39 0 0 100 1 256 7200 0 0 30 \n\r",
    "chirpCfg 0 0 0 0 0 0 0 1 \n\r",
    "chirpCfg 1 1 0 0 0 0 0 4 \n\r",
    "frameCfg 0 1 32 0 256 500 1 0 \n\r",
    "lowPower 0 1 \n\r",
    "guiMonitor -1 1 1 0 0 0 1 \n\r",
    "cfarCfg -1 0 2 8 4 3 0 15 1 \n\r",
    "cfarCfg -1 1 0 4 2 3 1 15 1 \n\r",
    "multiObjBeamForming -1 0 0.5 \n\r",
    "calibDcRangeSig -1 0 -5 8 256 \n\r",
    "clutterRemoval -1 0 \n\r",
    "compRangeBiasAndRxChanPhase 0.0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 \n\r",
    "measureRangeBiasAndRxChanPhase 0 1.5 0.2 \n\r",
    "aoaFovCfg -1 -90 90 -90 90 \n\r",
    "cfarFovCfg -1 0 0 22.88 \n\r",
    "cfarFovCfg -1 1 -1 1.00 \n\r",
    "extendedMaxVelocity -1 0 \n\r",
    "calibData 0 0 0 \n\r",
    "sensorStart \n\r",
    };


    /**************************************************************************
    **************************** CLI Functions *******************************
    **************************************************************************/

    /**
    * @b Description
    * @n
    * The function is the HELP generated by the CLI Module
    *
    * \ingroup CLI_UTIL_INTERNAL_FUNCTION
    *
    * @retval
    * Not Applicable.
    */
    static int32_t CLI_help (int32_t argc, char* argv[])
    {
    uint32_t index;

    /* Display the banner: */
    CLI_write ("Help: This will display the usage of the CLI commands\n");
    CLI_write ("Command: Help Description\n");

    /* Cycle through all the registered CLI commands: */
    for (index = 0; index < gCLI.numCLICommands; index++)
    {
    /* Display the help string*/
    CLI_write ("%s: %s\n",
    gCLI.cfg.tableEntry[index].cmd,
    (gCLI.cfg.tableEntry[index].helpString == NULL) ?
    "No help available" :
    gCLI.cfg.tableEntry[index].helpString);
    }

    /* Is the mmWave Extension enabled? */
    if (gCLI.cfg.enableMMWaveExtension == 1U)
    {
    /* YES: Pass the control to the extension help handler. */
    CLI_MMWaveExtensionHelp ();
    }
    return 0;
    }
    #ifdef CLI_BYPASS
    static int32_t CLI_ByPassApi(CLI_Cfg* ptrCLICfg)
    {
    char* tokenizedArgs[CLI_MAX_ARGS];
    char* ptrCLICommand;
    char delimitter[] = " \r\n";
    uint32_t argIndex;
    CLI_CmdTableEntry* ptrCLICommandEntry;
    int32_t cliStatus;
    uint32_t index, idx;
    uint16_t numCLICommands = 0U;

    printf("CLI Bypass Task\n");
    /* Sanity Check: Validate the arguments */
    if (ptrCLICfg == NULL)
    return -1;

    /* Construct semaphore for CLI BYPASS task. */
    SemaphoreP_constructBinary(&gCLI.cliBypasssemaphoreObj, 0);

    /* Cycle through and determine the number of supported CLI commands: */
    for (index = 0; index < CLI_MAX_CMD; index++)
    {
    /* Do we have a valid entry? */
    if (ptrCLICfg->tableEntry[index].cmd == NULL)
    {
    /* NO: This is the last entry */
    break;
    }
    else
    {
    /* YES: Increment the number of CLI commands */
    numCLICommands = numCLICommands + 1;
    }
    }

    /* Execute All Radar Commands */
    for (idx = 0; idx < MAX_RADAR_CMD; idx++)
    {
    /* Reset all the tokenized arguments: */
    memset ((void *)&tokenizedArgs, 0, sizeof(tokenizedArgs));
    argIndex = 0;
    ptrCLICommand = (char*)radarCmdString[idx];

    /* Set the CLI status: */
    cliStatus = -1;

    /* The command has been entered we now tokenize the command message */
    while (1)
    {
    /* Tokenize the arguments: */
    tokenizedArgs[argIndex] = strtok(ptrCLICommand, delimitter);
    if (tokenizedArgs[argIndex] == NULL)
    break;

    /* Increment the argument index: */
    argIndex++;
    if (argIndex >= CLI_MAX_ARGS)
    break;

    /* Reset the command string */
    ptrCLICommand = NULL;
    }

    /* Were we able to tokenize the CLI command? */
    if (argIndex == 0)
    continue;

    /* Cycle through all the registered CLI commands: */
    for (index = 0; index < numCLICommands; index++)
    {
    ptrCLICommandEntry = &ptrCLICfg->tableEntry[index];

    /* Do we have a match? */
    if (strcmp(ptrCLICommandEntry->cmd, tokenizedArgs[0]) == 0)
    {
    CLI_write("%d\n", index);
    CLI_write("%s\n", gCLI.cfg.tableEntry[index].cmd);
    /* YES: Pass this to the CLI registered function */
    cliStatus = ptrCLICommandEntry->cmdHandlerFxn (argIndex, tokenizedArgs);
    if (cliStatus == 0)
    {
    CLI_write ("Done\r\n\n");
    }
    else
    {
    CLI_write ("Error %d\r\n", cliStatus);
    }
    break;
    }
    }

    /* Did we get a matching CLI command? */
    if (index == numCLICommands)
    {
    /* NO matching command found. Is the mmWave extension enabled? */
    if (ptrCLICfg->enableMMWaveExtension == 1U)
    {
    /* Yes: Pass this to the mmWave extension handler */
    cliStatus = CLI_MMWaveExtensionHandler (argIndex, tokenizedArgs);
    }

    /* Was the CLI command found? */
    if (cliStatus == -1)
    {
    /* No: The command was still not found */
    CLI_write ("'%s' is not recognized as a CLI command\n", tokenizedArgs[0]);
    }
    }
    }

    /* CLI BYPASS task should never retrun */
    SemaphoreP_pend(&gCLI.cliBypasssemaphoreObj, SystemP_WAIT_FOREVER);

    return 0;
    }
    #endif

    void MmwDemo_Bypass_CLI (void)

    {

    if (CLI_ByPassApi(&gCLI.cfg) != 0)

    {

    printf ("Error: Unable to CLI_ByPassApi\n");

    return;

    }

    return;

    } /*wang*/

    然后重新编译更新了cli lib以及相关Demo,刷录了am273x_mmw_demoTDMLVDS.appimage固件,板子换到QSPI模式重新上电后,在CCS UART Terminal中可以看到部分参数配置是成功的,但是没有完整的显示整个参数配置的状态,中间有两个参数配置命令显示无效,如下:

    CCS UART Terminal中完整的log如下,看着不是全部运行输出的log:


    Done
    8
    adcbufCfg
    Done

    Done
    Done
    Done
    Done
    Done
    Error: Invalid usage of the CLI command
    Error -1
    2
    guiMonitor
    Done

    3
    cfarCfg
    Done

    3
    cfarCfg
    Done

    5
    multiObjBeamForming
    Done

    6
    calibDcRangeSig
    Done

    7
    clutterRemoval
    Done

    9
    compRangeBiasAndRxChanPhase
    Error: Invalid usage of the CLI command
    Error -1
    10
    measureRangeBiasAndRxChanPhase
    Done

    4
    aoaFovCfg
    Done

    1

    请问上述cli.c里面的参数配置命令是否完整,有没有哪里函数定义调用不对呢,在ccs中看着没有完全运行相关的参数配置、部分命令无效,麻烦帮忙看下,非常感谢。

  • 您好,

    在原始的cli.c文件参数配置中lowpower命令有两个(如下代码黄色标记),不知道是否是重复运行,昨天在CCS UART Terminal  Console中显示Invalid usage的错误,当前已屏蔽其中一个命令,看着没报错了;

    然后compRangeBiasAndRxChanPhase(如下代码绿色标记)应该是位数不对才显示Invalid usage,AWR2243+AM2732对应3T4R的,当前已修改;

    此外,在cli.c配置文件中,我又对比修改了下,只重新定义了#define CLI_BYPASS 1 (如下代码红色标记),应该也是能将参数配置固化到代码中去的,我重新编译更新下载后,在CCS UART Terminal  Console没有看到错误信息,但是console里面始终没有完整的运行参数配置命令,如下第二段log和截图(Done都没打印完),当前cli.c文件的配置应该是可以的,也有相关log输出,请问此处还有其他的办法确定参数固化成功了吗?

    /**************************************************************************
     *************************** Include Files ********************************
     **************************************************************************/

    /* Standard Include Files. */
    #include <stdint.h>
    #include <stdlib.h>
    #include <stddef.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdbool.h>

    #include <drivers/uart.h>

    /* mmWave SDK Include Files: */
    #include <ti/utils/cli/cli.h>
    #include <ti/utils/cli/include/cli_internal.h>

    #define CLI_TASK_STACK_SIZE  (4 *1024U)

    /**************************************************************************
     *************************** Global Variables *****************************
     **************************************************************************/
    TaskHandle_t    gCliTask;
    StaticTask_t    gCliTaskObj;

    StackType_t gCliTskStack[CLI_TASK_STACK_SIZE] __attribute__((aligned(32)));

    /**
     * @brief   Global variable which tracks the CLI MCB
     */
    CLI_MCB     gCLI;

    //extern CLI_MCB     gCLI;  /*wang*/
    //extern void MmwDemo_Bypass_CLI (void);  /*wang*/

    // #define CLI_BYPASS
    #define CLI_BYPASS 1   /*wang*/
    //#define MAX_RADAR_CMD               34
    #define MAX_RADAR_CMD               34    /*wang*/
    char* radarCmdString[MAX_RADAR_CMD] =
    {
        "sensorStop \n\r",
        "flushCfg \n\r",
        "dfeDataOutputMode 1 \n\r",
        "channelCfg 15 5 0 \n\r",
        "adcCfg 2 1 \n\r",
        "adcbufCfg -1 0 1 1 1 \n\r",
        "lowPower 0 1 \n\r",
        "profileCfg 0 77 7 3 39 0 0 100 1 256 7200 0 0 30 \n\r",
        "chirpCfg 0 0 0 0 0 0 0 1 \n\r",
        "chirpCfg 1 1 0 0 0 0 0 4 \n\r",
        "frameCfg 0 1 32 0 256 500 1 0 \n\r",
        //"lowPower 0 1 \n\r",
        "guiMonitor -1 1 1 0 0 0 1 \n\r",
        "cfarCfg -1 0 2 8 4 3 0 15 1 \n\r",
        "cfarCfg -1 1 0 4 2 3 1 15 1 \n\r",
        "multiObjBeamForming -1 0 0.5 \n\r",
        "calibDcRangeSig -1 0 -5 8 256 \n\r",
        "clutterRemoval -1 0 \n\r",
        "compRangeBiasAndRxChanPhase 0.0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 \n\r",
        "measureRangeBiasAndRxChanPhase 0 1.5 0.2 \n\r",
        "aoaFovCfg -1 -90 90 -90 90 \n\r",
        "cfarFovCfg -1 0 0 22.88 \n\r",
        "cfarFovCfg -1 1 -1 1.00 \n\r",
        "extendedMaxVelocity -1 0 \n\r",
        "calibData 0 0 0 \n\r",
        "sensorStart \n\r",
    };
    CCS UART Terminal  Console:
    1
    sensorStop
    Ignored: Sensor is already stopped
    Done

    Done
    Done
    Done
    Done
    8
    adcbufCfg
    Done

    Done
    Done
    Done
    Done
    Done
    2
    guiMonitor
    Done

    3
    cfarCfg
    Done

    3
    cfarCfg
    Done

    5
    multiObjBeamForming
    Done

    6
    calibDcRangeSig
    Done

    7
    clutterRemoval
    Don
  • Kun,

    我看了一下sdk 4.2里的cli.c,里面已经有CLI_BYPASS相关代码了,只是没有使能。

    但代码里的默认的配置和AM2732的有些不同,你需要根据你使用的demo(TDM or DDM or 2d or 3d等)使用demo目录下profile下的cfg文件内容更新相关配置,看是否能正确运行?

  • 您好,

    我按照TDM里面LVDS.cfg的参数修改了下cli.c里面的配置,重新刷录编译后在CCS UART Terminal  Console里面输出的log如下,这个算是成功的吗?JoyJoyJoy

    没有显示multiObjBeamForming之后的命令,但是有Debug: Init Calibration Status = 0x1ffe    Done这个log输出,是不是有Init Calibration Status = 0x1ffe这个log说明是可以的?

    1
    sensorStop
    Ignored: Sensor is already stopped
    Done

    Done
    Done
    Done
    Done
    8
    adcbufCfg
    Done

    Done
    Done
    Done
    Done
    Done
    Done
    Done
    Done
    Done
    Done
    2
    guiMonitor
    Done

    3
    cfarCfg
    Done

    3
    cfarCfg
    Done

    5
    multiObjBeamForming
    Done
    Debug: Init Calibration Status = 0x1ffe
    Done

  • CCS UART Terminal  Console里面的log感觉有点乱啊,重新上电输出的log又不一样了,但是有Init Calibration Status = 0x1ffe,请问这个可以说明配置成功了吗?这个不像Visualizer里面下载的参数配置那样完整的运行所有参数命令。

  • Kun,

    我这里测试没有问题,流程如下:

    1. cli.c里设置CLI_BYPSS=1, 修改配置为tdm 2d cfg。重新编译cli库,重新编译tdm demo。

    2. 打开visualizer,先运行原始的tdm demo,发射2d的配置,可以看到plot下的信息输出。然后断开visualizer下的串口连接(网页左下角)

    3. 板子重新上电,运行新编译好的固化配置的tdm demo,在visulizer里连接串口,我可以在plot下看到动态的信息输出。

  • Kun,

    我参考blog修改了下面两个文件,现在上电后配置会自动下发,同时CLI也工作正常。不过在visualizer里plot里的stop工作正常,但下发start会说配置有变化,但你可以手动下载cfg文件,也可以重新让射频发射工作的。

    我修改的文件如下,仍然需要重新编译cli库,重新编译tdm demo。

    cli.c
    /*
     *   @file  cli.c
     *
     *   @brief
     *      CLI Utility implementation
     *
     *  \par
     *  NOTE:
     *      (C) Copyright 2016-2021 Texas Instruments, Inc.
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /**************************************************************************
     *************************** Include Files ********************************
     **************************************************************************/
    
    /* Standard Include Files. */
    #include <stdint.h>
    #include <stdlib.h>
    #include <stddef.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdbool.h>
    
    #include <drivers/uart.h>
    
    /* mmWave SDK Include Files: */
    #include <ti/utils/cli/cli.h>
    #include <ti/utils/cli/include/cli_internal.h>
    
    #define CLI_TASK_STACK_SIZE  (4 *1024U)
    
    /**************************************************************************
     *************************** Global Variables *****************************
     **************************************************************************/
    TaskHandle_t    gCliTask;
    StaticTask_t    gCliTaskObj;
    
    StackType_t gCliTskStack[CLI_TASK_STACK_SIZE] __attribute__((aligned(32)));
    
    /**
     * @brief   Global variable which tracks the CLI MCB
     */
    CLI_MCB     gCLI;
    #define CLI_BYPASS                  1
    #define MAX_RADAR_CMD               34
    char* radarCmdString[MAX_RADAR_CMD] =
    {
        "sensorStop \n\r",
        "flushCfg \n\r",
        "dfeDataOutputMode 1 \n\r",
        "channelCfg 15 5 0 \n\r",
        "adcCfg 2 1 \n\r",
        "adcbufCfg -1 0 1 1 1 \n\r",
        "lowPower 0 1 \n\r",
        "dataPathClkCfg 1 1 \n\r",
        "profileCfg 0 77 7 3 39 0 0 100 1 256 7200 0 0 30 \n\r",
    	"dataPathConfig 0 1 0 2 64 64 64 0",
    	"hsiClockConfig 9 0",
    	"hsiLaneConfig 15 1 0 2 0 4 0 5 0 3 0 0",
    	"dataFormatConfig 1 1",
        "chirpCfg 0 0 0 0 0 0 0 1 \n\r",
        "chirpCfg 1 1 0 0 0 0 0 4 \n\r",
        "frameCfg 0 1 32 0 256 500 1 0 \n\r",
        "guiMonitor -1 1 1 0 0 0 1 \n\r",
        "cfarCfg -1 0 2 8 4 3 0 15 1 \n\r",
        "cfarCfg -1 1 0 4 2 3 1 15 1 \n\r",
        "multiObjBeamForming -1 0 0.5 \n\r",
        "calibDcRangeSig -1 0 -5 8 256 \n\r",
        "clutterRemoval -1 0 \n\r",
        "compRangeBiasAndRxChanPhase 0.0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 \n\r",
        "measureRangeBiasAndRxChanPhase 0 1. 0.2 \n\r",
        "aoaFovCfg -1 -90 90 -90 90 \n\r",
        "cfarFovCfg -1 0 0.25 8.64 \n\r",
        "cfarFovCfg -1 1 -10.59 10.59 \n\r",
        "extendedMaxVelocity -1 0 \n\r",
        "calibData 0 0 0 \n\r",
        "sensorStart \n\r",
         
    };
    
    
    /**************************************************************************
     **************************** CLI Functions *******************************
     **************************************************************************/
    
    /**
     *  @b Description
     *  @n
     *      The function is the HELP generated by the CLI Module
     *
     *  \ingroup CLI_UTIL_INTERNAL_FUNCTION
     *
     *  @retval
     *      Not Applicable.
     */
    static int32_t CLI_help (int32_t argc, char* argv[])
    {
        uint32_t    index;
    
        /* Display the banner: */
        CLI_write ("Help: This will display the usage of the CLI commands\n");
        CLI_write ("Command: Help Description\n");
    
        /* Cycle through all the registered CLI commands: */
        for (index = 0; index < gCLI.numCLICommands; index++)
        {
            /* Display the help string*/
            CLI_write ("%s: %s\n",
                        gCLI.cfg.tableEntry[index].cmd,
                       (gCLI.cfg.tableEntry[index].helpString == NULL) ?
                        "No help available" :
                        gCLI.cfg.tableEntry[index].helpString);
        }
    
        /* Is the mmWave Extension enabled? */
        if (gCLI.cfg.enableMMWaveExtension == 1U)
        {
            /* YES: Pass the control to the extension help handler. */
            CLI_MMWaveExtensionHelp ();
        }
        return 0;
    }
    #ifdef CLI_BYPASS
    static int32_t CLI_ByPassApi(CLI_Cfg* ptrCLICfg)
    {
        char*                   tokenizedArgs[CLI_MAX_ARGS];
        char*                   ptrCLICommand;
        char                    delimitter[] = " \r\n";
        uint32_t                argIndex;
        CLI_CmdTableEntry*      ptrCLICommandEntry;
        int32_t                 cliStatus;
        uint32_t                index, idx;
        uint16_t numCLICommands = 0U;
        
        printf("CLI Bypass Task\n");
        /* Sanity Check: Validate the arguments */
        if (ptrCLICfg == NULL)
            return -1;
    
        /* Construct semaphore for CLI BYPASS task. */
        SemaphoreP_constructBinary(&gCLI.cliBypasssemaphoreObj, 0);
    
        /* Cycle through and determine the number of supported CLI commands: */
        for (index = 0; index < CLI_MAX_CMD; index++)
        {
            /* Do we have a valid entry? */
            if (ptrCLICfg->tableEntry[index].cmd == NULL)
            {
                /* NO: This is the last entry */
                break;
            }
            else
            {
                /* YES: Increment the number of CLI commands */
                numCLICommands = numCLICommands + 1;
            }
        }
    
        /* Execute All Radar Commands */
        for (idx = 0; idx < MAX_RADAR_CMD; idx++)
        {
            /* Reset all the tokenized arguments: */
            memset ((void *)&tokenizedArgs, 0, sizeof(tokenizedArgs));
            argIndex      = 0;
            ptrCLICommand = (char*)radarCmdString[idx];
    
            /* Set the CLI status: */
            cliStatus = -1;
    
            /* The command has been entered we now tokenize the command message */
            while (1)
            {
                /* Tokenize the arguments: */
                tokenizedArgs[argIndex] = strtok(ptrCLICommand, delimitter);
                if (tokenizedArgs[argIndex] == NULL)
                    break;
    
                /* Increment the argument index: */
                argIndex++;
                if (argIndex >= CLI_MAX_ARGS)
                    break;
    
                /* Reset the command string */
                ptrCLICommand = NULL;
            }
    
            /* Were we able to tokenize the CLI command? */
            if (argIndex == 0)
                continue;
    
            /* Cycle through all the registered CLI commands: */
            for (index = 0; index < numCLICommands; index++)
            {
                ptrCLICommandEntry = &ptrCLICfg->tableEntry[index];
    
                /* Do we have a match? */
                if (strcmp(ptrCLICommandEntry->cmd, tokenizedArgs[0]) == 0)
                {
                    CLI_write("%d\n", index);
                    CLI_write("%s\n", gCLI.cfg.tableEntry[index].cmd);
                    /* YES: Pass this to the CLI registered function */
                    cliStatus = ptrCLICommandEntry->cmdHandlerFxn (argIndex, tokenizedArgs);
                    if (cliStatus == 0)
                    {
                        CLI_write ("Done\r\n\n");
                    }
                    else
                    {
                        CLI_write ("Error %d\r\n", cliStatus);
                    }
                    break;
                }
            }
    
            /* Did we get a matching CLI command? */
            if (index == numCLICommands)
            {
                /* NO matching command found. Is the mmWave extension enabled? */
                if (ptrCLICfg->enableMMWaveExtension == 1U)
                {
                    /* Yes: Pass this to the mmWave extension handler */
                    cliStatus = CLI_MMWaveExtensionHandler (argIndex, tokenizedArgs);
                }
    
                /* Was the CLI command found? */
                if (cliStatus == -1)
                {
                    /* No: The command was still not found */
                    CLI_write ("'%s' is not recognized as a CLI command\n", tokenizedArgs[0]);
                }
            }
        }
        
        /* CLI BYPASS task should never retrun */
        SemaphoreP_pend(&gCLI.cliBypasssemaphoreObj, SystemP_WAIT_FOREVER);
    
        return 0;
    }
    
    void MmwDemo_Bypass_CLI (void)
    
    {
    
                    if (CLI_ByPassApi(&gCLI.cfg) != 0)
    
                    {
    
                                    CLI_write ("Error: Unable to CLI_ByPassApi\n");
    
                                    return;
    
                    }
    
                    return;
    
    }
    #endif
    
    static int32_t CLI_readLine(UART_Handle uartHandle, char *lineBuf, uint32_t bufSize)
    {
        int32_t status = SystemP_FAILURE;
    
        if(uartHandle!=NULL)
        {
            uint32_t done = 0;
            UART_Transaction trans;
            uint8_t  readByte;
            int32_t  transferOK;
            uint32_t numCharRead = 0;
    
            while(!done)
            {
                UART_Transaction_init(&trans);
    
                status = SystemP_SUCCESS;
    
                /* Read one char */
                trans.buf   = &readByte;
                trans.count = 1;
                transferOK = UART_read(uartHandle, &trans);
                if((SystemP_SUCCESS != (transferOK)) || (UART_TRANSFER_STATUS_SUCCESS != trans.status))
                {
                    status = SystemP_FAILURE;
                }
                if(status == SystemP_SUCCESS)
                {
                    if(numCharRead < bufSize)
                    {
                        lineBuf[numCharRead] = readByte;
                        numCharRead++;
                    }
    
                    /* Echo the char */
                    trans.buf   = &readByte;
                    trans.count = 1;
                    transferOK = UART_write(uartHandle, &trans);
                    if((SystemP_SUCCESS != (transferOK)) || (UART_TRANSFER_STATUS_SUCCESS != trans.status))
                    {
                        status = SystemP_FAILURE;
                    }
                }
                if(status == SystemP_SUCCESS)
                {
                    if((readByte == 10) || (readByte == 13))/* "LINE FEED" "New Line" entered, (ASCII: 10, 13) */
                    {
                        /* terminate the string, reset numCharRead  */
                        lineBuf[numCharRead-1] = 0;
    
                        done = 1;
    
                        /* Echo a new line to terminal (ASCII: 10) */
                        readByte = 10;
                        trans.buf   = &readByte;
                        trans.count = 1;
                        transferOK = UART_write(uartHandle, &trans);
                        if((SystemP_SUCCESS != (transferOK)) || (UART_TRANSFER_STATUS_SUCCESS != trans.status))
                        {
                            status = SystemP_FAILURE;
                        }
                    }
                }
                if(status != SystemP_SUCCESS)
                {
                    done = 1; /* break out in case of error */
                }
            }
        }
        return status;
    }
    
    
    
    #define READ_LINE_BUFSIZE   256
    /**
     *  @b Description
     *  @n
     *      This is the CLI Execution Task
     *
     *  \ingroup CLI_UTIL_INTERNAL_FUNCTION
     *
     *  @retval
     *      Not Applicable.
     */
    static void CLI_task(void* args)
    {
    
        uint8_t                 cmdString[READ_LINE_BUFSIZE];
        char*                   tokenizedArgs[CLI_MAX_ARGS];
        char*                   ptrCLICommand;
        char                    delimitter[] = " \r\n";
        uint32_t                argIndex;
        CLI_CmdTableEntry*      ptrCLICommandEntry;
        int32_t                 cliStatus, status;
        uint32_t                index;
    
        /* Do we have a banner to be displayed? */
        if (gCLI.cfg.cliBanner != NULL)
        {
            /* YES: Display the banner */
            CLI_write (gCLI.cfg.cliBanner);
        }
    
        /* Loop around forever: */
        while (1)
        {
            /* Demo Prompt: */
            CLI_write (gCLI.cfg.cliPrompt);
    
            /* Reset the command string: */
            memset ((void *)&cmdString[0], 0, sizeof(cmdString));
            
            status = CLI_readLine(gCLI.cfg.cliUartHandle, (char*)&cmdString[0], READ_LINE_BUFSIZE);
            if(status != SystemP_SUCCESS)
            {
                CLI_write("Error reading\n");
            }
    
            /* Reset all the tokenized arguments: */
            memset ((void *)&tokenizedArgs, 0, sizeof(tokenizedArgs));
            argIndex      = 0;
            ptrCLICommand = (char*)&cmdString[0];
    
            /* comment lines found - ignore the whole line*/
            if (cmdString[0]=='%' || cmdString[1]=='%')
            {
                CLI_write ("Skipped\n");
                continue;
            }
    
            /* Set the CLI status: */
            cliStatus = -1;
    
            /* The command has been entered we now tokenize the command message */
            while (1)
            {
                /* Tokenize the arguments: */
                tokenizedArgs[argIndex] = strtok(ptrCLICommand, delimitter);
                if (tokenizedArgs[argIndex] == NULL)
                    break;
    
                /* Increment the argument index: */
                argIndex++;
                if (argIndex >= CLI_MAX_ARGS)
                    break;
    
                /* Reset the command string */
                ptrCLICommand = NULL;
            }
    
            /* Were we able to tokenize the CLI command? */
            if (argIndex == 0)
                continue;
    
            /* Cycle through all the registered CLI commands: */
            for (index = 0; index < gCLI.numCLICommands; index++)
            {
                ptrCLICommandEntry = &gCLI.cfg.tableEntry[index];
    
                /* Do we have a match? */
                if (strcmp(ptrCLICommandEntry->cmd, tokenizedArgs[0]) == 0)
                {
                    /* YES: Pass this to the CLI registered function */
                    cliStatus = ptrCLICommandEntry->cmdHandlerFxn (argIndex, tokenizedArgs);
                    if (cliStatus == 0)
                    {
                        CLI_write ("Done\r\n");
                    }
                    else
                    {
                        CLI_write ("Error %d\r\n", cliStatus);
                    }
                    break;
                }
            }
    
            /* Did we get a matching CLI command? */
            if (index == gCLI.numCLICommands)
            {
                /* NO matching command found. Is the mmWave extension enabled? */
                if (gCLI.cfg.enableMMWaveExtension == 1U)
                {
                    /* Yes: Pass this to the mmWave extension handler */
                    cliStatus = CLI_MMWaveExtensionHandler (argIndex, tokenizedArgs);
                }
    
                /* Was the CLI command found? */
                if (cliStatus == -1)
                {
                    /* No: The command was still not found */
                    CLI_write ("'%s' is not recognized as a CLI command\n", tokenizedArgs[0]);
                }
            }
        }
    
    }
    
    /**
     *  @b Description
     *  @n
     *      Logging function which can log the messages to the CLI console
     *
     *  @param[in]  format
     *      Format string
     *
     *  \ingroup CLI_UTIL_EXTERNAL_FUNCTION
     *
     *  @retval
     *      Not Applicable.
     */
    void CLI_write (const char* format, ...)
    {
        va_list     arg;
        char        logMessage[256];
        int32_t     sizeMessage;
        UART_Transaction trans;
    
        UART_Transaction_init(&trans);
    
        /* Format the message: */
        va_start (arg, format);
        sizeMessage = vsnprintf (&logMessage[0], sizeof(logMessage), format, arg);
        va_end (arg);
    
        /* If CLI_write is called before CLI init has happened, return */
        if (gCLI.cfg.cliUartHandle == NULL)
        {
            return;
        }
    
        trans.buf   = &logMessage[0U];
        trans.count = sizeMessage;
    
        /* Log the message on the UART CLI console: */
        /* Blocking Mode: */
        UART_write (gCLI.cfg.cliUartHandle, &trans);
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the function which is used to initialize and setup the CLI
     *
     *  @param[in]  ptrCLICfg
     *      Pointer to the CLI configuration
     *
     *  \ingroup CLI_UTIL_EXTERNAL_FUNCTION
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    int32_t CLI_open (CLI_Cfg* ptrCLICfg)
    {
        uint32_t        index;
    
        /* Sanity Check: Validate the arguments */
        if (ptrCLICfg == NULL)
            return -1;
    
        /* Initialize the CLI MCB: */
        memset ((void*)&gCLI, 0, sizeof(CLI_MCB));
    
        /* Copy over the configuration: */
        memcpy ((void *)&gCLI.cfg, (void *)ptrCLICfg, sizeof(CLI_Cfg));
    
        /* Cycle through and determine the number of supported CLI commands: */
        for (index = 0; index < CLI_MAX_CMD; index++)
        {
            /* Do we have a valid entry? */
            if (gCLI.cfg.tableEntry[index].cmd == NULL)
            {
                /* NO: This is the last entry */
                break;
            }
            else
            {
                /* YES: Increment the number of CLI commands */
                gCLI.numCLICommands = gCLI.numCLICommands + 1;
            }
        }
    
        /* Is the mmWave Extension enabled? */
        if (gCLI.cfg.enableMMWaveExtension == 1U)
        {
            /* YES: Initialize the CLI Extension: */
            if (CLI_MMWaveExtensionInit (ptrCLICfg) < 0)
                return -1;
        }
    
        /* Do we have a CLI Prompt specified?  */
        if (gCLI.cfg.cliPrompt == NULL)
            gCLI.cfg.cliPrompt = "CLI:/>";
    
        /* The CLI provides a help command by default:
         * - Since we are adding this at the end of the table; a user of this module can also
         *   override this to provide its own implementation. */
        gCLI.cfg.tableEntry[gCLI.numCLICommands].cmd           = "help";
        gCLI.cfg.tableEntry[gCLI.numCLICommands].helpString    = NULL;
        gCLI.cfg.tableEntry[gCLI.numCLICommands].cmdHandlerFxn = CLI_help;
    
        /* Increment the number of CLI commands: */
        gCLI.numCLICommands++;
    
        gCliTask = xTaskCreateStatic( CLI_task,   /* Pointer to the function that implements the task. */
                                      "cli_task_main", /* Text name for the task.  This is to facilitate debugging only. */
                                      CLI_TASK_STACK_SIZE,  /* Stack depth in units of StackType_t typically uint32_t on 32b CPUs */
                                      NULL,              /* We are not using the task parameter. */
                                      ptrCLICfg->taskPriority,      /* task priority, 0 is lowest priority, configMAX_PRIORITIES-1 is highest */
                                      gCliTskStack,  /* pointer to stack base */
                                      &gCliTaskObj );    /* pointer to statically allocated task object memory */
        configASSERT(gCliTask != NULL);
    
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the function which is used to close the CLI module
     *
     *  \ingroup CLI_UTIL_EXTERNAL_FUNCTION
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    int32_t CLI_close (void)
    {
        /* Shutdown the CLI Task */
        vTaskDelete(gCliTask);
    
        /* Cleanup the memory */
        memset ((void*)&gCLI, 0, sizeof(CLI_MCB));
        return 0;
    }
    
    

    mmw_cli.c
    /*
     *   @file  mmw_cli.c
     *
     *   @brief
     *      Mmw (Milli-meter wave) DEMO CLI Implementation
     *
     *  \par
     *  NOTE:
     *      (C) Copyright 2018-2021 Texas Instruments, Inc.
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /**************************************************************************
     *************************** Include Files ********************************
     **************************************************************************/
    
    /* Standard Include Files. */
    #include <stdint.h>
    #include <stdlib.h>
    #include <stddef.h>
    #include <string.h>
    #include <stdio.h>
    
    /* MCU + SDK Include Files: */
    #include <drivers/uart.h>
    
    /* mmWave SDK Include Files: */
    #include <ti/common/syscommon.h>
    #include <ti/common/mmwavesdk_version.h>
    #include <ti/control/mmwavelink/mmwavelink.h>
    #include <ti/utils/cli/cli.h>
    #include <ti/utils/mathutils/mathutils.h>
    
    /* Demo Include Files */
    #include <ti/demo/am273x/mmw/include/mmw_config.h>
    #include <ti/demo/am273x/mmw/mss/mmw_mss.h>
    #include <ti/demo/utils/mmwdemo_adcconfig.h>
    #include <ti/demo/utils/mmwdemo_rfparser.h>
    #ifdef MMWDEMO_TDM
    #include <ti/datapath/dpc/dpu/cfarproc/cfarproccommon.h>
    #endif
    
    //add by Chris for cli hcc test
    #include <ti/utils/cli/include/cli_internal.h>
    extern CLI_MCB     gCLI;
    extern void MmwDemo_Bypass_CLI (void);
    //
    
    /**************************************************************************
     *************************** Local function prototype****************************
     **************************************************************************/
    
    /* CLI Extended Command Functions */
    static int32_t MmwDemo_CLICfarCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLISensorStart (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLISensorStop (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIGuiMonSel (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIADCBufCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIAoAFovCfg (int32_t argc, char* argv[]);
    #ifdef MMWDEMO_DDM
    static int32_t MmwDemo_CLICompressionCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLILocalMaxCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIIntfMitigCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIAntennaCalibParams (int32_t argc, char* argv[]);
    #endif
    #ifdef MMWDEMO_TDM
    static int32_t MmwDemo_CLIMultiObjBeamForming (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLICalibDcRangeSig (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIClutterRemoval (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLICompRangeBiasAndRxChanPhaseCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIMeasureRangeBiasAndRxChanPhaseCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLICfarFovCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIExtendedMaxVelocity (int32_t argc, char* argv[]);
    #endif
    static int32_t MmwDemo_CLIChirpQualityRxSatMonCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIChirpQualitySigImgMonCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIAnalogMonitorCfg (int32_t argc, char* argv[]);
    #ifdef LVDS_STREAM
    static int32_t MmwDemo_CLILvdsStreamCfg (int32_t argc, char* argv[]);
    #endif
    static int32_t MmwDemo_CLIConfigDataPort (int32_t argc, char* argv[]);
    #ifdef ENET_STREAM
    static int32_t MmwDemo_CLIQueryLocalIp (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIEnetCfg(int32_t argc, char* argv[]);
    #endif
    
    /**************************************************************************
     *************************** Extern Definitions *******************************
     **************************************************************************/
    
    extern MmwDemo_MSS_MCB    gMmwMssMCB;
    
    /**************************************************************************
     *************************** Local Definitions ****************************
     **************************************************************************/
    
    #define MMWDEMO_DATAUART_MAX_BAUDRATE_SUPPORTED 3125000
    
    /**************************************************************************
     *************************** CLI  Function Definitions **************************
     **************************************************************************/
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for the sensor start command
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLISensorStart (int32_t argc, char* argv[])
    {
        bool        doReconfig = true;
        int32_t     retVal = 0;
    
        /*  Only following command syntax will be supported 
            sensorStart
            sensorStart 0
        */
        if (argc == 2)
        {
            doReconfig = (bool) atoi (argv[1]);
    
            if (doReconfig == true)
            {
                CLI_write ("Error: Reconfig is not supported, only argument of 0 is\n"
                           "(do not reconfig, just re-start the sensor) valid\n");
                return -1;
            }
        }
        else
        {
            /* In case there is no argument for sensorStart, always do reconfig */
            doReconfig = true;
        }
    
        /***********************************************************************************
         * Do sensor state management to influence the sensor actions
         ***********************************************************************************/
    
        /* Error checking initial state: no partial config is allowed 
           until the first sucessful sensor start state */
        if ((gMmwMssMCB.sensorState == MmwDemo_SensorState_INIT) || 
             (gMmwMssMCB.sensorState == MmwDemo_SensorState_OPENED))
        {
            MMWave_CtrlCfg ctrlCfg;
    
            /* need to get number of sub-frames so that next function to check
             * pending state can work */
            CLI_getMMWaveExtensionConfig (&ctrlCfg);
            gMmwMssMCB.objDetCommonCfg.preStartCommonCfg.numSubFrames =
                MmwDemo_RFParser_getNumSubFrames(&ctrlCfg);
    
    #ifdef MMWDEMO_TDM
            if (MmwDemo_isAllCfgInPendingState() == 0)
            {
                CLI_write ("Error: Full configuration must be provided before sensor can be started "
                           "the first time\n");
    
                /* Although not strictly needed, bring back to the initial value since we
                 * are rejecting this first time configuration, prevents misleading debug. */
                gMmwMssMCB.objDetCommonCfg.preStartCommonCfg.numSubFrames = 0;
    
                return -1;
            }
    #endif
    
        }
    
        if (gMmwMssMCB.sensorState == MmwDemo_SensorState_STARTED)
        {
            CLI_write ("Ignored: Sensor is already started\n");
            return 0;
        }
    
        if (doReconfig == false)
        {
    #ifdef MMWDEMO_TDM
             /* User intends to issue sensor start without config, check if no
                config was issued after stop and generate error if this is the case. */
             if (MmwDemo_isAllCfgInNonPendingState() == 0)
             {
                 /* Message user differently if all config was issued or partial config was
                    issued. */
                 if (MmwDemo_isAllCfgInPendingState())
                 {
                     CLI_write ("Error: You have provided complete new configuration, "
                                "issue \"sensorStart\" (without argument) if you want it to "
                                "take effect\n");
                 }
                 else
                 {
                     CLI_write ("Error: You have provided partial configuration between stop and this "
                                "command and partial configuration cannot be undone."
                                "Issue the full configuration and do \"sensorStart\" \n");
                 }
                 return -1;
             }
    #endif
        }
        else
        {
            /* User intends to issue sensor start with full config, check if all config
               was issued after stop and generate error if  is the case. */
            MMWave_CtrlCfg ctrlCfg;
    
            /* need to get number of sub-frames so that next function to check
             * pending state can work */
            CLI_getMMWaveExtensionConfig (&ctrlCfg);
            gMmwMssMCB.objDetCommonCfg.preStartCommonCfg.numSubFrames =
                MmwDemo_RFParser_getNumSubFrames(&ctrlCfg);
    
    #ifdef MMWDEMO_TDM 
            if (MmwDemo_isAllCfgInPendingState() == 0)
            {
                /* Message user differently if no config was issued or partial config was
                   issued. */
                if (MmwDemo_isAllCfgInNonPendingState())
                {
                    CLI_write ("Error: You have provided no configuration, "
                               "issue \"sensorStart 0\" OR provide "
                               "full configuration and issue \"sensorStart\"\n");
                }
                else
                {
                    CLI_write ("Error: You have provided partial configuration between stop and this "
                               "command and partial configuration cannot be undone."
                               "Issue the full configuration and do \"sensorStart\" \n");
                }
                /* Although not strictly needed, bring back to the initial value since we
                 * are rejecting this first time configuration, prevents misleading debug. */
                gMmwMssMCB.objDetCommonCfg.preStartCommonCfg.numSubFrames = 0;
                return -1;
            }
    #endif
        }
    
        /***********************************************************************************
         * Retreive and check mmwave Open related config before calling openSensor
         ***********************************************************************************/
    
        /*  Fill demo's MCB mmWave openCfg structure from the CLI configs*/
        if (gMmwMssMCB.sensorState == MmwDemo_SensorState_INIT)
        {
            /* Get the open configuration: */
            CLI_getMMWaveExtensionOpenConfig (&gMmwMssMCB.cfg.openCfg);
            /* call sensor open */
            retVal = MmwDemo_openSensor(true);
            if(retVal != 0)
            {
                return -1;
            }
            gMmwMssMCB.sensorState = MmwDemo_SensorState_OPENED;    
        }
        else
        {
            /* openCfg related configurations like chCfg, lowPowerMode, adcCfg
             * are only used on the first sensor start. If they are different
             * on a subsequent sensor start, then generate a fatal error
             * so the user does not think that the new (changed) configuration
             * takes effect, the board needs to be reboot for the new
             * configuration to be applied.
             */
            MMWave_OpenCfg openCfg;
            CLI_getMMWaveExtensionOpenConfig (&openCfg);
            /* Compare openCfg->chCfg*/
            if(memcmp((void *)&gMmwMssMCB.cfg.openCfg.frontEndCfg[0].chCfg, (void *)&openCfg.frontEndCfg[0].chCfg,
                              sizeof(rlChanCfg_t)) != 0)
            {
                MmwDemo_debugAssert(0);
            }
            
            /* Compare openCfg->lowPowerMode*/
            if(memcmp((void *)&gMmwMssMCB.cfg.openCfg.lowPowerMode, (void *)&openCfg.lowPowerMode,
                              sizeof(rlLowPowerModeCfg_t)) != 0)
            {
                MmwDemo_debugAssert(0);
            }
            /* Compare openCfg->adcOutCfg*/
            if(memcmp((void *)&gMmwMssMCB.cfg.openCfg.adcOutCfg, (void *)&openCfg.adcOutCfg,
                              sizeof(rlAdcOutCfg_t)) != 0)
            {
                MmwDemo_debugAssert(0);
            }
        }
    
    
    
        /***********************************************************************************
         * Retrieve mmwave Control related config before calling startSensor
         ***********************************************************************************/
        /* Get the mmWave ctrlCfg from the CLI mmWave Extension */
        if(doReconfig)
        {
            /* if MmwDemo_openSensor has non-first time related processing, call here again*/
            /* call sensor config */
            CLI_getMMWaveExtensionConfig (&gMmwMssMCB.cfg.ctrlCfg);
            retVal = MmwDemo_configSensor();
            if(retVal != 0)
            {
                return -1;
            }
        }
        retVal = MmwDemo_startSensor();
        if(retVal != 0)
        {
            return -1;
        }
    
        /***********************************************************************************
         * Set the state
         ***********************************************************************************/
        gMmwMssMCB.sensorState = MmwDemo_SensorState_STARTED;
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for the sensor stop command
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLISensorStop (int32_t argc, char* argv[])
    {
        if ((gMmwMssMCB.sensorState == MmwDemo_SensorState_STOPPED) ||
            (gMmwMssMCB.sensorState == MmwDemo_SensorState_INIT) ||
            (gMmwMssMCB.sensorState == MmwDemo_SensorState_OPENED))
        {
            CLI_write ("Ignored: Sensor is already stopped\n");
            return 0;
        }
    
        MmwDemo_stopSensor();
    
        gMmwMssMCB.sensorState = MmwDemo_SensorState_STOPPED;
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      Utility function to get sub-frame number
     *
     *  @param[in] argc  Number of arguments
     *  @param[in] argv  Arguments
     *  @param[in] expectedArgc Expected number of arguments
     *  @param[out] subFrameNum Sub-frame Number (0 based)
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIGetSubframe (int32_t argc, char* argv[], int32_t expectedArgc,
                                           int8_t* subFrameNum)
    {
        int8_t subframe;
        
        /* Sanity Check: Minimum argument check */
        if (argc != expectedArgc)
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
    
        /*Subframe info is always in position 1*/
        subframe = (int8_t) atoi(argv[1]);
    
        if(subframe >= (int8_t)RL_MAX_SUBFRAMES)
        {
            CLI_write ("Error: Subframe number is invalid\n");
            return -1;
        }
    
        *subFrameNum = (int8_t)subframe;
    
        return 0;
    }
    
    
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for gui monitoring configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIGuiMonSel (int32_t argc, char* argv[])
    {
        MmwDemo_GuiMonSel   guiMonSel;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 8, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize the guiMonSel configuration: */
        memset ((void *)&guiMonSel, 0, sizeof(MmwDemo_GuiMonSel));
    
        /* Populate configuration: */
        guiMonSel.detectedObjects           = atoi (argv[2]);
        guiMonSel.logMagRange               = atoi (argv[3]);
        guiMonSel.noiseProfile              = atoi (argv[4]);
        guiMonSel.rangeAzimuthHeatMap       = atoi (argv[5]);
        guiMonSel.rangeDopplerHeatMap       = atoi (argv[6]);
        guiMonSel.statsInfo                 = atoi (argv[7]);
    
        MmwDemo_CfgUpdate((void *)&guiMonSel, MMWDEMO_GUIMONSEL_OFFSET,
            sizeof(MmwDemo_GuiMonSel), subFrameNum);
    
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for AoA FOV (Field Of View) configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIAoAFovCfg (int32_t argc, char* argv[])
    {
        
    #ifdef MMWDEMO_TDM
        DPU_AoAProc_FovAoaCfg   fovCfg;
    #elif defined(MMWDEMO_DDM)
        DPC_ObjectDetection_FovAoaCfg   fovCfg;
    #endif
    
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 6, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&fovCfg, 0, sizeof(fovCfg));
    
        /* Populate configuration: */
        fovCfg.minAzimuthDeg      = (float) atoi (argv[2]);
        fovCfg.maxAzimuthDeg      = (float) atoi (argv[3]);
        fovCfg.minElevationDeg    = (float) atoi (argv[4]);
        fovCfg.maxElevationDeg    = (float) atoi (argv[5]);
    
        /* Save Configuration to use later */
        MmwDemo_CfgUpdate((void *)&fovCfg, MMWDEMO_FOVAOA_OFFSET,
                          sizeof(fovCfg), subFrameNum);
        return 0;
    }
    
    
    #ifdef MMWDEMO_TDM
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for CFAR configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLICfarCfg (int32_t argc, char* argv[])
    {
        DPU_CFARProc_CfarCfg   cfarCfg;
        uint32_t            procDirection;
        int8_t              subFrameNum;
        float               threshold;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 10, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&cfarCfg, 0, sizeof(cfarCfg));
    
        /* Populate configuration: */
        procDirection             = (uint32_t) atoi (argv[2]);
        cfarCfg.averageMode       = (uint8_t) atoi (argv[3]);
        cfarCfg.winLen            = (uint8_t) atoi (argv[4]);
        cfarCfg.guardLen          = (uint8_t) atoi (argv[5]);
        cfarCfg.noiseDivShift     = (uint8_t) atoi (argv[6]);
        cfarCfg.cyclicMode        = (uint8_t) atoi (argv[7]);
        threshold                 = (float) atof (argv[8]);
        cfarCfg.peakGroupingEn    = (uint8_t) atoi (argv[9]);
    
        if (threshold > 100.0)
        {
            CLI_write("Error: Maximum value for CFAR thresholdScale is 100.0 dB.\n");
            return -1;
        }   
        
        /* threshold is a float value from 0-100dB. It needs to
           be later converted to linear scale (conversion can only be done
           when the number of virtual antennas is known) before passing it
           to CFAR DPU.
           For now, the threshold will be coded in a 16bit integer in the following
           way:
           suppose threshold is a float represented as XYZ.ABC
           it will be saved as a 16bit integer XYZAB       
           that is, 2 decimal cases are saved.*/
        threshold = threshold * MMWDEMO_CFAR_THRESHOLD_ENCODING_FACTOR;   
        cfarCfg.thresholdScale    = (uint16_t) threshold;
        
        /* Save Configuration to use later */     
        if (procDirection == 0)
        {
            MmwDemo_CfgUpdate((void *)&cfarCfg, MMWDEMO_CFARCFGRANGE_OFFSET,
                              sizeof(cfarCfg), subFrameNum);
        }
        else
        {
            MmwDemo_CfgUpdate((void *)&cfarCfg, MMWDEMO_CFARCFGDOPPLER_OFFSET,
                              sizeof(cfarCfg), subFrameNum);
        }
        return 0;
    }
    #endif
    
    #ifdef MMWDEMO_DDM
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for CFAR configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLICfarCfg (int32_t argc, char* argv[])
    {
        DPU_DopplerProc_CfarCfg   cfarCfg;
        uint32_t            procDirection;
        int8_t              subFrameNum;
        float               threshold;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 12, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&cfarCfg, 0, sizeof(cfarCfg));
    
        /* Populate configuration: */
        procDirection             = (uint32_t) atoi (argv[2]);
        cfarCfg.averageMode       = (uint8_t) atoi (argv[3]);
        cfarCfg.winLen            = (uint8_t) atoi (argv[4]);
        cfarCfg.guardLen          = (uint8_t) atoi (argv[5]);
        cfarCfg.noiseDivShift     = (uint8_t) atoi (argv[6]);
        cfarCfg.cyclicMode        = (uint8_t) atoi (argv[7]);
        threshold                 = (float) atof (argv[8]);
        cfarCfg.peakGroupingEn    = (uint8_t) atoi (argv[9]);
        cfarCfg.osKvalue          = (uint8_t) atoi (argv[10]);
        cfarCfg.osEdgeKscaleEn    = (uint8_t) atoi (argv[11]);
    
        if (threshold > 100.0)
        {
            CLI_write("Error: Maximum value for CFAR thresholdScale is 100.0 dB.\n");
            return -1;
        }   
        
        /* threshold is a float value from 0-100dB. It needs to
           be later converted to linear scale (conversion can only be done
           when the number of virtual antennas is known) before passing it
           to CFAR DPU.
           For now, the threshold will be coded in a 16bit integer in the following
           way:
           suppose threshold is a float represented as XYZ.ABC
           it will be saved as a 16bit integer XYZAB       
           that is, 2 decimal cases are saved.*/
        threshold = threshold * MMWDEMO_CFAR_THRESHOLD_ENCODING_FACTOR;   
        cfarCfg.thresholdScale    = (uint16_t) threshold;
        
        /* Save Configuration to use later */     
        if (procDirection == 0)
        {
            MmwDemo_CfgUpdate((void *)&cfarCfg, MMWDEMO_CFARCFGRANGE_OFFSET,
                              sizeof(cfarCfg), subFrameNum);
        }
        else
        {
            MmwDemo_CfgUpdate((void *)&cfarCfg, MMWDEMO_CFARDOPPLERCFG_OFFSET,
                              sizeof(cfarCfg), subFrameNum);
        }
        return 0;
    }
    #endif
    
    #ifdef MMWDEMO_DDM
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for Compression configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLICompressionCfg (int32_t argc, char* argv[])
    {
        DPU_RangeProcHWA_CompressionCfg   compressionCfg;
        int8_t                            subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 6, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&compressionCfg, 0, sizeof(compressionCfg));
    
        /* Populate configuration: */
        compressionCfg.isEnabled              = (bool) atoi (argv[2]);
        compressionCfg.compressionMethod      = (uint16_t) atoi (argv[3]);
        compressionCfg.compressionRatio       = (float) atof (argv[4]);
        compressionCfg.rangeBinsPerBlock      = (uint16_t) atoi (argv[5]);
        /* rxAntennasPerBlock will be fixed to the number of Rx antennas */
    
        if (!((compressionCfg.rangeBinsPerBlock & (compressionCfg.rangeBinsPerBlock - 1)) == 0)) /* is it a power of 2? */
        {
            CLI_write("Error: rangeBinsPerBlock should be a power of 2 \n");
            return -1;
        }   
        
        MmwDemo_CfgUpdate((void *)&compressionCfg, MMWDEMO_COMPRESSIONCFG_OFFSET,
                              sizeof(compressionCfg), subFrameNum);
        
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for Local Max configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLILocalMaxCfg (int32_t argc, char* argv[])
    {
    
        DPU_DopplerProc_LocalMaxCfg         localMaxCfg;
        int8_t                              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 4, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&localMaxCfg, 0, sizeof(localMaxCfg));
    
        /* Populate configuration: */
        localMaxCfg.azimThreshold                = (uint16_t) atoi (argv[2]);
        localMaxCfg.dopplerThreshold             = (uint16_t) atoi (argv[3]);
        
        MmwDemo_CfgUpdate((void *)&localMaxCfg, MMWDEMO_LOCALMAXCFG_OFFSET,
                              sizeof(localMaxCfg), subFrameNum);
        
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for Interference Mitigation configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIIntfMitigCfg (int32_t argc, char* argv[])
    {
    
        DPU_RangeProcHWADDMA_intfStatsdBCfg  intfStatsdBCfg;
        int8_t                               subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 4, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&intfStatsdBCfg, 0, sizeof(intfStatsdBCfg));
    
        /* Populate configuration: */
        intfStatsdBCfg.intfMitgMagSNRdB               = (uint32_t) atoi (argv[2]);
        intfStatsdBCfg.intfMitgMagDiffSNRdB           = (uint32_t) atoi (argv[3]);
        
        MmwDemo_CfgUpdate((void *)&intfStatsdBCfg, MMWDEMO_INTFMITIGCFG_OFFSET,
                              sizeof(intfStatsdBCfg), subFrameNum);
        
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for Antenna Calibration configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIAntennaCalibParams (int32_t argc, char* argv[])
    {
    
        /*! @brief      Antenna Calbration parameters in Im/Re format */
        float antennaCalibParams[SYS_COMMON_NUM_RX_CHANNEL * SYS_COMMON_NUM_TX_ANTENNAS * 2];
        int32_t argInd, i;
    
        /* Sanity Check: Minimum argument check */
        if (argc < (1 + SYS_COMMON_NUM_TX_ANTENNAS*SYS_COMMON_NUM_RX_CHANNEL*2))
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&antennaCalibParams, 0, sizeof(antennaCalibParams));
    
        argInd = 1;
        for (i = 0; i < SYS_COMMON_NUM_TX_ANTENNAS * SYS_COMMON_NUM_RX_CHANNEL * 2; i++)
        {
            antennaCalibParams[i] = (float) atof (argv[i+argInd]);
        }
    
        /* Save Configuration to use later */
        memcpy((void *) &gMmwMssMCB.objDetCommonCfg.preStartCommonCfg.antennaCalibParams,
               &antennaCalibParams, sizeof(antennaCalibParams));
    
        gMmwMssMCB.objDetCommonCfg.isAntennaCalibParamCfgPending = 1;
    
        return 0;
    
    }
    #endif
    
    #ifdef MMWDEMO_TDM
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for CFAR FOV (Field Of View) configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLICfarFovCfg (int32_t argc, char* argv[])
    {
        
        DPU_CFARProc_FovCfg   fovCfg;
        uint32_t            procDirection;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 5, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&fovCfg, 0, sizeof(fovCfg));
    
        /* Populate configuration: */
        procDirection             = (uint32_t) atoi (argv[2]);
        fovCfg.min                = (float) atof (argv[3]);
        fovCfg.max                = (float) atof (argv[4]);
    
        /* Save Configuration to use later */
        if (procDirection == 0)
        {
            MmwDemo_CfgUpdate((void *)&fovCfg, MMWDEMO_FOVRANGE_OFFSET,
                              sizeof(fovCfg), subFrameNum);
        }
        else
        {
            MmwDemo_CfgUpdate((void *)&fovCfg, MMWDEMO_FOVDOPPLER_OFFSET,
                              sizeof(fovCfg), subFrameNum);
        }
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for extended maximum velocity configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIExtendedMaxVelocity (int32_t argc, char* argv[])
    {
        DPU_AoAProc_ExtendedMaxVelocityCfg   cfg;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 3, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&cfg, 0, sizeof(cfg));
    
        /* Populate configuration: */
        cfg.enabled      = (uint8_t) atoi (argv[2]);
    
        /* Save Configuration to use later */
        MmwDemo_CfgUpdate((void *)&cfg, MMWDEMO_EXTMAXVEL_OFFSET,
                          sizeof(cfg), subFrameNum);
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for multi object beam forming configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIMultiObjBeamForming (int32_t argc, char* argv[])
    {
        DPU_AoAProc_MultiObjBeamFormingCfg cfg;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 4, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&cfg, 0, sizeof(cfg));
    
        /* Populate configuration: */
        cfg.enabled                     = (uint8_t) atoi (argv[2]);
        cfg.multiPeakThrsScal           = (float) atof (argv[3]);
    
        /* Save Configuration to use later */
        MmwDemo_CfgUpdate((void *)&cfg, MMWDEMO_MULTIOBJBEAMFORMING_OFFSET,
                          sizeof(cfg), subFrameNum);
    
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for DC range calibration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLICalibDcRangeSig (int32_t argc, char* argv[])
    {
        DPU_RangeProc_CalibDcRangeSigCfg cfg;
        uint32_t                   log2NumAvgChirps;
        int8_t                     subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 6, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration for DC range signature calibration */
        memset ((void *)&cfg, 0, sizeof(cfg));
    
        /* Populate configuration: */
        cfg.enabled          = (uint16_t) atoi (argv[2]);
        cfg.negativeBinIdx   = (int16_t)  atoi (argv[3]);
        cfg.positiveBinIdx   = (int16_t)  atoi (argv[4]);
        cfg.numAvgChirps     = (uint16_t) atoi (argv[5]);
    
        if (cfg.negativeBinIdx > 0)
        {
            CLI_write ("Error: Invalid negative bin index\n");
            return -1;
        }
        if (cfg.positiveBinIdx < 0)
        {
            CLI_write ("Error: Invalid positive bin index\n");
            return -1;
        }	
        if ((cfg.positiveBinIdx - cfg.negativeBinIdx + 1) > DPU_RANGEPROC_SIGNATURE_COMP_MAX_BIN_SIZE)
        {
            CLI_write ("Error: Number of bins exceeds the limit\n");
            return -1;
        }
        log2NumAvgChirps = (uint32_t) mathUtils_ceilLog2(cfg.numAvgChirps);
        if (cfg.numAvgChirps != (1U << log2NumAvgChirps))
        {
            CLI_write ("Error: Number of averaged chirps is not power of two\n");
            return -1;
        }
    
        /* Save Configuration to use later */
        MmwDemo_CfgUpdate((void *)&cfg, MMWDEMO_CALIBDCRANGESIG_OFFSET,
                          sizeof(cfg), subFrameNum);
    
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      Clutter removal Configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIClutterRemoval (int32_t argc, char* argv[])
    {
        DPC_ObjectDetection_StaticClutterRemovalCfg_Base cfg;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 3, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration for clutter removal */
        memset ((void *)&cfg, 0, sizeof(cfg));
    
        /* Populate configuration: */
        cfg.enabled          = (uint16_t) atoi (argv[2]);
    
        /* Save Configuration to use later */
        MmwDemo_CfgUpdate((void *)&cfg, MMWDEMO_STATICCLUTTERREMOFVAL_OFFSET,
                          sizeof(cfg), subFrameNum);
    
        return 0;
    }
    #endif
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for data logger set command
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIADCBufCfg (int32_t argc, char* argv[])
    {
        MmwDemo_ADCBufCfg   adcBufCfg;
        int8_t              subFrameNum;
    
        if (gMmwMssMCB.sensorState == MmwDemo_SensorState_STARTED)
        {
            CLI_write ("Ignored: This command is not allowed after sensor has started\n");
            return 0;
        }
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 6, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize the ADC Output configuration: */
        memset ((void *)&adcBufCfg, 0, sizeof(adcBufCfg));
    
        /* Populate configuration: */
        adcBufCfg.adcFmt          = (uint8_t) atoi (argv[2]);
        adcBufCfg.iqSwapSel       = (uint8_t) atoi (argv[3]);
        adcBufCfg.chInterleave    = (uint8_t) atoi (argv[4]);
        adcBufCfg.chirpThreshold  = (uint8_t) atoi (argv[5]);
    
        /* This demo is using HWA for 1D processing which does not allow multi-chirp
         * processing */
        if (adcBufCfg.chirpThreshold != 1)
        {
            CLI_write("Error: chirpThreshold must be 1, multi-chirp is not allowed\n");
            return -1;
        }
    
        /* Save Configuration to use later */
        MmwDemo_CfgUpdate((void *)&adcBufCfg,
                          MMWDEMO_ADCBUFCFG_OFFSET,
                          sizeof(MmwDemo_ADCBufCfg), subFrameNum);
        return 0;
    }
    
    #ifdef MMWDEMO_TDM
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for compensation of range bias and channel phase offsets
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLICompRangeBiasAndRxChanPhaseCfg (int32_t argc, char* argv[])
    {
        DPU_AoAProc_compRxChannelBiasCfg   cfg;
        int32_t Re, Im;
        int32_t argInd;
        int32_t i;
    
        /* Sanity Check: Minimum argument check */
        if (argc != (1+1+SYS_COMMON_NUM_TX_ANTENNAS*SYS_COMMON_NUM_RX_CHANNEL*2))
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&cfg, 0, sizeof(cfg));
    
        /* Populate configuration: */
        cfg.rangeBias          = (float) atof (argv[1]);
    
        argInd = 2;
        for (i=0; i < SYS_COMMON_NUM_TX_ANTENNAS*SYS_COMMON_NUM_RX_CHANNEL; i++)
        {
            Re = (int32_t) (atof (argv[argInd++]) * 32768.);
            MATHUTILS_SATURATE16(Re);
            cfg.rxChPhaseComp[i].real = (int16_t) Re;
    
            Im = (int32_t) (atof (argv[argInd++]) * 32768.);
            MATHUTILS_SATURATE16(Im);
            cfg.rxChPhaseComp[i].imag = (int16_t) Im;
    
        }
        /* Save Configuration to use later */
        memcpy((void *) &gMmwMssMCB.objDetCommonCfg.preStartCommonCfg.compRxChanCfg,
               &cfg, sizeof(cfg));
    
        gMmwMssMCB.objDetCommonCfg.isCompRxChannelBiasCfgPending = 1;
    
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for measurement configuration of range bias
     *      and channel phase offsets
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIMeasureRangeBiasAndRxChanPhaseCfg (int32_t argc, char* argv[])
    {
        DPC_ObjectDetection_MeasureRxChannelBiasCfg   cfg;
    
        /* Sanity Check: Minimum argument check */
        if (argc != 4)
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&cfg, 0, sizeof(cfg));
    
        /* Populate configuration: */
        cfg.enabled          = (uint8_t) atoi (argv[1]);
        cfg.targetDistance   = (float) atof (argv[2]);
        cfg.searchWinSize   = (float) atof (argv[3]);
    
        /* Save Configuration to use later */
        memcpy((void *) &gMmwMssMCB.objDetCommonCfg.preStartCommonCfg.measureRxChannelBiasCfg,
               &cfg, sizeof(cfg));
    
        gMmwMssMCB.objDetCommonCfg.isMeasureRxChannelBiasCfgPending = 1;
    
        return 0;
    }
    #endif
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for configuring CQ RX Saturation monitor
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIChirpQualityRxSatMonCfg (int32_t argc, char* argv[])
    {
        rlRxSatMonConf_t        cqSatMonCfg;
    
        if (gMmwMssMCB.sensorState == MmwDemo_SensorState_STARTED)
        {
            CLI_write ("Ignored: This command is not allowed after sensor has started\n");
            return 0;
        }
    
        /* Sanity Check: Minimum argument check */
        if (argc != 6)
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&cqSatMonCfg, 0, sizeof(rlRxSatMonConf_t));
    
        /* Populate configuration: */
        cqSatMonCfg.profileIndx                 = (uint8_t) atoi (argv[1]);
    
        if(cqSatMonCfg.profileIndx < RL_MAX_PROFILES_CNT)
        {
    
            cqSatMonCfg.satMonSel                   = (uint8_t) atoi (argv[2]);
            cqSatMonCfg.primarySliceDuration        = (uint16_t) atoi (argv[3]);
            cqSatMonCfg.numSlices                   = (uint16_t) atoi (argv[4]);
            cqSatMonCfg.rxChannelMask               = (uint8_t) atoi (argv[5]);
    
            /* Save Configuration to use later */
            gMmwMssMCB.cqSatMonCfg[cqSatMonCfg.profileIndx] = cqSatMonCfg;
    
            return 0;
        }
        else
        {
            return -1;
        }
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for configuring CQ Signal & Image band monitor
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIChirpQualitySigImgMonCfg (int32_t argc, char* argv[])
    {
        rlSigImgMonConf_t       cqSigImgMonCfg;
    
        if (gMmwMssMCB.sensorState == MmwDemo_SensorState_STARTED)
        {
            CLI_write ("Ignored: This command is not allowed after sensor has started\n");
            return 0;
        }
    
        /* Sanity Check: Minimum argument check */
        if (argc != 4)
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&cqSigImgMonCfg, 0, sizeof(rlSigImgMonConf_t));
    
        /* Populate configuration: */
        cqSigImgMonCfg.profileIndx              = (uint8_t) atoi (argv[1]);
    
        if(cqSigImgMonCfg.profileIndx < RL_MAX_PROFILES_CNT)
        {
            cqSigImgMonCfg.numSlices            = (uint8_t) atoi (argv[2]);
            cqSigImgMonCfg.timeSliceNumSamples  = (uint16_t) atoi (argv[3]);
    
            /* Save Configuration to use later */
            gMmwMssMCB.cqSigImgMonCfg[cqSigImgMonCfg.profileIndx] = cqSigImgMonCfg;
    
            return 0;
        }
        else
        {
            return -1;
        }
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for enabling analog monitors
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIAnalogMonitorCfg (int32_t argc, char* argv[])
    {
        if (gMmwMssMCB.sensorState == MmwDemo_SensorState_STARTED)
        {
            CLI_write ("Ignored: This command is not allowed after sensor has started\n");
            return 0;
        }
    
        /* Sanity Check: Minimum argument check */
        if (argc != 3)
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
    
        /* Save Configuration to use later */
        gMmwMssMCB.anaMonCfg.rxSatMonEn = atoi (argv[1]);
        gMmwMssMCB.anaMonCfg.sigImgMonEn = atoi (argv[2]);
        gMmwMssMCB.isAnaMonCfgPending = 1;
    
        return 0;
    }
    
    #ifdef LVDS_STREM
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for the High Speed Interface
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLILvdsStreamCfg (int32_t argc, char* argv[])
    {
        MmwDemo_LvdsStreamCfg   cfg;
        int8_t                  subFrameNum;
    
        if (gMmwMssMCB.sensorState == MmwDemo_SensorState_STARTED)
        {
            CLI_write ("Ignored: This command is not allowed after sensor has started\n");
            return 0;
        }
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 5, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration for DC range signature calibration */
        memset ((void *)&cfg, 0, sizeof(MmwDemo_LvdsStreamCfg));
    
        /* Populate configuration: */
        cfg.isHeaderEnabled = (bool)    atoi(argv[2]);
        cfg.dataFmt         = (uint8_t) atoi(argv[3]);
        cfg.isSwEnabled     = (bool)    atoi(argv[4]);
    
        /* If both h/w and s/w are enabled, HSI header must be enabled, because
         * we don't allow mixed h/w session without HSI header
         * simultaneously with s/w session with HSI header (s/w session always
         * streams HSI header) */
        if ((cfg.isSwEnabled == true) && (cfg.dataFmt != MMW_DEMO_LVDS_STREAM_CFG_DATAFMT_DISABLED))
        {
            if (cfg.isHeaderEnabled == false)
            {
                CLI_write("Error: header must be enabled when both h/w and s/w streaming are enabled\n");
                return -1;
            }
        }
    
        /* Save Configuration to use later */
        MmwDemo_CfgUpdate((void *)&cfg,
                          MMWDEMO_LVDSSTREAMCFG_OFFSET,
                          sizeof(MmwDemo_LvdsStreamCfg), subFrameNum);
    
        return 0;
    }
    #endif
    
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for configuring the data port
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIConfigDataPort (int32_t argc, char* argv[])
    {
        uint32_t baudrate;
        bool  ackPing;
        uint8_t ackData[16];
        UART_Transaction trans;
    
        UART_Transaction_init(&trans);
    
        trans.buf   = &ackData[0U];
        trans.count = sizeof(ackData);
    
    
        if (gMmwMssMCB.sensorState == MmwDemo_SensorState_STARTED)
        {
            CLI_write ("Ignored: This command is not allowed after sensor has started\n");
            return 0;
        }
    
        /* Populate configuration: */
        baudrate = (uint32_t) atoi(argv[1]);
        ackPing = (bool) atoi(argv[2]);
    
        /* check if requested value is less than max supported value */
        if (baudrate > MMWDEMO_DATAUART_MAX_BAUDRATE_SUPPORTED)
        {
            CLI_write ("Ignored: Invalid baud rate (%d) specified\n",baudrate);
            return 0;
        }
    
        /* regardless of baud rate update, ack back to the host over this UART 
           port if handle is valid and user has requested the ack back */
        if ((gMmwMssMCB.loggingUartHandle != NULL) && (ackPing == true))
        {
            memset(ackData,0xFF,sizeof(ackData));
            UART_write(gMmwMssMCB.loggingUartHandle, &trans);
        }
    
        return 0;
    }
    
    
    
    
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for querying Demo status
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIQueryDemoStatus (int32_t argc, char* argv[])
    {
        CLI_write ("Sensor State: %d\n",gMmwMssMCB.sensorState);
        CLI_write ("Data port baud rate: %d\n",gMmwMssMCB.cfg.platformCfg.loggingBaudRate);
    
        return 0;
    }
    
    #ifdef ENET_STREAM
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for querying Local IP
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIQueryLocalIp (int32_t argc, char* argv[])
    {
        if(gMmwMssMCB.enetCfg.status == 1){
            CLI_write ("Local IP is: %s\n", ip4addr_ntoa((const ip4_addr_t *)&gMmwMssMCB.enetCfg.localIp));
        }
        else{
            CLI_write ("Local IP is not up yet !!\n");
        }
    
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for ethernet configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIEnetCfg(int32_t argc, char* argv[])
    {
    
        volatile uint32_t remoteIp[4] = {0};
        uint8_t idx;
    
        if (gMmwMssMCB.sensorState == MmwDemo_SensorState_STARTED)
        {
            CLI_write ("Ignored: This command is not allowed after sensor has started\n");
            return 0;
        }
    
        /* Sanity Check: Minimum argument check */
        if (argc != 6)
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
        
        /* Populate configuration: */
        gMmwMssMCB.enetCfg.streamEnable = (bool) atoi(argv[1]);
        /* Get the IP Address */
        for(idx = 0; idx < 4; idx++){
            remoteIp[idx] = (uint32_t)atoi(argv[idx+2]);
        }
        /* Populate the IP Address */
        gMmwMssMCB.enetCfg.remoteIp = (ip_addr_t) IPADDR4_INIT_BYTES(remoteIp[0],remoteIp[1],remoteIp[2],remoteIp[3]);
        CLI_write("Remote IP Address is %s\n", ip4addr_ntoa(&gMmwMssMCB.enetCfg.remoteIp));
    
        if(gMmwMssMCB.enetCfg.streamEnable){
            MmwDemo_mssEnetCfgDone();
        }
    
        return 0;
    }
    #endif
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for save/restore calibration data to/from flash
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLICalibDataSaveRestore(int32_t argc, char* argv[])
    {
        if (gMmwMssMCB.sensorState == MmwDemo_SensorState_STARTED)
        {
            CLI_write ("Ignored: This command is not allowed after sensor has started\n");
            return 0;
        }
    
        /* Validate inputs */
        if ( ((uint32_t) atoi(argv[1]) == 1) && ((uint32_t) atoi(argv[2] ) == 1))
        {
            CLI_write ("Error: Save and Restore can be enabled only one at a time\n");
            return -1;
        }
    
        /* Populate configuration: */
        gMmwMssMCB.calibCfg.saveEnable = (uint32_t) atoi(argv[1]);
        gMmwMssMCB.calibCfg.restoreEnable = (uint32_t) atoi(argv[2]);
        sscanf(argv[3], "0x%x", &gMmwMssMCB.calibCfg.flashOffset);
    
        gMmwMssMCB.isCalibCfgPending = 1;
    
        return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler to send out the processing chain type
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIProcChain(int32_t argc, char* argv[])
    {
        
    #ifdef MMWDEMO_DDM
            CLI_write ("ProcChain: DDM\n");
    #elif defined(MMWDEMO_TDM)
            CLI_write ("ProcChain: TDM\n");
    #endif
    
        return 0;
    
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Execution Task
     *
     *  @retval
     *      Not Applicable.
     */
    void MmwDemo_CLIInit (uint8_t taskPriority)
    {
        CLI_Cfg     cliCfg;
        char        demoBanner[256];
        uint32_t    cnt;
    
        /* Create Demo Banner to be printed out by CLI */
        sprintf(&demoBanner[0], 
                           "******************************************\n" \
                           "AM273X MMW Demo %02d.%02d.%02d.%02d\n"  \
                           "******************************************\n", 
                            MMWAVE_SDK_VERSION_MAJOR,
                            MMWAVE_SDK_VERSION_MINOR,
                            MMWAVE_SDK_VERSION_BUGFIX,
                            MMWAVE_SDK_VERSION_BUILD
                );
    
        /* Initialize the CLI configuration: */
        memset ((void *)&cliCfg, 0, sizeof(CLI_Cfg));
    
        /* Populate the CLI configuration: */
        cliCfg.cliPrompt                    = "mmwDemo:/>";
        cliCfg.cliBanner                    = demoBanner;
        cliCfg.cliUartHandle                = gMmwMssMCB.commandUartHandle;
        cliCfg.taskPriority                 = taskPriority;
        cliCfg.mmWaveHandle                 = gMmwMssMCB.ctrlHandle;
        cliCfg.enableMMWaveExtension        = 1U;
        cliCfg.usePolledMode                = true;
        cliCfg.overridePlatform             = true;
        cliCfg.overridePlatformString       = "AM273X";
    #ifdef MMWDEMO_DDM
        cliCfg.procChain                    = 1;
    #else
        cliCfg.procChain                    = 0;
    #endif
            
        cnt=0;
        cliCfg.tableEntry[cnt].cmd            = "sensorStart";
        cliCfg.tableEntry[cnt].helpString     = "[doReconfig(optional, default:enabled)]";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLISensorStart;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "sensorStop";
        cliCfg.tableEntry[cnt].helpString     = "No arguments";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLISensorStop;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "guiMonitor";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <detectedObjects> <logMagRange> <noiseProfile> <rangeAzimuthHeatMap> <rangeDopplerHeatMap> <statsInfo>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIGuiMonSel;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "cfarCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <procDirection> <averageMode> <winLen> <guardLen> <noiseDiv> <cyclicMode> <thresholdScale> <peakGroupingEn>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLICfarCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "aoaFovCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <minAzimuthDeg> <maxAzimuthDeg> <minElevationDeg> <maxElevationDeg>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIAoAFovCfg;
        cnt++;
    
    #ifdef MMWDEMO_TDM
        cliCfg.tableEntry[cnt].cmd            = "multiObjBeamForming";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <enabled> <threshold>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIMultiObjBeamForming;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "calibDcRangeSig";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <enabled> <negativeBinIdx> <positiveBinIdx> <numAvgFrames>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLICalibDcRangeSig;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "clutterRemoval";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <enabled>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIClutterRemoval;
        cnt++;
    #endif
    
        cliCfg.tableEntry[cnt].cmd            = "adcbufCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <adcOutputFmt> <SampleSwap> <ChanInterleave> <ChirpThreshold>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIADCBufCfg;
        cnt++;
    
    #ifdef MMWDEMO_TDM
        cliCfg.tableEntry[cnt].cmd            = "compRangeBiasAndRxChanPhase";
        cliCfg.tableEntry[cnt].helpString     = "<rangeBias> <Re00> <Im00> <Re01> <Im01> <Re02> <Im02> <Re03> <Im03> <Re10> <Im10> <Re11> <Im11> <Re12> <Im12> <Re13> <Im13> ";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLICompRangeBiasAndRxChanPhaseCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "measureRangeBiasAndRxChanPhase";
        cliCfg.tableEntry[cnt].helpString     = "<enabled> <targetDistance> <searchWin>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIMeasureRangeBiasAndRxChanPhaseCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "cfarFovCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <procDirection> <min (meters or m/s)> <max (meters or m/s)>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLICfarFovCfg;
        cnt++;
        cliCfg.tableEntry[cnt].cmd            = "extendedMaxVelocity";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <enabled>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIExtendedMaxVelocity;
        cnt++;
    #endif
    
        cliCfg.tableEntry[cnt].cmd            = "CQRxSatMonitor";
        cliCfg.tableEntry[cnt].helpString     = "<profile> <satMonSel> <priSliceDuration> <numSlices> <rxChanMask>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIChirpQualityRxSatMonCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "CQSigImgMonitor";
        cliCfg.tableEntry[cnt].helpString     = "<profile> <numSlices> <numSamplePerSlice>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIChirpQualitySigImgMonCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "analogMonitor";
        cliCfg.tableEntry[cnt].helpString     = "<rxSaturation> <sigImgBand>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIAnalogMonitorCfg;
        cnt++;
    
    #ifdef LVDS_STREAM
        cliCfg.tableEntry[cnt].cmd            = "lvdsStreamCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <enableHeader> <dataFmt> <enableSW>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLILvdsStreamCfg;
        cnt++;
    #endif
        
        cliCfg.tableEntry[cnt].cmd            = "configDataPort";
        cliCfg.tableEntry[cnt].helpString     = "<baudrate> <ackPing>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIConfigDataPort;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "queryDemoStatus";
        cliCfg.tableEntry[cnt].helpString     = "";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIQueryDemoStatus;
        cnt++;
    
    #ifdef ENET_STREAM
        cliCfg.tableEntry[cnt].cmd            = "queryLocalIp";
        cliCfg.tableEntry[cnt].helpString     = "";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIQueryLocalIp;
        cnt++;
    #endif
    
        cliCfg.tableEntry[cnt].cmd            = "calibData";
        cliCfg.tableEntry[cnt].helpString    = "<save enable> <restore enable> <Flash offset>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLICalibDataSaveRestore;
        cnt++;
    
    #ifdef ENET_STREAM
        cliCfg.tableEntry[cnt].cmd            = "enetStreamCfg";
        cliCfg.tableEntry[cnt].helpString     = "<isEnabled> <remoteIpD> <remoteIpC> <remoteIpB> <remoteIpA>"; /* Ip: D.C.B.A */
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIEnetCfg;
        cnt++;
    #endif
    
    #ifdef MMWDEMO_DDM
        cliCfg.tableEntry[cnt].cmd            = "compressionCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <compressionRatio> <rangeBinsPerBlock> <compressionMethod>"; 
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLICompressionCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "localMaxCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <azimThreshdB> <dopplerThreshdB>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLILocalMaxCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "intfMitigCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx>  <magSNRdB> <magDiffSNRdB>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIIntfMitigCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "antennaCalibParams";
        cliCfg.tableEntry[cnt].helpString     = "<I0> <Q0> .... <I11> <Q11>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIAntennaCalibParams;
        cnt++;
    #endif
    
        cliCfg.tableEntry[cnt].cmd            = "procChain";
        cliCfg.tableEntry[cnt].helpString     = "";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIProcChain;
        cnt++;
    
    
        /* Open the CLI: */
        if (CLI_open (&cliCfg) < 0)
        {
            test_print ("Error: Unable to open the CLI\n");
            return;
        }
        MmwDemo_Bypass_CLI();
        test_print ("Debug: CLI is operational\n");
        return;
    }
    
    
    

  • 您好,

    我昨天修改cli.c(但是我没有修改mmw_cli.c)重新编译的Demo在CCS UART Terminal(visualizer里面几次没有连接上,不知何缘故)里面看着profile的参数配置有运行,但是log没有完全打印完,也有Debug: Init Calibration Status = 0x1ffe    Done的命令;

    然后我直接用您这边修改的文件重新编译刷录,在visiualizer里面没有看到运行profile的参数配置命令,它会提示sensor start后某个命令不允许,手动下载profile.cfg还是可以的,在CCS UART Terminal里面也是只看到了 Debug: Init Calibration Status = 0x1ffe    Done的命令,您这边有这样的情况吗,怎么修改确定上电后参数自动配置下发一定是成功的呢,对于产品应用上还是需要固化参数的配置,谢谢。

  • 怎么修改确定上电后参数自动配置下发一定是成功的呢,

    用下面的方法:

    我这里测试没有问题,流程如下:

    1. cli.c里设置CLI_BYPSS=1, 修改配置为tdm 2d cfg。重新编译cli库,重新编译tdm demo。

    2. 打开visualizer,先运行原始的tdm demo,发射2d的配置,可以看到plot下的信息输出。然后断开visualizer下的串口连接(网页左下角)

    3. 板子重新上电,运行新编译好的固化配置的tdm demo,在visulizer里连接串口,我可以在plot下看到动态的信息输出。

  • 就是我也按照您这边修改的两个文件重新编译、刷录Demo后,在visualizer上没有看到动态的目标显示,不确定是否自动下载配置完成了,Console里面有如下的提示,手动Load参数配置是可以的,想请问下有没有哪里细节没注意到,step2一定要先刷录原始的tdm demo,然后再刷录运行固化参数的tdm demo吗,这样岂不是要刷两次?

    谢谢。

  • 您好,

    我重新按照您上面的方法验证了下,刷固化后的image,在visualizer里面一定要先在plots里Load Demo的配置参数(比如2d cfg),然后断电连接串口才能在plots里面看到动态的目标显示,这个是visualizer的问题吗,为什么不能直接刷固化后的参数上电显示发射配置的参数并且显示动态的目标呢?

    此外,刷完固化参数后的image后,上电在visualizer里面configure   console有如下的命令“Ignored: This command is not allowed after sensor has started
    Done”,请问这个对参数的配置有影响吗,并且这个不像刷2d.cfg那样load后能看到每条参数配置执行的命令,想确认下这个刷完固化参数的image后上电就自动下发参数配置命令了吗,因为到时候我们自己的雷达可能不会通过visualizer去下载demo的cfg配置,然后再重新上电看是否成功。

    谢谢。

  • 打开visualizer,先运行原始的tdm demo,发射2d的配置,可以看到plot下的信息输出。然后断开visualizer下的串口连接(网页左下角)

    请问这一步你做了么?是运行的原始的tdm demo么?这一步的目的是配置好visualizer,因为固化好的的image不下载cfg,visualizer是不清楚自己应该如何配置(例如是2d的界面,还是3d的界面,GUI哪些需要输出等。

  • 我现在就是刷了固化参数配置的image,先在visualizer里面load 比如2d.cfg配置,可以看到plots动态目标显示,然后断开串口重新上电之后才可以在plots里面看到动态目标显示,就是一定需要先下载Demo的cfg配置文件才可以。

    请问这个第二步里面“运行的原始的tdm demo”是需要刷原始Demo的image吗,在visualizer里面先配置运行一遍,再刷固化参数的image,还是像我上面那样只刷固化参数的image,先load一遍demo的cfg文件,再重新上电即可?

    此外,后续我们自己做的话可能不用visualizer了,这种方法可以直接固化参数配置,上电就下发配置正常运行吗?

    谢谢。

  • “我现在就是刷了固化参数配置的image,先在visualizer里面load 比如2d.cfg配置,可以看到plots动态目标显示,然后断开串口重新上电之后才可以在plots里面看到动态目标显示,就是一定需要先下载Demo的cfg配置文件才可以。”

    这个先配置2d.cfg,然后重新上电可以看到动态目标显示,就是configure  console里面会有如下的提示,也想确认下是否对参数配置啥的有影响。

    感谢。

  • 请问这个第二步里面“运行的原始的tdm demo”是需要刷原始Demo的image吗,在visualizer里面先配置运行一遍,再刷固化参数的image

    第二步我使用的就是原始的demo。

    后续我们自己做的话可能不用visualizer了,这种方法可以直接固化参数配置,上电就下发配置正常运行吗?

    我上面的测试方法已经证明了固化参数的运行,你还有什么疑问?

  • 如果你们有高频测量仪器,可以在demo起来后直接测量发射信号,这样是最直接的。

  • 这个先配置2d.cfg,然后重新上电可以看到动态目标显示,就是configure  console里面会有如下的提示,

    这个提示的意思是在sensor start后不能配置串口速率。这个没有什么影响啊。

  • 好嘞,非常感谢,我一直疑惑的是对于开发板可以按照您那样的方法在visualizer里面去看是否固化配置成功,我们后面自己设计的期望就是固化参数配置上电就直接下发配置,刷一遍固化参数配置的image就可以了,不用刷两次image或者在visualizer里面额外load一次比如2d.cfg的配置,目标显示后面也需要在自己做的上位机查看,我按照您这边的修改的配置文件先去验证下,看下直接上电后是否有信号发出,是否能正常检测到设定目标。

    谢谢。