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.

TDA4VM: After upgrading to sdk8.06, the camera images are all green

Part Number: TDA4VM

Hi, TI expert
We are using tda4vm and are currently performing a baseline upgrade from sdk8.02 (Linux&rtos) to sdk8.06 (Linux&rtos).
After the upgrade, running the camera demo (run_app_single_cam) is running normally from the log, but the captured camera images are all green. Please assist in investigating.

Thank you~!

  • Add captured image files 1280x920 uyvy4225287.cap_0000.zip

  • Hi jia wentao,

    I think there is a bug in the drive, can you please make below highlighted change in CsirxDrv_getDMACfgParams API in ti-processor-sdk-rtos-j721e-evm-08_06_00_12\pdk_jacinto_08_06_00_31\packages\ti\drv\csirx\src\csirx_drvUdma.c file and check the output?

    else if ((chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV420_10B) ||
    (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV422_10B) ||
    (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW10) ||
    (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW12) ||
    (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW14) ||
    (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW16) ||
    (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV422_8B))
    {
    if (createParams->instCfg.numPixelsStrm0 == 0U)
    {
    chObj->dmaCfgParams.dataSizeShift =
    (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_16BITS;
    }
    else if(createParams->instCfg.numPixelsStrm0 == 1U)
    {
    chObj->dmaCfgParams.dataSizeShift =
    (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_32BITS;
    }
    else if (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV422_8B)
    {
    chObj->dmaCfgParams.dataSizeShift =
    (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_8BITS;
    }
    else
    {
    /* Do nothing as above two conditions should be hit
    and check has done before entering this function */
    }
    }

    Regards,

    Brijesh

  • Hi,Brijesh

    After the modification, the same phenomenon still exists. The captured camera image is still green, and the attached file is my modified file.

    Can you help me check it?

    /*
     *  Copyright (c) Texas Instruments Incorporated 2018-2019
     *  All rights reserved.
     *
     *  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 csirx_drvUdma.c
     *
     *  \brief File containing the CSIRX driver UDMA initialization and
     *         configuration code.
     *
     */
    
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    #include <ti/drv/csirx/src/csirx_drvUdma.h>
    
    /* ========================================================================== */
    /*                           Macros & Typedefs                                */
    /* ========================================================================== */
    
    /* None */
    
    /* ========================================================================== */
    /*                         Structure Declarations                             */
    /* ========================================================================== */
    /* None */
    
    /* ========================================================================== */
    /*                          Function Declarations                             */
    /* ========================================================================== */
    /* None */
    
    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */
    /*
     * UDMA Memories
     */
    static uint8_t gCsirxRingMem[CSIRX_INSTANCE_ID_MAX][CSIRX_NUM_CH][CSIRX_DRV_RING_MEM_SIZE_ALIGN]
                                __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    #if defined (SOC_J721E)
    static uint8_t gCsirxCompRingMem[CSIRX_INSTANCE_ID_MAX][CSIRX_NUM_CH][CSIRX_DRV_RING_MEM_SIZE_ALIGN]
                                __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    static uint8_t gCsirxTdCompRingMem[CSIRX_INSTANCE_ID_MAX][CSIRX_NUM_CH][CSIRX_DRV_RING_MEM_SIZE_ALIGN]
                                __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    #endif
    static uint8_t gCsirxUdmaTprdMem
            [CSIRX_INSTANCE_ID_MAX][CSIRX_NUM_CH][CSIRX_CAPT_QUEUE_DEPTH_PER_CH][CSIRX_DRV_TRPD_SIZE_ALIGN]
                                __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    extern CsirxDrv_CommonObj gCsirxCommonObj;
    
    #if (CSIRX_DRV_ENABLE_DEBUG == 1U)
    extern uint32_t gTrSubmit[CSIRX_DRV_TR_LOG_CNT][4];
    extern uint32_t gTrSubmitCnt;
    extern uint32_t gTrOut[CSIRX_DRV_TR_LOG_CNT][4];
    extern uint32_t gTrOutCnt;
    #endif
    /* ========================================================================== */
    /*                  Internal/Private Function Declarations                   */
    /* ========================================================================== */
    static uint16_t CsirxDrv_getIcnt0(const Csirx_ChCfg *chCfg);
    
    /* ========================================================================== */
    /*                          Function Definitions                              */
    /* ========================================================================== */
    int32_t CsirxDrv_getDMACfgParams(CsirxDrv_ChObj *chObj)
    {
        int32_t retVal = FVID2_SOK;
        Csirx_CreateParams *createParams;
        uint32_t chType;
    
        createParams = &chObj->instObj->createParams;
    
        /* Assign UDMA Rx channel params from channel configurations */
        chObj->rxChParams = &chObj->chCfg->rxChParams;
        /* Init UDMA channel parameters */
        chType = UDMA_CH_TYPE_RX;
        UdmaChPrms_init(&chObj->chParams, chType);
        chObj->trpdMem = &gCsirxUdmaTprdMem[chObj->instObj->drvInstId][chObj->psilThreadId][0U][0U];
        chObj->rxFqRingMem = &gCsirxRingMem[chObj->instObj->drvInstId][chObj->psilThreadId][0U];
    #if defined (SOC_J721E)
        chObj->rxCqRingMem = &gCsirxCompRingMem[chObj->instObj->drvInstId][chObj->psilThreadId][0U];
        chObj->rxTdCqRingMem = &gCsirxTdCompRingMem[chObj->instObj->drvInstId][chObj->psilThreadId][0U];
    #endif
        chObj->chParams.peerChNum            = (chObj->instObj->psilThreadIdStart +
                                                chObj->psilThreadId);
        chObj->chParams.fqRingPrms.ringMem   = chObj->rxFqRingMem;
        chObj->chParams.fqRingPrms.orderId   = chObj->chCfg->ringOrderId;
        chObj->chParams.fqRingPrms.elemCnt   = CSIRX_CAPT_QUEUE_DEPTH_PER_CH;
    #if defined (SOC_J721E)
        chObj->chParams.cqRingPrms.ringMem   = chObj->rxCqRingMem;
        chObj->chParams.tdCqRingPrms.ringMem = chObj->rxTdCqRingMem;
        /* Initialize ring order ID */
        chObj->chParams.cqRingPrms.orderId   = chObj->chCfg->ringOrderId;
        chObj->chParams.tdCqRingPrms.orderId = chObj->chCfg->ringOrderId;
        chObj->chParams.cqRingPrms.elemCnt   = CSIRX_CAPT_QUEUE_DEPTH_PER_CH;
        chObj->chParams.tdCqRingPrms.elemCnt = CSIRX_CAPT_QUEUE_DEPTH_PER_CH;
    #endif
    
        /* Get the PSI-L Threads/DMA channel configuration parameters */
        chObj->dmaCfgParams.chNum = chObj->psilThreadId;
        chObj->dmaCfgParams.virtCh = chObj->chCfg->vcNum;
        chObj->dmaCfgParams.dataType = chObj->chCfg->inCsiDataType;
        chObj->dmaCfgParams.dstTag = CSIRX_DRV_PSI_DEST_TAG;
        chObj->dmaCfgParams.srcTag = CSIRX_DRV_PSI_SRC_TAG;
        chObj->dmaCfgParams.psFlags = 0U;
        chObj->dmaCfgParams.pktType = 0U;
    
        chObj->dmaCfgParams.dualPkgEnable = 0U;
        /* Storage mode for YUV422 data format */
        if (chObj->chCfg->outFmt.dataFormat == FVID2_DF_YUV422I_UYVY)
        {
            chObj->dmaCfgParams.yuv422Mode = (uint32_t)CSL_CSIRX_YUV422_MODE_YVYU;
        }
        else if (chObj->chCfg->outFmt.dataFormat == FVID2_DF_YUV422I_YUYV)
        {
            chObj->dmaCfgParams.yuv422Mode = (uint32_t)CSL_CSIRX_YUV422_MODE_VYUY;
        }
        else if (chObj->chCfg->outFmt.dataFormat == FVID2_DF_YUV422I_YVYU)
        {
            chObj->dmaCfgParams.yuv422Mode = (uint32_t)CSL_CSIRX_YUV422_MODE_UYVY;
        }
        else if (chObj->chCfg->outFmt.dataFormat == FVID2_DF_YUV422I_VYUY)
        {
            chObj->dmaCfgParams.yuv422Mode = (uint32_t)CSL_CSIRX_YUV422_MODE_YUYV;
        }
        else
        {
            /* If input format is not YUV422, this parameter values is not used */
            chObj->dmaCfgParams.yuv422Mode = (uint32_t)CSL_CSIRX_YUV422_MODE_UYVY;
        }
        chObj->dmaCfgParams.pck12CfgEnable = 0U;
        /* Change 12 bit packed mode only if DT(inCsiDataType) is
           FVID2_CSI2_DF_RAW12 */
        if (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW12)
        {
            if (chObj->chCfg->outFmt.ccsFormat == FVID2_CCSF_BITS12_PACKED)
            {
                chObj->dmaCfgParams.pck12CfgEnable = 1U;
            }
            else if (chObj->chCfg->outFmt.ccsFormat == FVID2_CCSF_BITS12_UNPACKED16)
            {
                chObj->dmaCfgParams.pck12CfgEnable = 0U;
            }
            else
            {
                /* If input format is not RAW12, this parameter values is not used */
                chObj->dmaCfgParams.pck12CfgEnable = 0U;
            }
        }
        if ((chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV422_8B) && 
            (createParams->instCfg.numPixelsStrm0 == 1U))
        {
            chObj->dmaCfgParams.dualPkgEnable = 1U;
        }
        if (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW20)
        {
            chObj->dmaCfgParams.dataSizeShift =
                                (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_32BITS;
        }
        else if (chObj->chCfg->outFmt.ccsFormat == FVID2_CCSF_BITS12_PACKED)
        {
            chObj->dmaCfgParams.dataSizeShift =
                                    (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_8BITS;
        }
        else if ((chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV420_10B) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV422_10B) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW10) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW12) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW14) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW16) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV422_8B))
        {
            if (createParams->instCfg.numPixelsStrm0 == 0U)
            {
                chObj->dmaCfgParams.dataSizeShift =
                                    (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_16BITS;
            }
            else if(createParams->instCfg.numPixelsStrm0 == 1U)
            {
                chObj->dmaCfgParams.dataSizeShift =
                                    (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_32BITS;
            }
            else if (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV422_8B)
            {
                chObj->dmaCfgParams.dataSizeShift = (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_8BITS;
            }
            else
            {
                /* Do nothing as above two conditions should be hit
                   and check has done before entering this function */
            }
        }
        else if (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW8)
        {
    
            if (createParams->instCfg.numPixelsStrm0 == 0U)
            {
                chObj->dmaCfgParams.dataSizeShift =
                                    (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_8BITS;
            }
            else if(createParams->instCfg.numPixelsStrm0 == 1U)
            {
                chObj->dmaCfgParams.dataSizeShift =
                                    (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_16BITS;
            }
            else if(createParams->instCfg.numPixelsStrm0 == 2U)
            {
                chObj->dmaCfgParams.dataSizeShift =
                                    (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_32BITS;
            }
            else
            {
                /* Do nothing as above two conditions should be hit
                   and check has done before entering this function */
            }
        }
        else
        {
            chObj->dmaCfgParams.dataSizeShift =
                                (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_8BITS;
        }
    
        return retVal;
    }
    
    int32_t CsirxDrv_setChUdmaParams(CsirxDrv_ChObj *chObj)
    {
        int32_t retVal = FVID2_SOK, tempRetVal = UDMA_SOK;
        uint32_t chType;
        Udma_EventHandle eventHandle;
        Udma_EventPrms eventParams;
        CsirxDrv_CommonObj *captObj;
    
        captObj = chObj->instObj->commonObjRef;
        if (chObj->chCfg->chType == CSIRX_CH_TYPE_CAPT)
        {
            /* Program UDMA channels only for capture channels */
            chType = UDMA_CH_TYPE_RX;
            /* Open UDMA channel */
            tempRetVal = Udma_chOpen(captObj->initParams.drvHandle,
                                     &chObj->rxChObj,
                                     chType,
                                     &chObj->chParams);
            if(tempRetVal != UDMA_SOK)
            {
                retVal = FVID2_EFAIL;
                GT_0trace(CsirxTrace,
                          GT_ERR,
                          "[ERROR]UDMA channel open FAILED!!!\r\n");
            }
            if (retVal == FVID2_SOK)
            {
                /* Configure UDMA Rx Channel */
                chObj->rxChParams->configDefaultFlow = FALSE;
                tempRetVal = Udma_chConfigRx(&chObj->rxChObj,
                                             chObj->rxChParams);
                if(tempRetVal != UDMA_SOK)
                {
                    retVal = FVID2_EFAIL;
                    GT_0trace(CsirxTrace,
                          GT_ERR,
                          "[ERROR]UDMA RX channel config FAILED!!!\r\n");
                }
            }
            if (retVal == FVID2_SOK)
            {
                /* UDMA Master event is registered only once. Subsequent Event
                 * registrations use the same Master event */
                if(captObj->masterEvent.eventInitDone != UDMA_INIT_DONE)
                {
                      UdmaEventPrms_init(&eventParams);
                      eventParams.eventType         = UDMA_EVENT_TYPE_MASTER;
                      eventParams.appData           = captObj;
                      retVal = Udma_eventRegister(captObj->initParams.drvHandle,
                                                  &captObj->masterEvent,
                                                  &eventParams);
                      if(retVal != UDMA_SOK)
                      {
                          retVal = FVID2_EFAIL;
                      }
                }
                if (retVal == FVID2_SOK)
                {
                      /* Register callbacks here */
                      /* Register ring completion callback */
                      eventHandle = &chObj->cqEventObj;
                      UdmaEventPrms_init(&eventParams);
                      eventParams.eventType         = UDMA_EVENT_TYPE_DMA_COMPLETION;
                      eventParams.eventMode         = UDMA_EVENT_MODE_SHARED;
                      eventParams.chHandle          = &chObj->rxChObj;
                      eventParams.masterEventHandle = &captObj->masterEvent;
                      eventParams.eventCb           = &CsirxDrv_udmaCQEventCb;
                      eventParams.appData           = chObj;
                      tempRetVal = Udma_eventRegister(captObj->initParams.drvHandle,
                                                      eventHandle,
                                                      &eventParams);
                }
                if(tempRetVal != UDMA_SOK)
                {
                    retVal = FVID2_EFAIL;
                    GT_0trace(CsirxTrace,
                          GT_ERR,
                          "[ERROR]UDMA CQ event register FAILED!!!\r\n");
                }
            }
    
    #if defined (SOC_J721E)
            if(retVal == UDMA_SOK)
            {
                /* Register teardown ring completion callback */
                eventHandle = &chObj->tdcEventObj;
                UdmaEventPrms_init(&eventParams);
                eventParams.eventType         = UDMA_EVENT_TYPE_TEARDOWN_PACKET;
                eventParams.eventMode         = UDMA_EVENT_MODE_SHARED;
                eventParams.chHandle          = &chObj->rxChObj;
                eventParams.masterEventHandle = &captObj->masterEvent;
                eventParams.eventCb           = &CsirxDrv_udmaTDCEventCb;
                eventParams.appData           = chObj;
                tempRetVal = Udma_eventRegister(captObj->initParams.drvHandle,
                                                eventHandle,
                                                &eventParams);
                if(tempRetVal != UDMA_SOK)
                {
                    retVal = FVID2_EFAIL;
                    GT_0trace(CsirxTrace,
                        GT_ERR,
                        "[ERROR]UDMA Tear Down Q event register FAILED!!!\r\n");
                }
            }
    #endif
        }
        if (retVal == FVID2_SOK)
        {
            /* Set channel status to created */
            chObj->status = CSIRX_DRV_CH_STATE_CREATED;
        }
    
        return retVal;
    }
    
    int32_t CsirxDrv_clearUdmaParams(CsirxDrv_ChObj *chObj)
    {
        int32_t retVal = FVID2_SOK, tempRetVal = UDMA_SOK;
        Udma_EventHandle eventHandle;
    
        if (chObj->chCfg->chType == CSIRX_CH_TYPE_CAPT)
        {
            /* Unregister ring completion callback */
            eventHandle = &chObj->cqEventObj;
            tempRetVal += Udma_eventUnRegister(eventHandle);
    #if defined (SOC_J721E)
            /* Unregister teardown ring completion callback */
            eventHandle = &chObj->tdcEventObj;
            tempRetVal += Udma_eventUnRegister(eventHandle);
    #endif
    
            /* Close UDMA channel */
            tempRetVal += Udma_chClose(&chObj->rxChObj);
        }
    
        if (tempRetVal != UDMA_SOK)
        {
            retVal = FVID2_EFAIL;
        }
    
        return retVal;
    }
    
    int32_t CsirxDrv_udmaRxTrpdInit(Udma_ChHandle rxChHandle,
                                    uint8_t *pTrpdMem,
                                    const uint32_t *destBuf,
                                    const Csirx_ChCfg *chCfg,
                                    uint32_t chIdx)
    {
        int32_t retVal = FVID2_SOK;
        CSL_UdmapCppi5TRPD *pTrpd = (CSL_UdmapCppi5TRPD *) pTrpdMem;
        uint32_t descType = (uint32_t)CSL_UDMAP_CPPI5_PD_DESCINFO_DTYPE_VAL_TR;
        uint32_t cqRingNum = Udma_chGetCqRingNum(rxChHandle);
        CSL_UdmapTR1 *pTr = (CSL_UdmapTR1 *)(pTrpdMem + sizeof(CSL_UdmapTR15));
        uint32_t *pTrResp =
                    (uint32_t *) (pTrpdMem + (sizeof(CSL_UdmapTR15) *
                                             (1U + 1U)));
    
        /* Setup descriptor */
        CSL_udmapCppi5SetDescType(pTrpd, descType);
    
        CSL_udmapCppi5TrSetReload(pTrpd, FALSE, 0U);
        /* Since each TRPD will always have only one TR */
        CSL_udmapCppi5SetPktLen(pTrpd, descType, 1U);
        /* Flow ID and Packet ID */
        CSL_udmapCppi5SetIds(pTrpd, descType, 0U, (uint32_t)UDMA_DEFAULT_FLOW_ID);
        CSL_udmapCppi5SetSrcTag(pTrpd, 0x0044);             /* Not used */
        CSL_udmapCppi5SetDstTag(pTrpd, 0x0416);             /* Not used */
        CSL_udmapCppi5TrSetEntryStride(pTrpd,
            CSL_UDMAP_CPPI5_TRPD_PKTINFO_RECSIZE_VAL_64B);
        CSL_udmapCppi5SetReturnPolicy(pTrpd,
            descType,
            /* Don't care for TR */
            CSL_UDMAP_CPPI5_PD_PKTINFO2_RETPOLICY_VAL_ENTIRE_PKT,
            CSL_UDMAP_CPPI5_PD_PKTINFO2_EARLYRET_VAL_NO,
            CSL_UDMAP_CPPI5_PD_PKTINFO2_RETPUSHPOLICY_VAL_TO_TAIL,
            cqRingNum);
    
        /* Initialize TR packet: Start */
        /* Setup TR */
        /* Bit fields::
           Bit No.->Info
           3:0->Type: 2D transfer
           7:6->Event Size: Event is only generated with the TR is complete
           9:8->Trigger0: No Trigger
           10:11->Trigger0 Type:
                        The second inner most loop (ICNT1) will be decremented by 1.
           13:12->Trigger1: No Trigger
           15:14->Trigger1 Type:
                        The second inner most loop (ICNT1) will be decremented by 1.
           23:16->Command ID: The Command ID for the TR
           31:24->Conf Flags: Configuration Specific Flags
           */
        pTr->flags = 0U;
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TYPE,
                                CSL_UDMAP_TR_FLAGS_TYPE_2D_DATA_MOVE);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_STATIC, FALSE);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_EOL, (uint32_t)FALSE);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_EVENT_SIZE,
                                CSL_UDMAP_TR_FLAGS_EVENT_SIZE_COMPLETION);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0,
                                CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0_TYPE,
                                CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1,
                                CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1_TYPE,
                                CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_CMD_ID, chIdx);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_SA_INDIRECT, (uint32_t)0U);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_DA_INDIRECT, (uint32_t)0U);
        pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_EOP, (uint32_t)0U);
        pTr->icnt0    = CsirxDrv_getIcnt0(chCfg);
        pTr->icnt1    = (uint16_t)(chCfg->outFmt.height);
        pTr->dim1     = (int32_t)(chCfg->outFmt.pitch[0U]);
        /* Destination address does not needed to be programmed,
           this will overwritten in Queue */
        pTr->addr     = (uint64_t) destBuf;
    
        /* Clear TR response memory */
        *pTrResp = 0xFFFFFFFFU;
        /* Initialize TR packet: End */
        /* Writeback cache */
        CsirxDrv_cacheWb(pTrpdMem,
                         (int32_t)CSIRX_DRV_TRPD_SIZE_ALIGN);
        /* check if line size is greater than pitch provided, pitch should be
           equal to or more than line size in bytes */
        if ((pTr->icnt0 > (uint32_t)pTr->dim1) || (pTr->icnt0 == 0U))
        {
            retVal = FVID2_EFAIL;
        }
    
        return retVal;
    }
    
    void CsirxDrv_udmaCQEventCb(Udma_EventHandle eventHandle,
                                uint32_t eventType,
                                void *appData)
    {
        int32_t retVal = UDMA_SOK, tempVal = UDMA_SOK;
        CsirxDrv_ChObj *chObj;
        CsirxDrv_QueObj *qObj;
        CsirxDrv_BufManObj *bmObj;
        uint64_t pDesc = 0;
        uint32_t *pTrResp;
        uint32_t curQCnt, appCb = 0U, cookie, chIdx;
        uint64_t timeStamp;
        CSL_UdmapTR1 *pTr;
    
        if(eventHandle == NULL)
    	{
    		/*To remove unused variable warning*/
    	}
    
        chObj = (CsirxDrv_ChObj *) appData;
        GT_assert(CsirxTrace, (chObj != NULL));
    
        /* Take out completed TRPD from UDMA CQ Ring */
        if(eventType == UDMA_EVENT_TYPE_DMA_COMPLETION)
        {
            /* Disable HW interrupts here */
            cookie = HwiP_disable();
            bmObj = &chObj->bufManObj;
            /* Response received in completion queue, empty up full CQ Ring */
            while (retVal == UDMA_SOK)
            {
                retVal = Udma_ringDequeueRaw(
                             Udma_chGetCqRingHandle(&chObj->rxChObj), &pDesc);
                if(retVal == UDMA_SOK)
                {
    #if (CSIRX_DRV_ENABLE_DEBUG == 1U)
                    {
                        gTrOut[gTrOutCnt][0U] = (uint32_t)pDesc;
                        gTrOut[gTrOutCnt][1U] = chObj->instObj->drvInstId;
                        gTrOut[gTrOutCnt][2U] = chObj->chId;
                        if (gCsirxCommonObj.getTimeStamp != NULL)
                        {
                            gTrOut[gTrOutCnt][3U] =
                                            (uint32_t)gCsirxCommonObj.getTimeStamp(NULL);;
                        }
                        else
                        {
                            gTrOut[gTrOutCnt][3U] = 0U;
                        }
                        gTrOutCnt = (gTrOutCnt + 1U) % CSIRX_DRV_TR_LOG_CNT;
                        CsirxDrv_cacheWb(&gTrOut[0U],
                                         sizeof(gTrOut));
                    }
    #endif
                    if (gCsirxCommonObj.getTimeStamp != NULL)
                    {
                        timeStamp = gCsirxCommonObj.getTimeStamp(NULL);
                    }
                    else
                    {
                        timeStamp = 0U;
                    }
                    /* De-queue from curQ */
                    qObj = (CsirxDrv_QueObj *) Fvid2Utils_dequeue(bmObj->curQ);
                    GT_assert(CsirxTrace, (qObj != NULL));
    				if(qObj != NULL)
    				{
    					GT_assert(CsirxTrace,
                              (chObj->chId == qObj->chObj->chId));
    					/* Check returned descriptor pointer */
    					GT_assert(CsirxTrace, (pDesc == ((uint64_t) qObj->trpd)));
    #if (CSIRX_DRV_ENABLE_DEBUG == 1U)
    					gCsirxCommonObj.frmChId[gCsirxCommonObj.frmCnt] =
    													qObj->chObj->chId;
    					gCsirxCommonObj.frmInstId[gCsirxCommonObj.frmCnt] =
    											qObj->chObj->instObj->drvInstId;
    					if (gCsirxCommonObj.getTimeStamp != NULL)
    					{
    						gCsirxCommonObj.frmTS[gCsirxCommonObj.frmCnt] =
    												(uint32_t)(timeStamp / 1000U);
    					}
    #endif
                        pTr = (CSL_UdmapTR1 *)((uint8_t *)qObj->trpd +
                                               (sizeof(CSL_UdmapTR15)));
                        if (pTr->addr == (uint64_t)(chObj->instObj->createParams.frameDropBuf))
                        {
                            /* Mark qBoj as Normal Frame which can be used next time */
                            qObj->type = CSIRX_DRV_Q_OBJ_TYPE_NORMAL;
                            /* This is frame drop buffer so no need to issue CB */
                            appCb = 0U;
                            /* Invalidate cache */
                            CsirxDrv_cacheInv(qObj->trpd,
                                              (int32_t)CSIRX_DRV_TRPD_SIZE_ALIGN);
                            /* de-queued TRPD was for frame submitted
                               by application */
                            /* Check for truncated/elongated frame */
                            pTrResp = (uint32_t *) ((uint8_t *)(qObj->trpd) +
                                                   (sizeof(CSL_UdmapTR15) *
                                                   (1U + 1U)));
                            /* NO need to put it to done queue, put it to FreeQ */
                            Fvid2Utils_queue(bmObj->freeQ, &qObj->qElem, qObj);
    #if (CSIRX_DRV_ENABLE_DEBUG == 1U)
                            gCsirxCommonObj.trResp[gCsirxCommonObj.frmCnt] =
                                                    CSL_REG32_RD(pTrResp);
                            gCsirxCommonObj.frmType[gCsirxCommonObj.frmCnt] = 0U;
    #endif
                        }
                        else
                        {
                            /* This is frame provided by application so issue CB */
                            appCb = 1U;
                            /*GT_assert(CsirxTrace, (qObj->frm != NULL));*/
                            qObj->frm->timeStamp64 = timeStamp;
                            /* Invalidate cache */
                            CsirxDrv_cacheInv(qObj->trpd,
                                              (int32_t)CSIRX_DRV_TRPD_SIZE_ALIGN);
                            /* de-queued TRPD was for frame submitted
                               by application */
                            /* Check for truncated/elongated frame */
                            pTrResp = (uint32_t *) ((uint8_t *)(qObj->trpd) +
                                                   (sizeof(CSL_UdmapTR15) *
                                                   (1U + 1U)));
                            /* check only 'STATUS_TYPE' fields of TR response */
                            if ((CSL_REG32_RD(pTrResp) & 0xFU) != 0U)
                            {
                                if ((chObj->status == CSIRX_DRV_CH_STATE_STOPPING) ||
                                    (chObj->status == CSIRX_DRV_CH_STATE_STOPPED))
                                {
                                    /* Aborted frame due to forced teardown at
                                       Udma_chDisable() */
                                    qObj->frm->status = (uint32_t)FVID2_FRAME_STATUS_ABORTED;
                                }
                                else
                                {
                                    /* Received frame is either truncated/elongated */
                                    qObj->frm->status = (uint32_t)FVID2_FRAME_STATUS_ERROR;
                                    chObj->instObj->status.errorFrameCount[chObj->chCfg->chId]++;
                                }
    #if (CSIRX_DRV_ENABLE_DEBUG == 1U)
                                gCsirxCommonObj.frmStatus[gCsirxCommonObj.frmCnt] =
                                                            qObj->frm->status;
    #endif
                            }
                            else
                            {
                                /* Received frame has no error */
                                qObj->frm->status = (uint32_t)FVID2_FRAME_STATUS_COMPLETED;
    #if (CSIRX_DRV_ENABLE_DEBUG == 1U)
                                gCsirxCommonObj.frmStatus[gCsirxCommonObj.frmCnt] =
                                                                qObj->frm->status;
    #endif
    #if (CSIRX_DRV_ENABLE_DEBUG == 1U)
                        gCsirxCommonObj.trResp[gCsirxCommonObj.frmCnt] =
                                                    CSL_REG32_RD(pTrResp);
                        gCsirxCommonObj.frmType[gCsirxCommonObj.frmCnt] = 1U;
    #endif
                            }
                            /* Return the frame to done queue */
                            Fvid2Utils_queue(
                                chObj->bufManObj.doneQ,
                                &qObj->qElem,
                                qObj);
                        }
    #if (CSIRX_DRV_ENABLE_DEBUG == 1U)
    					uint32_t oldFrmCnt;
    
    					oldFrmCnt = gCsirxCommonObj.frmCnt;
    					gCsirxCommonObj.frmCnt = (gCsirxCommonObj.frmCnt + 1U) %
    											  CSIRX_DRV_LOG_CNT;
    					if (oldFrmCnt > gCsirxCommonObj.frmCnt)
    					{
    						gCsirxCommonObj.frmCntOverflow = 1U;
    					}
    #endif
    				}
                }
            }
            /** Enable HW interrupts here */
            HwiP_restore(cookie);
    
            if (chObj->status == CSIRX_DRV_CH_STATE_RUNNING)
            {
                /* Application call back */
                if (appCb == 1U)
                {
                    if(chObj->virtContext->fdmCbParams.fdmCbFxn != NULL)
                    {
                        (void)chObj->virtContext->fdmCbParams.fdmCbFxn(
                                        chObj->virtContext->fdmCbParams.fdmData);
                    }
                }
            }
    
            /* Disable HW interrupts here */
            cookie = HwiP_disable();
            if (retVal == UDMA_ETIMEOUT)
            {
                /* this will happen if there in no TR in the Ring of UDMA channel */
                retVal = FVID2_SOK;
            }
            if (retVal == FVID2_SOK)
            {
                if (chObj->status == CSIRX_DRV_CH_STATE_RUNNING)
                {
                    bmObj = &chObj->bufManObj;
                    /* Check if one more frame is queued by application,
                       if not then submit TR with frame drop buffer */
                    curQCnt = Fvid2Utils_getNumQElem(bmObj->curQ);
                    if (curQCnt <= 1U)
                    {
                        while (curQCnt < CSIRX_DRV_FRAME_DROP_TRPD_NUM)
                        {
                            /* Allocate a free queue object from the pool */
                            qObj =
                             (CsirxDrv_QueObj *) Fvid2Utils_dequeue(bmObj->freeQ);
                            if (qObj == NULL)
                            {
                                GT_0trace(
                                    CsirxTrace, GT_ERR,
                                    "ALLOC: Q object allocation failed\r\n");
                                retVal = FVID2_EALLOC;
                            }
                            if(retVal == FVID2_SOK)
                            {
                                /* Copy the frame to the driver's queue object */
                                qObj->frm = NULL;
                                /* Re-program dim0 and destination buffer */
                                pTr = (CSL_UdmapTR1 *)((uint8_t *)qObj->trpd +
                                                       sizeof(CSL_UdmapTR15));
                                /* Keep over-writing frameDrop buffer with each incoming line */
                                pTr->dim1 = 0;
                                pTr->addr =
                                    (uint64_t)(chObj->instObj->createParams.frameDropBuf);
                                /* Mark qBoj as Frame Drop */
                                qObj->type = CSIRX_DRV_Q_OBJ_TYPE_FD;
                                /* Submit TR to FQ ring for UDMA channel */
                                /* Writeback cache */
                                CsirxDrv_cacheWb(qObj->trpd,
                                                 (int32_t)CSIRX_DRV_TRPD_SIZE_ALIGN);
                                /* Submit TRPD to channel */
        #if (CSIRX_DRV_ENABLE_DEBUG == 1U)
                                {
                                    gTrSubmit[gTrSubmitCnt][0U] =
                                                (uint32_t)qObj->trpd;
                                    gTrSubmit[gTrSubmitCnt][1U] =
                                                chObj->instObj->drvInstId;
                                    gTrSubmit[gTrSubmitCnt][2U] =
                                                qObj->chObj->chId;;
                                    if (gCsirxCommonObj.getTimeStamp != NULL)
                                    {
                                        gTrSubmit[gTrSubmitCnt][3U] =
                                                (uint32_t)gCsirxCommonObj.getTimeStamp(NULL);
                                    }
                                    else
                                    {
                                        gTrSubmit[gTrSubmitCnt][3U] = 0U;
                                    }
                                    gTrSubmitCnt =
                                        (gTrSubmitCnt + 1U) % CSIRX_DRV_TR_LOG_CNT;
                                    CsirxDrv_cacheWb(&gTrSubmit[0U],
                                                     sizeof(gTrSubmit));
                                }
        #endif
                                tempVal = Udma_ringQueueRaw(
                                                Udma_chGetFqRingHandle(&chObj->rxChObj),
                                                (uint64_t)qObj->trpd);
                                if(tempVal != UDMA_SOK)
                                {
                                    GT_0trace(
                                        CsirxTrace, GT_ERR,
                                        "Queue: Submitting of TR failed\r\n");
                                    /* Queue back the Object which was
                                       de-queued earlier from freeQ */
                                    Fvid2Utils_queue(bmObj->freeQ, &qObj->qElem, qObj);
                                    retVal = FVID2_EFAIL;
                                }
                                else
                                {
                                    /* Add the queue object in driver's current queue */
                                    Fvid2Utils_queue(bmObj->curQ, &qObj->qElem, qObj);
                                    /* update frame drop count here */
                                    chIdx = chObj->chId;
                                    chObj->instObj->status.dropCount[chIdx]++;
                                }
                            }
                            curQCnt = Fvid2Utils_getNumQElem(bmObj->curQ);
                        }
                    }
                }
            }
            /** Enable HW interrupts here */
            HwiP_restore(cookie);
        }
        else
        {
            chObj->instObj->status.spuriousUdmaIntrCount++;
        }
    }
    
    #if defined (SOC_J721E)
    void CsirxDrv_udmaTDCEventCb(Udma_EventHandle eventHandle,
                                 uint32_t eventType,
                                 void *appData)
    {
        int32_t retVal = UDMA_SOK;
        CsirxDrv_ChObj *chObj;
        CSL_UdmapTdResponse tdResp;
    
        if(eventHandle == NULL)
    	{
    		//To remove unused variable warning
    	}
    
        chObj = (CsirxDrv_ChObj *) appData;
        GT_assert(CsirxTrace, (chObj != NULL));
        /* Take out completed TRPD from UDMA TDC Ring */
        if(eventType == UDMA_EVENT_TYPE_TEARDOWN_PACKET)
        {
            /* Response received in Teardown completion queue */
            retVal = Udma_chDequeueTdResponse(&chObj->rxChObj, &tdResp);
            if(retVal != UDMA_SOK)
            {
                /* [Error] No TD response after callback!! */
                GT_0trace(
                            CsirxTrace, GT_ERR,
                            "UDMA Tear Down Failed!!!\r\n");
            }
        }
        else
        {
            chObj->instObj->status.spuriousUdmaIntrCount++;
        }
    }
    #endif
    
    void CsirxDrv_cacheWb(const void *addr, int32_t size)
    {
        uint32_t    isCacheCoherent = Udma_isCacheCoherent();
    
        if(isCacheCoherent != TRUE)
        {
            CacheP_wb(addr, size);
        }
    
        return;
    }
    
    void CsirxDrv_cacheInv(const void * addr, int32_t size)
    {
        uint32_t    isCacheCoherent = Udma_isCacheCoherent();
    
        if(isCacheCoherent != TRUE)
        {
            CacheP_Inv(addr, size);
        }
    
        return;
    }
    
    uint8_t* CsirxDrv_getTrpdMemAddr(CsirxDrv_ChObj *chObj, uint32_t qCnt)
    {
        return (&gCsirxUdmaTprdMem[chObj->instObj->drvInstId][chObj->chId][qCnt][0U]);
    }
    /* ========================================================================== */
    /*                       Static Function Definitions                          */
    /* ========================================================================== */
    static uint16_t CsirxDrv_getIcnt0(const Csirx_ChCfg *chCfg)
    {
        uint16_t icnt0 = 0U;
        uint32_t bpp  = 0U;
        uint32_t tempicnt0 = 0U;
    
        bpp = CsirxDrv_getStorageBpp(chCfg->inCsiDataType);
    
        if ((chCfg->inCsiDataType == FVID2_CSI2_DF_RAW12) &&
             (chCfg->outFmt.ccsFormat == FVID2_CCSF_BITS12_PACKED))
        {
            /* over-writing bpp as this is packed format and it is valid only for RAW12 */
            bpp = CSIRX_BITS_PER_PIXEL_12_BITS;
            /* icnt0 expressed in bits */
            tempicnt0 = (chCfg->outFmt.width * bpp);
            /* icnt0 currently in bits, rounding off to next word boundary */
            icnt0 = (uint16_t)((tempicnt0 + 31U) / 32U);
            /* icnt0 in bytes */
            icnt0 = icnt0 * 4U;
        }
        else
        {
            /* icnt0 expressed in bits */
            tempicnt0 = (chCfg->outFmt.width * bpp);
            /* icnt0 in bytes */
            icnt0 = (uint16_t)(tempicnt0 / 8U);
        }
    
        return icnt0;
    }
    

    Regards,

    jiawentao

  • Hi jin wentao,

    Did you rebuild PDK & SDK after this change? Because that's the only change from the last SDK release. 

    Can you try removing YUV422 from this check, like below?

        else if ((chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV420_10B) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV422_10B) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW10) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW12) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW14) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW16))
    
        {
            if (createParams->instCfg.numPixelsStrm0 == 0U)
            {
                chObj->dmaCfgParams.dataSizeShift =
                                    (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_16BITS;
            }
    

    Regards,

    Brijesh

  • Hi, Brijesh

    If deleted (chObj ->chCfg ->inCsiDataType==FVID2CSI2DF_YUV422_8B)

    I can see the image, but it is deformed.

    cap_0000--01.zip

    Regards,

    Brijesh

  • But this image looks to be fine to me. What deformation are you seeing in the image?

  • Hi,Brijesh

    Oh, sorry. Yes, it can be seen. I checked again and there is a problem with the settings of the YUV image viewing tool. Thank you for your help~~

    Regards,

    jiawentao

  • else if ((chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV420_10B) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV422_10B) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW10) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW12) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW14) ||
                 (chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_RAW16))
        {
            if (createParams->instCfg.numPixelsStrm0 == 0U)
            {
                chObj->dmaCfgParams.dataSizeShift =
                                    (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_16BITS;
            }
            else if(createParams->instCfg.numPixelsStrm0 == 1U)
            {
                chObj->dmaCfgParams.dataSizeShift =
                                    (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_32BITS;
            }
            else
            {
                /* Do nothing as above two conditions should be hit
                   and check has done before entering this function */
            }
        }
        else if(chObj->chCfg->inCsiDataType == FVID2_CSI2_DF_YUV422_8B)
        {
            chObj->dmaCfgParams.dataSizeShift = (uint32_t)CSL_CSIRX_DMA_DATA_SIZE_SHIFT_8BITS;
        }
    

  • Hi Yang,

    Sorry, what's the question here? 

    Regards,

    Brijesh

  • No question . 

    After modifying the code to the above, the image output is correct.

    thanks for you help

  • Sure, thanks, closing this ticket.