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: CSIRX unwanted stream enable

Part Number: TDA4VM

All PSDK versions up to 11.2 seem to have this issue.

If csirx gets a header ecc error (which can happen if csirx is tuned on in the middle of transmission), then the ISR handler CsirxDrv_errorEventIsrFxn() is called, and goes to the errStatus.headerEccIrq==1U branch. From there, it calls CsirxDrv_resetStream() for all 4 streams, regardless of which streams are enabled.

Inside CsirxDrv_resetStream(), the stream it was called for is always enabled. So this results into all streams getting enabled.

For stream that was not properly configured and enabled before, this will cause stream FIFO overflow error soon - which results into false safety event in the system.

Possible fix is:

diff --git a/pdk_j784s4_11_02_00_15/packages/ti/drv/csirx/src/csirx_event.c b/pdk_j784s4_11_02_00_15/packages/ti/drv/csirx/src/csirx_event.c
index d2bc7ff8f..97b3faf49 100755
--- a/pdk_j784s4_11_02_00_15/packages/ti/drv/csirx/src/csirx_event.c
+++ b/pdk_j784s4_11_02_00_15/packages/ti/drv/csirx/src/csirx_event.c
@@ -1143,6 +1143,7 @@ static int32_t CsirxDrv_resetStream(const CsirxDrv_InstObj *instObj,
     CSIRX_StreamStatus strmStatus;
     CSIRX_StreamCtrl strmCtrlParams;
     uint32_t status, currTimeout = 0U;
+    uint32_t wasRunning = 0U;
 
     /* check if stream is enabled */
     if (CDN_EOK != CSIRX_GetStreamStatus(&instObj->cslObj.cslCfgData,
@@ -1156,6 +1157,8 @@ static int32_t CsirxDrv_resetStream(const CsirxDrv_InstObj *instObj,
     {
         if (1U == strmStatus.running)
         {
+            wasRunning = 1U;
+
             /* Stream is enabled */
             strmCtrlParams.softRst = 1U;
             strmCtrlParams.abrt    = 0U;
@@ -1202,7 +1205,7 @@ static int32_t CsirxDrv_resetStream(const CsirxDrv_InstObj *instObj,
         }
     }
     /* Re-start stream */
-    if (FVID2_SOK == retVal)
+    if (FVID2_SOK == retVal && 1U == wasRunning)
     {
         strmCtrlParams.softRst = 0U;
         strmCtrlParams.abrt    = 0U;
  • Hi ,

    CsirxDrv_resetStream should check only a specific stream ID?

    Do you have logs of the error or have you stepped through?

    Best,
    Jared

  • I was researching situation that, while using CSIRX over TIOVX capture node that only enables stream 0 (to memory) and never enables stream 1 (to CSITX), still sometimes, once per several 10s of executions, I am getting CSIRX_EVENT_TYPE_ERR_FIFO_OVERFLOW_STRM1 error.

    TIOVX capture node never sets instCfg.enableStrm for streams other than 0, so stream 1 shall be never started and shall never get an overflow.

    So I was looking for a path in CSIRX driver that could cause stream 1 to be started despite of driver was never requested to do that. And, I found such a path.

    It looks valid to reset any running streams in case of ECC error. So looping over all streams and calling CsirxDrv_resetStream() looks ok. However, there shall be a condition to either not call CsirxDrv_resetStream() for streams that are not running, or to make CsirxDrv_resetStream() not start stream if it was not running at call time. My patch does the second.

  • Hi ,

    The stream shouldn't be reset/started if the stream is not enabled.

        /* check if stream is enabled */
        if (CDN_EOK != CSIRX_GetStreamStatus(&instObj->cslObj.cslCfgData,
                                  &strmStatus,
                                  strmIdx))
        {
            retVal = FVID2_EFAIL;
        }
        ...
        /* Re-start stream */
        if (FVID2_SOK == retVal)
        {
            strmCtrlParams.softRst = 0U;
            strmCtrlParams.abrt    = 0U;
            strmCtrlParams.stop    = 0U;
            strmCtrlParams.start   = 1U;
            status = CSIRX_SetStreamCtrl(&instObj->cslObj.cslCfgData,
                                         &strmCtrlParams,
                                         strmIdx);
            if (CDN_EOK != status)
            {
                retVal = FVID2_EBADARGS;
            }
        }

    Have you noticed any CSIRX_EVENT_TYPE_ERR_FIFO_OVERFLOW_STRM1 after your patch?

    Have you placed a breakpoint or print statement within the function to see if the disabled streams are being started even when disabled?

    Best,
    Jared

  • For stream that was not started, CSIRX_GetStreamStatus() returns 0 (the non-started flag is returned inside strmStatus).  So the CSIRX_SetStreamCtrl() enabling the stream is executed.

  • Hi ,

    I see. I will file a bug.

    Looking at the current code, it doesn't look like the stream will be reset if the stream is not running. It's just the the restarting that occurs.

        /* Reset stream */
        if (FVID2_SOK == retVal)
        {
            if (1U == strmStatus.running)
            {
                /* Stream is enabled */
                strmCtrlParams.softRst = 1U;
                strmCtrlParams.abrt    = 0U;

    I moved the restarting logic into the resetting block.

    diff --git a/packages/ti/drv/csirx/src/csirx_event.c b/./csirx_event.c
    index d2bc7ff..640381d 100755
    --- a/packages/ti/drv/csirx/src/csirx_event.c
    +++ b/./csirx_event.c
    @@ -1199,21 +1199,22 @@ static int32_t CsirxDrv_resetStream(const CsirxDrv_InstObj *instObj,
                         currTimeout++;
                     }
                 }
    -        }
    -    }
    -    /* Re-start stream */
    -    if (FVID2_SOK == retVal)
    -    {
    -        strmCtrlParams.softRst = 0U;
    -        strmCtrlParams.abrt    = 0U;
    -        strmCtrlParams.stop    = 0U;
    -        strmCtrlParams.start   = 1U;
    -        status = CSIRX_SetStreamCtrl(&instObj->cslObj.cslCfgData,
    -                                     &strmCtrlParams,
    -                                     strmIdx);
    -        if (CDN_EOK != status)
    -        {
    -            retVal = FVID2_EBADARGS;
    +
    +            /* Re-start stream */
    +            if (FVID2_SOK == retVal)
    +            {
    +                strmCtrlParams.softRst = 0U;
    +                strmCtrlParams.abrt    = 0U;
    +                strmCtrlParams.stop    = 0U;
    +                strmCtrlParams.start   = 1U;
    +                status = CSIRX_SetStreamCtrl(&instObj->cslObj.cslCfgData,
    +                                            &strmCtrlParams,
    +                                            strmIdx);
    +                if (CDN_EOK != status)
    +                {
    +                    retVal = FVID2_EBADARGS;
    +                }
    +            }
             }
         }
     
    

    Best,
    Jared

  • Hmm shouldn't you put the start call into else clause if the 'if' operation?  In your current version, you restart if error happened...

  • Hi ,

    It just appears that way due to the way the diff looks.

        /* Reset stream */
        if (FVID2_SOK == retVal)
        {
            if (1U == strmStatus.running)
            {
                /* Stream is enabled */
                strmCtrlParams.softRst = 1U;
                strmCtrlParams.abrt    = 0U;
                strmCtrlParams.stop    = 0U;
                strmCtrlParams.start   = 0U;
                status = CSIRX_SetStreamCtrl(&instObj->cslObj.cslCfgData,
                                             &strmCtrlParams,
                                             strmIdx);
                if (CDN_EOK != status)
                {
                    retVal = FVID2_EBADARGS;
                }
                currTimeout = 0U;
                status = CSIRX_GetStreamStatus(&instObj->cslObj.cslCfgData,
                                               &strmStatus,
                                               strmIdx);
                if (CDN_EOK != status)
                {
                    retVal = FVID2_EBADARGS;
                }
                /* Wait for stream to become IDLE */
                while ((0x0U != strmStatus.readyState) &&
                       (0x0U != strmStatus.streamFsm)  &&
                       (FVID2_SOK == retVal))
                {
                     status = CSIRX_GetStreamStatus(&instObj->cslObj.cslCfgData,
                                               &strmStatus,
                                               strmIdx);
                    if (CDN_EOK != status)
                    {
                        retVal = FVID2_EBADARGS;
                        break;
                    }
                    if (CSIRX_TIMEOUT_VAL_MS < currTimeout)
                    {
                        retVal = FVID2_ETIMEOUT;
                    }
                    else
                    {
                        (void)Osal_delay(1U);
                        currTimeout++;
                    }
                }
    
                /* Re-start stream */
                if (FVID2_SOK == retVal)
                {
                    strmCtrlParams.softRst = 0U;
                    strmCtrlParams.abrt    = 0U;
                    strmCtrlParams.stop    = 0U;
                    strmCtrlParams.start   = 1U;
                    status = CSIRX_SetStreamCtrl(&instObj->cslObj.cslCfgData,
                                                &strmCtrlParams,
                                                strmIdx);
                    if (CDN_EOK != status)
                    {
                        retVal = FVID2_EBADARGS;
                    }
                }
            }
        }

    Best,
    Jared

  • This version looks ok

  • Hi ,

    If this patch solves the issue, can we mark this thread as closed? A ticket has been created, and the fix should be integrated into the SDK in the future. 

    Best,
    Jared