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.

RTOS/TDA2HV: Need example code to run in the use case mode

Part Number: TDA2HV
Other Parts Discussed in Thread: SYSBIOS, TDA2

Tool/software: TI-RTOS

Hi All,

We are working on the ADAS's TDA2x platform.We designed our custom board using a TDA2HV processor.We use using the vision SDK for development.We are using the lvds_vip_multicam_view use case. We want to use SPI's data to in our use case.For SPI interfacing TI provided the utils_Mcspi.c and utils_MCspi.h file, This file only contains SPI initialization function.So, how we can write and read into the SPI transmit and receive buffer.

My query is,
1) Can you please share SPI'slave example code in which we can run in the use case?

Please let me know if you need the more information from our side.

Thanks,
Parth Modi

  • Hi Parth,

    Drivers folder has mcspi master slave app that you can refer.
    I can help you with exact path if you specify the VSDK version you are using.
    Thanks.

    Regards,
    Rishabh
  • Hi Rishabh,

    Thanks for the quick support.

    We are using the Vision_SDK 3.0. We want to use this data in the lvds use case.So, Can you please provide as function call for spi init,spi read and writeI?

    Thanks,
    Parth
  • Hi Parth,

    The mcspi example that caters to you requirement is present here: ti_components\drivers\pdk_01_07_00_16\packages\ti\drv\bsp_lld\mcspi\examples\mcspi_spi1tospi2.
    Sysbios mcspi driver is based on GIO model. For init you can use GIO_create API.
    API GIO_issue is used to submit the buffer to the driver and GIO_reclaim is used to get the buffer from the driver.

    Regards,
    Rishabh
  • Hi Rishabh,

    As per your suggestion, I explored the MCSPI example code and I made demo code to test the MCSPI1 on our side. I run this code and I get all the initializing function going pass and but the code is stuck at the GIO_reclaim(mcspiHandle, (Ptr *) &dataparam, NULL, NULL);. I measured the SPI clock and SPI_cs0 line for confirmation to SPI initialization is worked or not.But it not works. I cant get any SPI clock and cs0 line low.

    I called start_spi_sample_new(Void) for all the operation. I attached my code for your information.

    I have some below queries for that,

    1) Is there any mistake in flow?

    2) Can you please share your suggestion to work this code?

    Please let me know if you need more information on our side.

    Thanks,

    Parth Modi

    mcspiSample_io.c
    /*
     *  Copyright (C) 2012-2017 Texas Instruments Incorporated
     *
     *  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.
     *
     */
    /**
     *  \file   mcspiSample_io.c
     *
     *  \brief  McSPI evm to evm communication sample application
     *
     *          This file demonstrates the use of Mcspi by using an
     *          EVM to EVM communication setup.This file configures one of the evm
     *          in master mode.
     */
    
    /* ========================================================================== */
    /*                          INCLUDE FILES                                     */
    /* ========================================================================== */
    
    #include <stdio.h>
    #include <string.h>
    #include <xdc/std.h>
    #include <ti/sysbios/io/GIO.h>
    #include <ti/sysbios/BIOS.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <ti/sysbios/knl/Task.h>
    #include <xdc/runtime/IHeap.h>
    #include <ti/sysbios/heaps/HeapMem.h>
    #include <ti/drv/bsp_lld/mcspi/bsp_mcspi.h>
    #include <xdc/runtime/Memory.h>
    #include <ti/sdo/edma3/drv/edma3_drv.h>
    #include <xdc/std.h>
    #include <stdio.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/io/GIO.h>
    #include <ti/sysbios/io/IOM.h>
    #include <xdc/runtime/Log.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/heaps/HeapMem.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <ti/sdo/edma3/drv/edma3_drv.h>
    #include <ti/drv/vps/include/common/bsp_types.h>
    #include <ti/drv/vps/include/common/trace.h>
    #include <ti/drv/vps/include/common/bsp_config.h>
    #include <ti/drv/vps/include/common/bsp_utils.h>
    #include <ti/drv/vps/include/common/bsp_common.h>
    #include <ti/drv/bsp_lld/mcspi/bsp_mcspi.h>
    #include <ti/drv/vps/include/platforms/bsp_platform.h>
    #include <ti/drv/vps/include/boards/bsp_board.h>
    #include <ti/drv/vps/include/devices/bsp_device.h>
    #include <ti/drv/bsp_lld/i2c/bsp_i2c.h>
    #include <ti/drv/vps/include/fvid2/fvid2.h>
    #include <ti/drv/vps/examples/utility/bsputils_mem.h>
    #include <ti/drv/vps/examples/utility/bsputils_prf.h>
    #include <ti/drv/vps/examples/utility/bsputils_app.h>
    #include "mcspiSample_io.h"
    
    /* ========================================================================== */
    /*                          LOCAL FUNCTION PROTOTYPES                         */
    /* ========================================================================== */
    EDMA3_DRV_Handle edma3init(UInt32 edma3Id, EDMA3_DRV_Result *);
    Int32 App_mcspiDefaultInit(UInt32 isI2cInitReq);
    void SPI_init(void);
    /* ========================================================================== */
    /*                            MACRO DEFINITONS                                */
    /* ========================================================================== */
    
    /* ========================================================================== */
    /*                              GLOBAL VARIABLES                              */
    /* ========================================================================== */
    
    EDMA3_DRV_Handle      gEdmaHandle;
    UInt32       gIsI2cInitReq;
    extern const IOM_Fxns Mcspi_IOMFXNS;
    HeapMem_Handle myHeap;
    
    /*
     * Buffers placed in external memory are aligned on a 128 bytes boundary.
     * In addition, the buffer should be of a size multiple of 128 bytes for
     * the cache to work optimally.
     */
    
    #define BUFLEN          (1024 * 4) /* Buffer size */
    #define BUFALIGN        128        /* Alignment of buffer for use of L2 cache */
    #define ITERATION_CNT   100        /* Number of Iterations */
    #define NUM_BUFS        3          /* Num Bufs to be issued and reclaimed */
    
    /* handle to the input and output streams   */
    GIO_Handle mcspiHandle = NULL;
    
    /* Global SPI init config data structure    */
    Mcspi_Params   mcspiPrms;
    
    Mcspi_DataParam       issueDataparam[NUM_BUFS];
    
    /* Buffer alignement is required when working in DMA Mode */
    #pragma DATA_ALIGN(rxbuf, BUFALIGN);
    Ptr  rxbuf[NUM_BUFS];
    
    /* Buffer alignement is required when working in DMA Mode */
    #pragma DATA_ALIGN(txbuf, BUFALIGN);
    Ptr  txbuf[NUM_BUFS];
    
    Bool failFlag = FALSE;
    
    /* Function prototype */
    
    static void createStream(void);
    static void prime(void);
    
    /* ========================================================================== */
    /*                           FUNCTION DEFINITIONS                             */
    /* ========================================================================== */
    
    /*
     * ======== createStream ========
     */
    
    static void createStream(void)
    {
        GIO_Params       ioParams;
        Mcspi_ChanParams chanParams;
        Error_Block      eb;
    
        Error_init(&eb);
    
        /*
         * Initialize channel attributes.
         */
        GIO_Params_init(&ioParams);
    
        /* update the edma Handle                                                 */
        chanParams.hEdma = gEdmaHandle;
        chanParams.chipSelTimeControl = MCSPI_CLK_CYCLE0;
        chanParams.fifoEnable         = (UInt32) TRUE;
        chanParams.spiChipSelectHold  = (UInt32) TRUE;
        chanParams.chanNum = 0;
    
        /* If cross bar events are being used then make isCrossBarIntEn = TRUE and
         * choose appropriate interrupt number to be mapped (assign it to
         * intNumToBeMapped)
         */
        /* Cross bar evt disabled */
        chanParams.crossBarEvtParam.isCrossBarIntEn  = (UInt32) FALSE;
        chanParams.crossBarEvtParam.intNumToBeMapped = 0xFF;  /* Invalid number */
    
        ioParams.chanParams = (Ptr) & chanParams;
        ioParams.model      = GIO_Model_ISSUERECLAIM;
        ioParams.numPackets = NUM_BUFS + 1;
    
        mcspiHandle = GIO_create("/mcspi0", GIO_INOUT, &ioParams, &eb);
        if (mcspiHandle == NULL)
        {
            System_printf("\r\nCreate input stream FAILED.\r\n");
            BIOS_exit(0);
        }
        System_printf("\r\nCreate input stream completed.\r\n");
    }
    /*
     * \brief   Function to submit request the driver.Depending on the macro
     *          "NUM_BUFS" either the driver can be buffered with multiple requests
     *          or only one buffer by using the NUM_BUFS as 1.
     *
     * \param   None
     *
     * \return  None
     */
    static void prime(void)
    {
    
        Error_Block  eb;
        Int32        count = 0;
        IHeap_Handle iheap;
        UInt32       tempCount = 0;
        UInt32       size      = 0;
        Int          status    = IOM_COMPLETED;
    
        iheap = HeapMem_Handle_to_xdc_runtime_IHeap(myHeap);
        Error_init(&eb);
    
        /* Allocate buffers for the GIO buffer exchanges                          */
       for (count = 0; count < (NUM_BUFS); count++)
        {
            rxbuf[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
            if (NULL == rxbuf[count])
            {
                System_printf("\r\nMEM_calloc failed.\r\n");
            }
    
            txbuf[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
            if (NULL == txbuf[count])
            {
               System_printf("\r\nMEM_calloc failed.\r\n");
            }
        }
    
        /* Fill the buffers with known data and transmit the same and check if the*
         * same pattern is received on the other EVM                              */
        for (count = 0; count < (NUM_BUFS); count++)
        {
            for (tempCount = 0; tempCount < BUFLEN; tempCount++)
            {
                ((Uint8 *) txbuf[count])[tempCount] = tempCount;
            }
        }
        for (count = 0; count < NUM_BUFS; count++)
        {
            issueDataparam[count].bufLen    = BUFLEN;
            issueDataparam[count].inBuffer  = rxbuf[count];
            issueDataparam[count].outBuffer = txbuf[count];
    
            size = issueDataparam[count].bufLen;
    
            /* Issue the first & second empty buffers to the input stream         */
            status = GIO_issue(mcspiHandle, &issueDataparam[count], size, NULL);
    
            if (status != IOM_PENDING && status != IOM_COMPLETED)
            {
                System_printf("\r\nFailed to issue empty buffer to stream\r\n");
            }
        }
        System_printf("\r\nprime completed\r\n");
    }
    
    void spiSampleTask(void)
    {
          Int32 retVal = FVID2_SOK;
          Bsp_PlatformInitParams platInitPrms;
    
        /* isPinMuxSettingReq parameter will be initialised to TRUE */
        BspPlatformInitParams_init(&platInitPrms);
    
        platInitPrms.isAllMcSPIInitReq  = TRUE;
        platInitPrms.isPinMuxSettingReq = TRUE;
    
        /* Initialize pinmux and evm related configurations */
        Bsp_platformInit(&platInitPrms);
        /* System init */
    
        if (retVal != FVID2_SOK)
        {
            System_printf("Error: : System Init Failed!!!\r\n");
        }
        /* Set the pin Mux */
        Bsp_boardSetPinMux(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_0,
                           BSP_BOARD_MODE_DEFAULT);
    
    
        /* Set the board muxes */
        Bsp_boardSelectDevice(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_0);
        /* call the function for the SPI application test                     */
    
    }
    
    /*
     * \brief   This function demostrates the use of Mcspi using an EVM to EVM
     *          communication setup.
     *
     * \param   None
     *
     * \return  None
     */
    void start_spi_sample_new(Void)
    {
        System_printf("\r\nIn start SPI sample new\r\n");
        volatile Int32   i32Count  = 0;
        Mcspi_DataParam *dataparam = {0};
        UInt32           tempCount = 0;
        UInt32           i, loopcount = 0;
        UInt32           dataMismatchError = 0;
        UInt8            temp8InBufVal = 0, temp8OutBufVal = 0;
        UInt16           temp16InBufVal = 0, temp16OutBufVal = 0;
        UInt32           temp32InBufVal = 0, temp32OutBufVal = 0;
        UInt32           maskVal        = 0;
    
        Int status = IOM_COMPLETED;
    
        spiSampleTask();
        SPI_init();
    
        EDMA3_DRV_Result edmaResult = 0;
    
        gEdmaHandle = edma3init(0, &edmaResult);
    
        if (edmaResult != EDMA3_DRV_SOK)
        {
            /* Report EDMA Error */
            System_printf("\r\nEDMA driver initialization FAIL\r\n");
        }
        else
        {
            System_printf("\r\nEDMA driver initialization PASS.\r\n");
        }
    
        /* Call createStream function to create I/O streams                       */
        createStream();
    
        /* Call prime function to do priming                                      */
        prime();
    
        for (i = 0; i < NUM_BUFS; i++)
        {
            dataparam = NULL;
            /* Reclaim full buffer from the stream                                */
            System_printf("before the reclaim \r\n");
            status = GIO_reclaim(mcspiHandle, (Ptr *) &dataparam, NULL, NULL);
            System_printf("In for loop\r\n");
            if (IOM_COMPLETED != status)
            {
                System_printf("Iteration %d\r\n", i32Count);
    
                System_printf(
                    "Error reclaiming empty buffer from the streams %x"
                    " error = 0x%d\r\n",
                    ((Uint8) (dataparam->outBuffer[i32Count])),
                    status);
                break;
            }
    
            maskVal =
                ((1 << (mcspiPrms.spiHWCfgData.configChfmt[0].charLength)) - 1);
    
            for (tempCount = 0; tempCount < BUFLEN; )
            {
                if (mcspiPrms.spiHWCfgData.configChfmt[0].charLength <= 8)
                {
                    temp8InBufVal  = dataparam->inBuffer[tempCount];
                    temp8OutBufVal = dataparam->outBuffer[tempCount];
    
                    /* temp8OutBufVal & temp8InBufVal is to be aligned with
                     * charLength.
                     * temp8InBufVal alignment is required only in case of DMA Mode
                     */
                    if ((temp8OutBufVal & maskVal) != (temp8InBufVal & maskVal))
                    {
                        dataMismatchError = 1;
                        break;
                    }
                    tempCount++;
                }
                else if (mcspiPrms.spiHWCfgData.configChfmt[0].charLength <= 16)
                {
                    temp16InBufVal = dataparam->inBuffer[tempCount] +
                                     (dataparam->inBuffer[tempCount + 1] << 8);
                    temp16OutBufVal = dataparam->outBuffer[tempCount] +
                                      (dataparam->outBuffer[tempCount + 1] << 8);
    
                    /* temp16OutBufVal & temp16InBufVal is to be aligned with
                     * charLength.
                     * temp16InBufVal alignment is required only in case of DMA Mode
                     */
                    if ((temp16OutBufVal & maskVal) != (temp16InBufVal & maskVal))
                    {
                        dataMismatchError = 1;
                        break;
                    }
                    tempCount = tempCount + 2;
                }
                else if (mcspiPrms.spiHWCfgData.configChfmt[0].charLength <= 32)
                {
                    temp32InBufVal = dataparam->inBuffer[tempCount] +
                                     (dataparam->inBuffer[tempCount + 1] << 8) +
                                     (dataparam->inBuffer[tempCount + 2] << 16) +
                                     (dataparam->inBuffer[tempCount + 3] << 24);
                    temp32OutBufVal = dataparam->inBuffer[tempCount] +
                                      (dataparam->inBuffer[tempCount + 1] << 8) +
                                      (dataparam->inBuffer[tempCount + 2] << 16) +
                                      (dataparam->inBuffer[tempCount + 3] << 24);
    
                    /* temp32OutBufVal & temp32InBufVal is to be aligned with
                     * charLength
                     * temp32InBufVal alignment is required only in case of DMA Mode
                     */
                    if ((temp32OutBufVal & maskVal) != (temp32InBufVal & maskVal))
                    {
                        dataMismatchError = 1;
                        break;
                    }
                    tempCount = tempCount + 4;
                }
                else
                {
                    System_printf("Invalid Word Length\r\n");
                }
            }
        }
        if (dataMismatchError == 0)
        {
            System_printf("Loop back test passed\r\n");
            System_printf(
                "\r\nRunning McSpi read in a loop to probe and verify the signals\r\n");
        }
        else
        {
            System_printf("Loop back test Failed\r\n");
            System_printf(
                "Error matching data in Buffer no: %d at location %d\r\n", i,
                tempCount);
            while (1) ;
        }
        /* Forever loop to continously recevie and transmit data            */
        for (loopcount = 0;; loopcount++)
        {
            status = GIO_issue(mcspiHandle, &issueDataparam[0], BUFLEN, NULL);
            if (status != IOM_PENDING && status != IOM_COMPLETED)
            {
                System_printf("\r\nFailed to issue empty buffer to stream\r\n");
            }
            status = GIO_reclaim(mcspiHandle, (Ptr *) &dataparam, NULL, NULL);
            if (IOM_COMPLETED != status)
            {
                System_printf("\r\nError In reclaim in continuous loop\r\n");
            }
            if (loopcount % 100 == 0)
            {
                System_printf(".\r\n");
            }
        }
    }
    
    void user_mcspi_init(void)
    {
      
        Mcspi_init();
    
        mcspiPrms.opMode = MCSPI_OPMODE_POLLED;
    
        mcspiPrms.instNum         = 0;
        mcspiPrms.hwiNumber       = 7;
        mcspiPrms.enableCache     = (UInt32) TRUE;
        mcspiPrms.edma3EventQueue = 0;
        mcspiPrms.enableErrIntr   = (UInt32) FALSE;
    
        mcspiPrms.spiHWCfgData.masterOrSlave         = MCSPI_COMMMODE_MASTER;
        mcspiPrms.spiHWCfgData.singleOrMultiChEnable = MCSPI_SINGLE_CHANNEL;
        mcspiPrms.spiHWCfgData.pinOpModes    = MCSPI_PINOPMODE_4PIN;
        mcspiPrms.spiHWCfgData.fifoRxTrigLvl = 32;
        mcspiPrms.spiHWCfgData.fifoTxTrigLvl = 32;
        mcspiPrms.spiHWCfgData.configChfmt[0].charLength = MCSPI_LEN_8BIT;
        mcspiPrms.spiHWCfgData.configChfmt[0].multiWordAccessEnable =
            (UInt32) FALSE;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiChipSelectEnablePol =
            (UInt32) FALSE;
        mcspiPrms.spiHWCfgData.configChfmt[0].clockMode           = MCSPI_MODE0;
        mcspiPrms.spiHWCfgData.configChfmt[0].clockRatioExtension = 0;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiWordInitDelay    = MCSPI_NO_DELAY;
        mcspiPrms.spiHWCfgData.configChfmt[0].trasmitReceiveMode  = MCSPI_BOTH_RXTX;
        mcspiPrms.spiHWCfgData.configChfmt[0].granularityEnable   = (UInt32) TRUE;
        mcspiPrms.spiHWCfgData.configChfmt[0].busFreq             = 1000000;
        mcspiPrms.spiHWCfgData.configChfmt[0].spienHighPolarity   = (UInt32) FALSE;
        mcspiPrms.spiHWCfgData.configChfmt[0].slaveModeChipSelect = MCSPI_SPIEN_0;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiDat0Dir          = MCSPI_IN;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiDat1Dir          = MCSPI_OUT;
    
        if (MCSPI_OPMODE_POLLED == mcspiPrms.opMode)
        {
            System_printf("\r\nMcspi is configured in polled mode\r\n");
        }
        else if (MCSPI_OPMODE_INTERRUPT == mcspiPrms.opMode)
        {
            System_printf("\r\nMcspi is configured in interrupt mode\r\n");
        }
        else if (MCSPI_OPMODE_DMAINTERRUPT == mcspiPrms.opMode)
        {
            System_printf("\r\nMcspi is configured in dma mode\r\n");
        }
        else
        {
            System_printf("\r\nError: unknown mode of operation!!!!!!!!!!\r\n");
        }
    }
    /*spi intialization*/
    void SPI_init(void)
    {
    System_printf("Running McSPI Loopback test.\r\n");
    GIO_addDevice("/mcspi0", (xdc_Ptr) & Mcspi_IOMFXNS, &user_mcspi_init,
                      0U, (xdc_Ptr) & mcspiPrms);
    }
    
    

  • Hi Parth,

    You should use GIO_create to first create MCSPI handle.
    Then issue empty buffers using GIO_issue.
    Then only buffers can be reclaimed.
    Can you please modify the start_spi_sample_new and try.

    Regards,
    Rishabh
  • Hi Rishabh,

    According to your suggestion, i check in the code and below is my observation,

    GIO_Create() function is already called by the creat steam function.

    then, We are calling GIO_issue,

    We also checked the return value of MCSPI Handler and it is not null.

    During debugging, i observe that in prime function, GIO_issue is getting fail with below error.

    "Failed to issue empty buffer to stream"

    I am attaching my debug logs and sample application for your reference.

    Please provide your inputs for resolving this.

    Thanks,

    Parth Modi

      

    3146.mcspiSample_io.c
    /*
     *  Copyright (C) 2012-2017 Texas Instruments Incorporated
     *
     *  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.
     *
     */
    /**
     *  \file   mcspiSample_io.c
     *
     *  \brief  McSPI evm to evm communication sample application
     *
     *          This file demonstrates the use of Mcspi by using an
     *          EVM to EVM communication setup.This file configures one of the evm
     *          in master mode.
     */
    
    /* ========================================================================== */
    /*                          INCLUDE FILES                                     */
    /* ========================================================================== */
    
    #include <stdio.h>
    #include <string.h>
    #include <xdc/std.h>
    #include <ti/sysbios/io/GIO.h>
    #include <ti/sysbios/BIOS.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <ti/sysbios/knl/Task.h>
    #include <xdc/runtime/IHeap.h>
    #include <ti/sysbios/heaps/HeapMem.h>
    #include <ti/drv/bsp_lld/mcspi/bsp_mcspi.h>
    #include <xdc/runtime/Memory.h>
    #include <ti/sdo/edma3/drv/edma3_drv.h>
    #include <xdc/std.h>
    #include <stdio.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/io/GIO.h>
    #include <ti/sysbios/io/IOM.h>
    #include <xdc/runtime/Log.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/heaps/HeapMem.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <ti/sdo/edma3/drv/edma3_drv.h>
    #include <ti/drv/vps/include/common/bsp_types.h>
    #include <ti/drv/vps/include/common/trace.h>
    #include <ti/drv/vps/include/common/bsp_config.h>
    #include <ti/drv/vps/include/common/bsp_utils.h>
    #include <ti/drv/vps/include/common/bsp_common.h>
    #include <ti/drv/bsp_lld/mcspi/bsp_mcspi.h>
    #include <ti/drv/vps/include/platforms/bsp_platform.h>
    #include <ti/drv/vps/include/boards/bsp_board.h>
    #include <ti/drv/vps/include/devices/bsp_device.h>
    #include <ti/drv/bsp_lld/i2c/bsp_i2c.h>
    #include <ti/drv/vps/include/fvid2/fvid2.h>
    #include <ti/drv/vps/examples/utility/bsputils_mem.h>
    #include <ti/drv/vps/examples/utility/bsputils_prf.h>
    #include <ti/drv/vps/examples/utility/bsputils_app.h>
    #include "mcspiSample_io.h"
    
    /* ========================================================================== */
    /*                          LOCAL FUNCTION PROTOTYPES                         */
    /* ========================================================================== */
    EDMA3_DRV_Handle edma3init(UInt32 edma3Id, EDMA3_DRV_Result *);
    Int32 App_mcspiDefaultInit(UInt32 isI2cInitReq);
    void SPI_init(void);
    /* ========================================================================== */
    /*                            MACRO DEFINITONS                                */
    /* ========================================================================== */
    
    /* ========================================================================== */
    /*                              GLOBAL VARIABLES                              */
    /* ========================================================================== */
    
    EDMA3_DRV_Handle      gEdmaHandle;
    UInt32       gIsI2cInitReq;
    extern const IOM_Fxns Mcspi_IOMFXNS;
    HeapMem_Handle myHeap;
    
    /*
     * Buffers placed in external memory are aligned on a 128 bytes boundary.
     * In addition, the buffer should be of a size multiple of 128 bytes for
     * the cache to work optimally.
     */
    
    #define BUFLEN          (1024 * 4) /* Buffer size */
    #define BUFALIGN        128        /* Alignment of buffer for use of L2 cache */
    #define ITERATION_CNT   100        /* Number of Iterations */
    #define NUM_BUFS        3          /* Num Bufs to be issued and reclaimed */
    
    /* handle to the input and output streams   */
    GIO_Handle mcspiHandle = NULL;
    
    /* Global SPI init config data structure    */
    Mcspi_Params   mcspiPrms;
    
    Mcspi_DataParam       issueDataparam[NUM_BUFS];
    
    /* Buffer alignement is required when working in DMA Mode */
    #pragma DATA_ALIGN(rxbuf, BUFALIGN);
    Ptr  rxbuf[NUM_BUFS];
    
    /* Buffer alignement is required when working in DMA Mode */
    #pragma DATA_ALIGN(txbuf, BUFALIGN);
    Ptr  txbuf[NUM_BUFS];
    
    Bool failFlag = FALSE;
    
    /* Function prototype */
    //#if 0
    static void createStream(void);
    static void prime(void);
    //#endif
    /* ========================================================================== */
    /*                           FUNCTION DEFINITIONS                             */
    /* ========================================================================== */
    
    /*
     * ======== createStream ========
     */
    //#if 0
    static void createStream(void)
    {
        GIO_Params       ioParams;
        Mcspi_ChanParams chanParams;
        Error_Block      eb;
    
        Error_init(&eb);
    
        /*
         * Initialize channel attributes.
         */
        GIO_Params_init(&ioParams);
    
        /* update the edma Handle                                                 */
        chanParams.hEdma = gEdmaHandle;
        chanParams.chipSelTimeControl = MCSPI_CLK_CYCLE0;
        chanParams.fifoEnable         = (UInt32) TRUE;
        chanParams.spiChipSelectHold  = (UInt32) TRUE;
        chanParams.chanNum = 0;
    
        /* If cross bar events are being used then make isCrossBarIntEn = TRUE and
         * choose appropriate interrupt number to be mapped (assign it to
         * intNumToBeMapped)
         */
        /* Cross bar evt disabled */
        chanParams.crossBarEvtParam.isCrossBarIntEn  = (UInt32) FALSE;
        chanParams.crossBarEvtParam.intNumToBeMapped = 0xFF;  /* Invalid number */
    
        ioParams.chanParams = (Ptr) & chanParams;
        ioParams.model      = GIO_Model_ISSUERECLAIM;
        ioParams.numPackets = NUM_BUFS + 1;
    
        mcspiHandle = GIO_create("/mcspi0", GIO_INOUT, &ioParams, &eb);
        if (mcspiHandle == NULL)
        {
            System_printf("\r\nCreate input stream FAILED.\r\n");
            BIOS_exit(0);
        }
        System_printf("\r\nCreate input stream completed.\r\n");
    }
    //#endif
    /*
     * \brief   Function to submit request the driver.Depending on the macro
     *          "NUM_BUFS" either the driver can be buffered with multiple requests
     *          or only one buffer by using the NUM_BUFS as 1.
     *
     * \param   None
     *
     * \return  None
     */
    //#if 0
    static void prime(void)
    {
    
        Error_Block  eb;
        Int32        count = 0;
        IHeap_Handle iheap;
        UInt32       tempCount = 0;
        UInt32       size      = 0;
        Int          status    = IOM_COMPLETED;
    
        iheap = HeapMem_Handle_to_xdc_runtime_IHeap(myHeap);
        Error_init(&eb);
    
        /* Allocate buffers for the GIO buffer exchanges                          */
        for (count = 0; count < (NUM_BUFS); count++)
        {
            rxbuf[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
            if (NULL == rxbuf[count])
            {
                System_printf("\r\nMEM_calloc failed.\r\n");
            }
    
            txbuf[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
            if (NULL == txbuf[count])
            {
                System_printf("\r\nMEM_calloc failed.\r\n");
            }
        }
    
        /* Fill the buffers with known data and transmit the same and check if the*
         * same pattern is received on the other EVM                              */
        for (count = 0; count < (NUM_BUFS); count++)
        {
            for (tempCount = 0; tempCount < BUFLEN; tempCount++)
            {
                ((Uint8 *) txbuf[count])[tempCount] = tempCount;
            }
        }
        for (count = 0; count < NUM_BUFS; count++)
        {
            issueDataparam[count].bufLen    = BUFLEN;
            issueDataparam[count].inBuffer  = rxbuf[count];
            issueDataparam[count].outBuffer = txbuf[count];
    
            size = issueDataparam[count].bufLen;
    
            /* Issue the first & second empty buffers to the input stream         */
            status = GIO_issue(mcspiHandle, &issueDataparam[count], size, NULL);
    
            if (status != IOM_PENDING && status != IOM_COMPLETED)
            {
                System_printf("\r\nFailed to issue empty buffer to stream\r\n");
            }
        }
        System_printf("\r\nprime completed\r\n");
    }
    //#endif
    void spiSampleTask(void)
    {
          Int32 retVal = FVID2_SOK;
          Bsp_PlatformInitParams platInitPrms;
    
        /* isPinMuxSettingReq parameter will be initialised to TRUE */
        BspPlatformInitParams_init(&platInitPrms);
    //
        platInitPrms.isAllMcSPIInitReq  = TRUE;
        platInitPrms.isPinMuxSettingReq = TRUE;
    
        /* Initialize pinmux and evm related configurations */
        Bsp_platformInit(&platInitPrms);
        /* System init */
    //    gIsI2cInitReq = TRUE;
    //    retVal       = App_mcspiDefaultInit(gIsI2cInitReq);
        if (retVal != FVID2_SOK)
        {
            System_printf("Error: : System Init Failed!!!\r\n");
        }
        /* Set the pin Mux */
        Bsp_boardSetPinMux(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_0,
                           BSP_BOARD_MODE_DEFAULT);
    //    Bsp_boardSetPinMux(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_1,
    //                       BSP_BOARD_MODE_DEFAULT);
    
        /* Set the board muxes */
        Bsp_boardSelectDevice(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_0);
    //    Bsp_boardSelectDevice(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_1);
        /* call the function for the SPI application test                     */
    
    //    start_spi_sample();
    //
    //    App_mcspiDefaultDeInit(gIsI2cInitReq);
    //
    //    /* Start the Heart Beat Print                                         */
    //    tskHeartBeat();
    //
    //    return;
    }
    
    /*
     * \brief   This function demostrates the use of Mcspi using an EVM to EVM
     *          communication setup.
     *
     * \param   None
     *
     * \return  None
     */
    void start_spi_sample_new(Void)
    {
        System_printf("\r\nIn start SPI sample new\r\n");
        volatile Int32   i32Count  = 0;
        Mcspi_DataParam *dataparam = {0};
        UInt32           tempCount = 0;
        UInt32           i, loopcount = 0;
        UInt32           dataMismatchError = 0;
        UInt8            temp8InBufVal = 0, temp8OutBufVal = 0;
        UInt16           temp16InBufVal = 0, temp16OutBufVal = 0;
        UInt32           temp32InBufVal = 0, temp32OutBufVal = 0;
        UInt32           maskVal        = 0;
    
        Int status = IOM_COMPLETED;
    //    Sleep(1000);
        spiSampleTask();
    //    createStream();
        SPI_init();
    
        EDMA3_DRV_Result edmaResult = 0;
    
        gEdmaHandle = edma3init(0, &edmaResult);
    
        if (edmaResult != EDMA3_DRV_SOK)
        {
            /* Report EDMA Error */
            System_printf("\r\nEDMA driver initialization FAIL\r\n");
        }
        else
        {
            System_printf("\r\nEDMA driver initialization PASS.\r\n");
        }
    
        /* Call createStream function to create I/O streams                       */
        createStream();
    
        /* Call prime function to do priming                                      */
        prime();
    
        for (i = 0; i < NUM_BUFS; i++)
        {
            dataparam = NULL;
            /* Reclaim full buffer from the stream                                */
            System_printf("before the reclaim \r\n");
            status = GIO_issue(mcspiHandle, &issueDataparam[0], BUFLEN, NULL);
            System_printf("status =%u\r\n",status);
            status = GIO_reclaim(mcspiHandle, (Ptr *) &dataparam, NULL, NULL);
            System_printf("In for loop\r\n");
            if (IOM_COMPLETED != status)
            {
                System_printf("Iteration %d\r\n", i32Count);
    
                System_printf(
                    "Error reclaiming empty buffer from the streams %x"
                    " error = 0x%d\r\n",
                    ((Uint8) (dataparam->outBuffer[i32Count])),
                    status);
                break;
            }
    
            maskVal =
                ((1 << (mcspiPrms.spiHWCfgData.configChfmt[0].charLength)) - 1);
    
            for (tempCount = 0; tempCount < BUFLEN; )
            {
                if (mcspiPrms.spiHWCfgData.configChfmt[0].charLength <= 8)
                {
                    temp8InBufVal  = dataparam->inBuffer[tempCount];
                    temp8OutBufVal = dataparam->outBuffer[tempCount];
    
                    /* temp8OutBufVal & temp8InBufVal is to be aligned with
                     * charLength.
                     * temp8InBufVal alignment is required only in case of DMA Mode
                     */
                    if ((temp8OutBufVal & maskVal) != (temp8InBufVal & maskVal))
                    {
                        dataMismatchError = 1;
                        break;
                    }
                    tempCount++;
                }
                else if (mcspiPrms.spiHWCfgData.configChfmt[0].charLength <= 16)
                {
                    temp16InBufVal = dataparam->inBuffer[tempCount] +
                                     (dataparam->inBuffer[tempCount + 1] << 8);
                    temp16OutBufVal = dataparam->outBuffer[tempCount] +
                                      (dataparam->outBuffer[tempCount + 1] << 8);
    
                    /* temp16OutBufVal & temp16InBufVal is to be aligned with
                     * charLength.
                     * temp16InBufVal alignment is required only in case of DMA Mode
                     */
                    if ((temp16OutBufVal & maskVal) != (temp16InBufVal & maskVal))
                    {
                        dataMismatchError = 1;
                        break;
                    }
                    tempCount = tempCount + 2;
                }
                else if (mcspiPrms.spiHWCfgData.configChfmt[0].charLength <= 32)
                {
                    temp32InBufVal = dataparam->inBuffer[tempCount] +
                                     (dataparam->inBuffer[tempCount + 1] << 8) +
                                     (dataparam->inBuffer[tempCount + 2] << 16) +
                                     (dataparam->inBuffer[tempCount + 3] << 24);
                    temp32OutBufVal = dataparam->inBuffer[tempCount] +
                                      (dataparam->inBuffer[tempCount + 1] << 8) +
                                      (dataparam->inBuffer[tempCount + 2] << 16) +
                                      (dataparam->inBuffer[tempCount + 3] << 24);
    
                    /* temp32OutBufVal & temp32InBufVal is to be aligned with
                     * charLength
                     * temp32InBufVal alignment is required only in case of DMA Mode
                     */
                    if ((temp32OutBufVal & maskVal) != (temp32InBufVal & maskVal))
                    {
                        dataMismatchError = 1;
                        break;
                    }
                    tempCount = tempCount + 4;
                }
                else
                {
                    System_printf("Invalid Word Length\r\n");
                }
            }
        }
        if (dataMismatchError == 0)
        {
            System_printf("Loop back test passed\r\n");
            System_printf(
                "\r\nRunning McSpi read in a loop to probe and verify the signals\r\n");
        }
        else
        {
            System_printf("Loop back test Failed\r\n");
            System_printf(
                "Error matching data in Buffer no: %d at location %d\r\n", i,
                tempCount);
            while (1) ;
        }
        /* Forever loop to continously recevie and transmit data            */
        for (loopcount = 0;; loopcount++)
        {
            status = GIO_issue(mcspiHandle, &issueDataparam[0], BUFLEN, NULL);
            if (status != IOM_PENDING && status != IOM_COMPLETED)
            {
                System_printf("\r\nFailed to issue empty buffer to stream\r\n");
            }
            status = GIO_reclaim(mcspiHandle, (Ptr *) &dataparam, NULL, NULL);
            if (IOM_COMPLETED != status)
            {
                System_printf("\r\nError In reclaim in continuous loop\r\n");
            }
            if (loopcount % 100 == 0)
            {
                System_printf(".\r\n");
            }
        }
    }
    
    void user_mcspi_init(void)
    {
      //  Int32 opMode;
        Mcspi_init();
    
    //    mcspiPrms = Mcspi_PARAMS;
    //    System_printf("Please Connect the McSPI%d MISO (DAT0) to MOSI (DAT1)\r\n",
    //                  (inst_num + 1U));
    //    System_printf(
    //        "And then enter the Operating mode\r\n0 - Polled Mode\
    //            \r\n1 - Interrupt Mode\
    //            \r\n2 - DMA Interrupt mode\r\n$>");
    ////    scanf("%d", &opMode);
    //    if (opMode == 0)
    //    {
            mcspiPrms.opMode = MCSPI_OPMODE_POLLED;
    //    }
    //    else if (opMode == 1)
    //    {
    //        mcspiPrms.opMode = MCSPI_OPMODE_INTERRUPT;
    //    }
    //    else if (opMode == 2)
    //    {
    //        mcspiPrms.opMode = MCSPI_OPMODE_DMAINTERRUPT;
    //    }
    //    else
    //    {
    //        mcspiPrms.opMode = MCSPI_OPMODE_POLLED;
    //    }
    
        mcspiPrms.instNum         = 0;
        mcspiPrms.hwiNumber       = 7;
        mcspiPrms.enableCache     = (UInt32) TRUE;
        mcspiPrms.edma3EventQueue = 0;
        mcspiPrms.enableErrIntr   = (UInt32) FALSE;
    
        mcspiPrms.spiHWCfgData.masterOrSlave         = MCSPI_COMMMODE_MASTER;
        mcspiPrms.spiHWCfgData.singleOrMultiChEnable = MCSPI_SINGLE_CHANNEL;
        mcspiPrms.spiHWCfgData.pinOpModes    = MCSPI_PINOPMODE_4PIN;
        mcspiPrms.spiHWCfgData.fifoRxTrigLvl = 32;
        mcspiPrms.spiHWCfgData.fifoTxTrigLvl = 32;
        mcspiPrms.spiHWCfgData.configChfmt[0].charLength = MCSPI_LEN_8BIT;
        mcspiPrms.spiHWCfgData.configChfmt[0].multiWordAccessEnable =
            (UInt32) FALSE;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiChipSelectEnablePol =
            (UInt32) FALSE;
        mcspiPrms.spiHWCfgData.configChfmt[0].clockMode           = MCSPI_MODE0;
        mcspiPrms.spiHWCfgData.configChfmt[0].clockRatioExtension = 0;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiWordInitDelay    = MCSPI_NO_DELAY;
        mcspiPrms.spiHWCfgData.configChfmt[0].trasmitReceiveMode  = MCSPI_BOTH_RXTX;
        mcspiPrms.spiHWCfgData.configChfmt[0].granularityEnable   = (UInt32) TRUE;
        mcspiPrms.spiHWCfgData.configChfmt[0].busFreq             = 1000000;
        mcspiPrms.spiHWCfgData.configChfmt[0].spienHighPolarity   = (UInt32) FALSE;
        mcspiPrms.spiHWCfgData.configChfmt[0].slaveModeChipSelect = MCSPI_SPIEN_0;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiDat0Dir          = MCSPI_IN;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiDat1Dir          = MCSPI_OUT;
    
        if (MCSPI_OPMODE_POLLED == mcspiPrms.opMode)
        {
            System_printf("\r\nMcspi is configured in polled mode\r\n");
        }
        else if (MCSPI_OPMODE_INTERRUPT == mcspiPrms.opMode)
        {
            System_printf("\r\nMcspi is configured in interrupt mode\r\n");
        }
        else if (MCSPI_OPMODE_DMAINTERRUPT == mcspiPrms.opMode)
        {
            System_printf("\r\nMcspi is configured in dma mode\r\n");
        }
        else
        {
            System_printf("\r\nError: unknown mode of operation!!!!!!!!!!\r\n");
        }
    }
    void SPI_init(void)
    {
    System_printf("Running McSPI Loopback test.\r\n");
    //    System_printf(
    //        "Enter McSPI instance on which test to be run\
    //        \r\n0 - McSPI1 instance\r\n1 - McSPI2 instance\r\n$>");
    //    scanf("%d", &inst_num);
    //    if (inst_num != 0 && inst_num != 1)
    //    {
    //        inst_num = 0;
    //    }
        GIO_addDevice("/mcspi0", (xdc_Ptr) & Mcspi_IOMFXNS, &user_mcspi_init,
                      0U, (xdc_Ptr) & mcspiPrms);
    }
    #if 0
    Int32 App_mcspiDefaultInit(UInt32 isI2cInitReq)
    {
        Int32  retVal = BSP_SOK;
        UInt32 instCnt;
        Bsp_CommonInitParams    commonInitPrms;
        Bsp_BoardInitParams     boardInitPrms;
        Bsp_PlatformInitParams  platInitPrms;
        Bsp_DeviceInitParams    deviceInitPrms;
        lld_hsi2c_initParam_t   i2cInitParams[BSP_DEVICE_I2C_INST_ID_MAX];
        const Bsp_BoardI2cData *i2cData;
        Bsp_BoardI2cInstData   *i2cInstData;
        BspCommonInitParams_init(&commonInitPrms);
        retVal += Bsp_commonInit(&commonInitPrms);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: BSP Common Init failed!!\r\n");
        }
    
        BspBoardInitParams_init(&boardInitPrms);
        /* Override board detection if I2C is disabled */
        if (((Bool) TRUE) != ((Bool) isI2cInitReq))
        {
            boardInitPrms.boardId      = BSP_BOARD_UNKNOWN;
            boardInitPrms.baseBoardRev = BSP_BOARD_REV_UNKNOWN;
            boardInitPrms.dcBoardRev   = BSP_BOARD_REV_UNKNOWN;
        }
        retVal += Bsp_boardInit(&boardInitPrms);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: Board Init failed!!\r\n");
        }
    
        BspPlatformInitParams_init(&platInitPrms);
        retVal += Bsp_platformInit(&platInitPrms);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: Platform Init failed!!\r\n");
        }
    
        retVal += Fvid2_init(NULL);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: FVID2 Init failed!!\r\n");
        }
    
        /* Override I2C init for non-EVM builds */
        if (BSP_PLATFORM_ID_EVM != Bsp_platformGetId())
        {
            isI2cInitReq = FALSE;
        }
    
        if (((Bool) TRUE) == ((Bool) isI2cInitReq))
        {
            i2cData = Bsp_boardGetI2cData();
            GT_assert(BspAppTrace, (NULL != i2cData));
            GT_assert(BspAppTrace,
                      (i2cData->numInst <= BSP_DEVICE_I2C_INST_ID_MAX));
            GT_assert(BspAppTrace, (NULL != i2cData->instData));
    
            for (instCnt = 0U; instCnt < i2cData->numInst; instCnt++)
            {
                i2cInstData = &i2cData->instData[instCnt];
                GT_assert(BspAppTrace,
                          (i2cInstData->instId < BSP_DEVICE_I2C_INST_ID_MAX));
                i2cInitParams[instCnt].opMode       = HSI2C_OPMODE_INTERRUPT;
                i2cInitParams[instCnt].isMasterMode = TRUE;
                i2cInitParams[instCnt].is10BitAddr  = FALSE;
                i2cInitParams[instCnt].i2cBusFreq   =
                    (lld_i2c_busspeed) i2cInstData->busClkKHz;
                i2cInitParams[instCnt].i2cIntNum      = i2cInstData->intNum;
                i2cInitParams[instCnt].i2cOwnAddr     = 0xCC;
                gI2cDevInitParams[instCnt].initParams = &i2cInitParams[instCnt];
                gI2cDevInitParams[instCnt].hsi2c_sem  =
                    BspOsal_semCreate((Int32) 1, (Bool) TRUE);
                gI2cDevInitParams[instCnt].instId = i2cInstData->instId;
            }
    
            if (i2cData->numInst > 0)
            {
                retVal = I2c_GlobalInit(i2cData->numInst, &gI2cDevInitParams[0U]);
                if (BSP_SOK != retVal)
                {
                    GT_0trace(BspAppTrace, GT_ERR, "Error: I2C Init failed!!\r\n");
                }
            }
    
            BspDeviceInitParams_init(&deviceInitPrms);
            deviceInitPrms.isI2cProbingReq = FALSE;
            retVal += Bsp_deviceInit(&deviceInitPrms);
            if (BSP_SOK != retVal)
            {
                GT_0trace(BspAppTrace, GT_ERR, "Error: Device Init failed!!\r\n");
            }
        }
    
        retVal += BspUtils_memInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: App MEM Utils Init failed!!\r\n");
        }
    
        retVal += BspUtils_prfInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: App PRF Utils Init failed!!\r\n");
        }
    
        retVal += BspUtils_appInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: App Utils Init failed!!\r\n");
        }
    
        /* Print BSP version string and platform info*/
        GT_0trace(BspAppTrace, GT_INFO, " \r\n");
        GT_2trace(BspAppTrace, GT_INFO,
                  " Build time            : [%s %s]\r\n", __TIME__, __DATE__);
        GT_1trace(BspAppTrace, GT_INFO,
                  " BSP Version           : [%s]\r\n", Bsp_getVersionString());
        Bsp_platformPrintInfo();
        Bsp_boardPrintInfo();
        GT_0trace(BspAppTrace, GT_INFO, " \r\n");
    
        return (retVal);
    }
    #endif
    

  • Hi Parth,

    I have asked MCSPI expert to help you further.

    Regards,

    Rishabh

  • Hi Rishabh,

    Thanks for the quick response.

    I am seriously struggling with this issues.
    I very appreciate if you can help us ASAP.

    Let us know if you need any information from our side.

    Thanks,

    Parth Modi
  • Hi Parth,

    You should not do the edma3_init when calling from the vision sdk code, use the sdk utility function to get the edma handle and use it.

    Can you check the return value of the GIO_Issue function and let me know for further analysis?

    Regards,
    Prasad
  • Hi Prasad,

    We have used utility fuction as per your suggession,but Utils_dmaInit() is failing with error "UTILS: DMA: Utils_dmaInit() for instance 0 ... FAILED (-128)".

    We find out  the reson for the failure and it is happening due to we have commented out below two function.

    /*retVal += BspUtils_memInit();

       if (BSP_SOK != retVal)

       {

           GT_0trace(BspAppTrace, GT_ERR, "Error: App MEM Utils Init failed!!\r\n");

       }

       retVal += BspUtils_prfInit();

       if (BSP_SOK != retVal)

       {

           GT_0trace(BspAppTrace, GT_ERR, "Error: App PRF Utils Init failed!!\r\n");

       }*/

    If we tried to uncommented this fuction then during code compilation we are getting below error

     program will not fit into available memory.  run placement with alignment

      fails for section "GROUP_1" size 0xf816696 .  Available memory ranges:

      IPU1_0_DATA_MEM   size: 0xb00000     unused: 0x70ceaa     max hole: 0x70cea8

    So, please suggest us the possible solution to resolve this compilation error.

    We have attached the source code and debug log and comiplation error snapshot for your referance.

    Thanks,

    Parth Modi

    4885.mcspiSample_io.c
    /*
     *  Copyright (C) 2012-2017 Texas Instruments Incorporated
     *
     *  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.
     *
     */
    /**
     *  \file   mcspiSample_io.c
     *
     *  \brief  McSPI evm to evm communication sample application
     *
     *          This file demonstrates the use of Mcspi by using an
     *          EVM to EVM communication setup.This file configures one of the evm
     *          in master mode.
     */
    
    /* ========================================================================== */
    /*                          INCLUDE FILES                                     */
    /* ========================================================================== */
    
    #include <stdio.h>
    #include <string.h>
    #include <xdc/std.h>
    #include <ti/sysbios/io/GIO.h>
    #include <ti/sysbios/BIOS.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <ti/sysbios/knl/Task.h>
    #include <xdc/runtime/IHeap.h>
    #include <ti/sysbios/heaps/HeapMem.h>
    #include <ti/drv/bsp_lld/mcspi/bsp_mcspi.h>
    #include <xdc/runtime/Memory.h>
    #include <ti/sdo/edma3/drv/edma3_drv.h>
    #include <xdc/std.h>
    #include <stdio.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/io/GIO.h>
    #include <ti/sysbios/io/IOM.h>
    #include <xdc/runtime/Log.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/heaps/HeapMem.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <ti/sdo/edma3/drv/edma3_drv.h>
    #include <ti/drv/vps/include/common/bsp_types.h>
    #include <ti/drv/vps/include/common/trace.h>
    #include <ti/drv/vps/include/common/bsp_config.h>
    #include <ti/drv/vps/include/common/bsp_utils.h>
    #include <ti/drv/vps/include/common/bsp_common.h>
    #include <ti/drv/bsp_lld/mcspi/bsp_mcspi.h>
    #include <ti/drv/vps/include/platforms/bsp_platform.h>
    #include <ti/drv/vps/include/boards/bsp_board.h>
    #include <ti/drv/vps/include/devices/bsp_device.h>
    #include <ti/drv/bsp_lld/i2c/bsp_i2c.h>
    #include <ti/drv/vps/include/fvid2/fvid2.h>
    #include <ti/drv/vps/examples/utility/bsputils_mem.h>
    #include <ti/drv/vps/examples/utility/bsputils_prf.h>
    #include <ti/drv/vps/examples/utility/bsputils_app.h>
    #include <src/rtos/utils_common/include/utils_dma.h>
    #include "mcspiSample_io.h"
    
    /* ========================================================================== */
    /*                          LOCAL FUNCTION PROTOTYPES                         */
    /* ========================================================================== */
    EDMA3_DRV_Handle edma3init(UInt32 edma3Id, EDMA3_DRV_Result *);
    Int32 App_mcspiDefaultInit(UInt32 isI2cInitReq);
    void SPI_init(void);
    /* ========================================================================== */
    /*                            MACRO DEFINITONS                                */
    /* ========================================================================== */
    
    /* ========================================================================== */
    /*                              GLOBAL VARIABLES                              */
    /* ========================================================================== */
    
    EDMA3_DRV_Handle      gEdmaHandle;
    UInt32       gIsI2cInitReq;
    extern const IOM_Fxns Mcspi_IOMFXNS;
    HeapMem_Handle myHeap;
    //static I2c_DevInitParams gI2cDevInitParams[BSP_DEVICE_I2C_INST_ID_MAX];
    
    /*
     * Buffers placed in external memory are aligned on a 128 bytes boundary.
     * In addition, the buffer should be of a size multiple of 128 bytes for
     * the cache to work optimally.
     */
    
    #define BUFLEN          (1024 * 4) /* Buffer size */
    #define BUFALIGN        128        /* Alignment of buffer for use of L2 cache */
    #define ITERATION_CNT   100        /* Number of Iterations */
    #define NUM_BUFS        3          /* Num Bufs to be issued and reclaimed */
    
    /* handle to the input and output streams   */
    GIO_Handle mcspiHandle = NULL;
    
    /* Global SPI init config data structure    */
    Mcspi_Params   mcspiPrms;
    
    Mcspi_DataParam       issueDataparam[NUM_BUFS];
    
    /* Buffer alignement is required when working in DMA Mode */
    #pragma DATA_ALIGN(rxbuf, BUFALIGN);
    Ptr  rxbuf[NUM_BUFS];
    
    /* Buffer alignement is required when working in DMA Mode */
    #pragma DATA_ALIGN(txbuf, BUFALIGN);
    Ptr  txbuf[NUM_BUFS];
    
    Bool failFlag = FALSE;
    
    /* Function prototype */
    //#if 0
    static void createStream(void);
    static void prime(void);
    //#endif
    /* ========================================================================== */
    /*                           FUNCTION DEFINITIONS                             */
    /* ========================================================================== */
    
    /*
     * ======== createStream ========
     */
    //#if 0
    static void createStream(void)
    {
        GIO_Params       ioParams;
        Mcspi_ChanParams chanParams;
        Error_Block      eb;
    
        Error_init(&eb);
    
        /*
         * Initialize channel attributes.
         */
        GIO_Params_init(&ioParams);
    
        /* update the edma Handle                                                 */
        chanParams.hEdma = gEdmaHandle;
        chanParams.chipSelTimeControl = MCSPI_CLK_CYCLE0;
        chanParams.fifoEnable         = (UInt32) TRUE;
        chanParams.spiChipSelectHold  = (UInt32) TRUE;
        chanParams.chanNum = 0;
    
        /* If cross bar events are being used then make isCrossBarIntEn = TRUE and
         * choose appropriate interrupt number to be mapped (assign it to
         * intNumToBeMapped)
         */
        /* Cross bar evt disabled */
        chanParams.crossBarEvtParam.isCrossBarIntEn  = (UInt32) FALSE;
        chanParams.crossBarEvtParam.intNumToBeMapped = 0xFF;  /* Invalid number */
    
        ioParams.chanParams = (Ptr) & chanParams;
        ioParams.model      = GIO_Model_ISSUERECLAIM;
        ioParams.numPackets = NUM_BUFS + 1;
    
        mcspiHandle = GIO_create("/mcspi0", GIO_INOUT, &ioParams, &eb);
        if (mcspiHandle == NULL)
        {
            System_printf("\r\nCreate input stream FAILED.\r\n");
            BIOS_exit(0);
        }
        System_printf("\r\nCreate input stream completed.\r\n");
    }
    //#endif
    /*
     * \brief   Function to submit request the driver.Depending on the macro
     *          "NUM_BUFS" either the driver can be buffered with multiple requests
     *          or only one buffer by using the NUM_BUFS as 1.
     *
     * \param   None
     *
     * \return  None
     */
    //#if 0
    static void prime(void)
    {
    
        Error_Block  eb;
        Int32        count = 0;
        IHeap_Handle iheap;
        UInt32       tempCount = 0;
        UInt32       size      = 0;
        Int          status    = IOM_COMPLETED;
    
        iheap = HeapMem_Handle_to_xdc_runtime_IHeap(myHeap);
        Error_init(&eb);
    
        /* Allocate buffers for the GIO buffer exchanges                          */
        for (count = 0; count < (NUM_BUFS); count++)
        {
            rxbuf[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
            if (NULL == rxbuf[count])
            {
                System_printf("\r\nMEM_calloc failed.\r\n");
            }
    
            txbuf[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
            if (NULL == txbuf[count])
            {
                System_printf("\r\nMEM_calloc failed.\r\n");
            }
        }
    
        /* Fill the buffers with known data and transmit the same and check if the*
         * same pattern is received on the other EVM                              */
        for (count = 0; count < (NUM_BUFS); count++)
        {
            for (tempCount = 0; tempCount < BUFLEN; tempCount++)
            {
                ((Uint8 *) txbuf[count])[tempCount] = tempCount;
            }
        }
        for (count = 0; count < NUM_BUFS; count++)
        {
            issueDataparam[count].bufLen    = BUFLEN;
            issueDataparam[count].inBuffer  = rxbuf[count];
            issueDataparam[count].outBuffer = txbuf[count];
    
            size = issueDataparam[count].bufLen;
    
            /* Issue the first & second empty buffers to the input stream         */
            status = GIO_issue(mcspiHandle, &issueDataparam[count], size, NULL);
    
            if (status != IOM_PENDING && status != IOM_COMPLETED)
            {
                System_printf("\r\nsatus =%d\r\n",status);
                System_printf("\r\nFailed to issue empty buffer to stream\r\n");
            }
        }
        System_printf("\r\nprime completed\r\n");
    }
    //#endif
    void spiSampleTask(void)
    {
          Int32 retVal = FVID2_SOK;
          Bsp_PlatformInitParams platInitPrms;
    
        /* isPinMuxSettingReq parameter will be initialised to TRUE */
        BspPlatformInitParams_init(&platInitPrms);
    //
        platInitPrms.isAllMcSPIInitReq  = TRUE;
        platInitPrms.isPinMuxSettingReq = TRUE;
    
        /* Initialize pinmux and evm related configurations */
        Bsp_platformInit(&platInitPrms);
        /* System init */
        gIsI2cInitReq = FALSE;
        retVal       = App_mcspiDefaultInit(gIsI2cInitReq);
        if (retVal != FVID2_SOK)
        {
            System_printf("Error: : System Init Failed!!!\r\n");
        }
        /* Set the pin Mux */
        Bsp_boardSetPinMux(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_0,
                           BSP_BOARD_MODE_DEFAULT);
    //    Bsp_boardSetPinMux(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_1,
    //                       BSP_BOARD_MODE_DEFAULT);
    
        /* Set the board muxes */
        Bsp_boardSelectDevice(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_0);
    //    Bsp_boardSelectDevice(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_1);
        /* call the function for the SPI application test                     */
    
    //    start_spi_sample();
    //
    //    App_mcspiDefaultDeInit(gIsI2cInitReq);
    //
    //    /* Start the Heart Beat Print                                         */
    //    tskHeartBeat();
    //
    //    return;
    }
    
    /*
     * \brief   This function demostrates the use of Mcspi using an EVM to EVM
     *          communication setup.
     *
     * \param   None
     *
     * \return  None
     */
    void start_spi_sample_new(Void)
    {
        System_printf("\r\nIn start SPI sample new\r\n");
        volatile Int32   i32Count  = 0;
    
        Mcspi_DataParam *dataparam = {0};
        UInt32           tempCount = 0;
        UInt32           i, loopcount = 0;
        UInt32           dataMismatchError = 0;
        UInt8            temp8InBufVal = 0, temp8OutBufVal = 0;
        UInt16           temp16InBufVal = 0, temp16OutBufVal = 0;
        UInt32           temp32InBufVal = 0, temp32OutBufVal = 0;
        UInt32           maskVal        = 0;
    
        Int status = IOM_COMPLETED;
    //    Sleep(1000);
        spiSampleTask();
    //    createStream();
        SPI_init();
    
    //    EDMA3_DRV_Result edmaResult = 0;
        Utils_dmaInit();
        gEdmaHandle = Utils_dmaGetEdma3Hndl(0);
    //    gEdmaHandle = edma3init(0, &edmaResult);
    
        if (gEdmaHandle != NULL)
        {
            /* Report EDMA Error */
            System_printf("\r\nEDMA driver initialization FAIL\r\n");
        }
        else
        {
            System_printf("\r\nEDMA driver initialization PASS.\r\n");
        }
    
        /* Call createStream function to create I/O streams                       */
        createStream();
    
        /* Call prime function to do priming                                      */
        prime();
    //#if 0
        for (i = 0; i < NUM_BUFS; i++)
        {
            dataparam = NULL;
            /* Reclaim full buffer from the stream                                */
            System_printf("before the reclaim \r\n");
            status = GIO_issue(mcspiHandle, &issueDataparam[0], BUFLEN, NULL);
            System_printf("status of GIO_issue =%d\r\n",status);
            status = GIO_reclaim(mcspiHandle, (Ptr *) &dataparam, NULL, NULL);
            System_printf("In for loop\r\n");
            if (IOM_COMPLETED != status)
            {
                System_printf("Iteration %d\r\n", i32Count);
    
                System_printf(
                    "Error reclaiming empty buffer from the streams %x"
                    " error = 0x%d\r\n",
                    ((Uint8) (dataparam->outBuffer[i32Count])),
                    status);
                break;
            }
    
            maskVal =
                ((1 << (mcspiPrms.spiHWCfgData.configChfmt[0].charLength)) - 1);
    
            for (tempCount = 0; tempCount < BUFLEN; )
            {
                if (mcspiPrms.spiHWCfgData.configChfmt[0].charLength <= 8)
                {
                    temp8InBufVal  = dataparam->inBuffer[tempCount];
                    temp8OutBufVal = dataparam->outBuffer[tempCount];
    
                    /* temp8OutBufVal & temp8InBufVal is to be aligned with
                     * charLength.
                     * temp8InBufVal alignment is required only in case of DMA Mode
                     */
                    if ((temp8OutBufVal & maskVal) != (temp8InBufVal & maskVal))
                    {
                        dataMismatchError = 1;
                        break;
                    }
                    tempCount++;
                }
                else if (mcspiPrms.spiHWCfgData.configChfmt[0].charLength <= 16)
                {
                    temp16InBufVal = dataparam->inBuffer[tempCount] +
                                     (dataparam->inBuffer[tempCount + 1] << 8);
                    temp16OutBufVal = dataparam->outBuffer[tempCount] +
                                      (dataparam->outBuffer[tempCount + 1] << 8);
    
                    /* temp16OutBufVal & temp16InBufVal is to be aligned with
                     * charLength.
                     * temp16InBufVal alignment is required only in case of DMA Mode
                     */
                    if ((temp16OutBufVal & maskVal) != (temp16InBufVal & maskVal))
                    {
                        dataMismatchError = 1;
                        break;
                    }
                    tempCount = tempCount + 2;
                }
                else if (mcspiPrms.spiHWCfgData.configChfmt[0].charLength <= 32)
                {
                    temp32InBufVal = dataparam->inBuffer[tempCount] +
                                     (dataparam->inBuffer[tempCount + 1] << 8) +
                                     (dataparam->inBuffer[tempCount + 2] << 16) +
                                     (dataparam->inBuffer[tempCount + 3] << 24);
                    temp32OutBufVal = dataparam->inBuffer[tempCount] +
                                      (dataparam->inBuffer[tempCount + 1] << 8) +
                                      (dataparam->inBuffer[tempCount + 2] << 16) +
                                      (dataparam->inBuffer[tempCount + 3] << 24);
    
                    /* temp32OutBufVal & temp32InBufVal is to be aligned with
                     * charLength
                     * temp32InBufVal alignment is required only in case of DMA Mode
                     */
                    if ((temp32OutBufVal & maskVal) != (temp32InBufVal & maskVal))
                    {
                        dataMismatchError = 1;
                        break;
                    }
                    tempCount = tempCount + 4;
                }
                else
                {
                    System_printf("Invalid Word Length\r\n");
                }
            }
        }
        if (dataMismatchError == 0)
        {
            System_printf("Loop back test passed\r\n");
            System_printf(
                "\r\nRunning McSpi read in a loop to probe and verify the signals\r\n");
        }
        else
        {
            System_printf("Loop back test Failed\r\n");
            System_printf(
                "Error matching data in Buffer no: %d at location %d\r\n", i,
                tempCount);
            while (1) ;
        }
        /* Forever loop to continously recevie and transmit data            */
        for (loopcount = 0;; loopcount++)
        {
            status = GIO_issue(mcspiHandle, &issueDataparam[0], BUFLEN, NULL);
            if (status != IOM_PENDING && status != IOM_COMPLETED)
            {
                System_printf("\r\nFailed to issue empty buffer to stream\r\n");
            }
            status = GIO_reclaim(mcspiHandle, (Ptr *) &dataparam, NULL, NULL);
            if (IOM_COMPLETED != status)
            {
                System_printf("\r\nError In reclaim in continuous loop\r\n");
            }
            if (loopcount % 100 == 0)
            {
                System_printf(".\r\n");
            }
        }
    //#endif
    }
    
    void user_mcspi_init(void)
    {
      //  Int32 opMode;
        Mcspi_init();
    
    //    mcspiPrms = Mcspi_PARAMS;
    //    System_printf("Please Connect the McSPI%d MISO (DAT0) to MOSI (DAT1)\r\n",
    //                  (inst_num + 1U));
    //    System_printf(
    //        "And then enter the Operating mode\r\n0 - Polled Mode\
    //            \r\n1 - Interrupt Mode\
    //            \r\n2 - DMA Interrupt mode\r\n$>");
    ////    scanf("%d", &opMode);
    //    if (opMode == 0)
    //    {
            mcspiPrms.opMode = MCSPI_OPMODE_POLLED;
    //    }
    //    else if (opMode == 1)
    //    {
    //        mcspiPrms.opMode = MCSPI_OPMODE_INTERRUPT;
    //    }
    //    else if (opMode == 2)
    //    {
    //        mcspiPrms.opMode = MCSPI_OPMODE_DMAINTERRUPT;
    //    }
    //    else
    //    {
    //        mcspiPrms.opMode = MCSPI_OPMODE_POLLED;
    //    }
    
        mcspiPrms.instNum         = 0;
        mcspiPrms.hwiNumber       = 7;
        mcspiPrms.enableCache     = (UInt32) TRUE;
        mcspiPrms.edma3EventQueue = 0;
        mcspiPrms.enableErrIntr   = (UInt32) FALSE;
    
        mcspiPrms.spiHWCfgData.masterOrSlave         = MCSPI_COMMMODE_MASTER;
        mcspiPrms.spiHWCfgData.singleOrMultiChEnable = MCSPI_SINGLE_CHANNEL;
        mcspiPrms.spiHWCfgData.pinOpModes    = MCSPI_PINOPMODE_4PIN;
        mcspiPrms.spiHWCfgData.fifoRxTrigLvl = 32;
        mcspiPrms.spiHWCfgData.fifoTxTrigLvl = 32;
        mcspiPrms.spiHWCfgData.configChfmt[0].charLength = MCSPI_LEN_8BIT;
        mcspiPrms.spiHWCfgData.configChfmt[0].multiWordAccessEnable =
            (UInt32) FALSE;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiChipSelectEnablePol =
            (UInt32) FALSE;
        mcspiPrms.spiHWCfgData.configChfmt[0].clockMode           = MCSPI_MODE0;
        mcspiPrms.spiHWCfgData.configChfmt[0].clockRatioExtension = 0;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiWordInitDelay    = MCSPI_NO_DELAY;
        mcspiPrms.spiHWCfgData.configChfmt[0].trasmitReceiveMode  = MCSPI_BOTH_RXTX;
        mcspiPrms.spiHWCfgData.configChfmt[0].granularityEnable   = (UInt32) TRUE;
        mcspiPrms.spiHWCfgData.configChfmt[0].busFreq             = 1000000;
        mcspiPrms.spiHWCfgData.configChfmt[0].spienHighPolarity   = (UInt32) FALSE;
        mcspiPrms.spiHWCfgData.configChfmt[0].slaveModeChipSelect = MCSPI_SPIEN_0;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiDat0Dir          = MCSPI_IN;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiDat1Dir          = MCSPI_OUT;
    
        if (MCSPI_OPMODE_POLLED == mcspiPrms.opMode)
        {
            System_printf("\r\nMcspi is configured in polled mode\r\n");
        }
        else if (MCSPI_OPMODE_INTERRUPT == mcspiPrms.opMode)
        {
            System_printf("\r\nMcspi is configured in interrupt mode\r\n");
        }
        else if (MCSPI_OPMODE_DMAINTERRUPT == mcspiPrms.opMode)
        {
            System_printf("\r\nMcspi is configured in dma mode\r\n");
        }
        else
        {
            System_printf("\r\nError: unknown mode of operation!!!!!!!!!!\r\n");
        }
    }
    void SPI_init(void)
    {
    System_printf("Running McSPI Loopback test.\r\n");
    //    System_printf(
    //        "Enter McSPI instance on which test to be run\
    //        \r\n0 - McSPI1 instance\r\n1 - McSPI2 instance\r\n$>");
    //    scanf("%d", &inst_num);
    //    if (inst_num != 0 && inst_num != 1)
    //    {
    //        inst_num = 0;
    //    }
        GIO_addDevice("/mcspi0", (xdc_Ptr) & Mcspi_IOMFXNS, &user_mcspi_init,
                      0U, (xdc_Ptr) & mcspiPrms);
    }
    
    Int32 App_mcspiDefaultInit(UInt32 isI2cInitReq)
    {
        Int32  retVal = BSP_SOK;
        //UInt32 instCnt;
        Bsp_CommonInitParams    commonInitPrms;
        Bsp_BoardInitParams     boardInitPrms;
        Bsp_PlatformInitParams  platInitPrms;
        //Bsp_DeviceInitParams    deviceInitPrms;
        //lld_hsi2c_initParam_t   i2cInitParams[BSP_DEVICE_I2C_INST_ID_MAX];
        //const Bsp_BoardI2cData *i2cData;
        //Bsp_BoardI2cInstData   *i2cInstData;
        BspCommonInitParams_init(&commonInitPrms);
        retVal += Bsp_commonInit(&commonInitPrms);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: BSP Common Init failed!!\r\n");
        }
    
        BspBoardInitParams_init(&boardInitPrms);
        /* Override board detection if I2C is disabled */
        if (((Bool) TRUE) != ((Bool) isI2cInitReq))
        {
            boardInitPrms.boardId      = BSP_BOARD_UNKNOWN;
            boardInitPrms.baseBoardRev = BSP_BOARD_REV_UNKNOWN;
            boardInitPrms.dcBoardRev   = BSP_BOARD_REV_UNKNOWN;
        }
        retVal += Bsp_boardInit(&boardInitPrms);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: Board Init failed!!\r\n");
        }
    
        BspPlatformInitParams_init(&platInitPrms);
        retVal += Bsp_platformInit(&platInitPrms);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: Platform Init failed!!\r\n");
        }
    
        retVal += Fvid2_init(NULL);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: FVID2 Init failed!!\r\n");
        }
    
        /* Override I2C init for non-EVM builds */
        if (BSP_PLATFORM_ID_EVM != Bsp_platformGetId())
        {
            isI2cInitReq = FALSE;
        }
    
       /* if (((Bool) TRUE) == ((Bool) isI2cInitReq))
        {
            i2cData = Bsp_boardGetI2cData();
            GT_assert(BspAppTrace, (NULL != i2cData));
            GT_assert(BspAppTrace,
                      (i2cData->numInst <= BSP_DEVICE_I2C_INST_ID_MAX));
            GT_assert(BspAppTrace, (NULL != i2cData->instData));
    
            for (instCnt = 0U; instCnt < i2cData->numInst; instCnt++)
            {
                i2cInstData = &i2cData->instData[instCnt];
                GT_assert(BspAppTrace,
                          (i2cInstData->instId < BSP_DEVICE_I2C_INST_ID_MAX));
                i2cInitParams[instCnt].opMode       = HSI2C_OPMODE_INTERRUPT;
                i2cInitParams[instCnt].isMasterMode = TRUE;
                i2cInitParams[instCnt].is10BitAddr  = FALSE;
                i2cInitParams[instCnt].i2cBusFreq   =
                    (lld_i2c_busspeed) i2cInstData->busClkKHz;
                i2cInitParams[instCnt].i2cIntNum      = i2cInstData->intNum;
                i2cInitParams[instCnt].i2cOwnAddr     = 0xCC;
                gI2cDevInitParams[instCnt].initParams = &i2cInitParams[instCnt];
                gI2cDevInitParams[instCnt].hsi2c_sem  =
                    BspOsal_semCreate((Int32) 1, (Bool) TRUE);
                gI2cDevInitParams[instCnt].instId = i2cInstData->instId;
            }
    
            if (i2cData->numInst > 0)
            {
                retVal = I2c_GlobalInit(i2cData->numInst, &gI2cDevInitParams[0U]);
                if (BSP_SOK != retVal)
                {
                    GT_0trace(BspAppTrace, GT_ERR, "Error: I2C Init failed!!\r\n");
                }
            }
    
            BspDeviceInitParams_init(&deviceInitPrms);
            deviceInitPrms.isI2cProbingReq = FALSE;
            retVal += Bsp_deviceInit(&deviceInitPrms);
            if (BSP_SOK != retVal)
            {
                GT_0trace(BspAppTrace, GT_ERR, "Error: Device Init failed!!\r\n");
            }
        }*/
    
        /*retVal += BspUtils_memInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: App MEM Utils Init failed!!\r\n");
        }
    
        retVal += BspUtils_prfInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: App PRF Utils Init failed!!\r\n");
        }*/
    
        retVal += BspUtils_appInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: App Utils Init failed!!\r\n");
        }
    
        /* Print BSP version string and platform info*/
        GT_0trace(BspAppTrace, GT_INFO, " \r\n");
        GT_2trace(BspAppTrace, GT_INFO,
                  " Build time            : [%s %s]\r\n", __TIME__, __DATE__);
        GT_1trace(BspAppTrace, GT_INFO,
                  " BSP Version           : [%s]\r\n", Bsp_getVersionString());
        Bsp_platformPrintInfo();
        Bsp_boardPrintInfo();
        GT_0trace(BspAppTrace, GT_INFO, " \r\n");
    
        return (retVal);
    }
    

  • Hi Parth,

    Utils_dmaInit will be called during system init once, after this you can use the API Utils_dmaGetEdma3Hndl to get the edma handle.
    Use this handle and pass it to the McSPI driver.

    Also the GIO_Issue function will call internally mcspiMdSubmitChan() function of driver code present at,
    ti_components\drivers\pdk_01_07_00_16\packages\ti\drv\bsp_lld\mcspi\src\bsp_mcspi.c. Can you check where you are getting the error from driver?

    Regards,
    Prasad
  • Hi Prasad,

    Thanks for the quick response.

    We find out the reason for the failure and it is happening due to we have commented out on two function.

    /*retVal += BspUtils_memInit();

      if (BSP_SOK != retVal)

      {

          GT_0trace(BspAppTrace, GT_ERR, "Error: App MEM Utils Init failed!!\r\n");

      }

      retVal += BspUtils_prfInit();

      if (BSP_SOK != retVal)

      {

          GT_0trace(BspAppTrace, GT_ERR, "Error: App PRF Utils Init failed!!\r\n");

      }*/

    If we tried to uncommented this function then during code compilation we are getting below error

    the program will not fit into available memory.  run placement with alignment

     fails for section "GROUP_1" size 0xf816696 .  Available memory ranges:

     IPU1_0_DATA_MEM   size: 0xb00000     unused: 0x70ceaa     max hole: 0x70cea8

    So, please suggest us the possible solution to resolve this compilation error.

    We have attached the source code and debug log and compilation error snapshot for your reference.

    Thanks,

    Parth Modi

  • Hi,

    Is there any update on the previous post?

    We are waiting for your response.

    Thanks,

    Parth

  • Hi Parth,

    You should modify the memory definition xs file to resolve the compilation error.
    The files is present in directory: vision_sdk\apps\build\<platform>\mem_segment_definition_bios.xs.

    Regards,
    Rishabh
  • Hi Rishabh,

    If we comment out Below code then it will affect our functionality ?
    Currently, we have commented Below code and when we issue GIO_reclaim then it is hang our application.

    Where we are going wrong ?
    Please suggest.

    Commented code:
    /*retVal += BspUtils_memInit();

    if (BSP_SOK != retVal)

    {

    GT_0trace(BspAppTrace, GT_ERR, "Error: App MEM Utils Init failed!!\r\n");

    }

    retVal += BspUtils_prfInit();

    if (BSP_SOK != retVal)

    {

    GT_0trace(BspAppTrace, GT_ERR, "Error: App PRF Utils Init failed!!\r\n");

    }*/

    Regards,
    Parth Modi
  • Hi Rishabh,

    Can you please update on above post?
    We have little urgency.We have to resolve this issues before EOD.

    Thanks,
    Parth Modi
  • Hi Parth,

    I think commenting these APIs should affect the functionality.
    I have asked MCSPI expert to look at it. We have to wait till he responds.

    Regards,
    Rishabh
  • Hi,

    We are sending the data from Slave to Master on MISO line. And, we have found an issue on Master side on MSB.

    The issue is like, the MSB is always missed out because the clock starts after the MSB.

    Attached the DSO's screenshot for the reference. In the screenshot, the Yellow channel is for CLK and the blue channel is for MISO.

    For resolving this issue, which SPI configuration we have to implement/use?

    Thanks,

  • Hi,

    Is there any update on the previous post?
    We are waiting for your reply.

    Thanks,
    Parth

  • Hi Parth,

    The BspUtils_ functions need not be called from vsdk framework.

    Utils_mcspi.c file has functions to add device, you need to call the Utils_mcspiInit function with the mcspi instance number.

    Then call the GIO_Create API with the same device name used in Utils_mcspi.c file.

    From your earlier posts, you were facing issues with GIO_submit right, Did you check in the driver code where you are getting error?

    Are you now able to receive the data but it is corrupted?

    Also in case of McSPI master will send the clock and slave has to respond to the clock recieved, how the slave is able to send the data before master initiates the clock?

    Regards,
    Prasad

  • Hi Prasad,

    Thanks for the reply,

    As of now, Our TDA2x Soc is working on the Slave mode.On slave side, we receive the data perfectly from the master (MOSI).But when we send the data from Slave to Master the First bit is missing on master side(MISO line).We used the SPI mode 3(CPOL = 1and CPHA = 1) for communication.

    if we send the data 129((binary)1000 0001) from the salve then we receive the master side 3 (0000 0011).

    I have attached CRO screenshot for your information.Inside screenshot yellow line is for SCLK and the blue channel is for the MISO line.

    My query  is,

    1) How to resolve this data going wrong on the master side?

    Please suggest us some solution to resolve this issue.

    Please let me know if you need more information on our side.

    Thanks,

    Parth Modi

  • Hi Parth,

    The TDA2 SOC when configured in McSPI slave mode, does not control the clock. It will only responds to the clock sent from the external master. So it cont send the bit before master initiates the clock.

    How have you connected the slave on the board? Are the track lengths of MOSI, MISO and clock same?

    Regards,
    Prasad

  • Hi Prasad,

    Our track length is as per below

    MOSI 312.61 + 4476.41 = 4789.02 mils

    MISO 306.11 + 3208.36 = 3514.47 mils

    CS# 211.32 + 3103.34 = 3314.66 mils

    CLK 248.9 + 3117.13 = 3366.03 mils

    We connected the Master device to the level shifter.

    Tad2x( slave) <-> levelshifter<->MCU(Master)

    We are getting GIO_reclaim stuck after calling GIO_issue for one time.if we call this function for 2 times than it works well(i.e one every time we need to call issues the 2 times data and reclaim claim the 2 times data).

    I have attached my code for your information.

    What is region to behind the struck the GIO_Reclaim?

    We want to take the SPI data on every instance of receive interrupt from the master.Can please share me some example code to implement it.

    Thanks,

    Parth Modi

    2744.mcspiSample_io.c
    /*
     *  Copyright (C) 2012-2017 Texas Instruments Incorporated
     *
     *  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.
     *
     */
    /**
     *  \file   mcspiSample_io.c
     *
     *  \brief  McSPI evm to evm communication sample application
     *
     *          This file demonstrates the use of Mcspi by using an
     *          EVM to EVM communication setup.This file configures one of the evm
     *          in master mode.
     */
    
    /* ========================================================================== */
    /*                          INCLUDE FILES                                     */
    /* ========================================================================== */
    
    #include <stdio.h>
    #include <string.h>
    #include <xdc/std.h>
    #include <ti/sysbios/io/GIO.h>
    #include <ti/sysbios/BIOS.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <ti/sysbios/knl/Task.h>
    #include <xdc/runtime/IHeap.h>
    #include <ti/sysbios/heaps/HeapMem.h>
    #include <ti/drv/bsp_lld/mcspi/bsp_mcspi.h>
    #include <xdc/runtime/Memory.h>
    #include <ti/sdo/edma3/drv/edma3_drv.h>
    #include <xdc/std.h>
    #include <stdio.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/io/GIO.h>
    #include <ti/sysbios/io/IOM.h>
    #include <xdc/runtime/Log.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/heaps/HeapMem.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <ti/sdo/edma3/drv/edma3_drv.h>
    #include <ti/drv/vps/include/common/bsp_types.h>
    #include <ti/drv/vps/include/common/trace.h>
    #include <ti/drv/vps/include/common/bsp_config.h>
    #include <ti/drv/vps/include/common/bsp_utils.h>
    #include <ti/drv/vps/include/common/bsp_common.h>
    #include <ti/drv/bsp_lld/mcspi/bsp_mcspi.h>
    #include <ti/drv/vps/include/platforms/bsp_platform.h>
    #include <ti/drv/vps/include/boards/bsp_board.h>
    #include <ti/drv/vps/include/devices/bsp_device.h>
    #include <ti/drv/bsp_lld/i2c/bsp_i2c.h>
    #include <ti/drv/vps/include/fvid2/fvid2.h>
    #include <ti/drv/vps/examples/utility/bsputils_mem.h>
    #include <ti/drv/vps/examples/utility/bsputils_prf.h>
    #include <ti/drv/vps/examples/utility/bsputils_app.h>
    #include <src/rtos/utils_common/include/utils_dma.h>
    #include <ti/csl/csl_mcspi.h>
    #include <ti/csl/soc.h>
    #include "mcspiSample_io.h"
    
    /* ========================================================================== */
    /*                          LOCAL FUNCTION PROTOTYPES                         */
    /* ========================================================================== */
    EDMA3_DRV_Handle edma3init(UInt32 edma3Id, EDMA3_DRV_Result *);
    Int32 App_mcspiDefaultInit(UInt32 isI2cInitReq);
    static Int32 App_mcspiDefaultDeInit(UInt32 isI2cInitReq);
    void SPI_init(void);
    /* ========================================================================== */
    /*                            MACRO DEFINITONS                                */
    /* ========================================================================== */
    
    /* ========================================================================== */
    /*                              GLOBAL VARIABLES                              */
    /* ========================================================================== */
    
    EDMA3_DRV_Handle      gEdmaHandle;
    UInt32       gIsI2cInitReq;
    extern const IOM_Fxns Mcspi_IOMFXNS;
    HeapMem_Handle myHeap;
    Bool garbej_on_boot = TRUE;
    //static I2c_DevInitParams gI2cDevInitParams[BSP_DEVICE_I2C_INST_ID_MAX];
    
    /*
     * Buffers placed in external memory are aligned on a 128 bytes boundary.
     * In addition, the buffer should be of a size multiple of 128 bytes for
     * the cache to work optimally.
     */
    
    //#define BUFLEN          (1024 * 4) /* Buffer size */
    #define BUFLEN          (16 * 1) /* Buffer size */
    #define BUFALIGN        128        /* Alignment of buffer for use of L2 cache */
    #define ITERATION_CNT   100        /* Number of Iterations */
    //#define NUM_BUFS        3          /* Num Bufs to be issued and reclaimed */
    #define NUM_BUFS        1         /* Num Bufs to be issued and reclaimed *///value is must be two
    /* handle to the input and output streams   */
    GIO_Handle mcspiHandle = NULL;
    
    /* Global SPI init config data structure    */
    Mcspi_Params   mcspiPrms;
    
    Mcspi_DataParam       issueDataparam[NUM_BUFS];
    
    //Mcspi_DataParam       issueDataparam1[NUM_BUFS];
    
    /* Buffer alignement is required when working in DMA Mode */
    #pragma DATA_ALIGN(rxbuf, BUFALIGN);
    Ptr  rxbuf[NUM_BUFS];
    
    /* Buffer alignement is required when working in DMA Mode */
    #pragma DATA_ALIGN(txbuf, BUFALIGN);
    Ptr  txbuf[NUM_BUFS];
    
    #pragma DATA_ALIGN(rxbuf, BUFALIGN);
    Ptr  rxbuf1[NUM_BUFS];
    
    /* Buffer alignement is required when working in DMA Mode */
    #pragma DATA_ALIGN(txbuf, BUFALIGN);
    Ptr  txbuf1[NUM_BUFS];
    
    Bool failFlag = FALSE;
    
    /* Function prototype */
    //#if 0
    static void createStream(void);
    static void prime(void);
    static void memory_allocated(void);
    //static void prime1(void);
    //#endif
    /* ========================================================================== */
    /*                           FUNCTION DEFINITIONS                             */
    /* ========================================================================== */
    
    /*
     * ======== createStream ========
     */
    //#if 0
    static void createStream(void)
    {
        GIO_Params       ioParams;
        Mcspi_ChanParams chanParams;
        Error_Block      eb;
    
        Error_init(&eb);
    
        /*
         * Initialize channel attributes.
         */
        GIO_Params_init(&ioParams);
    
        /* update the edma Handle                                                 */
        chanParams.hEdma = gEdmaHandle;
        chanParams.chipSelTimeControl = MCSPI_CLK_CYCLE0;
        chanParams.fifoEnable         = (UInt32) TRUE;
        chanParams.spiChipSelectHold  = (UInt32) TRUE;
        chanParams.chanNum = 0;
    
        /* If cross bar events are being used then make isCrossBarIntEn = TRUE and
         * choose appropriate interrupt number to be mapped (assign it to
         * intNumToBeMapped)
         */
        /* Cross bar evt disabled */
        chanParams.crossBarEvtParam.isCrossBarIntEn  = (UInt32) FALSE;
        chanParams.crossBarEvtParam.intNumToBeMapped = 0xFF;  /* Invalid number */
    
        ioParams.chanParams = (Ptr) & chanParams;
        ioParams.model      = GIO_Model_ISSUERECLAIM;
        ioParams.numPackets = NUM_BUFS + 1;
    //    ioParams.sync=NULL;
        mcspiHandle = GIO_create("/mcspi0", GIO_INOUT, &ioParams, &eb);
        if (mcspiHandle == NULL)
        {
            System_printf("\r\nCreate input stream FAILED.\r\n");
            BIOS_exit(0);
        }
        System_printf("\r\nCreate input stream completed.\r\n");
    }
    //#endif
    /*
     * \brief   Function to submit request the driver.Depending on the macro
     *          "NUM_BUFS" either the driver can be buffered with multiple requests
     *          or only one buffer by using the NUM_BUFS as 1.
     *
     * \param   None
     *
     * \return  None
     */
    
    
    static void memory_allocated(void)
    {
        Error_Block  eb;
        Int32        count = 0;
        IHeap_Handle iheap;
    
        iheap = HeapMem_Handle_to_xdc_runtime_IHeap(myHeap);
        Error_init(&eb);
    
        /* Allocate buffers for the GIO buffer exchanges                          */
        for (count = 0; count < (NUM_BUFS); count++)
        {
            rxbuf[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
            if (NULL == rxbuf[count])
            {
                System_printf("\r\nMEM_calloc failed.\r\n");
            }
            txbuf[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
            if (NULL == txbuf[count])
            {
                System_printf("\r\nMEM_calloc failed.\r\n");
            }
        }
    }
    //if 0
    static void prime(void)
    {
    
        Int32        count = 0;
        UInt32       tempCount = 0;
        UInt32       size      = 0;
        Int          status    = IOM_COMPLETED;
        UInt8           j;
        UInt8 spi_dummy_data[13]={0x00,0x20,0x09,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F};
        unsigned char data = 0x0F;
    
            if(garbej_on_boot == TRUE)
            {
               for (count = 0; count < (NUM_BUFS); count++)
               {
                    for (tempCount = 0; tempCount < BUFLEN; tempCount++)
                    {
                        ((Uint8 *) txbuf[count])[tempCount] = data;
                    }
    
               }
               garbej_on_boot =FALSE;
            }
            else
            {
                for (count = 0; count < (NUM_BUFS); count++)
               {
                for (tempCount = 0,j=0; tempCount < BUFLEN; tempCount++)
                {
                   ((Uint8 *) txbuf[count])[tempCount] = spi_dummy_data[j++];
                   if(j==13)
                       j=0;
                }
               }
            }
        for (count = 0; count < NUM_BUFS; count++)
        {
            issueDataparam[count].bufLen    = BUFLEN;
            issueDataparam[count].inBuffer  = rxbuf[count];
            issueDataparam[count].outBuffer = txbuf[count];
    
            size = issueDataparam[count].bufLen;
            System_printf("\r\n before GIO_issue \r\n");
            /* Issue the first & second empty buffers to the input stream         */
            status = GIO_issue(mcspiHandle, &issueDataparam[count], size, NULL);
    
            if (status != IOM_PENDING && status != IOM_COMPLETED)
            {
                System_printf("\r\nsatus =%d\r\n",status);
                System_printf("\r\nFailed to issue empty buffer to stream\r\n");
            }
            System_printf("SPI TDA2x-> MCU write frame replay\r\n");
            for(j=0;j<BUFLEN;j++ )
            {
                System_printf("SPI Data[%d byte]=0x%x\r\n", j,issueDataparam[count].outBuffer[j]);
    
            }
            System_printf("SPI End frame\r\n");
        }
        System_printf("\r\n prime completed\r\n");
    
    }
    #if 0
    static void prime1(void)
    {
    
        Error_Block  eb;
        Int32        count = 0;
        IHeap_Handle iheap;
        UInt32       tempCount = 0;
        UInt32       size      = 0;
        Int          status    = IOM_COMPLETED;
    
        iheap = HeapMem_Handle_to_xdc_runtime_IHeap(myHeap);
        Error_init(&eb);
    
        /* Allocate buffers for the GIO buffer exchanges                          */
        for (count = 0; count < (NUM_BUFS); count++)
        {
            rxbuf[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
            if (NULL == rxbuf[count])
            {
                System_printf("\r\nMEM_calloc failed.\r\n");
            }
    
            txbuf[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
            if (NULL == txbuf[count])
            {
                System_printf("\r\nMEM_calloc failed.\r\n");
            }
        }
    
        /* Fill the buffers with known data and transmit the same and check if the*
         * same pattern is received on the other EVM                              */
        for (count = 0; count < (NUM_BUFS); count++)
        {
            for (tempCount = 0; tempCount < BUFLEN; tempCount++)
            {
    //            ((Uint8 *) txbuf[count])[tempCount] = tempCount;
                ((Uint8 *) txbuf[count])[tempCount] =238;
            }
        }
        for (count = 0; count < NUM_BUFS; count++)
        {
            issueDataparam1[count].bufLen    = BUFLEN;
            issueDataparam1[count].inBuffer  = rxbuf[count];
            issueDataparam1[count].outBuffer = txbuf[count];
    
            size = issueDataparam1[count].bufLen;
    
            /* Issue the first & second empty buffers to the input stream         */
            status = GIO_issue(mcspiHandle, &issueDataparam1[count], size, NULL);
    
            if (status != IOM_PENDING && status != IOM_COMPLETED)
            {
                System_printf("\r\nsatus =%d\r\n",status);
                System_printf("\r\nFailed to issue empty buffer to stream\r\n");
            }
        }
        System_printf("\r\n prime completed\r\n");
        GIO_reclaim(mcspiHandle, (Ptr *)&issueDataparam1[count], NULL, NULL);
    //    status = GIO_reclaim(mcspiHandle, (Ptr *)&issueDataparam[i], NULL, NULL);
    }
    #endif
    void spiSampleTask(void)
    {
          Int32 retVal = FVID2_SOK;
          Bsp_PlatformInitParams platInitPrms;
    
        /* isPinMuxSettingReq parameter will be initialised to TRUE */
        BspPlatformInitParams_init(&platInitPrms);
    //
        platInitPrms.isAllMcSPIInitReq  = TRUE;
        platInitPrms.isPinMuxSettingReq = TRUE;
    
        /* Initialize pinmux and evm related configurations */
        Bsp_platformInit(&platInitPrms);
        /* System init */
        gIsI2cInitReq = FALSE;
        retVal       = App_mcspiDefaultInit(gIsI2cInitReq);
        if (retVal != FVID2_SOK)
        {
            System_printf("Error: : System Init Failed!!!\r\n");
        }
        /* Set the pin Mux */
        Bsp_boardSetPinMux(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_0,
                           BSP_BOARD_MODE_DEFAULT);
    //    Bsp_boardSetPinMux(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_1,
    //                       BSP_BOARD_MODE_DEFAULT);
    
        /* Set the board muxes */
        Bsp_boardSelectDevice(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_0);
    //    Bsp_boardSelectDevice(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_1);
        /* call the function for the SPI application test                     */
    
    //    start_spi_sample();
    //
    //    App_mcspiDefaultDeInit(gIsI2cInitReq);
    //
    //    /* Start the Heart Beat Print                                         */
    //    tskHeartBeat();
    //
    //    return;
    }
    
    /*
     * \brief   This function demostrates the use of Mcspi using an EVM to EVM
     *          communication setup.
     *
     * \param   None
     *
     * \return  None
     */
    void start_spi_sample_new(Void)
    {
        System_printf("\r\nIn start SPI sample new\r\n");
        volatile Int32   i32Count  = 0;
    
    //    Mcspi_DataParam  dataparam = {0};
    //    Mcspi_DataParam *dataparam = {0};
        UInt32           tempCount = 0;
        UInt32           i /*loopcount = 0*/;
        UInt32             k,j;
    //    UInt32           dataMismatchError = 0;
    //    UInt8            temp8InBufVal = 0, temp8OutBufVal = 0;
    //    UInt16           temp16InBufVal = 0, temp16OutBufVal = 0;
    //    UInt32           temp32InBufVal = 0, temp32OutBufVal = 0;
    //    UInt32           maskVal        = 0;
        UInt8               SPIdata[13] = {0};
    //    UInt8            SPIReplaydata[13] = {0};
        Int status = IOM_COMPLETED;
    //    size_t       size      = 0;
    //    Sleep(1000);
        SPI_init();
        spiSampleTask();
    //    createStream();
    
    
    //    EDMA3_DRV_Result edmaResult = 0;
        //Utils_dmaInit();
    //    gEdmaHandle = Utils_dmaGetEdma3Hndl(0);
    ////    gEdmaHandle = edma3init(0, &edmaResult);
    //
    //    if (gEdmaHandle != NULL)
    //    {
    //        /* Report EDMA Error */
    //        System_printf("\r\nEDMA driver initialization FAIL\r\n");
    //    }
    //    else
    //    {
    //        System_printf("\r\nEDMA driver initialization PASS.\r\n");
    //    }
    
        /* Call createStream function to create I/O streams                       */
        createStream();
        memory_allocated();
    for(k=0;k<1;k++)
    {
        prime();
    
        for (i = 0; i < NUM_BUFS; i++)
        {
    
            status = GIO_reclaim(mcspiHandle, (Ptr *)&issueDataparam[i], NULL, NULL);
            if (IOM_COMPLETED != status)
            {
                System_printf("Iteration %d\r\n", i32Count);
    
                System_printf(
                    "Error reclaiming empty buffer from the streams %x"
                    " error = 0x%d\r\n",
                    ((Uint8) (issueDataparam[i].outBuffer[i32Count])),
                    status);
                break;
            }
    
            for (tempCount = 0; tempCount < BUFLEN; )
            {
    //            System_printf("Out Buffer Data %x\r\n", ((Uint8) (issueDataparam[i].outBuffer[tempCount])));
    //            System_printf("In Buffer Data [byte %d]=0x%x\r\n", tempCount,((Uint8) (issueDataparam[i].inBuffer[tempCount])));
                if (mcspiPrms.spiHWCfgData.configChfmt[0].charLength <= 8)
                {
                    if( (issueDataparam[i].inBuffer[tempCount] == 0x00) && (issueDataparam[i].inBuffer[tempCount+1] == 0x22))
                    {
    
                        SPIdata[0]=issueDataparam[i].inBuffer[tempCount];
                        SPIdata[1]=issueDataparam[i].inBuffer[tempCount + 1];
                        SPIdata[2]=issueDataparam[i].inBuffer[tempCount + 2];
                        SPIdata[3]=issueDataparam[i].inBuffer[tempCount + 3];
                        SPIdata[4]=issueDataparam[i].inBuffer[tempCount + 4];
                        SPIdata[5]=issueDataparam[i].inBuffer[tempCount + 5];
                        SPIdata[6]=issueDataparam[i].inBuffer[tempCount + 6];
                        SPIdata[7]=issueDataparam[i].inBuffer[tempCount + 7];
                        SPIdata[8]=issueDataparam[i].inBuffer[tempCount + 8];
                        SPIdata[9]=issueDataparam[i].inBuffer[tempCount + 9];
                        SPIdata[10]=issueDataparam[i].inBuffer[tempCount + 10];
                        SPIdata[11]=issueDataparam[i].inBuffer[tempCount + 11];
                        SPIdata[12]=issueDataparam[i].inBuffer[tempCount + 12];
    
                       System_printf("SPI Master-> TDA2x write frame\r\n");
                       for(j=0;j<13;j++ )
                       {
                          System_printf("SPI Data[%d byte]=%x\r\n", j,SPIdata[j]);
    
                       }
                       System_printf("SPI End frame\r\n");
    
                    }
                    else if((issueDataparam[i].inBuffer[tempCount] == 0x01) && (issueDataparam[i].inBuffer[tempCount+1] == 0x22))
                    {
                        SPIdata[0]=issueDataparam[i].inBuffer[tempCount];
                        SPIdata[1]=issueDataparam[i].inBuffer[tempCount + 1];
                        SPIdata[2]=issueDataparam[i].inBuffer[tempCount + 2];
                        SPIdata[3]=issueDataparam[i].inBuffer[tempCount + 3];
                        SPIdata[4]=issueDataparam[i].inBuffer[tempCount + 4];
                        SPIdata[5]=issueDataparam[i].inBuffer[tempCount + 5];
                        SPIdata[6]=issueDataparam[i].inBuffer[tempCount + 6];
                        SPIdata[7]=issueDataparam[i].inBuffer[tempCount + 7];
                        SPIdata[8]=issueDataparam[i].inBuffer[tempCount + 8];
                        SPIdata[9]=issueDataparam[i].inBuffer[tempCount + 9];
                        SPIdata[10]=issueDataparam[i].inBuffer[tempCount + 10];
                        SPIdata[11]=issueDataparam[i].inBuffer[tempCount + 11];
                        SPIdata[12]=issueDataparam[i].inBuffer[tempCount + 12];
    
                        System_printf("SPI start read frame\r\n");
                        for(j=0;j<13;j++ )
                        {
                           System_printf("SPI Data[%d byte]=%x\r\n", j,SPIdata[j]);
    
                        }
                        System_printf("SPI End frame\r\n");
                    }
                }
                else
                {
                    System_printf("Invalid Word Length\r\n");
    
                }
                System_printf("in temp count=%d\r\n",tempCount);
                tempCount++;
            }
            System_printf("in time NUM_BUFS = %d\r\n",i);
        }
    //    System_printf("loop time = %d\r\n",k);
    }
        gIsI2cInitReq = FALSE;
        GIO_delete(&mcspiHandle);
        App_mcspiDefaultDeInit(gIsI2cInitReq);
        return;
    }
    
    void user_mcspi_init(void)
    {
      //  Int32 opMode;
        Mcspi_init();
    
    //    mcspiPrms = Mcspi_PARAMS;
    //    System_printf("Please Connect the McSPI%d MISO (DAT0) to MOSI (DAT1)\r\n",
    //                  (inst_num + 1U));
    //    System_printf(
    //        "And then enter the Operating mode\r\n0 - Polled Mode\
    //            \r\n1 - Interrupt Mode\
    //            \r\n2 - DMA Interrupt mode\r\n$>");
    ////    scanf("%d", &opMode);
    //    if (opMode == 0)
    //    {
    //        mcspiPrms.opMode = MCSPI_OPMODE_POLLED;
    //    }
    //    else if (opMode == 1)
    //    {
            mcspiPrms.opMode = MCSPI_OPMODE_INTERRUPT;
    //    }
    //    else if (opMode == 2)
    //    {
    //        mcspiPrms.opMode = MCSPI_OPMODE_DMAINTERRUPT;
    //    }
    //    else
    //    {
    //        mcspiPrms.opMode = MCSPI_OPMODE_POLLED;
    //    }
    
        mcspiPrms.instNum         = 0;
        mcspiPrms.hwiNumber       = 7;
        mcspiPrms.enableCache     = (UInt32) TRUE;
        mcspiPrms.edma3EventQueue = 0;
        mcspiPrms.enableErrIntr   = (UInt32) FALSE;
    
        mcspiPrms.spiHWCfgData.masterOrSlave         = MCSPI_COMMMODE_SLAVE;
        mcspiPrms.spiHWCfgData.singleOrMultiChEnable = MCSPI_SINGLE_CHANNEL;
        mcspiPrms.spiHWCfgData.pinOpModes    = MCSPI_PINOPMODE_4PIN;
    //    mcspiPrms.spiHWCfgData.fifoRxTrigLvl = 32;
    //    mcspiPrms.spiHWCfgData.fifoTxTrigLvl = 32;
        mcspiPrms.spiHWCfgData.fifoRxTrigLvl = 16;
        mcspiPrms.spiHWCfgData.fifoTxTrigLvl = 16;
        mcspiPrms.spiHWCfgData.configChfmt[0].charLength = MCSPI_LEN_8BIT;
        mcspiPrms.spiHWCfgData.configChfmt[0].multiWordAccessEnable =
            (UInt32) FALSE;
    
        mcspiPrms.spiHWCfgData.configChfmt[0].spiChipSelectEnablePol =
                (UInt32) FALSE;
    
    //    mcspiPrms.spiHWCfgData.configChfmt[0].spiChipSelectEnablePol =
    //              (UInt32) TRUE;
    
    
        mcspiPrms.spiHWCfgData.configChfmt[0].clockMode           = MCSPI_MODE3;
    //    mcspiPrms.spiHWCfgData.configChfmt[0].clockMode           = MCSPI_MODE1;
        mcspiPrms.spiHWCfgData.configChfmt[0].clockRatioExtension = 0;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiWordInitDelay    = MCSPI_NO_DELAY;
        mcspiPrms.spiHWCfgData.configChfmt[0].trasmitReceiveMode  = MCSPI_BOTH_RXTX;
        mcspiPrms.spiHWCfgData.configChfmt[0].granularityEnable   = (UInt32) TRUE;
    //    mcspiPrms.spiHWCfgData.configChfmt[0].busFreq             = 1000000;
        mcspiPrms.spiHWCfgData.configChfmt[0].busFreq             =  200000;
        mcspiPrms.spiHWCfgData.configChfmt[0].spienHighPolarity   = (UInt32) FALSE;
        mcspiPrms.spiHWCfgData.configChfmt[0].slaveModeChipSelect = MCSPI_SPIEN_0;
    //    mcspiPrms.spiHWCfgData.configChfmt[0].spiDat0Dir          = MCSPI_IN;
    //    mcspiPrms.spiHWCfgData.configChfmt[0].spiDat1Dir          = MCSPI_OUT;
    
        mcspiPrms.spiHWCfgData.configChfmt[0].spiDat0Dir          = MCSPI_OUT;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiDat1Dir          = MCSPI_IN;
    
        if (MCSPI_OPMODE_POLLED == mcspiPrms.opMode)
        {
            System_printf("\r\nMcspi is configured in polled mode\r\n");
        }
        else if (MCSPI_OPMODE_INTERRUPT == mcspiPrms.opMode)
        {
            System_printf("\r\nMcspi is configured in interrupt mode\r\n");
        }
        else if (MCSPI_OPMODE_DMAINTERRUPT == mcspiPrms.opMode)
        {
            System_printf("\r\nMcspi is configured in dma mode\r\n");
        }
        else
        {
            System_printf("\r\nError: unknown mode of operation!!!!!!!!!!\r\n");
        }
    
    }
    void SPI_init(void)
    {
    System_printf("Running McSPI Loopback test.\r\n");
    //    System_printf(
    //        "Enter McSPI instance on which test to be run\
    //        \r\n0 - McSPI1 instance\r\n1 - McSPI2 instance\r\n$>");
    //    scanf("%d", &inst_num);
    //    if (inst_num != 0 && inst_num != 1)
    //    {
    //        inst_num = 0;
    //    }
        GIO_addDevice("/mcspi0", (xdc_Ptr) & Mcspi_IOMFXNS, &user_mcspi_init,
                      0, (xdc_Ptr) & mcspiPrms);
    //    McSPIStartBitEnable(SOC_MCSPI1_BASE, MCSPI_CHANNEL_0);
    //    McSPIStartBitPolarityConfig(SOC_MCSPI1_BASE,
    //                                       MCSPI_START_BIT_POL_LOW,
    //                                            MCSPI_CHANNEL_0);
    }
    
    Int32 App_mcspiDefaultInit(UInt32 isI2cInitReq)
    {
        Int32  retVal = BSP_SOK;
        //UInt32 instCnt;
        Bsp_CommonInitParams    commonInitPrms;
        Bsp_BoardInitParams     boardInitPrms;
        Bsp_PlatformInitParams  platInitPrms;
        //Bsp_DeviceInitParams    deviceInitPrms;
        //lld_hsi2c_initParam_t   i2cInitParams[BSP_DEVICE_I2C_INST_ID_MAX];
        //const Bsp_BoardI2cData *i2cData;
        //Bsp_BoardI2cInstData   *i2cInstData;
        BspCommonInitParams_init(&commonInitPrms);
        retVal += Bsp_commonInit(&commonInitPrms);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: BSP Common Init failed!!\r\n");
        }
    
        BspBoardInitParams_init(&boardInitPrms);
        /* Override board detection if I2C is disabled */
        if (((Bool) TRUE) != ((Bool) isI2cInitReq))
        {
            boardInitPrms.boardId      = BSP_BOARD_UNKNOWN;
            boardInitPrms.baseBoardRev = BSP_BOARD_REV_UNKNOWN;
            boardInitPrms.dcBoardRev   = BSP_BOARD_REV_UNKNOWN;
        }
        retVal += Bsp_boardInit(&boardInitPrms);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: Board Init failed!!\r\n");
        }
    
        BspPlatformInitParams_init(&platInitPrms);
        retVal += Bsp_platformInit(&platInitPrms);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: Platform Init failed!!\r\n");
        }
    
        retVal += Fvid2_init(NULL);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: FVID2 Init failed!!\r\n");
        }
    
        /* Override I2C init for non-EVM builds */
        if (BSP_PLATFORM_ID_EVM != Bsp_platformGetId())
        {
            isI2cInitReq = FALSE;
        }
    
       /* if (((Bool) TRUE) == ((Bool) isI2cInitReq))
        {
            i2cData = Bsp_boardGetI2cData();
            GT_assert(BspAppTrace, (NULL != i2cData));
            GT_assert(BspAppTrace,
                      (i2cData->numInst <= BSP_DEVICE_I2C_INST_ID_MAX));
            GT_assert(BspAppTrace, (NULL != i2cData->instData));
    
            for (instCnt = 0U; instCnt < i2cData->numInst; instCnt++)
            {
                i2cInstData = &i2cData->instData[instCnt];
                GT_assert(BspAppTrace,
                          (i2cInstData->instId < BSP_DEVICE_I2C_INST_ID_MAX));
                i2cInitParams[instCnt].opMode       = HSI2C_OPMODE_INTERRUPT;
                i2cInitParams[instCnt].isMasterMode = TRUE;
                i2cInitParams[instCnt].is10BitAddr  = FALSE;
                i2cInitParams[instCnt].i2cBusFreq   =
                    (lld_i2c_busspeed) i2cInstData->busClkKHz;
                i2cInitParams[instCnt].i2cIntNum      = i2cInstData->intNum;
                i2cInitParams[instCnt].i2cOwnAddr     = 0xCC;
                gI2cDevInitParams[instCnt].initParams = &i2cInitParams[instCnt];
                gI2cDevInitParams[instCnt].hsi2c_sem  =
                    BspOsal_semCreate((Int32) 1, (Bool) TRUE);
                gI2cDevInitParams[instCnt].instId = i2cInstData->instId;
            }
    
            if (i2cData->numInst > 0)
            {
                retVal = I2c_GlobalInit(i2cData->numInst, &gI2cDevInitParams[0U]);
                if (BSP_SOK != retVal)
                {
                    GT_0trace(BspAppTrace, GT_ERR, "Error: I2C Init failed!!\r\n");
                }
            }
    
            BspDeviceInitParams_init(&deviceInitPrms);
            deviceInitPrms.isI2cProbingReq = FALSE;
            retVal += Bsp_deviceInit(&deviceInitPrms);
            if (BSP_SOK != retVal)
            {
                GT_0trace(BspAppTrace, GT_ERR, "Error: Device Init failed!!\r\n");
            }
        }*/
    
    //    retVal += BspUtils_memInit();
    //    if (BSP_SOK != retVal)
    //    {
    //        GT_0trace(BspAppTrace, GT_ERR, "Error: App MEM Utils Init failed!!\r\n");
    //    }
    //
    //    retVal += BspUtils_prfInit();
    //    if (BSP_SOK != retVal)
    //    {
    //        GT_0trace(BspAppTrace, GT_ERR, "Error: App PRF Utils Init failed!!\r\n");
    //    }
    
        retVal += BspUtils_appInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: App Utils Init failed!!\r\n");
        }
    
        /* Print BSP version string and platform info*/
        GT_0trace(BspAppTrace, GT_INFO, " \r\n");
        GT_2trace(BspAppTrace, GT_INFO,
                  " Build time            : [%s %s]\r\n", __TIME__, __DATE__);
        GT_1trace(BspAppTrace, GT_INFO,
                  " BSP Version           : [%s]\r\n", Bsp_getVersionString());
        Bsp_platformPrintInfo();
        Bsp_boardPrintInfo();
        GT_0trace(BspAppTrace, GT_INFO, " \r\n");
    
        return (retVal);
    }
    /**
     *  App_mcspiDefaultDeInit
     *  \brief Application utils function to call all the default de-init
     *  functions.
     */
    static Int32 App_mcspiDefaultDeInit(UInt32 isI2cDeInitReq)
    {
        Int32  retVal = BSP_SOK;
    //    const Bsp_BoardI2cData *i2cData;
    //    UInt32 instCnt;
    
        retVal += BspUtils_appDeInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: App Utils De-Init failed!!\r\n");
        }
    
        retVal += BspUtils_prfDeInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR,
                      "Error: App PRF Utils De-Init failed!!\r\n");
        }
    
        retVal += BspUtils_memDeInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR,
                      "Error: App MEM Utils De-Init failed!!\r\n");
        }
    
        /* Override I2C de-init for non-EVM builds */
        if (BSP_PLATFORM_ID_EVM != Bsp_platformGetId())
        {
            isI2cDeInitReq = FALSE;
        }
    
        if (((Bool) TRUE) == ((Bool) isI2cDeInitReq))
        {
    //        i2cData = Bsp_boardGetI2cData();
    //        GT_assert(BspAppTrace, (NULL != i2cData));
    //        GT_assert(BspAppTrace,
    //                  (i2cData->numInst <= BSP_DEVICE_I2C_INST_ID_MAX));
    //
    //        retVal += Bsp_deviceDeInit(NULL);
    //        if (BSP_SOK != retVal)
    //        {
    //            GT_0trace(BspAppTrace, GT_ERR, "Error: Device De-Init failed!!\r\n");
    //        }
    //        if (i2cData->numInst > 0)
    //        {
    //            for (instCnt = 0U; instCnt < i2cData->numInst; instCnt++)
    //            {
    //                BspOsal_semDelete(&(gI2cDevInitParams[instCnt].hsi2c_sem));
    //            }
    //            retVal += I2c_GlobalDeInit(NULL);
    //            if (BSP_SOK != retVal)
    //            {
    //                GT_0trace(BspAppTrace, GT_ERR, "Error: I2C De-Init failed!!\r\n");
    //            }
    //        }
        }
    
        retVal += Fvid2_deInit(NULL);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: FVID2 De-Init failed!!\r\n");
        }
    
        retVal += Bsp_platformDeInit(NULL);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR,
                      "Error: BSP Platform De-Init failed!!\r\n");
        }
    
        retVal += Bsp_boardDeInit(NULL);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: BSP Board De-Init failed!!\r\n");
        }
    
        retVal += Bsp_commonDeInit(NULL);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: BSP Common De-Init failed!!\r\n");
        }
    
        return (retVal);
    }
    

  • Parth,

    Only for the first time you need 2 GIO_issue, This is to prime the data to be sent as default response from slave.

    The driver internally maintains the queue for the response to be sent in case of slave mode.

    After this you can do GIO_reclaim followed by a GIO_issue.

    In the attached code I see that the issue is called only during priming.

    You can refer the example itself, which does multiple GIO_issue and reclaims.

    Regards,
    Prasad

  • Hi,

    We are still facing issues in doing SPI communication So I would like to clear few points here based on your previous suggestions.

    For SPI communication , we should first make a call of GIO_issue twice followed by 2 GIO_reclaim call and these are calls to make SPI initialization only, please verify.

    Actual data transmission will start after above steps, till now no valid data read/write.

    Now in for loop we can call GIO_issue and GIO_reclaim for each data read/write , I mean one issue/reclaim in each loop, right ?

    Please clear our understanding here.

    Thanks.

  • Hi,

    The first 2 GIO_Issue are required for priming to the driver with the data to be sent as response.
    After the first 2 GIO_Issue the transfer can start. Transfer will be initiated by the external SPI master.

    After this you can do the reclaim and issue in a loop.
    The GIO_reclaim is a blocking call and does not return till the first transfer is complete.

    At the end outside the loop you can do the final recalim to get all the buffers from driver.

    Regards,
    Prasad
  • Hi Prasad,

    We are trying to implement SPI communication since long time and struggling to understand the issue, please read below description for our requirement and the issue details.

    We are using TDA2XX board and Vision SDK 3.1 and we are running in the slave mode.
    Our motive is to read 13 byte data (including checksum) from Master.

    Please refer attached file for our implementation, we are using GIO_ISSUE and GIO_RECLAIM API for the receiving the data.
    To simulate data send from Master, we are using "HI-WAVE" tool.

    Below is the scenario which happens while changing the data from HI-WAVE tool.

    1. After SPI init, first we are changing data from HI-WAVE tool to simulate master to slave communication, and with this simulation slave should receive 13 byte from master but no data is received on slave side.
    2. Now again changing data from HI-WAVE to different value, we are receiving two frames of 13 byte in which first frame is incorrect while second frame has valid data.
    3. Changing data third time from HI-WAVE, we are receiving 13 byte on slave side which is garbage value.

    This above three points keeps repeating in subsequent changes.

    Please review our implementation and let us know how we can receive correct data from master to slave in single transmission only whenever master sends any data.

    You can refer function "getSpiData" in the attached file for the actual communication code and here are some constants which we have used in that file.

    / Macros for SPI Implementation /

    / Buffer size /
    #define BUFLEN (16 * 1)

    / Alignment of buffer for use of L2 cache /
    #define BUFALIGN 128

    / Number of Iterations /
    #define ITERATION_CNT 100

    / Num Bufs to be issued and reclaimed /
    #define NUM_BUFS 2

    We are struggling with the SPI since long time, please reply with the priority as we have some urgency.

    Regards,







    chains_lvdsVipMultiCamMirrorReplacement.c
    /********************************************************************************
    * @file		: chains_lvdsVipMultiCamMirrorReplacement.c
    *
    * @brief	: This is the top-level use-case file.
    * 		  This file  creates and initializes all the links and starts
    *                 the usecase chain.
    *		  The read and write from/to QSPI also happens here.
    *
    * @author	: VVDN Technologies Pvt. Ltd.
    *
    * @Copyright	: (c) 2012-2017 , VVDN Technologies Pvt. Ltd.
    *		  Permission is hereby granted to everyone in VVDN Technologies
    *		  to use the Software without restriction, including without
    *		  limitation the rights to use, copy, modify, merge, publish,
    *		  distribute, distribute with modifications.
    ********************************************************************************
    */
    
    /*******************************************************************************
     *  INCLUDE FILES
     *******************************************************************************
     */
    #include "chains_lvdsVipMultiCamMirrorReplacement_priv.h"
    #include <src/include/chains_common.h>
    #include <src/rtos/utils_common/include/utils_qspi.h>
    #include <src/rtos/utils_common/include/utils_mem.h>
    #include <ti/csl/csl_gpio.h>
    #include "src/rtos/mirror_replacement_files/chains_vipLvdsMultiCamMirrorReplacement_globals.h"
    
    /*******************************************************************************
     *  GLOBALS
     *******************************************************************************
     */
    
    /* Heap Handle */
    HeapMem_Handle        myHeap;
    
    /*EDMA Handle */
    EDMA3_DRV_Handle      gEdmaHandle;
    
    /* To initialize/de-initialize I2C */
    UInt32       gIsI2cInitReq;
    
    /* Buffer to receive date from MCU via SPI */
    Ptr  rxbuf[NUM_BUFS];
    
    /*Buffer to transmit data to MCU via SPI */
    Ptr  txbuf[NUM_BUFS];
    
    /* Flag to transmit grabage upon booting i.e upon
     * receving data first time from MCU via SPI. 
     */
    Bool garbageOnBoot = TRUE;
    
    /* Structure for the spi specific buffer address to be passed to the
     *  Stream.
     */
    Mcspi_DataParam       issueDataparam[NUM_BUFS];
    
    /* Handle to the input and output streams */
    GIO_Handle mcspiHandle = NULL;
    
    /* Global SPI init config data structure    */
    Mcspi_Params   mcspiPrms;
    
    /* Data received from MCU via SPI.
     * This will be passed on to algorithms.
     * It allows the user to change between views on the centre LCD.
     */
    UInt32 ucSpiData;
    
    /* Data received from MCU via SPI.
     * It allows the user to configure the Y-coordinate from where the
     * top camera cropping must start.
     */
    UInt16 ucSpiCropDataTopY=0;
    
    /* Data received from MCU via SPI.
     * It allows the user to configure the Y-coordinate from where the 
     * left camera cropping must start.
     */
    UInt16 ucSpiCropDataLeftY=0;
    
    /* Data received from MCU via SPI.
     * It allows the user to configure the X-coordinate from where the 
     * left camera cropping must start.
     */
    UInt16 ucSpiCropDataLeftX=0;
    
    /* Data received from MCU via SPI.
     * It allows the user to configure the Y-coordinate from where the 
     * right camera cropping must start.
     */
    UInt16 ucSpiCropDataRightY=0;
    
    /* Data received from MCU via SPI.
     * It allows the user to configure the X-coordinate from where the 
     * right camera cropping must start.
     */
    UInt16 ucSpiCropDataRightX=0;
    
    /*******************************************************************************
     *  MACROS
     *******************************************************************************
     */
    
    /* To turn on a LED indicating start of the use-case */
    #define WR_MEM_32(addr, data)   *(unsigned int*)(addr) = (unsigned int)(data)
    
    /* The mode in which each look-up table file must be opened. */
    #define FILE_MODE 			"r"
    
    /* The look-up table has 4 values in each element. */
    #define VALUES_IN_EACH_ELEMENT		4
    
    /* Width of the video frame to be captured from camera */
    #define CAPTURE_SENSOR_WIDTH      	(1280)
    
    /*Height of the video frame to captured from camera */
    #define CAPTURE_SENSOR_HEIGHT     	(720)
    
    /* \brief Channels with timestamp difference <= SYNC_DELTA_IN_MSEC
     *        are synced together by sync link
     */
    #define SYNC_DELTA_IN_MSEC              (16)
    
    /* \brief Channels with timestamp older than SYNC_DROP_THRESHOLD_IN_MSEC
     *        are dropped by sync link
     */
    #define SYNC_DROP_THRESHOLD_IN_MSEC     (33)
    
    /* Turn debug statements on/off 
     * MIRROR_REPLACEMENT_DEBUGS_OFF : to turn off the debugs for mirror replacement use-case
     * MIRROR_REPLACEMENT_DEBUGS_ON  : to turn on the debugs for mirror replacement use-case
     */
    #define MIRROR_REPLACEMENT_DEBUGS_OFF
    
    /* Height of 10" centre LCD */
    #define CENTRE_LCD_HEIGHT		320
    
    /* Shift a byte left/right */
    #define BYTE_SHIFT			8
    /**
     *******************************************************************************
     *
     *  \brief  Use-case object
     *
     *        This structure contains all the LinksId's and create Params.
     *        The same is passed to all create, start, stop functions.
     *
     *******************************************************************************
    */
    typedef struct {
    
        chains_lvdsVipMultiCamMirrorReplacementObj ucObj;
    
        UInt32  captureOutWidth;
        UInt32  captureOutHeight;
        UInt32  displayWidth;
        UInt32  displayHeight;
    
        UInt32  displayActiveChId;
        /**< CH ID which is shown on display */
    
        UInt32  numLvdsCh;
        /**< Number of channels of LVDS to enable */
    
        Chains_Ctrl *chainsCfg;
    
    } chains_lvdsVipMultiCamMirrorReplacementAppObj;
    
    /**
     *****************************************************************************************
     *
     * \brief   Store values from character buffer to integer buffer.
     *
     *          This function converts 'char' values to 'int'.
     *          It is called in SetAlgLutPrm function.
     *
     * \param   lutBufferString    [IN]     Buffer which holds the LUT in the form of string
     * \param   LUT    	       [OUT]    Buffer to store the LUT in the form of integer
     *
     *****************************************************************************************
    */
    
    Void chains_lvdsVipMultiCamMirrorReplacement_ConvertToArray(UInt8 *lutBufferString,UInt32 *LUT)
    {
    	
    	char *str = NULL;
    	UInt32 index = 0;
       
    	/* 'strtok' is a pre-defined C library function.
    	 * It breaks the string (given as its first argument) into several smaller 
    	 * strings i.e. tokens, using the delimiter given as the second argument.
    	 */
    	str = strtok(((char *)lutBufferString)," ");
    	
    	while(str != NULL)
    	{
    		/* Converting the token into integer using 'atoi' C library
    		 * function.
    		 */
    		LUT[index] = atoi(str);
            	index++;
            	
            	/* Signalling 'strtok' to keep searching the same string.
            	 * This operations fetches the other LUT elements. 
            	 */
    		str = strtok(NULL, " ");
    	}
    	index--;
    	Vps_printf("\nLUT[0]=%d , LUT[1]=%d , LUT [2]=%d , LUT[3]=%d",LUT[0],LUT[1],LUT[2],LUT[3]);
        Vps_printf("\nLUT[%d]=%d , LUT[%d]=%d , LUT [%d]=%d , LUT[%d]=%d\n",
                                        index-3,LUT[index-3],index-2,LUT[index-2],index-1,LUT[index-1],index,LUT[index-0]);
        Vps_printf("Number of elements in the LUT table : %d \n",index);
    }
    
    /**
     *******************************************************************************
     *
     * \brief   Set Sync Create Parameters
     *
     *          This function is used to set the sync params.
     *          It is called in Create function. It is advisable to have
     *          chains_lvdsVipMultiCamMirrorReplacement_ResetLinkPrm prior to set params
     *          so all the default params get set.
     *          Number of channels to be synced and sync delta and threshold.
     *
     * \param   pPrm    [OUT]    SyncLink_CreateParams
     *
     *******************************************************************************
    */
    static Void chains_lvdsVipMultiCamMirrorReplacement_SetSyncPrm(
                        SyncLink_CreateParams *pPrm,
                        UInt32 numLvdsCh
                        )
    {
        pPrm->syncDelta = SYNC_DELTA_IN_MSEC;
        pPrm->syncThreshold = SYNC_DROP_THRESHOLD_IN_MSEC;
    }
    
    /**
     *******************************************************************************
     *
     * \brief   Set LUT algorithm Create Parameters
     *
     *          It is called in Create function.
     *          In this function SwMs alg link params are set
     *          The algorithm which is to run on core is set to
     *          baseClassCreate.algId. The input whdth and height to alg are set.
     *          Number of input buffers required by alg are also set here.
     *
     *
     *******************************************************************************
    */
    static Void chains_lvdsVipMultiCamMirrorReplacement_SetAlgLutPrm(
                        AlgorithmLink_LutCreateParams *pPrm,
                        UInt32 numLvdsCh,
                        UInt32 displayWidth,
                        UInt32 displayHeight
                       )
    {
    
        
        /* Initializing link specific paramters */
        pPrm->maxOutBufWidth     = displayWidth;
        pPrm->maxOutBufHeight    = displayHeight;
        pPrm->numOutBuf          = 4;
        pPrm->useLocalEdma       = FALSE;
    
        pPrm->initLayoutParams.numWin = numLvdsCh;
        pPrm->initLayoutParams.outBufWidth  = pPrm->maxOutBufWidth;
        pPrm->initLayoutParams.outBufHeight = pPrm->maxOutBufHeight;
    
    }
    
    /**
     *******************************************************************************
     *
     * \brief   Set Framecopy Create Parameters
     *
     *          It is called in Create function.
     *          In this function framecopy alg link params are set
     *          The algorithm which is to run on core is set to
     *          baseClassCreate.algId. The input whdth and height to alg are set.
     *          Number of input buffers required by alg are also set here.
     *
     *
     *******************************************************************************
    */
    Void chains_lvdsVipMultiCamMirrorReplacement_SetStitchAlgPrms(
                                        AlgorithmLink_StitchCreateParams *pPrm,
                                          Chains_Ctrl *chainsCfg)
    {
        /* Setting algorithm ID for the link */
        if( chainsCfg->algProcId == SYSTEM_PROC_DSP1
                 ||
                 chainsCfg->algProcId == SYSTEM_PROC_DSP2)
                 {
                     pPrm->baseClassCreate.algId = ALGORITHM_LINK_DSP_ALG_FRAMECOPY;
                 }
        else if( chainsCfg->algProcId == SYSTEM_PROC_EVE1
                 ||
                 chainsCfg->algProcId == SYSTEM_PROC_EVE2
                 ||
                 chainsCfg->algProcId == SYSTEM_PROC_EVE3
                 ||
                 chainsCfg->algProcId == SYSTEM_PROC_EVE4)
                {
                    pPrm->baseClassCreate.algId = ALGORITHM_LINK_EVE_ALG_FRAMECOPY;
                }
        else if(chainsCfg->algProcId == SYSTEM_PROC_A15_0)
                {
                    pPrm->baseClassCreate.algId = ALGORITHM_LINK_A15_ALG_FRAMECOPY;
                }
    
        pPrm->maxWidth    = CAPTURE_SENSOR_WIDTH;
        pPrm->maxHeight   = CENTRE_LCD_HEIGHT;
    
        pPrm->numOutputFrames = 3;
    }
    
    /**
     *******************************************************************************
     *
     * \brief   Set CrModule Create Parameters
     *
     *          It is called in Create function.
     *          In this function Centre Right Seamline alg link params are set
     *          The algorithm which is to run on core is set to
     *          baseClassCreate.algId. The input whdth and height to alg are set.
     *          Number of input buffers required by alg are also set here.
     *
     *
     *******************************************************************************
    */
    Void chains_lvdsVipMultiCamMirrorReplacement_SetCrModuleAlgPrms(
                                        AlgorithmLink_CrModuleCreateParams *pPrm)
    {
    	
    	/* Setting algorithm ID for the link */
    	pPrm->baseClassCreate.algId = ALGORITHM_LINK_DSP_ALG_CRMODULE;
    
    	pPrm->maxWidth    = CAPTURE_SENSOR_WIDTH;
    	pPrm->maxHeight   = CAPTURE_SENSOR_HEIGHT;
    
            pPrm->numOutputFrames = 3;
    }
    
    /**
     *******************************************************************************
     *
     * \brief   Set LcModule Create Parameters
     *
     *          It is called in Create function.
     *          In this function Left Centre Seamline alg link params are set
     *          The algorithm which is to run on core is set to
     *          baseClassCreate.algId. The input whdth and height to alg are set.
     *          Number of input buffers required by alg are also set here.
     *
     *
     *******************************************************************************
    */
    Void chains_lvdsVipMultiCamMirrorReplacement_SetLcModuleAlgPrms(
                                        AlgorithmLink_LcModuleCreateParams *pPrm)
    {
    	
    	/* Setting algorithm ID for the link */
    	pPrm->baseClassCreate.algId = ALGORITHM_LINK_DSP_ALG_LCMODULE;
    
    	pPrm->maxWidth    = CAPTURE_SENSOR_WIDTH;
    	pPrm->maxHeight   = CAPTURE_SENSOR_HEIGHT;
    
            pPrm->numOutputFrames = 3;
    }
    
    /**
     *******************************************************************************
     *
     * \brief   Set Left LCD View Change Create Parameters
     *
     *          It is called in Create function.
     *          In this function Left LCD View Change alg link params are set
     *          The algorithm which is to run on core is set to
     *          baseClassCreate.algId. The input whdth and height to alg are set.
     *          Number of input buffers required by alg are also set here.
     *
     *
     *******************************************************************************
    */
    Void chains_lvdsVipMultiCamMirrorReplacement_SetLeftLcdViewChangeAlgPrms(
                                        AlgorithmLink_LeftLcdViewChangeCreateParams *pPrm)
    {
        
        /* Setting algorithm ID for the link */
        pPrm->baseClassCreate.algId = ALGORITHM_LINK_A15_ALG_LEFTLCDVIEWCHANGE;
    
        pPrm->maxWidth    = 800;
        pPrm->maxHeight   = 480;
    
        pPrm->numOutputFrames = 3;
    }
    
    /**
     *******************************************************************************
     *
     * \brief   Set Right LCD View Change Create Parameters
     *
     *          It is called in Create function.
     *          In this function Right LCD View Change alg link params are set
     *          The algorithm which is to run on core is set to
     *          baseClassCreate.algId. The input whdth and height to alg are set.
     *          Number of input buffers required by alg are also set here.
     *
     *
     *******************************************************************************
    */
    Void chains_lvdsVipMultiCamMirrorReplacement_SetRightLcdViewChangeAlgPrms(
                                        AlgorithmLink_RightLcdViewChangeCreateParams *pPrm)
    {
        
        /* Setting algorithm ID for the link */
        pPrm->baseClassCreate.algId = ALGORITHM_LINK_A15_ALG_RIGHTLCDVIEWCHANGE;
    
        pPrm->maxWidth    = 800;
        pPrm->maxHeight   = 480;
    
        pPrm->numOutputFrames = 3;
    }
    
    
    /**
     *******************************************************************************
     *
     * \brief   Set Select Link Create Parameters
     *
     *          This function is used to set the Select link params.
     *          It is called in Create function. It is advisable to have
     *          chains_lvdsVipDualCam_DualDisplay_ResetLinkPrms prior to set params
     *          so all the default params get set.
     *
     * \param   pPrm         [IN]    SelectLink_CreateParams
     *
     *******************************************************************************
    */
    Void chains_lvdsVipMultiCamMirrorReplacement_SetSelectlinkPrms(SelectLink_CreateParams *pPrm)
    {
        pPrm->numOutQue = 2;  
        
        pPrm->outQueChInfo[0].outQueId   = 0;
        pPrm->outQueChInfo[0].numOutCh   = 1;
        pPrm->outQueChInfo[0].inChNum[0] = 0;
    
        pPrm->outQueChInfo[1].outQueId   = 1;
        pPrm->outQueChInfo[1].numOutCh   = 1;
        pPrm->outQueChInfo[1].inChNum[0] = 1;
    }
    
    /**
     *******************************************************************************
     *
     * \brief   Set Display Create Parameters for all LCD's
     *
     *          This function is used to set the Display params.
     *          It is called in Create function. It is advisable to have
     *          chains_lvdsVipDualCam_DualDisplay_ResetLinkPrms prior to set params
     *          so all the default params get set.
     *
     * \param   pPrm         [IN]    DisplayLink_CreateParams
     *
     *******************************************************************************
    */
    Void chains_lvdsVipMultiCamMirrorReplacement_SetDisplayPrms(
                                        DisplayLink_CreateParams *pPrm_VideoLCD1,
                                        DisplayLink_CreateParams *pPrm_VideoLCD2,
                                        DisplayLink_CreateParams *pPrm_VideoLCD3,
                                        UInt32 displayWidthLCD,
                                        UInt32 displayHeightLCD
                                         
                                        )                                    
    {
    
        if(pPrm_VideoLCD1)
        {
            pPrm_VideoLCD1->rtParams.tarWidth         = 800;
            pPrm_VideoLCD1->rtParams.tarHeight        = 480;
            pPrm_VideoLCD1->displayId                 = DISPLAY_LINK_INST_DSS_VID1;
        }
    
         if(pPrm_VideoLCD2)
        {
            pPrm_VideoLCD2->rtParams.tarWidth         = 800;
            pPrm_VideoLCD2->rtParams.tarHeight        = 480;
            pPrm_VideoLCD2->displayId                 = DISPLAY_LINK_INST_DSS_VID2;
        }
    
        if(pPrm_VideoLCD3)
        {
            pPrm_VideoLCD3->rtParams.tarWidth         = 1280;
            pPrm_VideoLCD3->rtParams.tarHeight        = 320;
            pPrm_VideoLCD3->displayId                 = DISPLAY_LINK_INST_DSS_VID3;
        }
    }
    
    /**
     *******************************************************************************
     *
     * \brief   Set link Parameters
     *
     *          It is called in Create function of the auto generated use-case file.
     *
     * \param pUcObj    [IN] Auto-generated usecase object
     * \param appObj    [IN] Application specific object
     *
     *******************************************************************************
    */
    Void chains_lvdsVipMultiCamMirrorReplacement_SetAppPrms(chains_lvdsVipMultiCamMirrorReplacementObj *pUcObj, Void *appObj)
    {
    
    
    
    
        chains_lvdsVipMultiCamMirrorReplacementAppObj *pObj
            = (chains_lvdsVipMultiCamMirrorReplacementAppObj*)appObj;
    
        UInt32 portId[VIDEO_SENSOR_MAX_LVDS_CAMERAS];
    
        /* Initializing the seamline values to zero*/
        pUcObj->centreRightSeamline=0;
        pUcObj->leftCentreSeamline=0;
        
        /* Assigning the address of 'centreRightSeamline' variable to centre right module algorithm object */
        pUcObj->Alg_CrModulePrm.centreRightSeamline = &(pUcObj->centreRightSeamline);
        /* Assigning the address of 'leftCentreSeamline' variable to left centre module algorithm object */
        pUcObj->Alg_LcModulePrm.leftCentreSeamline = &(pUcObj->leftCentreSeamline);
    
        /* Assigning the address of 'centreRightSeamline' variable to stitch algorithm object */
        pUcObj->Alg_StitchPrm.centreRightSeamline = &(pUcObj->centreRightSeamline);
        /* Assigning the address of 'leftCentreSeamline' variable to stitch algorithm object */
        pUcObj->Alg_StitchPrm.leftCentreSeamline = &(pUcObj->leftCentreSeamline);
    
        /* Passing on the view selection byte to algorithms */
        pUcObj->Alg_LutPrm.lutSpiData = &(ucSpiData);
        pUcObj->Alg_LcModulePrm.lcSpiData = &(ucSpiData);
        pUcObj->Alg_CrModulePrm.crSpiData = &(ucSpiData);
        pUcObj->Alg_StitchPrm.stitchSpiData = &(ucSpiData);
    
        /* Passing on the Y0 cropping byte to algorithm (for TOP camera) */
        pUcObj->Alg_StitchPrm.configureCropY0 = &(ucSpiCropDataTopY);
    
        /* Passing on the Y0 cropping byte to algorithm (for LEFT camera) */
        pUcObj->Alg_LeftLcdViewChangePrm.leftLcdY0 = &(ucSpiCropDataLeftY);
        
        /* Passing on the X0 cropping byte to algorithm (for LEFT camera) */
        pUcObj->Alg_LeftLcdViewChangePrm.leftLcdX0 = &(ucSpiCropDataLeftX);
        
        /* Passing on the Y0 cropping byte to algorithm (for RIGHT camera) */
        pUcObj->Alg_RightLcdViewChangePrm.rightLcdY0 = &(ucSpiCropDataRightY);
        
        /* Passing on the X0 cropping byte to algorithm (for RIGHT camera) */
        pUcObj->Alg_RightLcdViewChangePrm.rightLcdX0 = &(ucSpiCropDataRightX);
        
        
        
         UInt32 *llut,*rlut,*clut,*cd,*length,*size;
    
    
        /* Logic for QSPI read and write starts */
        
        /* 
        // QSPI write starts 
        //UNCOMMENT THE BELOW CODE IF YOU WISH TO WRITE TO QSPI
        
    
        Int32 fileHandle;
        
        // Allocate 6 buffers to read 6 lut files from SD card    
        char *qspiWriteLeftLutBuff      = NULL;
        char *qspiWriteRightLutBuff     = NULL;
        char *qspiWriteCentreLutBuff    = NULL;
        char *qspiWriteLutSizeBuff      = NULL;
        char *qspiWriteLutCdBuff        = NULL;
        char *qspiWriteLutLengthBuff    = NULL;
       
        qspiWriteLeftLutBuff = Utils_memAlloc(
                                     UTILS_HEAPID_DDR_CACHED_SR,
                                     gLlutFileSize,
                                     32);
        UTILS_assert(qspiWriteLeftLutBuff != NULL);
                    
        qspiWriteRightLutBuff = Utils_memAlloc(
                                      UTILS_HEAPID_DDR_CACHED_SR,
                                      gRlutFileSize,
                                      32);
        UTILS_assert(qspiWriteRightLutBuff != NULL);
    
        qspiWriteCentreLutBuff = Utils_memAlloc(
                                   UTILS_HEAPID_DDR_CACHED_SR,
                                   gClutFileSize,
                                   32);
        UTILS_assert(qspiWriteCentreLutBuff != NULL);
    
        qspiWriteLutSizeBuff = Utils_memAlloc(
                                   UTILS_HEAPID_DDR_CACHED_SR,
                                   gSizeFileSize,
                                   32);
        UTILS_assert(qspiWriteLutSizeBuff != NULL);
    
        qspiWriteLutCdBuff = Utils_memAlloc(
                                   UTILS_HEAPID_DDR_CACHED_SR,
                                   gCdFileSize,
                                   32);
        UTILS_assert(qspiWriteLutCdBuff != NULL);
    
        qspiWriteLutLengthBuff = Utils_memAlloc(
                                   UTILS_HEAPID_DDR_CACHED_SR,
                                   gLengthFileSize,
                                  32);
        UTILS_assert(qspiWriteLutLengthBuff != NULL);
    
    
    
    
        //Open the file containing left look-up table from SD card
        fileHandle = File_open(gFileNameLlut, FILE_MODE);
        if(fileHandle < 0)
        {
        Vps_printf(" FILE OPEN ERROR: Could not open the left look-up table file from SD card!!! \n");
        }
        else
        {
        Vps_printf(" FILE OPEN SUCCESSFUL: Left look-up table file opened successfully from SD Card \n");
        }
    
        Vps_printf(" Copying the left look-up table from SD card to local buffer. \n");
        
        //Copy the left look-up table to 'qspiWriteLeftLutBuff'
    
        File_gets(qspiWriteLeftLutBuff,gLlutFileSize,fileHandle);
        
        Vps_printf(" Copied the contents of left look-up table into local buffer ! \n");
        
        
        //Initialize the QSPI before writing to it  
        System_qspiInit();
        
        //Write the data from 'qspiWriteLeftLutBuff' to QSPI location pointed to by 'gLlutOffset'
        System_qspiWriteSector(
                      gLlutOffset, 
                      (UInt32)((UInt32 *)qspiWriteLeftLutBuff) ,
                      gLlutFileSize);
    
        Vps_printf(" Left look-up table written from SD card to QSPI ! \n");
        
        //Close the left look-up table file
        File_close(fileHandle);
            
       
    
        //Open the file containing right look-up table from SD card
        fileHandle = File_open(gFileNameRlut, FILE_MODE);
        if(fileHandle < 0)
        {
        Vps_printf(" FILE OPEN ERROR: Could not open right LUT file from SD card!!! \n");
        }
        else
        {
        Vps_printf(" FILE OPEN SUCCESSFUL: Right LUT file opened successfully from SD Card \n");
        }
    
        Vps_printf(" Copying the right look-up table from SD card to local buffer. \n");
        
        //Copy the right look-up table to 'qspiWriteRightLutBuff'
        File_gets(qspiWriteRightLutBuff,gRlutFileSize,fileHandle);
        
        Vps_printf(" Copied the contents of right look-up table into local buffer ! \n");
    
        //Initialize the QSPI before writing to it  
        System_qspiInit();
        
        //Write the data from 'qspiWriteRightLutBuff' to QSPI location pointed to by 'gRlutOffset' 
        System_qspiWriteSector(
                      gRlutOffset, 
                      (UInt32)((UInt32 *)qspiWriteRightLutBuff),
                      gRlutFileSize);
    
        Vps_printf(" Right look-up table written from SD card to QSPI ! \n");
    
        //Close the right look-up table file
        File_close(fileHandle);
    
    
    
     
            
        //Open the file containing centre look-up table from SD card
        fileHandle = File_open(gFileNameClut, FILE_MODE);       
        if(fileHandle < 0)
        {
        Vps_printf(" FILE OPEN ERROR: Could not open centre LUT file from SD card!!! \n");
        }
        else
        {
        Vps_printf(" FILE OPEN SUCCESSFUL: Centre LUT file opened successfully from SD Card \n");
        }
    
        Vps_printf(" Copying the centre look-up table from SD card to local buffer. \n");
        
        //Copy the centre look-up table to 'qspiWriteRightLutBuff'
        File_gets(qspiWriteCentreLutBuff,gClutFileSize,fileHandle);
        
        Vps_printf(" Copied the contents of centre look-up table into local buffer ! \n");
    
        //Initialize the QSPI before writing to it  
        System_qspiInit();
        
        //Write the data from 'qspiWriteCentreLutBuff' to QSPI location pointed to by 'gClutOffset'     
        System_qspiWriteSector(
                      gClutOffset, 
                      (UInt32)((UInt32 *)qspiWriteCentreLutBuff),
                      gClutFileSize);
    
        Vps_printf(" Centre look-up table written from SD card to QSPI ! \n");
    
        //Close the centre look-up table file
        File_close(fileHandle);
      
    
       //Open the file containing size table from SD card
        fileHandle = File_open(gFileNameSize, FILE_MODE);       
        if(fileHandle < 0)
        {
        Vps_printf(" FILE OPEN ERROR: Could not open size file from SD card!!! \n");
        }
        else
        {
        Vps_printf(" FILE OPEN SUCCESSFUL: size file opened successfully from SD Card \n");
        }
    
        Vps_printf(" Copying the size table from SD card to local buffer. \n");
        
        //Copy the size table to 'qspiWriteLutSizeBuff'
        File_gets(qspiWriteLutSizeBuff,gSizeFileSize,fileHandle);
        
        Vps_printf(" Copied the contents of size table into local buffer ! \n");
    
        //Initialize the QSPI before writing to it  
        System_qspiInit();
        
        //Write the data from 'qspiWriteLutSizeBuff' to QSPI location pointed to by 'gSizeOffset'     
        System_qspiWriteSector(
                      gSizeOffset, 
                      (UInt32)((UInt32 *)qspiWriteLutSizeBuff),
                      gSizeFileSize);
    
        Vps_printf(" size table written from SD card to QSPI ! \n");
    
        //Close the size table file
        File_close(fileHandle);
      
    
    
        //Open the file containing cd table from SD card
        fileHandle = File_open(gFileNameCd, FILE_MODE);       
        if(fileHandle < 0)
        {
        Vps_printf(" FILE OPEN ERROR: Could not open cd file from SD card!!! \n");
        }
        else
        {
        Vps_printf(" FILE OPEN SUCCESSFUL: cd file opened successfully from SD Card \n");
        }
    
        Vps_printf(" Copying the cd table from SD card to local buffer. \n");
        
        //Copy the cd table to 'qspiWriteRightLutBuff'
        File_gets(qspiWriteLutCdBuff,gCdFileSize,fileHandle);
        
        Vps_printf(" Copied the contents of cd table into local buffer ! \n");
    
        //Initialize the QSPI before writing to it  
        System_qspiInit();
        
        //Write the data from 'qspiWriteLutCdBuff' to QSPI location pointed to by 'gCdOffset'     
        System_qspiWriteSector(
                      gCdOffset, 
                      (UInt32)((UInt32 *)qspiWriteLutCdBuff),
                      gCdFileSize);
    
        Vps_printf(" Cd table written from SD card to QSPI ! \n");
    
        //Close the cd table file
        File_close(fileHandle);
    
    
    
        //Open the file containing length table from SD card
        fileHandle = File_open(gFileNameLength, FILE_MODE);       
        if(fileHandle < 0)
        {
          Vps_printf(" FILE OPEN ERROR: Could not open length file from SD card!!! \n");
        }
        else
        {
          Vps_printf(" FILE OPEN SUCCESSFUL: length file opened successfully from SD Card \n");
        }
    
        Vps_printf(" Copying the length table from SD card to local buffer. \n");
        
        //Copy the length table to 'qspiWriteLutCdBuff'
        File_gets(qspiWriteLutLengthBuff,gLengthFileSize,fileHandle);
        
        Vps_printf(" Copied the contents of length table into local buffer ! \n");
    
        //Initialize the QSPI before writing to it  
        System_qspiInit();
        
        //Write the data from 'qspiWriteLutLengthBuff' to QSPI location pointed to by 'gLengthOffset'     
        System_qspiWriteSector(
                      gLengthOffset, 
                      (UInt32)((UInt32 *)qspiWriteLutLengthBuff),
                      gLengthFileSize);
    
        Vps_printf(" length table written from SD card to QSPI ! \n");
    
        //Close the length table file
        File_close(fileHandle);
    
        */
        /* QSPI write ends */
        
        /* QSPI read starts */
        
        /* Local buffers to read left look-up table from QSPI */
        char *qspiReadLeftLutBuff   = NULL;
        /* Local buffers to read right look-up table from QSPI */
        char *qspiReadRightLutBuff  = NULL;
        /* Local buffers to read centre look-up table from QSPI */
        char *qspiReadCentreLutBuff = NULL;
    
         /* Local buffers to read size table from QSPI */
        char *qspiReadLutSizeBuff   = NULL;
        /* Local buffers to read cd table from QSPI */
        char *qspiReadLutCdBuff  = NULL;
        /* Local buffers to read length table from QSPI */
        char *qspiReadLutLengthBuff = NULL;
    
    
        /* Allocating memory to the length table buffer pointer.
         * This buffer will then be used by the algorithm that does operations  
         * on the length table.
         */
        length = Utils_memAlloc(
                       UTILS_HEAPID_DDR_CACHED_SR,
                       100,
                       32);
    
          /* Allocating memory to length table local buffer */    
        qspiReadLutLengthBuff = Utils_memAlloc(
                                          UTILS_HEAPID_DDR_CACHED_SR,
                                          gLengthFileSize,
                                          32);
        UTILS_assert(qspiReadLutLengthBuff != NULL);
    
    
    
        Vps_printf("**********************************************************\n");
        Vps_printf("\nReading length table file from QSPI\n");
    
        /* Reading the length table from QSPI */
        System_qspiReadSector( 
                     (UInt32)(((UInt32 *)qspiReadLutLengthBuff)),
                     gLengthOffset,
                     SystemUtils_align(32U , SYSTEM_QSPI_READ_WRITE_SIZE*gLengthReadBlocks));
                     
        Vps_printf("\nlength table file read successfully\n");
    
        /* Function call to store the look-up table string into an integer array  */
        chains_lvdsVipMultiCamMirrorReplacement_ConvertToArray((UInt8 *)qspiReadLutLengthBuff, length);
    
        Vps_printf("**********************************************************\n");
    
        
        
        /* Allocating memory to the left look-up table buffer pointer.
         * This buffer will then be used by the algorithm that does operations  
         * on the left look-up table.
         */
        llut = Utils_memAlloc(
                    UTILS_HEAPID_DDR_CACHED_SR,
                    length[0]<<4,
                    32);
        
        /* Allocating memory to the right look-up table buffer pointer.
         * This buffer will then be used by the algorithm that does operations  
         * on the right look-up table.
         */              
        rlut = Utils_memAlloc(
                       UTILS_HEAPID_DDR_CACHED_SR,
                       length[2]<<4,
                       32);
        
        /* Allocating memory to the centre look-up table buffer pointer.
         * This buffer will then be used by the algorithm that does operations  
         * on the centre look-up table.
         */
        clut = Utils_memAlloc(
                       UTILS_HEAPID_DDR_CACHED_SR,
                       length[1]<<4,
                       32);
    
    
    
         /* Allocating memory to the size table buffer pointer.
         * This buffer will then be used by the algorithm that does operations  
         * on the size table.
         */
        size = Utils_memAlloc(
                       UTILS_HEAPID_DDR_CACHED_SR,
                       100,
                       32);
    
        /* Allocating memory to the cd table buffer pointer.
         * This buffer will then be used by the algorithm that does operations  
         * on the cd table.
         */
        cd = Utils_memAlloc(
                       UTILS_HEAPID_DDR_CACHED_SR,
                       100,
                       32);
    
        
    
    
        
        /* Allocating memory to left look-up table local buffer */    
        qspiReadLeftLutBuff = Utils_memAlloc(
                            UTILS_HEAPID_DDR_CACHED_SR,
                            gLlutFileSize,
                            32);
        UTILS_assert(qspiReadLeftLutBuff != NULL);
    
        /* Allocating memory to right look-up table local buffer */    
        qspiReadRightLutBuff = Utils_memAlloc(
                                         UTILS_HEAPID_DDR_CACHED_SR,
                                         gRlutFileSize,
                                         32);
        UTILS_assert(qspiReadRightLutBuff != NULL);
    
        /* Allocating memory to centre look-up table local buffer */    
        qspiReadCentreLutBuff = Utils_memAlloc(
                                          UTILS_HEAPID_DDR_CACHED_SR,
                                          gClutFileSize,
                                          32);
        UTILS_assert(qspiReadCentreLutBuff != NULL);
    
    
         /* Allocating memory to size table local buffer */    
        qspiReadLutSizeBuff = Utils_memAlloc(
                                          UTILS_HEAPID_DDR_CACHED_SR,
                                          gSizeFileSize,
                                          32);
        UTILS_assert(qspiReadLutSizeBuff != NULL);
    
         /* Allocating memory to cd table local buffer */    
        qspiReadLutCdBuff = Utils_memAlloc(
                                          UTILS_HEAPID_DDR_CACHED_SR,
                                          gCdFileSize,
                                          32);
        UTILS_assert(qspiReadLutCdBuff != NULL);
    
       
    
    
            
        Vps_printf("**********************************************************\n");
        Vps_printf("\nReading left look-up table file from QSPI\n");
        
        /* Reading the left look-up table from QSPI */
        System_qspiReadSector( 
                     (UInt32)(((UInt32 *)qspiReadLeftLutBuff)),
                     gLlutOffset,
                     SystemUtils_align(32U , SYSTEM_QSPI_READ_WRITE_SIZE*gLlutReadBlocks));
                     
        Vps_printf("\nLeft look-up table file read successfully\n");
        
        /* Function call to store the look-up table string into an integer array  */
        chains_lvdsVipMultiCamMirrorReplacement_ConvertToArray((UInt8 *)(qspiReadLeftLutBuff), llut);
        
        Vps_printf("**********************************************************\n");
    
    
    
    
    
                     
        Vps_printf("**********************************************************\n");
        Vps_printf("\nReading right look-up table file from QSPI\n");
        
        /* Reading the right look-up table from QSPI */
        System_qspiReadSector( 
                     (UInt32)(((UInt32 *)qspiReadRightLutBuff)),
                     gRlutOffset,
                     SystemUtils_align(32U , SYSTEM_QSPI_READ_WRITE_SIZE*gRlutReadBlocks));
                     
        Vps_printf("\nRight look-up table file read successfully\n");
    
        /* Function call to store the look-up table string into an integer array  */
        chains_lvdsVipMultiCamMirrorReplacement_ConvertToArray((UInt8 *)qspiReadRightLutBuff, rlut); 
        
        Vps_printf("**********************************************************\n");      
            
       
    
    
    
        Vps_printf("**********************************************************\n");
        Vps_printf("\nReading centre look-up table file from QSPI\n");
    
        /* Reading the centre look-up table from QSPI */
        System_qspiReadSector( 
                     (UInt32)(((UInt32 *)qspiReadCentreLutBuff)),
                     gClutOffset,
                     SystemUtils_align(32U , SYSTEM_QSPI_READ_WRITE_SIZE*gClutReadBlocks));
                     
        Vps_printf("\nCentre look-up table file read successfully\n");
    
        /* Function call to store the look-up table string into an integer array  */
        chains_lvdsVipMultiCamMirrorReplacement_ConvertToArray((UInt8 *)qspiReadCentreLutBuff, clut);
    
        Vps_printf("**********************************************************\n");
    
    
        
    
        Vps_printf("**********************************************************\n");
        Vps_printf("\nReading size table file from QSPI\n");
    
        /* Reading the size table from QSPI */
        System_qspiReadSector( 
                     (UInt32)(((UInt32 *)qspiReadLutSizeBuff)),
                     gSizeOffset,
                     SystemUtils_align(32U , SYSTEM_QSPI_READ_WRITE_SIZE*gSizeReadBlocks));
                     
        Vps_printf("\nsize table file read successfully\n");
    
        /* Function call to store the look-up table string into an integer array  */
        chains_lvdsVipMultiCamMirrorReplacement_ConvertToArray((UInt8 *)qspiReadLutSizeBuff, size);
    
        Vps_printf("**********************************************************\n");
    
    
        
    
        Vps_printf("**********************************************************\n");
        Vps_printf("\nReading cd table file from QSPI\n");
    
        /* Reading the cd table from QSPI */
        System_qspiReadSector( 
                     (UInt32)(((UInt32 *)qspiReadLutCdBuff)),
                     gCdOffset,
                     SystemUtils_align(32U , SYSTEM_QSPI_READ_WRITE_SIZE*gCdReadBlocks));
                     
        Vps_printf("\ncd table file read successfully\n");
    
        /* Function call to store the look-up table string into an integer array  */
        chains_lvdsVipMultiCamMirrorReplacement_ConvertToArray((UInt8 *)qspiReadLutCdBuff, cd);
    
        Vps_printf("**********************************************************\n");
    
    
        
        
        /* QSPI read ends */
        
        /* Logic for QSPI read and write ends */
    
        
    
        
        
        pObj->displayActiveChId = 0;
    
        pObj->numLvdsCh = pObj->chainsCfg->numLvdsCh;
        /* Limit max LVDS channels to 4 */
        if(pObj->numLvdsCh > VIDEO_SENSOR_NUM_LVDS_CAMERAS)
            pObj->numLvdsCh = VIDEO_SENSOR_NUM_LVDS_CAMERAS;
    
        pObj->captureOutWidth  = CAPTURE_SENSOR_WIDTH;
        pObj->captureOutHeight = CAPTURE_SENSOR_HEIGHT;
        
        ChainsCommon_GetDisplayWidthHeight(
            pObj->chainsCfg->displayType,
            &pObj->displayWidth,
            &pObj->displayHeight
            );
    
    
        ChainsCommon_MultiCam_StartCaptureDevice(
            pObj->chainsCfg->captureSrc,
            portId,
            pObj->numLvdsCh
            );
    
        ChainsCommon_MultiCam_SetCapturePrms(&pUcObj->CapturePrm,
                CAPTURE_SENSOR_WIDTH,
                CAPTURE_SENSOR_HEIGHT,
                portId,
                pObj->numLvdsCh
                );
    
        
        chains_lvdsVipMultiCamMirrorReplacement_SetSyncPrm(
                    &pUcObj->SyncPrm,
                    pObj->numLvdsCh
            );
    
        chains_lvdsVipMultiCamMirrorReplacement_SetAlgLutPrm(
                                &pUcObj->Alg_LutPrm,
                                pObj->numLvdsCh,
                                CAPTURE_SENSOR_WIDTH,
                                CAPTURE_SENSOR_HEIGHT
                                );
                                
        pUcObj->Alg_LutPrm.llut = llut;
        pUcObj->Alg_LutPrm.rlut = rlut;
        pUcObj->Alg_LutPrm.clut = clut;
        pUcObj->Alg_LutPrm.length = length;
        pUcObj->Alg_LutPrm.cd = cd;
        pUcObj->Alg_LutPrm.size = size;
    
        chains_lvdsVipMultiCamMirrorReplacement_SetStitchAlgPrms
                                                        (&pUcObj->Alg_StitchPrm,
                                                                pObj->chainsCfg);
                                                                
        pUcObj->Alg_StitchPrm.cd = cd;
        pUcObj->Alg_StitchPrm.size = size;
    
    
    
        chains_lvdsVipMultiCamMirrorReplacement_SetCrModuleAlgPrms
                                                        (&pUcObj->Alg_CrModulePrm);
                                                        
         pUcObj->Alg_CrModulePrm.cd = cd;
        pUcObj->Alg_CrModulePrm.size = size;    
    
    
        chains_lvdsVipMultiCamMirrorReplacement_SetLcModuleAlgPrms
                                                        (&pUcObj->Alg_LcModulePrm);
                                                        
         pUcObj->Alg_LcModulePrm.cd = cd;
        pUcObj->Alg_LcModulePrm.size = size;
    
    
        chains_lvdsVipMultiCamMirrorReplacement_SetSelectlinkPrms
        						    (&pUcObj->SelectPrm);
        
        chains_lvdsVipMultiCamMirrorReplacement_SetLeftLcdViewChangeAlgPrms
        						    (&pUcObj->Alg_LeftLcdViewChangePrm);
        
        chains_lvdsVipMultiCamMirrorReplacement_SetRightLcdViewChangeAlgPrms
        						    (&pUcObj->Alg_RightLcdViewChangePrm);
    
    /*
        ChainsCommon_SetGrpxSrcPrms(&pUcObj->GrpxSrcPrm,
                                                   pObj->displayWidth,
                                                   pObj->displayHeight
                                                  );
    
    
        ChainsCommon_SetDisplayPrms(&pUcObj->Display_videoPrm,
                                                   &pUcObj->Display_GrpxPrm,
                                                   pObj->chainsCfg->displayType,
                                                   pObj->displayWidth,
                                                   pObj->displayHeight
                                                    );
    
        ChainsCommon_StartDisplayCtrl(
            pObj->chainsCfg->displayType,
            pObj->displayWidth,
            pObj->displayHeight
            );
    */
    
        chains_lvdsVipMultiCamMirrorReplacement_SetDisplayPrms (&pUcObj->Display_leftLcdPrm,
                                                   &pUcObj->Display_rightLcdPrm,
                                                   &pUcObj->Display_videoPrm,
                                                   pObj->displayWidth,
                                                   pObj->displayHeight
                                                    );
        
        ChainsCommon_MirrorReplacement_StartDisplayCtrl(pObj->chainsCfg->displayType,
                                    	      pObj->displayWidth, 
                                    	      pObj->displayHeight
                                    	      );
                                    
        /* LED turn on to indicate start of the use-case */
        WR_MEM_32(0x4A003664, 0x0002000E);
    }
    
    /**
     *******************************************************************************
     *
     * \brief   Start the capture display Links
     *
     *          Function sends a control command to capture and display link to
     *          to Start all the required links . Links are started in reverce
     *          order as information of next link is required to connect.
     *          System_linkStart is called with LinkId to start the links.
     *
     * \param   pObj  [IN] chains_lvdsVipMultiCamMirrorReplacementObj
     *
     * \return  SYSTEM_LINK_STATUS_SOK on success
     *
     *******************************************************************************
    */
    static Void chains_lvdsVipMultiCamMirrorReplacement_StartApp(chains_lvdsVipMultiCamMirrorReplacementAppObj *pObj)
    {
        Chains_memPrintHeapStatus();
    
        ChainsCommon_StartDisplayDevice(pObj->chainsCfg->displayType);
    
        chains_lvdsVipMultiCamMirrorReplacement_Start(&pObj->ucObj);
    
        Chains_prfLoadCalcEnable(TRUE, FALSE, FALSE);
    }
    
    /**
     *******************************************************************************
     *
     * \brief   Delete the capture display Links
     *
     *          Function sends a control command to capture and display link to
     *          to delete all the prior created links
     *          System_linkDelete is called with LinkId to delete the links.
     *
     * \param   pObj   [IN]   chains_lvdsVipMultiCamMirrorReplacementObj
     *
     *******************************************************************************
    */
    static Void chains_lvdsVipMultiCamMirrorReplacement_StopAndDeleteApp(chains_lvdsVipMultiCamMirrorReplacementAppObj *pObj)
    {
        chains_lvdsVipMultiCamMirrorReplacement_Stop(&pObj->ucObj);
        chains_lvdsVipMultiCamMirrorReplacement_Delete(&pObj->ucObj);
    
        ChainsCommon_StopDisplayCtrl();
        ChainsCommon_StopCaptureDevice(pObj->chainsCfg->captureSrc);
        ChainsCommon_StopDisplayDevice(pObj->chainsCfg->displayType);
    
        /* Print the HWI, SWI and all tasks load */
        /* Reset the accumulated timer ticks */
        Chains_prfLoadCalcEnable(FALSE, TRUE, TRUE);
    }
    
    /* Call the GIO_issue to issue buffers from the driver for obtaining SPI data */
    static void prime(void)
    {
    
        Int32        count = 0;
        UInt32       tempCount = 0;
        UInt32       size      = 0;
        Int          status    = IOM_COMPLETED;
        UInt8        spiDummyDataCount;
        UInt8 spiDummyData[13]={0x00,0x20,0x09,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F};
        unsigned char data = 0x0F;
        
        /* Garbage data to be transmitted via SPI to the master, first time */
        if(garbageOnBoot == TRUE)
        {
           for (count = 0; count < (NUM_BUFS); count++)
           {
                for (tempCount = 0; tempCount < BUFLEN; tempCount++)
                {
                        ((Uint8 *) txbuf[count])[tempCount] = data;
                }
    
           }
           garbageOnBoot =FALSE;
        }
        
        /* Dummy data to be transmitted via SPI to the master, henceforth */
        else
        {
           for (count = 0; count < (NUM_BUFS); count++)
           {
                for (tempCount = 0,spiDummyDataCount=0; tempCount < BUFLEN; tempCount++)
                {
                   ((Uint8 *) txbuf[count])[tempCount] = spiDummyData[spiDummyDataCount++];
                   
                   if(spiDummyDataCount==13)
                       spiDummyDataCount=0;
                }
           }
        }
        
        for (count = 0; count < NUM_BUFS; count++)
        {
            issueDataparam[count].bufLen    = BUFLEN;
            issueDataparam[count].inBuffer  = rxbuf[count];
            issueDataparam[count].outBuffer = txbuf[count];
    
            size = issueDataparam[count].bufLen;
            
            /* Issue the first & second empty buffers to the input stream */
            status = GIO_issue(mcspiHandle, &issueDataparam[count], size, NULL);
    
            if (status != IOM_PENDING && status != IOM_COMPLETED)
            {
                Vps_printf("\r\nsatus =%d\r\n",status);
                Vps_printf("\r\nFailed to issue empty buffer to stream\r\n");
            }
            
            #if MIRROR_REPLACEMENT_DEBUGS_ON
            Vps_printf("\nIn prime\n");
            Vps_printf("SPI TDA2x-> MCU write frame reply\r\n");
            for(spiDummyDataCount=0;spiDummyDataCount<BUFLEN;spiDummyDataCount++ )
            {
                Vps_printf("SPI Data[%d byte]=0x%x\r\n", spiDummyDataCount,issueDataparam[count].outBuffer[spiDummyDataCount]);
    
            }
            #endif
        }
    }
    
    void user_mcspi_init(void)
    {
        Mcspi_init();
    
        mcspiPrms.opMode = MCSPI_OPMODE_INTERRUPT;
        mcspiPrms.instNum         = 0;
        mcspiPrms.hwiNumber       = 7;
        mcspiPrms.enableCache     = (UInt32) TRUE;
        mcspiPrms.edma3EventQueue = 0;
        mcspiPrms.enableErrIntr   = (UInt32) FALSE;
    
        mcspiPrms.spiHWCfgData.masterOrSlave         = MCSPI_COMMMODE_SLAVE;
        mcspiPrms.spiHWCfgData.singleOrMultiChEnable = MCSPI_SINGLE_CHANNEL;
        mcspiPrms.spiHWCfgData.pinOpModes    = MCSPI_PINOPMODE_4PIN;
        mcspiPrms.spiHWCfgData.fifoRxTrigLvl = 16;
        mcspiPrms.spiHWCfgData.fifoTxTrigLvl = 16;
        mcspiPrms.spiHWCfgData.configChfmt[0].charLength = MCSPI_LEN_8BIT;
        mcspiPrms.spiHWCfgData.configChfmt[0].multiWordAccessEnable =
            (UInt32) FALSE;
    
        mcspiPrms.spiHWCfgData.configChfmt[0].spiChipSelectEnablePol =
                (UInt32) FALSE;
    
        mcspiPrms.spiHWCfgData.configChfmt[0].clockMode           = MCSPI_MODE3;
        mcspiPrms.spiHWCfgData.configChfmt[0].clockRatioExtension = 0;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiWordInitDelay    = MCSPI_NO_DELAY;
        mcspiPrms.spiHWCfgData.configChfmt[0].trasmitReceiveMode  = MCSPI_BOTH_RXTX;
        mcspiPrms.spiHWCfgData.configChfmt[0].granularityEnable   = (UInt32) TRUE;
        mcspiPrms.spiHWCfgData.configChfmt[0].busFreq             =  200000;
        mcspiPrms.spiHWCfgData.configChfmt[0].spienHighPolarity   = (UInt32) FALSE;
        mcspiPrms.spiHWCfgData.configChfmt[0].slaveModeChipSelect = MCSPI_SPIEN_0;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiDat0Dir          = MCSPI_OUT;
        mcspiPrms.spiHWCfgData.configChfmt[0].spiDat1Dir          = MCSPI_IN;
    
        if (MCSPI_OPMODE_POLLED == mcspiPrms.opMode)
        {
            Vps_printf("\r\nMcspi is configured in polled mode\r\n");
        }
        else if (MCSPI_OPMODE_INTERRUPT == mcspiPrms.opMode)
        {
            Vps_printf("\r\nMcspi is configured in interrupt mode\r\n");
        }
        else if (MCSPI_OPMODE_DMAINTERRUPT == mcspiPrms.opMode)
        {
            Vps_printf("\r\nMcspi is configured in dma mode\r\n");
        }
        else
        {
            Vps_printf("\r\nError: unknown mode of operation!!!!!!!!!!\r\n");
        }
    
    }
    
    /* Initialize the SPI by setting appropriate values in the registers */
    void SPI_init(void)
    {
     GIO_addDevice("/mcspi0", (xdc_Ptr) &Mcspi_IOMFXNS, &user_mcspi_init, 0, (xdc_Ptr) & mcspiPrms);
    }
    
    
    Int32 App_mcspiDefaultInit(UInt32 isI2cInitReq)
    {
        Int32  retVal = BSP_SOK;
       
        return (retVal);
    }
    
    /* Allocate memory to the TX and RX buffers */
    static void memory_allocated(void)
    {
        Error_Block  eb;
        Int32        count = 0;
        IHeap_Handle iheap;
    
        iheap = HeapMem_Handle_to_xdc_runtime_IHeap(myHeap);
        Error_init(&eb);
    
        /* Allocate buffers for the GIO buffer exchanges */
        for (count = 0; count < (NUM_BUFS); count++)
        {
            rxbuf[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
            if (NULL == rxbuf[count])
            {
                Vps_printf("\r\nMEM_calloc failed.\r\n");
            }
            txbuf[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
            if (NULL == txbuf[count])
            {
                Vps_printf("\r\nMEM_calloc failed.\r\n");
            }
        }
    }
    
    /* Initialize the channel attributes and create input stream */
    static void createStream(void)
    {
        GIO_Params       ioParams;
        Mcspi_ChanParams chanParams;
        Error_Block      eb;
    
        Error_init(&eb);
    
        /*
         * Initialize channel attributes.
         */
        GIO_Params_init(&ioParams);
    
        /* update the Edma Handle                                                 */
        chanParams.hEdma = gEdmaHandle;
        chanParams.chipSelTimeControl = MCSPI_CLK_CYCLE0;
        chanParams.fifoEnable         = (UInt32) TRUE;
        chanParams.spiChipSelectHold  = (UInt32) TRUE;
        chanParams.chanNum = 0;
    
        /* Cross bar evt disabled */
        chanParams.crossBarEvtParam.isCrossBarIntEn  = (UInt32) FALSE;
        chanParams.crossBarEvtParam.intNumToBeMapped = 0xFF;  /* Invalid number */
    
        ioParams.chanParams = (Ptr) & chanParams;
        ioParams.model      = GIO_Model_ISSUERECLAIM;
        ioParams.numPackets = NUM_BUFS + 1;
    
        mcspiHandle = GIO_create("/mcspi0", GIO_INOUT, &ioParams, &eb);
        if (mcspiHandle == NULL)
        {
            Vps_printf("\r\nCreate input stream FAILED.\r\n");
            BIOS_exit(0);
        }
        Vps_printf("\r\nCreate input stream completed.\r\n");
    }
    
    /* Set board mux and pin mux */
    static void spiSampleTask(void)
    {
        Int32 retVal = FVID2_SOK;
    
        /* System init */
        gIsI2cInitReq = FALSE;
        retVal       = App_mcspiDefaultInit(gIsI2cInitReq);
        if (retVal != FVID2_SOK)
        {
            Vps_printf("Error: : System Init Failed!!!\r\n");
        }
    
        /* Set the pin Mux */
        Bsp_boardSetPinMux(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_0,
                           BSP_BOARD_MODE_DEFAULT);
        Vps_printf("\n ********************************Spi sample pin mux done\n");
    
        /* Set the board muxes */
        Bsp_boardSelectDevice(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_0);
    }
    
    /* 
     * Function to compute the checksum.
     * Validation is done to check if the recieved data is valid or invalid.
     */
    static Bool checkSum_Check(UInt8 *Buffer, UInt8 size)
    {
        UInt8 cal_checksum = 0, i; 
        UInt32 checksum=0;
        Bool validSpiFrame;
        
        /* Check the number of valid and invalid frames */
        static UInt32 validFrame=0;
        static UInt32 invalidFrame=0;
    
        for (i = 0; i < (size-1); i++)
        {
            checksum += Buffer[i];
        }
        
        /* Masking the 1st byte */
        checksum &= 0x000000ff;
        
        /* Calculating the checksum */
        cal_checksum = 0xff - checksum;
        
        #ifdef MIRROR_REPLACEMENT_DEBUGS_ON
        Vps_printf("\nInside checksum function. cal_checksum=%d\n",cal_checksum);
        Vps_printf("\nInside checksum function. Buffer[size-1]=%d\n",Buffer[size-1]);
        #endif
        
        /* Verifying the calculated checksum with received checksum */
        if (Buffer[size-1] == cal_checksum)
        {
        	validFrame++;
            validSpiFrame = TRUE;
        }
        else
        {
        	invalidFrame++;
            validSpiFrame = FALSE;
        }
        
        Vps_printf("\nvalid frame =%d \t invalid frame =%d \n",validFrame,invalidFrame);
        
        return validSpiFrame;
    }
    
    /* Turn the SPI Ready Pin HIGH */
    Void setSpiReadyHigh()
    {
        GPIOPinWrite(SOC_GPIO7_BASE, 24, GPIO_PIN_HIGH);
    }
    
    /* Turn the SPI Ready Pin LOW */
    Void setSpiReadyLow()
    {
        GPIOPinWrite(SOC_GPIO7_BASE, 24, GPIO_PIN_LOW);
    }
    
    /* Pin Muxing for SPI Ready PIN on TDA2X SOC */
    Void initSpiReady()
    {
    
        HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE+CTRL_CORE_PAD_UART1_CTSN,0x0006000E);
        HW_WR_REG32(SOC_L4PER_CM_CORE_BASE+CM_L4PER_GPIO7_CLKCTRL,0x102);
            
        while ((HW_RD_REG32(SOC_L4PER_CM_CORE_BASE+CM_L4PER_GPIO7_CLKCTRL) & (0x00030000U)) != 0x0) 
        { ; } 
        
        GPIOModuleReset(SOC_GPIO7_BASE); 
        GPIOModuleEnable(SOC_GPIO7_BASE); 
        GPIODirModeSet(SOC_GPIO7_BASE, 24, GPIO_DIR_OUTPUT);     
    }
    
    /* Start sending/receiving data via SPI.
     * THIS IS THE MAIN SPI FUNCTION.
     */ 
    Void getSpiData()
    {
        UInt32 i=0, tempCount = 0;
        /* Operate on the data received via SPI using this variable */
        UInt16 operateSpi=0;
        
        #ifdef MIRROR_REPLACEMENT_DEBUGS_ON
        UInt32 j=0;
        #endif
        
        UInt8 SPIdata[13] = {0};    
        volatile Int32   i32Count  = 0;
        Int  status = IOM_COMPLETED;
    
        /* Pin Muxing for SPI Ready PIN */     
        initSpiReady();
        /*SPI Init*/
        SPI_init();
        spiSampleTask();
        /* Initialize the channel attributes and create input stream */
        createStream();
        /* Allocate memory to the TX and RX buffers */
        memory_allocated();
        
        /* Check for SPI data continuosly via GIO_issue and GIO_reclaim calls */
        while(1)
        {
    
        /* Set the SPI Ready HIGH before issuing buffers */
        setSpiReadyHigh();
        /* Call the GIO_issue to issue buffers from the driver for obtaining SPI data.
         * Also fill the transmission buffer with dummy data 
         */
        prime();
        
        /* Call GIO_reclaim to reclaim as many buffers as were issued */
        for (i = 0; i < NUM_BUFS; i++)
        {
    	status = GIO_reclaim(mcspiHandle, (Ptr *)&issueDataparam[i], NULL, NULL);
            if (IOM_COMPLETED != status)
            {
                Vps_printf("Iteration %d\r\n", i32Count);
    
                Vps_printf(
                    "Error reclaiming empty buffer from the streams %x"
                    " error = 0x%d\r\n",
                    ((Uint8) (issueDataparam[i].outBuffer[i32Count])),
                    status);
                break;
            }
    
            for (tempCount = 0; tempCount < BUFLEN; )
            {
                if (mcspiPrms.spiHWCfgData.configChfmt[0].charLength <= 8)
                {
                    /* Fill SPIdata with Write Frame values i.e. the frame sent from MCU to SOC */
                    if( (issueDataparam[i].inBuffer[tempCount] == 0x00) && (issueDataparam[i].inBuffer[tempCount+1] == 0x22))
                    {
    
                        SPIdata[0]=issueDataparam[i].inBuffer[tempCount];
                        SPIdata[1]=issueDataparam[i].inBuffer[tempCount + 1];
                        SPIdata[2]=issueDataparam[i].inBuffer[tempCount + 2];
                        SPIdata[3]=issueDataparam[i].inBuffer[tempCount + 3];
                        SPIdata[4]=issueDataparam[i].inBuffer[tempCount + 4];
                        SPIdata[5]=issueDataparam[i].inBuffer[tempCount + 5];
                        SPIdata[6]=issueDataparam[i].inBuffer[tempCount + 6];
                        SPIdata[7]=issueDataparam[i].inBuffer[tempCount + 7];
                        SPIdata[8]=issueDataparam[i].inBuffer[tempCount + 8];
                        SPIdata[9]=issueDataparam[i].inBuffer[tempCount + 9];
                        SPIdata[10]=issueDataparam[i].inBuffer[tempCount + 10];
                        SPIdata[11]=issueDataparam[i].inBuffer[tempCount + 11];
                        SPIdata[12]=issueDataparam[i].inBuffer[tempCount + 12];
    
                       #ifdef MIRROR_REPLACEMENT_DEBUGS_ON
                       Vps_printf("SPI Master-> TDA2x Write Frame \r\n");
                                          
                       for(j=0;j<13;j++ )
                       {
                          Vps_printf("SPI Data[%d byte]=%x\r\n", j,SPIdata[j]);
                       }
                       #endif
                       
                       /* 
                        * Transfer the SPI values to algorithms only if the checksum is correct.
                        */
                       if (TRUE == (checkSum_Check(SPIdata, sizeof(SPIdata))))
                       {
                       
                                /* Assign the inside view selection data field to ucSpiData.
                        	    * This will be used across all agorithms.
                                * Views will be switched according to the value obtained.
                        	    * REFERENCE : SL SPI Guide.
                                */
                                ucSpiData = SPIdata[3];
         
    		           /* Allows the user to configure the Y-coordinate from where
    		            * cropping on the top camera image can start.
    		            */
    		            
    		           operateSpi = SPIdata[10];
    		           operateSpi <<= BYTE_SHIFT;
    		           operateSpi |= SPIdata[11];
    		           
    		           if (operateSpi > 400)
    		           	operateSpi = 400;
    		           
    		           ucSpiCropDataTopY = operateSpi;
    		           
    		           /* Allows the user to configure the X-coordinate from where
    		            * cropping on left camera image can start.
    		            */
    		           
    		           operateSpi = SPIdata[4];
    		           operateSpi <<= BYTE_SHIFT;
    		           operateSpi |= SPIdata[5];
    		           
    		           if (operateSpi > 480)
    		           	operateSpi = 480;
    		           
    		           ucSpiCropDataLeftX = operateSpi;
    			   
    			   /* Allows the user to configure the Y-coordinate from where
    		            * cropping on left camera image can start.
    		            */
    		           
    		           operateSpi = SPIdata[6];
    		           
    		           if (operateSpi > 240)
    		           	operateSpi = 240;
    		           
    		           ucSpiCropDataLeftY = operateSpi;
    			   
    			   /* Allows the user to configure the X-coordinate from where
    		            * cropping on right camera image can start.
    		            */
    		           
    		           operateSpi = SPIdata[7];
    		           operateSpi <<= BYTE_SHIFT;
    		           operateSpi |= SPIdata[8];
    		           
    		           if (operateSpi > 480)
    		           	operateSpi = 480;
    		           
    		           ucSpiCropDataRightX = operateSpi;
    			   
    			   /* Allows the user to configure the Y-coordinate from where
    		            * cropping on right camera image can start.
    		            */
    		           
    		           operateSpi = SPIdata[9];
    		           
    		           if (operateSpi > 240)
    		           	operateSpi = 240;
    		           
    		           ucSpiCropDataRightY = operateSpi;
    		   
                       }
                    }
                    
                    /* Fill SPIdata with Read Frame values i.e. the frame sent from SOC to MCU */
                    else if((issueDataparam[i].inBuffer[tempCount] == 0x01) && (issueDataparam[i].inBuffer[tempCount+1] == 0x22))
                    {
                        SPIdata[0]=issueDataparam[i].inBuffer[tempCount];
                        SPIdata[1]=issueDataparam[i].inBuffer[tempCount + 1];
                        SPIdata[2]=issueDataparam[i].inBuffer[tempCount + 2];
                        SPIdata[3]=issueDataparam[i].inBuffer[tempCount + 3];
                        SPIdata[4]=issueDataparam[i].inBuffer[tempCount + 4];
                        SPIdata[5]=issueDataparam[i].inBuffer[tempCount + 5];
                        SPIdata[6]=issueDataparam[i].inBuffer[tempCount + 6];
                        SPIdata[7]=issueDataparam[i].inBuffer[tempCount + 7];
                        SPIdata[8]=issueDataparam[i].inBuffer[tempCount + 8];
                        SPIdata[9]=issueDataparam[i].inBuffer[tempCount + 9];
                        SPIdata[10]=issueDataparam[i].inBuffer[tempCount + 10];
                        SPIdata[11]=issueDataparam[i].inBuffer[tempCount + 11];
                        SPIdata[12]=issueDataparam[i].inBuffer[tempCount + 12];
    
                        #ifdef MIRROR_REPLACEMENT_DEBUGS_ON
                        Vps_printf("SPI Read Frame\r\n");
                        for(j=0;j<13;j++ )
                        {
                           Vps_printf("SPI Data[%d byte]=%x\r\n", j,SPIdata[j]);
    
                        }
                        #endif
                    }
                }
                
                else
                {
                    Vps_printf("\nInvalid Frame\r\n");
    
                }
                tempCount++;
            }
          }
         /* Set the SPI Ready LOW after reclaiming all the issues buffers */
         setSpiReadyLow();
        }  
    }
    
    /* SPI De-Init kept commented as of now */
    #if 0
    static Int32 App_mcspiDefaultDeInit(UInt32 isI2cDeInitReq)
    {
        Int32  retVal = BSP_SOK;
    
        retVal += BspUtils_appDeInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: App Utils De-Init failed!!\r\n");
        }
    
        retVal += BspUtils_prfDeInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR,
                      "Error: App PRF Utils De-Init failed!!\r\n");
        }
    
        retVal += BspUtils_memDeInit();
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR,
                      "Error: App MEM Utils De-Init failed!!\r\n");
        }   
    
        retVal += Fvid2_deInit(NULL);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: FVID2 De-Init failed!!\r\n");
        }
    
        retVal += Bsp_platformDeInit(NULL);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR,
                      "Error: BSP Platform De-Init failed!!\r\n");
        }
    
        retVal += Bsp_boardDeInit(NULL);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: BSP Board De-Init failed!!\r\n");
        }
    
        retVal += Bsp_commonDeInit(NULL);
        if (BSP_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR, "Error: BSP Common De-Init failed!!\r\n");
        }
    
        return (retVal);
    }
    #endif
    
    /**
     *******************************************************************************
     *
     * \brief   Single Channel Capture Display usecase function
     *
     *          This functions executes the create, start functions
     *
     *          Further in a while loop displays run time menu and waits
     *          for user inputs to print the statistics or to end the demo.
     *
     *          Once the user inputs end of demo stop and delete
     *          functions are executed.
     *
     * \param   chainsCfg       [IN]   Chains_Ctrl/
     *
     *******************************************************************************
    */
    Void chains_lvdsVipMultiCamMirrorReplacement(Chains_Ctrl *chainsCfg)
    {
        char done=FALSE;
        char ch;
        chains_lvdsVipMultiCamMirrorReplacementAppObj chainsObj;
    
        chainsObj.numLvdsCh         = 0; /* KW error fix */
        chainsObj.displayActiveChId = 0; /* KW error fix */
        chainsObj.chainsCfg = chainsCfg;
        chainsObj.chainsCfg->numLvdsCh = 4;
    
        /* Create a seperate task to send and recive data via SPI */  
        Vps_printf("\nCalling SPI task\n");    
        Task_create((Task_FuncPtr) getSpiData, NULL, NULL);
           
        chains_lvdsVipMultiCamMirrorReplacement_Create(&chainsObj.ucObj, &chainsObj);
        chains_lvdsVipMultiCamMirrorReplacement_StartApp(&chainsObj);
    
        while(!done)
        {
             ch = Chains_menuRunTime();
             
             switch(ch)
             {
                case '0':
                    done = TRUE;
                    break;
                 case '1':
                     break;    
                default:
                    Vps_printf("\nUnsupported option '%c'. Please try again\n", ch);
                    break;    
    	      }
        }
    
        chains_lvdsVipMultiCamMirrorReplacement_StopAndDeleteApp(&chainsObj);
    }
    

  • Hi Rajesh,

    In your code the setSpiReadyHigh sets some GPIO pin, what is it used for?

    You can prime the buffers before the while, Then in the while loop you add 1 reclaim at the beginning and 1 issue at the end of the loop till you want to receive the data from external master.

    Regards,
    Prasad

  • Hi,

    setSpiReadyHigh sets pin high/low to send indication to MCD that SoC is ready for send/receive data.

    As I said earlier we would like to send/receive 13 byte data and after some work we found that making it 16 byte and setting buffer alignment and buffer size to 16 works for us in one direction (MCU -> SoC) but in reverse direction (SOC -> MCU) still data is received only once on MCU side for every two send from Soc.

    Please reply your feedback.

    Regards,

  • Hi,

    Can you change the GPIO toggle after the priming?

    Also as I mentioned earlier you need to issue 2 buffers at the beginning which is called priming.
    After this you can reclaim one buffer and issue one buffer in loop till you send/receive the desired number of bytes.
    Can you change the code flow as above and try?

    Regards,
    Prasad