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.

AWR1642BOOST: Minimum Configuration vs Full Configuration

Part Number: AWR1642BOOST
Other Parts Discussed in Thread: AWR1843, AWR1642

Hi there,

In the SDK, it mentions there is a difference between "full" configuration and "minimal" configuration, as noted below in the screenshot... what is the difference between the two?

Is the difference like: minimal = configuration through CLI command line, while full configuration is through mmwave studio?

Thanks!

George

  • Hi,

    Full configuration abstracts the mmwave link APIs used to configure the RF front end from the user. It is easier to use but provides less flexibility.

    Minimal configuration provides the user more flexibility in calling directly the mmWave Link APIs. In this case one needs to have more knowledge about the Link APIs

    thank you

    Cesar

  • Hello George,

    Minimal or Full configuration within mmwave SDK is meant for mmwave library where it requires to configure MSS/DSS and BSS based on selection.

    While mmwave studio is totally different  where you can select which are configuration you need to invoke to mmwave sensor over SPI interface.

     Now in the above snapshot, marked statement means that if you need to use BPM (rlSetBpmChirpConfig and rlSetBpmCommonConfig) then call it outside of mmwave, directly from application.

    Note: rlSetBpmChirpConfig API and rlSetMultiBpmChirpConfig are almost same. rlSetMultiBpmChirpConfig API uses multiple set of rlBpmChirpCfg_t structure within single API call, whereas rlSetBpmChirpConfig needs to call multiple times.

    Regards,

    Jitendra

  • Hi,

    Thank you so much for getting back to me!

    What do you mean by calling rlSetBpmChirpConfig and rlSetBpmCommonConfig "outside of mmwave, directly from application"? How would that look in an actual implementation? Is that in the C code or in the CLI script?

    This might be the issue I am having as for why my updates in mss_main.c that I defined are not getting configured in the BSS since I am not calling rlSetBpmChirpConfig and rlSetBpmCommonConfig elsewhere.

    Thanks!

    George

  • Hi Jitendra,

    Just checkin in on what you mean by "outside of mmwave, directly from application"? Does this mean that I need to do whatever this is to call random BPM sequence on OOB SDK demo image?

    Thanks!

    George

  • Hi,

    What Jiten meant by "outside of mmwave, directly from application" is that the application would have to call these APIs directly.

    For ease of use the SDK demo implements a set of mmWave APIs which call the mmWave Link APIs. The Demo application calls only the mmWave APIs and does not call directly the mmWave Link APIs. However the mmWave APIs do not support the specific Bpm mmWave Link APIs. So in order to use the Bpm mmwave Link APIs, the user must call them directly at the application level.

    Thank you

    Cesar

  • Hi Cesar,

    Thank you for clearing that up.

    What does it look like for the user to "call them directly at the application level"? What is the application level specifically? Is that the CLI script?

    Thanks!

    George

  • No,

    This would mean that the mmWave Link APIs are called directly in the application code. Please see as an example the MRR beamsteering demo

    mmwave_automotive_toolbox_2_9_1\labs\lab0011_mrr_beamsteering\src\mss\mss_main.c

    rlRfSetPhaseShiftConfig() is a mmwave link API called directly in application code

    static void MmwDemo_applyPhShift(UArg arg0, UArg arg1)
    {
        uint32_t retVal = RL_RET_CODE_OK;

        while(1)
            {
                Semaphore_pend(gMrrMSSMCB.phShftSemHandle, BIOS_WAIT_FOREVER);
                retVal = rlRfSetPhaseShiftConfig(RL_DEVICE_MAP_INTERNAL_BSS, 1U, (rlRfPhaseShiftCfg_t*) &g_ptrtxPhaseShiftCfg);
                if (retVal != RL_RET_CODE_OK)
                {
                   System_printf ("Error: Unable to configure per chirp phase shift [Error %d]\n",  retVal);
                   return -1;
                }

            }

    }

    Thank you

    Cesar

  • Hi Cesar,

    Thank you for this information.

    1) The example you posted above, could that be used in the AWR1843 demo to use the txPhaseShifter capability? Therefore, call the rlRfSetPhaseShiftConfig() mmwave link API through the code you posted through the application code (mss_main.c)?

    2) Could you post an example code segment for the mmwave link API CLI_MMWaveBPMCfgAdvanced()? I am trying to implement the attached CLI script on the AWR1843 (or on the AWR1642). Either one, I think I need to call this API in application to bring the CLI inputs to the BSS, if my understanding is correct.

    sensorStop
    flushCfg
    dfeDataOutputMode 3
    channelCfg 15 1 0
    adcCfg 2 1
    adcbufCfg -1 0 0 1 0
    profileCfg 0 77 7 7 160 0 0 20 1 512 6200 0 0 30
    chirpCfg 0 0 0 0 0 0 0 1
    chirpCfg 1 1 0 0 0 0 0 1
    chirpCfg 2 2 0 0 0 0 0 1
    chirpCfg 3 3 0 0 0 0 0 1
    bpmCfg -1 0 0 1
    advFrameCfg 1 0 120 1 0
    subFrameCfg 0 0 0 4 16 200 0 1 1 200
    bpmCfgAdvanced 0 0 0
    bpmCfgAdvanced 1 1 0
    bpmCfgAdvanced 2 2 3
    bpmCfgAdvanced 3 3 3
    lowPower 0 1
    guiMonitor -1 0 0 0 0 0 0
    cfarCfg -1 0 2 8 4 4 0 5120
    cfarCfg -1 1 0 8 4 4 0 5120
    peakGrouping -1 1 0 0 1 224
    multiObjBeamForming -1 0 0.5
    calibDcRangeSig -1 0 -5 8 256
    extendedMaxVelocity -1 0
    clutterRemoval -1 0
    compRangeBiasAndRxChanPhase 0.0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
    measureRangeBiasAndRxChanPhase 0 1.5 0.2
    nearFieldCfg -1 0 0 0
    CQRxSatMonitor 0 3 4 127 0
    CQSigImgMonitor 0 63 8
    analogMonitor 0 0
    lvdsStreamCfg -1 0 1 0
    sensorStart
    

    Thanks so much!

  • Hi,

    Sorry for the delay

    Q1 The example you posted above, could that be used in the AWR1843 demo to use the txPhaseShifter capability? Therefore, call the rlRfSetPhaseShiftConfig() mmwave link API through the code you posted through the application code (mss_main.c)?

    [Cesar] Yes, this could be used to configure the txPhaseShifter capability in the same way it was used in the mmwave_automotive_toolbox_2_9_1\labs\lab0011_mrr_beamsteering

    Q2 Could you post an example code segment for the mmwave link API CLI_MMWaveBPMCfgAdvanced()? I am trying to implement the attached CLI script on the AWR1843 (or on the AWR1642). Either one, I think I need to call this API in application to bring the CLI inputs to the BSS, if my understanding is correct.

    A2: Let me spend some more time on this and will get back to you tomorrow

    thank you

    Cesar

  • Hi,

    Thank you for getting back to me.

    1) Since the mrr_beamsteering switches TxPhase Shifts every frame, this will not be effective since I need to change the phase every chirp. That is why I am thinking about the mgmwavebpmcfgadvanced() API. 

    2) Sounds good, I really appreciate the help. To reiterate, I am able to input CLI script arguments for bpmCfgAdvanced in to the CLI script with correct values, but it did not change the outputs. And my thoughts is because that API was not sent to the BSS. Any snippets of code or steps you would take would be greatly appreciated!

    Thanks!

    George

  • George,

    Can you remind me why you can't use the bpmCfg config command provided in the16xx profile

    C:\ti\mmwave_sdk_03_03_00_03\packages\ti\demo\xwr16xx\mmw\profile\profile_2d_bpm.cfg?

    Thank you

    Cesar

  • Hi Cesar,

    Goal: To transmit a sequence of [0 0 1 1] BPM chirps on one transmitter. I have two other radars transmitting [0 0 0 0] and [0 1 0 1], where I can use both the regular bpmCfg config command in the 16xx profile and only enable a certain Tx path to get one Tx to transmit.

    Therefore, for the [0 0 1 1], I tried to change the bpmCfg command on the CLI to take 4 inputs and change the bpmCfg API in mss_main.c to call the API MMWave_addBpmChirp 4 times to send the bpm chirps to the BSS. And I was able to run it through with no errors thrown (all data was collected, etc.), but unfortunately it seemed like the BSS was not updated with my new BPM scheme.  I performed the decoding and analysis on the data to check if my [0 0 1 1] worked, but it turns out that the scheme out of the 1st Tx no matter what is [0 0 0 0] and out of Tx2 it is [0 1 0 1] regardless of the bpmChirpCfg.constBpmVal I initialized the chirp to be. Please reference this thread to understand more, even though this thread is discussing the idea of extending the chirps. https://e2e.ti.com/support/tools/ccs/f/81/t/931205?tisearch=e2e-sitesearch&keymatch=bpmChirpCfg.constBpmVal%2520%253D%25200xCU%253B 

    Therefore, I am thinking of using the BPM Advanced config API to accomplish my goal. Additionally, I have an AWR1843 also if that increases your options to help me accomplish my goal.

    Thanks!

    George

  • I understand,

    I looked at the demo, and I think that the demo was "hard coded" to support only the alternate pattern. So, I think that the implementation of the bpm command in the demo must be modified. It is not a matter of BPM Advanced config

    The following function in C:\ti\mmwave_sdk_02_01_00_04\packages\ti\demo\xwr16xx\mmw\mss\mss_main.c must be modified.

    MmwDemo_bpmConfig()

    In the SDK implementation this function forces the alternate pattern.

    Would it be possible for you to review this function?

    thank you

    Cesar

  • Hi Cesar,

    I believe I did this correctly before. Please see my attached mss_main.c file. I also attached the other c files I changed to ensure that the built BIN file/flash ran correctly and fully on the AWR1642. Do you see something wrong with what I did? Again, the issue I am having is that the front end BSS is not updating with my new hard coded BPM scheme.

    Please control + F "George" to find my exact changes quicker.

    5545.mss_main.c

    mmw_config.h

    /*
     *   @file  cli.c
     *
     *   @brief
     *      Mmw (Milli-meter wave) DEMO CLI Implementation
     *
     *  \par
     *  NOTE:
     *      (C) Copyright 2016 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>
    
    /* BIOS/XDC Include Files. */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/IHeap.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/Memory.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Event.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/heaps/HeapBuf.h>
    #include <ti/sysbios/heaps/HeapMem.h>
    #include <ti/sysbios/knl/Event.h>
    
    /* mmWave SDK Include Files: */
    #include <ti/common/sys_common.h>
    #include <ti/common/mmwave_sdk_version.h>
    #include <ti/drivers/uart/UART.h>
    #include <ti/control/mmwavelink/mmwavelink.h>
    #include <ti/utils/cli/cli.h>
    
    /* Demo Include Files */
    #include "ti/demo/xwr16xx/mmw/mss/mss_mmw.h"
    #include "ti/demo/xwr16xx/mmw/common/mmw_messages.h"
    
    /**************************************************************************
     *************************** Local Definitions ****************************
     **************************************************************************/
    
    /* CLI Extended Command Functions */
    static int32_t MmwDemo_CLICfarCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIPeakGroupingCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIMultiObjBeamForming (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLICalibDcRangeSig (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIExtendedMaxVelocity (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIClutterRemoval (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_CLISetDataLogger (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIADCBufCfg (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_CLINearFieldCorrection (int32_t argc, char* argv[]);
    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[]);
    static int32_t MmwDemo_CLILvdsStreamCfg (int32_t argc, char* argv[]);
    
    /**************************************************************************
     *************************** Extern Definitions *******************************
     **************************************************************************/
    
    extern MmwDemo_MCB    gMmwMssMCB;
    extern int32_t MmwDemo_mboxWrite(MmwDemo_message     * message);
    
    /**************************************************************************
     *************************** 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;
        if (argc==2)
        {
            doReconfig = (bool) atoi (argv[1]);
        }
        /* Post sensorSTart event to notify configuration is done */
        MmwDemo_notifySensorStart(doReconfig);
        /* Pend for completion */
        return (MmwDemo_waitSensorStartComplete());
    }
    
    
    /**
     *  @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[])
    {
        /* Post sensorSTOP event to notify sensor stop command */
        MmwDemo_notifySensorStop();
        /* Pend for completion */
        MmwDemo_waitSensorStopComplete();
        return 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;
    }
    
    static void MmwDemo_mssCfgUpdate(void *srcPtr, uint32_t offset, uint32_t size, int8_t subFrameNum)
    {    
        /* if subFrameNum undefined, broadcast to all sub-frames */
        if(subFrameNum == MMWDEMO_SUBFRAME_NUM_FRAME_LEVEL_CONFIG)
        {
            uint8_t  indx;
            for(indx = 0; indx < RL_MAX_SUBFRAMES; indx++)
            {
                memcpy((void *)((uint32_t) &gMmwMssMCB.cliCfg[indx] + offset), srcPtr, size);
            }
            
        }
        else
        {
            /* Apply configuration to specific subframe (or to position zero for the legacy case
               where there is no advanced frame config) */
            memcpy((void *)((uint32_t) &gMmwMssMCB.cliCfg[subFrameNum] + offset), srcPtr, size);
        }
    }
    
    /**
     *  @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;
        MmwDemo_message     message;
        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_mssCfgUpdate((void *)&guiMonSel, offsetof(MmwDemo_CliCfg_t, guiMonSel), 
            sizeof(MmwDemo_GuiMonSel), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_GUIMON_CFG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.guiMonSel, (void *)&guiMonSel, sizeof(MmwDemo_GuiMonSel));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @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[])
    {
        MmwDemo_CfarCfg     cfarCfg;
        MmwDemo_message     message;
        uint32_t            procDirection;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 9, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&cfarCfg, 0, sizeof(MmwDemo_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]);
        cfarCfg.thresholdScale    = (uint16_t) atoi (argv[8]);
    
        /* Save Configuration to use later */     
        if (procDirection == 0)
        {
            MmwDemo_mssCfgUpdate((void *)&cfarCfg, offsetof(MmwDemo_CliCfg_t, cfarCfgRange),
                sizeof(MmwDemo_CfarCfg), subFrameNum);    
        }
        else
        {
            MmwDemo_mssCfgUpdate((void *)&cfarCfg, offsetof(MmwDemo_CliCfg_t, cfarCfgDoppler),
                sizeof(MmwDemo_CfarCfg), subFrameNum);    
        }
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
        if (procDirection == 0)
        {
            message.type = MMWDEMO_MSS2DSS_CFAR_RANGE_CFG;
        }
        else if (procDirection == 1)
        {
            message.type = MMWDEMO_MSS2DSS_CFAR_DOPPLER_CFG;
        }
        else
        {
            return -1;
        }
    
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.cfarCfg, (void *)&cfarCfg, sizeof(MmwDemo_CfarCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;    
    }
    
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for Peak grouping configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIPeakGroupingCfg (int32_t argc, char* argv[])
    {
        MmwDemo_PeakGroupingCfg peakGroupingCfg;
        MmwDemo_message         message;
        int8_t                  subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 7, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&peakGroupingCfg, 0, sizeof(MmwDemo_PeakGroupingCfg));
    
        /* Populate configuration: */
        peakGroupingCfg.scheme               = (uint8_t) atoi (argv[2]);
        peakGroupingCfg.inRangeDirectionEn   = (uint8_t) atoi (argv[3]);
        peakGroupingCfg.inDopplerDirectionEn = (uint8_t) atoi (argv[4]);
        peakGroupingCfg.minRangeIndex    = (uint16_t) atoi (argv[5]);
        peakGroupingCfg.maxRangeIndex    = (uint16_t) atoi (argv[6]);
    
        if (peakGroupingCfg.scheme != 1 && peakGroupingCfg.scheme != 2)
        {
            CLI_write ("Error: Invalid peak grouping scheme\n");
            return -1;
        }
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&peakGroupingCfg, offsetof(MmwDemo_CliCfg_t, peakGroupingCfg),
            sizeof(MmwDemo_PeakGroupingCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_PEAK_GROUPING_CFG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.peakGroupingCfg, (void *)&peakGroupingCfg, sizeof(MmwDemo_PeakGroupingCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    
    /**
     *  @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[])
    {
        MmwDemo_MultiObjBeamFormingCfg cfg;
        MmwDemo_message     message;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 4, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&cfg, 0, sizeof(MmwDemo_MultiObjBeamFormingCfg));
    
        /* Populate configuration: */
        cfg.enabled                     = (uint8_t) atoi (argv[2]);
        cfg.multiPeakThrsScal           = (float) atof (argv[3]);
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, multiObjBeamFormingCfg),
            sizeof(MmwDemo_MultiObjBeamFormingCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_MULTI_OBJ_BEAM_FORM;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.multiObjBeamFormingCfg, (void *)&cfg, sizeof(MmwDemo_MultiObjBeamFormingCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    uint32_t log2Approx(uint32_t x)
    {
        uint32_t idx, detectFlag = 0;
    
        if ( x < 2)
        {
            return (0);
        }
    
        idx = 32U;
        while((detectFlag==0U) || (idx==0U))
        {
            if(x & 0x80000000U)
            {
                detectFlag = 1;
            }
            x <<= 1U;
            idx--;
        }
    
        if(x != 0)
        {
            idx = idx + 1;
        }
    
        return(idx);
    }
    
    /**
     *  @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[])
    {
        MmwDemo_CalibDcRangeSigCfg cfg;
        MmwDemo_message            message;
        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(MmwDemo_CalibDcRangeSigCfg));
    
        /* 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 - cfg.negativeBinIdx + 1) > DC_RANGE_SIGNATURE_COMP_MAX_BIN_SIZE)
        {
            CLI_write ("Error: Number of bins exceeds the limit\n");
            return -1;
        }
        log2NumAvgChirps = (uint32_t) log2Approx (cfg.numAvgChirps);
        if (cfg.numAvgChirps != (1 << log2NumAvgChirps))
        {
            CLI_write ("Error: Number of averaged chirps is not power of two\n");
            return -1;
        }
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, calibDcRangeSigCfg),
            sizeof(MmwDemo_CalibDcRangeSigCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_CALIB_DC_RANGE_SIG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.calibDcRangeSigCfg, (void *)&cfg, sizeof(MmwDemo_CalibDcRangeSigCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for Velocity Disambiguation 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[])
    {
        MmwDemo_ExtendedMaxVelocityCfg cfg;
        MmwDemo_message                message;
        int8_t                         subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 3, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration for DC range signature calibration */
        memset ((void *)&cfg, 0, sizeof(MmwDemo_ExtendedMaxVelocityCfg));
    
        /* Populate configuration: */
        cfg.enabled          = (uint16_t) atoi (argv[2]);
    
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, extendedMaxVelocityCfg),
            sizeof(MmwDemo_ExtendedMaxVelocityCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_EXTENDED_MAX_VELOCITY;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.extendedMaxVelocityCfg, (void *)&cfg, sizeof(MmwDemo_ExtendedMaxVelocityCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for Near field correction Configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLINearFieldCorrection (int32_t argc, char* argv[])
    {
        MmwDemo_NearFieldCorrectionCfg cfg;
        MmwDemo_message                message;
        int8_t                         subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 5, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration for Near Field Correction */
        memset ((void *)&cfg, 0, sizeof(MmwDemo_NearFieldCorrectionCfg));
    
        /* Populate configuration: */
        cfg.enabled       = (uint8_t) atoi(argv[2]);
        cfg.startRangeIdx = (uint16_t) atoi(argv[3]);
        cfg.endRangeIdx   = (uint16_t) atoi(argv[4]);
    
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, nearFieldCorrectionCfg),
            sizeof(MmwDemo_NearFieldCorrectionCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_NEAR_FIELD_CFG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.nearFieldCorrectionCfg, (void *)&cfg, 
               sizeof(MmwDemo_NearFieldCorrectionCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    /**
     *  @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[])
    {
        MmwDemo_ClutterRemovalCfg cfg;
        MmwDemo_message     message;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 3, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration for clutter removal */
        memset ((void *)&cfg, 0, sizeof(MmwDemo_ClutterRemovalCfg));
    
        /* Populate configuration: */
        cfg.enabled          = (uint16_t) atoi (argv[2]);
    
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, clutterRemovalCfg),
            sizeof(MmwDemo_ClutterRemovalCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_CLUTTER_REMOVAL;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.clutterRemovalCfg, (void *)&cfg, sizeof(MmwDemo_ClutterRemovalCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @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_CLISetDataLogger (int32_t argc, char* argv[])
    {
        MmwDemo_message     message;
    
        /* Sanity Check: Minimum argument check */
        if (argc != 2)
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
    
    
        /* Save Configuration to use later */
        if (strcmp(argv[1], "mssLogger") == 0)  
            gMmwMssMCB.cfg.dataLogger = 0;
        else if (strcmp(argv[1], "dssLogger") == 0)  
            gMmwMssMCB.cfg.dataLogger = 1;
        else
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
           
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_SET_DATALOGGER;
        message.body.dataLogger = gMmwMssMCB.cfg.dataLogger;
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @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;
        MmwDemo_message     message;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 6, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize the ADC Output configuration: */
        memset ((void *)&adcBufCfg, 0, sizeof(MmwDemo_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]);
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&adcBufCfg, offsetof(MmwDemo_CliCfg_t, adcBufCfg),
            sizeof(MmwDemo_ADCBufCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
        message.type = MMWDEMO_MSS2DSS_ADCBUFCFG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.adcBufCfg, (void *)&adcBufCfg, sizeof(MmwDemo_ADCBufCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    
    /**
     *  @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[])
    {
        MmwDemo_compRxChannelBiasCfg_t   cfg;
        MmwDemo_message     message;
        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(MmwDemo_compRxChannelBiasCfg_t));
    
        /* 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.);
            Re = MMWDEMO_SATURATE_HIGH(Re);
            Re = MMWDEMO_SATURATE_LOW(Re);
            cfg.rxChPhaseComp[i].real = (int16_t) Re;
    
            Im = (int32_t) (atof (argv[argInd++]) * 32768.);
            Im = MMWDEMO_SATURATE_HIGH(Im);
            Im = MMWDEMO_SATURATE_LOW(Im);
            cfg.rxChPhaseComp[i].imag = (int16_t) Im;
    
        }
        /* Save Configuration to use later */
        memcpy((void *) &gMmwMssMCB.cliCommonCfg.compRxChanCfg, &cfg, sizeof(MmwDemo_compRxChannelBiasCfg_t));
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
        message.type = MMWDEMO_MSS2DSS_COMP_RANGE_BIAS_AND_RX_CHAN_PHASE;
        memcpy((void *)&message.body.compRxChanCfg, (void *)&cfg, sizeof(MmwDemo_compRxChannelBiasCfg_t));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @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[])
    {
        MmwDemo_measureRxChannelBiasCfg_t   cfg;
        MmwDemo_message     message;
    
        /* 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(MmwDemo_measureRxChannelBiasCfg_t));
    
        /* 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.cliCommonCfg.measureRxChanCfg, &cfg, sizeof(MmwDemo_measureRxChannelBiasCfg_t));
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
        message.type = MMWDEMO_MSS2DSS_MEASURE_RANGE_BIAS_AND_RX_CHAN_PHASE;
        memcpy((void *)&message.body.measureRxChanCfg, (void *)&cfg, sizeof(MmwDemo_measureRxChannelBiasCfg_t));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for BPM configuration supported by the mmw Demo
     *      Note that there is a generic BPM configuration command supported by
     *      utils/cli and mmwave. The generic BPM command is not supported by the
     *      demo as the mmw demo assumes a specific BPM pattern for the TX antennas.
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    // George Edited this BPM section to include 2 more chirp indexes
    static int32_t MmwDemo_CLIBpmCfg (int32_t argc, char* argv[])
    {
    
        int8_t           subFrameNum;
        MmwDemo_BpmCfg   cfg;
        MmwDemo_message  message;
        
        /* Sanity Check: Minimum argument check */
        if (argc != 7)
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
        
        if(MmwDemo_CLIGetSubframe(argc, argv, 7, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration for DC range signature calibration */
        memset ((void *)&cfg, 0, sizeof(MmwDemo_BpmCfg));
    
        /* Populate configuration: */
        cfg.isEnabled = (bool) atoi(argv[2]) ;
        cfg.chirp0Idx = (uint16_t) atoi(argv[3]) ;
        cfg.chirp1Idx = (uint16_t) atoi(argv[4]) ;
        cfg.chirp2Idx = (uint16_t) atoi(argv[5]) ;
        cfg.chirp3Idx = (uint16_t) atoi(argv[6]) ;
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, bpmCfg),
            sizeof(MmwDemo_BpmCfg), subFrameNum);
            
        message.type = MMWDEMO_MSS2DSS_BPM_CFG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.bpmCfg, (void *)&cfg, sizeof(MmwDemo_BpmCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
            
    }
    
    /**
     *  @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;
        MmwDemo_message         message;
    
        /* 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 */
            memcpy((void *) &gMmwMssMCB.cliCommonCfg.cqSatMonCfg[cqSatMonCfg.profileIndx], 
                           &cqSatMonCfg, 
                           sizeof(rlRxSatMonConf_t));
    
            /* Send configuration to DSS */
            memset((void *)&message, 0, sizeof(MmwDemo_message));
            message.type = MMWDEMO_MSS2DSS_CQ_SATURATION_MONITOR;
            memcpy((void *)&message.body.cqSatMonCfg, (void *)&cqSatMonCfg, sizeof(rlRxSatMonConf_t));
    
            if (MmwDemo_mboxWrite(&message) == 0)
                return 0;
            else
                return -1;
        }
        else
        {
            return -1;
        }
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for configuring CQ Singal & 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;
        MmwDemo_message         message;
    
        /* 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 */
            memcpy((void *) &gMmwMssMCB.cliCommonCfg.cqSigImgMonCfg[cqSigImgMonCfg.profileIndx], 
                    &cqSigImgMonCfg, 
                    sizeof(rlSigImgMonConf_t));
    
            /* Send configuration to DSS */
            memset((void *)&message, 0, sizeof(MmwDemo_message));
            message.type = MMWDEMO_MSS2DSS_CQ_SIGIMG_MONITOR;
            memcpy((void *)&message.body.cqSigImgMonCfg, (void *)&cqSigImgMonCfg, sizeof(rlSigImgMonConf_t));
    
            if (MmwDemo_mboxWrite(&message) == 0)
                return 0;
            else
                return -1;
        }
        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[])
    {
        MmwDemo_message     message;
        
        /* 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.cliCommonCfg.anaMonCfg.rxSatMonEn = atoi (argv[1]);
        gMmwMssMCB.cliCommonCfg.anaMonCfg.sigImgMonEn = atoi (argv[2]);
        
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
        message.type = MMWDEMO_MSS2DSS_ANALOG_MONITOR;
        memcpy((void *)&message.body.anaMonCfg, 
                (void *)&gMmwMssMCB.cliCommonCfg.anaMonCfg, 
                sizeof(MmwDemo_AnaMonitorCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    
    /**
     *  @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[])
    {
    
        int8_t                  subFrameNum;
        MmwDemo_LvdsStreamCfg   cfg;
        MmwDemo_message         message;
        
        /* Sanity Check: Minimum argument check */
        if (argc != 5)
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
        
        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]) ;
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, lvdsStreamCfg),
            sizeof(MmwDemo_LvdsStreamCfg), subFrameNum);
            
        message.type = MMWDEMO_MSS2DSS_LVDSSTREAM_CFG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.lvdsStreamCfg, (void *)&cfg, sizeof(MmwDemo_LvdsStreamCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Execution Task
     *
     *  @retval
     *      Not Applicable.
     */
    void MmwDemo_CLIInit (void)
    {
        CLI_Cfg     cliCfg;
        char        demoBanner[256];
        uint32_t    cnt;
    
        /* Create Demo Banner to be printed out by CLI */
        sprintf(&demoBanner[0], 
                           "******************************************\n" \
                           "xWR16xx 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                 = 3;
        cliCfg.mmWaveHandle                 = gMmwMssMCB.ctrlHandle;
        cliCfg.enableMMWaveExtension        = 1U;
        cliCfg.usePolledMode                = true;
        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>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLICfarCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "peakGrouping";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <groupingMode> <rangeDimEn> <dopplerDimEn> <startRangeIdx> <endRangeIdx>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIPeakGroupingCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "dataLogger";
        cliCfg.tableEntry[cnt].helpString     = "<mssLogger | dssLogger>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLISetDataLogger;
        cnt++;
    
        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            = "extendedMaxVelocity";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <enabled>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIExtendedMaxVelocity;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "clutterRemoval";
        cliCfg.tableEntry[cnt].helpString     = "<enabled>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIClutterRemoval;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "adcbufCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <adcOutputFmt> <SampleSwap> <ChanInterleave> <ChirpThreshold>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIADCBufCfg;
        cnt++;
    
        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++;
    
    // George edited this to include 2 more chirp indexes
    
        cliCfg.tableEntry[cnt].cmd            = "bpmCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <enabled> <chirp0Idx> <chirp1Idx> <chirp2Idx> <chirp3Idx>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIBpmCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "nearFieldCfg";
        cliCfg.tableEntry[cnt].helpString     = "<enabled> <startRangeIndex> <endRangeIndex>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLINearFieldCorrection;
        cnt++;
    
        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++;
        
        cliCfg.tableEntry[cnt].cmd            = "lvdsStreamCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <enableHeader> <dataFmt> <enableSW>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLILvdsStreamCfg;
        cnt++;   
        
        /* Open the CLI: */
        if (CLI_open (&cliCfg) < 0)
        {
            System_printf ("Error: Unable to open the CLI\n");
            return;
        }
        System_printf ("Debug: CLI is operational\n");
        return;
    }
    
    
    

    0842.dss_main.c

    Thanks!

  • Hi,

    I am sorry, it will take a couple of days before I can get back to you

    Cesar

  • Hi Cesar, 

    Thank you for taking a look at this. I am unable to move forward for my customers until I figure this out so please send any questions at any time to me over the next few days if you have any and I will answer them ASAP so we can get this figured out.

    Have a great day and I really look forward to hearing back from you soon!

    George

  • George,

    I looked quickly at your code.

    I noticed that you have added the new chirpIdx which is the first step.

    Now, after that we need to be aware that a frame is built by looping from chirpMin to chirpMax. This information is provided in the frameCfg as follows:

    frameCfg 0 1 32 0 100 1 0

    In the example the first 0 is the chirpMinIdx and the following 1 is the chirpMaxIdx. The next number is the nb of loops 32. In total we will have 64 chirps

    So, if you want to use 4 different chirIdx in your frame you would need to use following if you want to have total 64 chirps

    frameCfg 0 3 16 0 100 1 0

    Thank you

    Cesar

  • Hi Cesar,

    Thank you for taking a look at my code. And yes, I agree about how a frame is built chirpMin to chirpMax. 

    When I ran the BIN file made up of the other .c codes I sent you a few posts before, I used the below CLI script, where I changed the frameCfg to go from 0 to 3. 

    sensorStop
    flushCfg
    dfeDataOutputMode 1
    channelCfg 15 2 0
    adcCfg 2 1
    adcbufCfg -1 0 0 1 0
    profileCfg 0 77 7 7 160 0 0 25 1 512 6200 0 0 30
    chirpCfg 0 0 0 0 0 0 0 2
    chirpCfg 1 1 0 0 0 0 0 2
    chirpCfg 2 2 0 0 0 0 0 2
    chirpCfg 3 3 0 0 0 0 0 2
    bpmCfg -1 1 0 1 2 3
    frameCfg 0 3 16 120 250 1 0
    lowPower 0 1
    guiMonitor -1 0 0 0 0 0 0
    cfarCfg -1 0 2 8 4 4 0 5120
    cfarCfg -1 1 0 8 4 4 0 5120
    peakGrouping -1 1 0 0 1 224
    multiObjBeamForming -1 0 0.5
    calibDcRangeSig -1 0 -5 8 256
    extendedMaxVelocity -1 0
    clutterRemoval -1 0
    compRangeBiasAndRxChanPhase 0.0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
    measureRangeBiasAndRxChanPhase 0 1.5 0.2
    nearFieldCfg -1 0 0 0
    CQRxSatMonitor 0 3 4 127 0
    CQSigImgMonitor 0 63 8
    analogMonitor 0 0
    lvdsStreamCfg -1 0 1 0
    sensorStart
    

    What is our next step?

    Thanks!

  • Hi,

    I am contacting the team that wrote the SDK demo.

    Will get back to you tomorrow

    thank you

    Cesar

  • Okay, thank you Cesar. If they have additional steps through the end goal, that would be great too! Talk soon.

    George

  • In the meantime I recommend that you try to step through the code, the MMWave_configBPM() function to make sure that the number of BPM chirps configured are what you expect

    thank you

    Cesar

  • Hi Cesar, 

    A few weeks ago, I made sure to do that (including drawing out which functions go where on paper), but when I ran the binary flash (made of the code I manipulated) the desired BPM chirps were not transmitted. Since I hard coded in the two additional chirps and changed their bpmConstVal value, I am not sure that the BSS is getting updated with what I hard coded. Which points to the MMWave_addBpmChirp function. I am unsure where this goes after and why my desired chirps are not getting "Added".

    How do you recommend seeing what BPM chirps are configured besides what I defined in the mss_main.c as well as the other documents I attached above? I do not have a debugger so I cannot import the code into CCS and place print statements if that is what you are referring to. If there is another way you would confirm the BPM chirps in the meantime, please let me know and I will do it.

    Thanks!

    George

  • Thank you George,

    I have discussed this with the sw team.

    At this point we think that the path forward is to check the chirp configuration to make sure it is correct.

    There are two points where we need to check the chirp configuration: before the chirp configuration is sent to the RF front end and after the configuration is received by the RF front end.

    Before the chirp configuration is sent to the RF front end we can check it in the code by stepping through the code.

    After the configuration is received by the RF front end we can check some memory addresses to check the chirp configuration. We would need to find out the addresses from the design team.

    Early next week we will work to run the code with your changes and see if we can check the chirp configuration.

    What is the SDK version your code is based on?

    Thank you

    Cesar

  • Hi Cesar,

    This is great news! I really cannot thank you and the sw team enough for your help. I look forward to hearing what you all find out.

    I am using mmwave_sdk_02_00_00_04. The reason for me using this SDK is because I was building my system prior to the release of the most recent sdk releases, like SDK 3.4. I have attached the manipulated documents again below for your and the sw team's reference. Also, attached is a CLI script that I would use in this case.

    7624.mss_main.c

    1882.mmw_config.h

    /*
     *   @file  cli.c
     *
     *   @brief
     *      Mmw (Milli-meter wave) DEMO CLI Implementation
     *
     *  \par
     *  NOTE:
     *      (C) Copyright 2016 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>
    
    /* BIOS/XDC Include Files. */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/IHeap.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/Memory.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Event.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/heaps/HeapBuf.h>
    #include <ti/sysbios/heaps/HeapMem.h>
    #include <ti/sysbios/knl/Event.h>
    
    /* mmWave SDK Include Files: */
    #include <ti/common/sys_common.h>
    #include <ti/common/mmwave_sdk_version.h>
    #include <ti/drivers/uart/UART.h>
    #include <ti/control/mmwavelink/mmwavelink.h>
    #include <ti/utils/cli/cli.h>
    
    /* Demo Include Files */
    #include "ti/demo/xwr16xx/mmw/mss/mss_mmw.h"
    #include "ti/demo/xwr16xx/mmw/common/mmw_messages.h"
    
    /**************************************************************************
     *************************** Local Definitions ****************************
     **************************************************************************/
    
    /* CLI Extended Command Functions */
    static int32_t MmwDemo_CLICfarCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIPeakGroupingCfg (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIMultiObjBeamForming (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLICalibDcRangeSig (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIExtendedMaxVelocity (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIClutterRemoval (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_CLISetDataLogger (int32_t argc, char* argv[]);
    static int32_t MmwDemo_CLIADCBufCfg (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_CLINearFieldCorrection (int32_t argc, char* argv[]);
    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[]);
    static int32_t MmwDemo_CLILvdsStreamCfg (int32_t argc, char* argv[]);
    
    /**************************************************************************
     *************************** Extern Definitions *******************************
     **************************************************************************/
    
    extern MmwDemo_MCB    gMmwMssMCB;
    extern int32_t MmwDemo_mboxWrite(MmwDemo_message     * message);
    
    /**************************************************************************
     *************************** 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;
        if (argc==2)
        {
            doReconfig = (bool) atoi (argv[1]);
        }
        /* Post sensorSTart event to notify configuration is done */
        MmwDemo_notifySensorStart(doReconfig);
        /* Pend for completion */
        return (MmwDemo_waitSensorStartComplete());
    }
    
    
    /**
     *  @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[])
    {
        /* Post sensorSTOP event to notify sensor stop command */
        MmwDemo_notifySensorStop();
        /* Pend for completion */
        MmwDemo_waitSensorStopComplete();
        return 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;
    }
    
    static void MmwDemo_mssCfgUpdate(void *srcPtr, uint32_t offset, uint32_t size, int8_t subFrameNum)
    {    
        /* if subFrameNum undefined, broadcast to all sub-frames */
        if(subFrameNum == MMWDEMO_SUBFRAME_NUM_FRAME_LEVEL_CONFIG)
        {
            uint8_t  indx;
            for(indx = 0; indx < RL_MAX_SUBFRAMES; indx++)
            {
                memcpy((void *)((uint32_t) &gMmwMssMCB.cliCfg[indx] + offset), srcPtr, size);
            }
            
        }
        else
        {
            /* Apply configuration to specific subframe (or to position zero for the legacy case
               where there is no advanced frame config) */
            memcpy((void *)((uint32_t) &gMmwMssMCB.cliCfg[subFrameNum] + offset), srcPtr, size);
        }
    }
    
    /**
     *  @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;
        MmwDemo_message     message;
        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_mssCfgUpdate((void *)&guiMonSel, offsetof(MmwDemo_CliCfg_t, guiMonSel), 
            sizeof(MmwDemo_GuiMonSel), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_GUIMON_CFG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.guiMonSel, (void *)&guiMonSel, sizeof(MmwDemo_GuiMonSel));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @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[])
    {
        MmwDemo_CfarCfg     cfarCfg;
        MmwDemo_message     message;
        uint32_t            procDirection;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 9, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&cfarCfg, 0, sizeof(MmwDemo_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]);
        cfarCfg.thresholdScale    = (uint16_t) atoi (argv[8]);
    
        /* Save Configuration to use later */     
        if (procDirection == 0)
        {
            MmwDemo_mssCfgUpdate((void *)&cfarCfg, offsetof(MmwDemo_CliCfg_t, cfarCfgRange),
                sizeof(MmwDemo_CfarCfg), subFrameNum);    
        }
        else
        {
            MmwDemo_mssCfgUpdate((void *)&cfarCfg, offsetof(MmwDemo_CliCfg_t, cfarCfgDoppler),
                sizeof(MmwDemo_CfarCfg), subFrameNum);    
        }
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
        if (procDirection == 0)
        {
            message.type = MMWDEMO_MSS2DSS_CFAR_RANGE_CFG;
        }
        else if (procDirection == 1)
        {
            message.type = MMWDEMO_MSS2DSS_CFAR_DOPPLER_CFG;
        }
        else
        {
            return -1;
        }
    
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.cfarCfg, (void *)&cfarCfg, sizeof(MmwDemo_CfarCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;    
    }
    
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for Peak grouping configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLIPeakGroupingCfg (int32_t argc, char* argv[])
    {
        MmwDemo_PeakGroupingCfg peakGroupingCfg;
        MmwDemo_message         message;
        int8_t                  subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 7, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&peakGroupingCfg, 0, sizeof(MmwDemo_PeakGroupingCfg));
    
        /* Populate configuration: */
        peakGroupingCfg.scheme               = (uint8_t) atoi (argv[2]);
        peakGroupingCfg.inRangeDirectionEn   = (uint8_t) atoi (argv[3]);
        peakGroupingCfg.inDopplerDirectionEn = (uint8_t) atoi (argv[4]);
        peakGroupingCfg.minRangeIndex    = (uint16_t) atoi (argv[5]);
        peakGroupingCfg.maxRangeIndex    = (uint16_t) atoi (argv[6]);
    
        if (peakGroupingCfg.scheme != 1 && peakGroupingCfg.scheme != 2)
        {
            CLI_write ("Error: Invalid peak grouping scheme\n");
            return -1;
        }
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&peakGroupingCfg, offsetof(MmwDemo_CliCfg_t, peakGroupingCfg),
            sizeof(MmwDemo_PeakGroupingCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_PEAK_GROUPING_CFG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.peakGroupingCfg, (void *)&peakGroupingCfg, sizeof(MmwDemo_PeakGroupingCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    
    /**
     *  @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[])
    {
        MmwDemo_MultiObjBeamFormingCfg cfg;
        MmwDemo_message     message;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 4, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration: */
        memset ((void *)&cfg, 0, sizeof(MmwDemo_MultiObjBeamFormingCfg));
    
        /* Populate configuration: */
        cfg.enabled                     = (uint8_t) atoi (argv[2]);
        cfg.multiPeakThrsScal           = (float) atof (argv[3]);
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, multiObjBeamFormingCfg),
            sizeof(MmwDemo_MultiObjBeamFormingCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_MULTI_OBJ_BEAM_FORM;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.multiObjBeamFormingCfg, (void *)&cfg, sizeof(MmwDemo_MultiObjBeamFormingCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    uint32_t log2Approx(uint32_t x)
    {
        uint32_t idx, detectFlag = 0;
    
        if ( x < 2)
        {
            return (0);
        }
    
        idx = 32U;
        while((detectFlag==0U) || (idx==0U))
        {
            if(x & 0x80000000U)
            {
                detectFlag = 1;
            }
            x <<= 1U;
            idx--;
        }
    
        if(x != 0)
        {
            idx = idx + 1;
        }
    
        return(idx);
    }
    
    /**
     *  @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[])
    {
        MmwDemo_CalibDcRangeSigCfg cfg;
        MmwDemo_message            message;
        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(MmwDemo_CalibDcRangeSigCfg));
    
        /* 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 - cfg.negativeBinIdx + 1) > DC_RANGE_SIGNATURE_COMP_MAX_BIN_SIZE)
        {
            CLI_write ("Error: Number of bins exceeds the limit\n");
            return -1;
        }
        log2NumAvgChirps = (uint32_t) log2Approx (cfg.numAvgChirps);
        if (cfg.numAvgChirps != (1 << log2NumAvgChirps))
        {
            CLI_write ("Error: Number of averaged chirps is not power of two\n");
            return -1;
        }
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, calibDcRangeSigCfg),
            sizeof(MmwDemo_CalibDcRangeSigCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_CALIB_DC_RANGE_SIG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.calibDcRangeSigCfg, (void *)&cfg, sizeof(MmwDemo_CalibDcRangeSigCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for Velocity Disambiguation 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[])
    {
        MmwDemo_ExtendedMaxVelocityCfg cfg;
        MmwDemo_message                message;
        int8_t                         subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 3, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration for DC range signature calibration */
        memset ((void *)&cfg, 0, sizeof(MmwDemo_ExtendedMaxVelocityCfg));
    
        /* Populate configuration: */
        cfg.enabled          = (uint16_t) atoi (argv[2]);
    
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, extendedMaxVelocityCfg),
            sizeof(MmwDemo_ExtendedMaxVelocityCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_EXTENDED_MAX_VELOCITY;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.extendedMaxVelocityCfg, (void *)&cfg, sizeof(MmwDemo_ExtendedMaxVelocityCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for Near field correction Configuration
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    static int32_t MmwDemo_CLINearFieldCorrection (int32_t argc, char* argv[])
    {
        MmwDemo_NearFieldCorrectionCfg cfg;
        MmwDemo_message                message;
        int8_t                         subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 5, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration for Near Field Correction */
        memset ((void *)&cfg, 0, sizeof(MmwDemo_NearFieldCorrectionCfg));
    
        /* Populate configuration: */
        cfg.enabled       = (uint8_t) atoi(argv[2]);
        cfg.startRangeIdx = (uint16_t) atoi(argv[3]);
        cfg.endRangeIdx   = (uint16_t) atoi(argv[4]);
    
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, nearFieldCorrectionCfg),
            sizeof(MmwDemo_NearFieldCorrectionCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_NEAR_FIELD_CFG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.nearFieldCorrectionCfg, (void *)&cfg, 
               sizeof(MmwDemo_NearFieldCorrectionCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    /**
     *  @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[])
    {
        MmwDemo_ClutterRemovalCfg cfg;
        MmwDemo_message     message;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 3, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration for clutter removal */
        memset ((void *)&cfg, 0, sizeof(MmwDemo_ClutterRemovalCfg));
    
        /* Populate configuration: */
        cfg.enabled          = (uint16_t) atoi (argv[2]);
    
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, clutterRemovalCfg),
            sizeof(MmwDemo_ClutterRemovalCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_CLUTTER_REMOVAL;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.clutterRemovalCfg, (void *)&cfg, sizeof(MmwDemo_ClutterRemovalCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @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_CLISetDataLogger (int32_t argc, char* argv[])
    {
        MmwDemo_message     message;
    
        /* Sanity Check: Minimum argument check */
        if (argc != 2)
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
    
    
        /* Save Configuration to use later */
        if (strcmp(argv[1], "mssLogger") == 0)  
            gMmwMssMCB.cfg.dataLogger = 0;
        else if (strcmp(argv[1], "dssLogger") == 0)  
            gMmwMssMCB.cfg.dataLogger = 1;
        else
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
           
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
    
        message.type = MMWDEMO_MSS2DSS_SET_DATALOGGER;
        message.body.dataLogger = gMmwMssMCB.cfg.dataLogger;
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @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;
        MmwDemo_message     message;
        int8_t              subFrameNum;
    
        if(MmwDemo_CLIGetSubframe(argc, argv, 6, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize the ADC Output configuration: */
        memset ((void *)&adcBufCfg, 0, sizeof(MmwDemo_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]);
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&adcBufCfg, offsetof(MmwDemo_CliCfg_t, adcBufCfg),
            sizeof(MmwDemo_ADCBufCfg), subFrameNum);
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
        message.type = MMWDEMO_MSS2DSS_ADCBUFCFG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.adcBufCfg, (void *)&adcBufCfg, sizeof(MmwDemo_ADCBufCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    
    /**
     *  @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[])
    {
        MmwDemo_compRxChannelBiasCfg_t   cfg;
        MmwDemo_message     message;
        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(MmwDemo_compRxChannelBiasCfg_t));
    
        /* 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.);
            Re = MMWDEMO_SATURATE_HIGH(Re);
            Re = MMWDEMO_SATURATE_LOW(Re);
            cfg.rxChPhaseComp[i].real = (int16_t) Re;
    
            Im = (int32_t) (atof (argv[argInd++]) * 32768.);
            Im = MMWDEMO_SATURATE_HIGH(Im);
            Im = MMWDEMO_SATURATE_LOW(Im);
            cfg.rxChPhaseComp[i].imag = (int16_t) Im;
    
        }
        /* Save Configuration to use later */
        memcpy((void *) &gMmwMssMCB.cliCommonCfg.compRxChanCfg, &cfg, sizeof(MmwDemo_compRxChannelBiasCfg_t));
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
        message.type = MMWDEMO_MSS2DSS_COMP_RANGE_BIAS_AND_RX_CHAN_PHASE;
        memcpy((void *)&message.body.compRxChanCfg, (void *)&cfg, sizeof(MmwDemo_compRxChannelBiasCfg_t));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @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[])
    {
        MmwDemo_measureRxChannelBiasCfg_t   cfg;
        MmwDemo_message     message;
    
        /* 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(MmwDemo_measureRxChannelBiasCfg_t));
    
        /* 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.cliCommonCfg.measureRxChanCfg, &cfg, sizeof(MmwDemo_measureRxChannelBiasCfg_t));
    
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
        message.type = MMWDEMO_MSS2DSS_MEASURE_RANGE_BIAS_AND_RX_CHAN_PHASE;
        memcpy((void *)&message.body.measureRxChanCfg, (void *)&cfg, sizeof(MmwDemo_measureRxChannelBiasCfg_t));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for BPM configuration supported by the mmw Demo
     *      Note that there is a generic BPM configuration command supported by
     *      utils/cli and mmwave. The generic BPM command is not supported by the
     *      demo as the mmw demo assumes a specific BPM pattern for the TX antennas.
     *
     *  @param[in] argc
     *      Number of arguments
     *  @param[in] argv
     *      Arguments
     *
     *  @retval
     *      Success -   0
     *  @retval
     *      Error   -   <0
     */
    // George Edited this BPM section to include 2 more chirp indexes
    static int32_t MmwDemo_CLIBpmCfg (int32_t argc, char* argv[])
    {
    
        int8_t           subFrameNum;
        MmwDemo_BpmCfg   cfg;
        MmwDemo_message  message;
        
        /* Sanity Check: Minimum argument check */
        if (argc != 7)
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
        
        if(MmwDemo_CLIGetSubframe(argc, argv, 7, &subFrameNum) < 0)
        {
            return -1;
        }
    
        /* Initialize configuration for DC range signature calibration */
        memset ((void *)&cfg, 0, sizeof(MmwDemo_BpmCfg));
    
        /* Populate configuration: */
        cfg.isEnabled = (bool) atoi(argv[2]) ;
        cfg.chirp0Idx = (uint16_t) atoi(argv[3]) ;
        cfg.chirp1Idx = (uint16_t) atoi(argv[4]) ;
        cfg.chirp2Idx = (uint16_t) atoi(argv[5]) ;
        cfg.chirp3Idx = (uint16_t) atoi(argv[6]) ;
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, bpmCfg),
            sizeof(MmwDemo_BpmCfg), subFrameNum);
            
        message.type = MMWDEMO_MSS2DSS_BPM_CFG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.bpmCfg, (void *)&cfg, sizeof(MmwDemo_BpmCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
            
    }
    
    /**
     *  @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;
        MmwDemo_message         message;
    
        /* 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 */
            memcpy((void *) &gMmwMssMCB.cliCommonCfg.cqSatMonCfg[cqSatMonCfg.profileIndx], 
                           &cqSatMonCfg, 
                           sizeof(rlRxSatMonConf_t));
    
            /* Send configuration to DSS */
            memset((void *)&message, 0, sizeof(MmwDemo_message));
            message.type = MMWDEMO_MSS2DSS_CQ_SATURATION_MONITOR;
            memcpy((void *)&message.body.cqSatMonCfg, (void *)&cqSatMonCfg, sizeof(rlRxSatMonConf_t));
    
            if (MmwDemo_mboxWrite(&message) == 0)
                return 0;
            else
                return -1;
        }
        else
        {
            return -1;
        }
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Handler for configuring CQ Singal & 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;
        MmwDemo_message         message;
    
        /* 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 */
            memcpy((void *) &gMmwMssMCB.cliCommonCfg.cqSigImgMonCfg[cqSigImgMonCfg.profileIndx], 
                    &cqSigImgMonCfg, 
                    sizeof(rlSigImgMonConf_t));
    
            /* Send configuration to DSS */
            memset((void *)&message, 0, sizeof(MmwDemo_message));
            message.type = MMWDEMO_MSS2DSS_CQ_SIGIMG_MONITOR;
            memcpy((void *)&message.body.cqSigImgMonCfg, (void *)&cqSigImgMonCfg, sizeof(rlSigImgMonConf_t));
    
            if (MmwDemo_mboxWrite(&message) == 0)
                return 0;
            else
                return -1;
        }
        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[])
    {
        MmwDemo_message     message;
        
        /* 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.cliCommonCfg.anaMonCfg.rxSatMonEn = atoi (argv[1]);
        gMmwMssMCB.cliCommonCfg.anaMonCfg.sigImgMonEn = atoi (argv[2]);
        
        /* Send configuration to DSS */
        memset((void *)&message, 0, sizeof(MmwDemo_message));
        message.type = MMWDEMO_MSS2DSS_ANALOG_MONITOR;
        memcpy((void *)&message.body.anaMonCfg, 
                (void *)&gMmwMssMCB.cliCommonCfg.anaMonCfg, 
                sizeof(MmwDemo_AnaMonitorCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    
    /**
     *  @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[])
    {
    
        int8_t                  subFrameNum;
        MmwDemo_LvdsStreamCfg   cfg;
        MmwDemo_message         message;
        
        /* Sanity Check: Minimum argument check */
        if (argc != 5)
        {
            CLI_write ("Error: Invalid usage of the CLI command\n");
            return -1;
        }
        
        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]) ;
    
        /* Save Configuration to use later */
        MmwDemo_mssCfgUpdate((void *)&cfg, offsetof(MmwDemo_CliCfg_t, lvdsStreamCfg),
            sizeof(MmwDemo_LvdsStreamCfg), subFrameNum);
            
        message.type = MMWDEMO_MSS2DSS_LVDSSTREAM_CFG;
        message.subFrameNum = subFrameNum;
        memcpy((void *)&message.body.lvdsStreamCfg, (void *)&cfg, sizeof(MmwDemo_LvdsStreamCfg));
    
        if (MmwDemo_mboxWrite(&message) == 0)
            return 0;
        else
            return -1;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the CLI Execution Task
     *
     *  @retval
     *      Not Applicable.
     */
    void MmwDemo_CLIInit (void)
    {
        CLI_Cfg     cliCfg;
        char        demoBanner[256];
        uint32_t    cnt;
    
        /* Create Demo Banner to be printed out by CLI */
        sprintf(&demoBanner[0], 
                           "******************************************\n" \
                           "xWR16xx 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                 = 3;
        cliCfg.mmWaveHandle                 = gMmwMssMCB.ctrlHandle;
        cliCfg.enableMMWaveExtension        = 1U;
        cliCfg.usePolledMode                = true;
        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>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLICfarCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "peakGrouping";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <groupingMode> <rangeDimEn> <dopplerDimEn> <startRangeIdx> <endRangeIdx>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIPeakGroupingCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "dataLogger";
        cliCfg.tableEntry[cnt].helpString     = "<mssLogger | dssLogger>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLISetDataLogger;
        cnt++;
    
        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            = "extendedMaxVelocity";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <enabled>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIExtendedMaxVelocity;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "clutterRemoval";
        cliCfg.tableEntry[cnt].helpString     = "<enabled>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIClutterRemoval;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "adcbufCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <adcOutputFmt> <SampleSwap> <ChanInterleave> <ChirpThreshold>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIADCBufCfg;
        cnt++;
    
        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++;
    
    // George edited this to include 2 more chirp indexes
    
        cliCfg.tableEntry[cnt].cmd            = "bpmCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <enabled> <chirp0Idx> <chirp1Idx> <chirp2Idx> <chirp3Idx>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIBpmCfg;
        cnt++;
    
        cliCfg.tableEntry[cnt].cmd            = "nearFieldCfg";
        cliCfg.tableEntry[cnt].helpString     = "<enabled> <startRangeIndex> <endRangeIndex>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLINearFieldCorrection;
        cnt++;
    
        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++;
        
        cliCfg.tableEntry[cnt].cmd            = "lvdsStreamCfg";
        cliCfg.tableEntry[cnt].helpString     = "<subFrameIdx> <enableHeader> <dataFmt> <enableSW>";
        cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLILvdsStreamCfg;
        cnt++;   
        
        /* Open the CLI: */
        if (CLI_open (&cliCfg) < 0)
        {
            System_printf ("Error: Unable to open the CLI\n");
            return;
        }
        System_printf ("Debug: CLI is operational\n");
        return;
    }
    
    
    

    6064.dss_main.c

    sensorStop
    flushCfg
    dfeDataOutputMode 1
    channelCfg 15 2 0
    adcCfg 2 1
    adcbufCfg -1 0 0 1 0
    profileCfg 0 77 7 7 160 0 0 25 1 512 6200 0 0 30
    chirpCfg 0 0 0 0 0 0 0 2
    chirpCfg 1 1 0 0 0 0 0 2
    chirpCfg 2 2 0 0 0 0 0 2
    chirpCfg 3 3 0 0 0 0 0 2
    bpmCfg -1 1 0 1 2 3
    frameCfg 0 3 16 120 250 1 0
    lowPower 0 1
    guiMonitor -1 0 0 0 0 0 0
    cfarCfg -1 0 2 8 4 4 0 5120
    cfarCfg -1 1 0 8 4 4 0 5120
    peakGrouping -1 1 0 0 1 224
    multiObjBeamForming -1 0 0.5
    calibDcRangeSig -1 0 -5 8 256
    extendedMaxVelocity -1 0
    clutterRemoval -1 0
    compRangeBiasAndRxChanPhase 0.0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
    measureRangeBiasAndRxChanPhase 0 1.5 0.2
    nearFieldCfg -1 0 0 0
    CQRxSatMonitor 0 3 4 127 0
    CQSigImgMonitor 0 63 8
    analogMonitor 0 0
    lvdsStreamCfg -1 0 1 0
    sensorStart
    

    Additionally, to restate the goal: I am solely trying to transmit a block of 64 chirps in one frame that contains 16 loops of a four-chirp block of [0 0 1 1] sequence. These chirps can be transmitted out of either transmitter. I only want one Tx active (as for commented out portion of the dss_main.c file that checks if both TXs are active).

    Thank you again and continue to send questions my way when they arise! 

    George

  • George,

    In your modified mss_main.c file, can you make the following changes and test today:

    - Find the four entries of bpmChirpCfg.constBpmVal in the mmwdemo_bpmconfig() function

    - Set the first two values to 0x0 to set the phase shift value to 0 on both TX0 and TX1

    - Set the second two values to 0xF to set the phase shift value to 180 on both TX0 and TX1

    Let's see if that change has any impact while I continue to debug your code.

    Regards,
    Kyle

  • Hi Kyle,

    Thank you very much for helping me debug my code! 

    I changed to code to include '0x0' and '0xF' and I did not get much different of a result. The correctly decoded signal [chip1+chirp2-chirp3-chirp4)/4] was fairly similar to the incorrectly decoded signal [chip1-chirp2+chirp3-chirp4)/4], which--if the signal actually transmitted [0011]--should have reduced the signal power significantly. See some preliminary graphs below:

    **Signal = [0011]

    Theoretically correct decoding: [chip1+chirp2-chirp3-chirp4)/4]

    Incorrect decoding: [chip1-chirp2+chirp3-chirp4)/4]

    What do you think of using the bpmAdvancedConfig CLI API to accomplish the [0011] bpm scheme on one Tx?

    Thanks!

    George

  • George,

    We are working with the design team to read the chirp configuration on the BSS side. We expect to have it tomorrow

    thank you

    Cesar

  • Awesome, thank you very much Cesar!

    Have a nice day and talk to you tomorrow.

    George

  • George,

    Using your modified source files, we have confirmed in the chirp RAM that BPM is enabled on TX2 for both chirp #3 and chirp #4. BPM is not enabled for chirp #1 and chirp #2.

    Perhaps there is an issue with decoding the BPM values?

    Regards,

    Kyle

  • Hi Kyle,

    Thank you so much for getting back to me! What do you mean by "BPM is not enabled for chirp1 and chirp2"? Are you saying 0's are being transmitted out of Tx2 for chirp 1 and chirp 2? So in the chirp RAM, are you noticing that the chirp sequence is [0011]?

    If yes to the above, does that mean that if we change chirp 1 and chirp 2 constBpmVal to 0U and chirp 3 and chirp 4 constBpmVal to 0x3, then we would still get the same chirp sequence [0011], but out of Tx1 (if we enabled the that channelCfg to be 1)? 

    Thanks!

    George

  • George,

    Let me attach this snapshot of what the Chirp RAM looks like. What Kyle tried to explain is that when he reads the Chirp RAM, BPM_TX2 bit is enabled only for chirp 3,4. So, regarding the BPM phase shift, yes we are reading

    chirp 1 - no phase shift

    chirp 2 - no phase shift

    chirp 3 - phase shift

    chrip 4 - phase shift

    Question

    If yes to the above, does that mean that if we change chirp 1 and chirp 2 constBpmVal to 0U and chirp 3 and chirp 4 constBpmVal to 0x3, then we would still get the same chirp sequence [0011], but out of Tx1 (if we enabled the that channelCfg to be 1)?

    Answer

    Yes, this would be my expectation. If you want to make the code changes, we can try it

    thank you
    Cesar

  • George,

    To echo Cesar's response, your understanding of my previous post is correct.

    I went ahead and confirmed that changing the constBpmVal to 0x3 results in the following BPM chirp sequence:

    Chirp 1 - no phase shift

    Chirp 2 - no phase shift

    Chirp 3 - phase shift

    Chirp 4 - phase shift

    Now in this case, the BPM is applied to TX1 where previously the BPM was applied to TX2.

    Regards,
    Kyle

  • Hi Kyle and Cesar,

    Thank you for running the above test cases and getting back to me. There are a few things I am noticing, discussed below, that I am concerned about. 

    Correct me if I am wrong, but the Chirp RAM (where you are looking) is located before the BSS, correct? I honestly still think that while the chirp RAM has the correct configuration, the BSS is still not either 1) not receiving that configuration or 2) not updating the front end with with the correct configuration to transmit. Here is why:

    - To confirm everything transmitted correctly, I changed the constBpmVal to 0U for all 4 chirps. I then ran a test with a corner reflector to see if there is no phase change across samples in consecutive chirps. Unfortunately, below show four screenshots, which depict the degrees I received for chirp 9-12 from Tx1, Tx2, Tx3, and Tx4. (**Assume indexes for the BPM decoding block is chirp1-chirp4**). I calculated these values by taking rad2deg(complex ADC samples) received at each receiver.

    Rx 1:

    Rx 2:

    Rx 3:

    Rx 4:

    As you can see, the same samples across chirps (independent of Rx) are not 0 degrees. Is there a particular reason why you would say that the chirps in the RAM are not being transmitted with the correct phase shift? 

    If you look closer, chirp 1 and chirp 3 for Rx 1 and 3 were relatively 180 degrees apart from chirp 2 and chirp 4 on Rx 1 and 3. But for Rx 2 and Rx 4, they are about 21 deg off. Why would you say they are not consistent? 

    Furthermore, as you look in the spatial domain (rather than the time domain -- across chirps) across Rx for the same chirp, there is weird things happening across Rx's. Regardless of BPM, shouldn't we expect the degrees received on the same Rx to be the same across chirps (since the corner reflector is directly in front of the radar)? There is another weird pattern.

    Thanks and I look forward to hearing your thoughts on these issues!

    George 

  • Hi George,

    Thank you for your patience. I think we are not using the right tools to investigate this issue.

    Since we are debugging RF configuration (at this point), I think the best tool is mmWave Studio + DCA1000.

    This should allow us to capture raw data and quickly analyze it.

    I will work with the team to create a short script to configure the RF front end with the parameters of interest and capture some raw data.

    It will take probably until the end of the week to get this done

    Will get back to you as soon as we have the data

    Thank you

    Cesar

  • Hi Cesar,

    Great, thank you for working with the team to help me solve this issue. I really appreciate the help!

    You may also tell the team that as of yesterday morning, I received the desired BPM sequence (not the default [01] bpm sequence) as seen in screenshots below similar to my last post by using bpmCfgAdvanced in the Advanced Frame Mode. BUT, the received power for the 180deg BPM phase shifted chirps was in the negative dB. I worked all yesterday trying to figure out why. Please see the screenshots below confirming the sequence, but also the very low power. I have also attached the CLI script that I used to configure the AWR1642. If I can understand why the received power is so low and fix it, it seems like everything should work out. 

    Chirp Sequence: [chirp1 chirp2 chirp3 chirp4], where the values shown are received adc samples converted from complex numbers to degrees.

    Range and Doppler FFT over all samples (no decoding): 

    Info for below graph: range_bin = 12; doppler_bin = 1; frameIndex = 20; rx_num = 1;

    Range and Doppler FFT across a range bin (Pre-decoded) with low power:

    Info for below graph: range_bin = 16; doppler_bin = 4; frameIndex = 20; rx_num = 1;

    Also, for evidence that my code works, I have attached below plots for the monostatic (0 deg phase shift for all chirps) case using the same MATLAB code:

    CLI Script used: 

    sensorStop
    flushCfg
    dfeDataOutputMode 3
    channelCfg 15 3 0
    adcCfg 2 1
    adcbufCfg -1 0 0 1 0
    profileCfg 0 77 7 7 160 0 0 20 1 512 6200 0 0 30
    chirpCfg 0 0 0 0 0 0 0 1
    chirpCfg 1 1 0 0 0 0 0 1
    chirpCfg 2 2 0 0 0 0 0 1
    chirpCfg 3 3 0 0 0 0 0 1
    advFrameCfg 1 0 60 1 0
    subFrameCfg 0 0 0 4 16 100 0 1 1 100
    bpmCfgAdvanced 0 1 0
    bpmCfgAdvanced 2 3 3
    lowPower 0 1
    guiMonitor -1 0 0 0 0 0 0
    cfarCfg -1 0 2 8 4 4 0 5120
    cfarCfg -1 1 0 8 4 4 0 5120
    peakGrouping -1 1 0 0 1 224
    multiObjBeamForming -1 0 0.5
    calibDcRangeSig -1 0 -5 8 256
    extendedMaxVelocity -1 0
    clutterRemoval -1 0
    compRangeBiasAndRxChanPhase 0.0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
    measureRangeBiasAndRxChanPhase 0 1.5 0.2
    nearFieldCfg -1 0 0 0
    CQRxSatMonitor 0 3 4 127 0
    CQSigImgMonitor 0 63 8
    analogMonitor 0 0
    lvdsStreamCfg -1 0 1 0
    sensorStart

    Collected and Processed Data for above screenshots Attached as excel file: bpm_0011_BTxE.csv

    MATLAB code to plot these samples and print out the BPM scheme: 5102.check_transmission.pdf

    Looking forward to hearing all advice and recommendations you and your team have as soon as you have them. As always, keep sending questions when they pop up. Have a great day!

    George

  • Hi,

    As a follow up, I have noticed a few additional observations after doing more testing today that may help us all come to some answer as to how to make this all work:

    1) The spikes in the graph may depend on how many bpm chirps there are in the sequence:

    Ex: Sequence [00110010]

    Exception: when I do all 0's, and still do bpmCfgAdvanced (but put the constBpmVal to 0), I get the below. No spikes... Also, all chirps in the 4 chirp sequence are the same degrees (ref. note #3)

    2) Maybe the FFT does some sort of cancelation to the 0011 signal (screenshot in previous thread reply) since I ran a 0010 test and I got the below graph. I am thinking the chirp 3 and chirp 4 are canceled and chirp 1 and 2 make up the very positive power, normal looking doppler FFT and Range FFT (disregard spikes).

    3) Since the all 0's exception worked (no spikes, high powered FFTs, and chirps that all correlate), I tried bpmCfgAdvanced where all 4 chirps have a 1. This was weird because I got the below graph and the below set of chirps.... If you look at the chirps, only 3 correlate to each other, and the fourth, usually the first one in the sequence/resolution block, is phase shifted differently than the others (which is not what I configured). Also, notice that the FFTs are very positive which proves maybe one was phase shifted (canceled with another through FFT operation?) then plotted two non canceling [11] chirps or [00] chirps (if the first chirp is the only one phase shifted).... I am unsure...

    Thanks, 

    George

  • Thank you for your analysis

    We are working to capture raw data with BPM enabled. We should get this by end of the week

    cesar

  • Great, thanks!

  • Closing this thread since issue is resolved

    thank you
    Cesar