Frames received by CX3, but not sent to PC. Why?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
EtWh_2921621
Level 3
Level 3
First like received

I inherited this project from somebody else, it's an OV4688 sensor connected to a CX3. The parameters are:

width = 1920

height = 1440

h_blank = 100

v_blank = 49

THS-prepare = 66.5

THS-zero = 152.75

data lanes = 4

CSI clock = 280Mhz

data format = RAW8

GPIF bus = 24bits

REFCLK=24

pre divider = 3

PLL out range = 250-500

clock dividers both set to 4.

if I set the multiplier of Unit CLK to 112, the CX3 receives frames from the sensor just fine. I know this because I'm debug printing over the UART the frames received, and the (zero) MIPI errors. The media-foundation based UVC app receives frames just fine.

If I set the multiplier of Unit CLK to 100, the CX3 continues to receive the frames just the same - at 90FPS, no mipi errors at all, and the frames are getting sent to the PC (I know, I spied on them with a hardware USB debugger), but the frames aren't being received by the UVC streaming system. I don't know where they are going!?

I don't know a thing about USB transmission, but the presence of an "Not Ready Transition" makes me wonder what is going on.

Only if I increase the clock multiplier to about 112, will the PC receive frames... so very, very odd.

Suggestions?

ack not ready.JPG

0 Likes
1 Solution

Hello,


The query has been resolved in the following threads from the customer:
1.) DMA callback - CX3 - don't understand produce vs consume

2.) CX3: moved to 1_3_4 sdk, bulk endpoint stopped working

3.) cx3 clocks

Regards,

Yashwant

View solution in original post

0 Likes
8 Replies
EtWh_2921621
Level 3
Level 3
First like received

never mind. The project I took over had the wrong REFCLK for the CX3 input. It was shown as "24" when it was really "19.2". I was not clocking the CX3 fast enough, so it was getting darned confused.

Tip: Use an oscilloscope to view the V and H blank signals out of CX3. HELPFUL.

0 Likes

Hello EtWh_2921621​,

Does changing the REFCLK value to "19.2 MHz" from the previous '24 MHz' solve the issue with the streaming?

Please confirm.

Regards,
Yashwant

0 Likes
EtWh_2921621
Level 3
Level 3
First like received

here's what I did: I changed the refclk from 24 to 19.2, then I set the clock multiplier to halfway between the min and the max, so it wasn't stressed out one way or the other. I set the FIFO to 0.

Now, it streams fine, but there is a problem which has been there for years: We're streaming 1920 x 1440 x 90 FPS x RAW8 over the USB 3.0. Occasionally, after a few minutes - 5 or 10, I will get a bunch of CyCx3UvcAppDmaCallback:CyU3PDmaMultiChannelCommitBuffer FAILURE 0x47 errors. sometimes 1 in a row, sometimes 2, and when there is 3 or more, for whatever reason, the PC "gives up" and streaming stops.  I read this weird hard to find article about various ways the CX3 can lock up, I think I found another case.

I work at MIcrosoft, and the streaming/USB team isn't sure what is going on either. Anybody at Cypress have a clue why the streaming would lock up like this over high-data-rate video streaming over USB 3.0?

I'm very unsure what the exact process should be, if there is an error, in the DMA callback. I know I can't spend a lot of time in the callback, that's why an event is set and the other thread handles it. But I'm not sure about the exact sequence of steps that needs to be taken in ApplnStop and ApplnStart. It COULD be that something I am doing during the DMA reset process is CAUSING the PC to stop accepting packets, or it could be no matter what I do, the problem is still there on the PC side. I'm not sure. If somebody has seen this before, I'd love to hear about it.

void CyCx3UvcAppStop (void)

{

    CyU3PReturnStatus_t status;

    if( !glIsApplnActive )

    {

        CyU3PDebugPrint( 4, "****CyCx3UvcAppStop, already stopped, returning\r\n");

        return;

    }

    /* Update the flag so that the application thread is notified of this. */

    glIsApplnActive = CyFalse;

    CyU3PDebugPrint( 4, "****CyCx3UvcAppStop****\r\n");

    /* Stop the image sensor and CX3 mipi interface */

    CyCx3_ImageSensor_Sleep();

    CyU3PBusyWait (100);

    // CyU3PDebugPrint( 4, "  AppStop - called ImageSensor_Sleep\r\n");

    #ifdef RESET_TIMER_ENABLE

    CyU3PTimerStop (&UvcTimer);

    CyU3PBusyWait (100);

#endif

    // CyU3PDebugPrint( 4, "  AppStop - called TimerStop\r\n");

    /* Pause the GPIF interface*/

    CyU3PGpifDisable(CyFalse);

    glMipiActive = CyFalse;

    CyU3PBusyWait (100);

    // CyU3PDebugPrint( 4, "  AppStop - disabled Gpif\r\n");

    // place the endpoint in NAK mode before cleaning up the pipe

    status = CyU3PUsbSetEpNak( VIDEOAR_EP_CAMERASTREAM_SWITCHABLE_IN, CyTrue );

    CyU3PBusyWait (100);

    if( status != CY_U3P_SUCCESS )

    {

        CyU3PDebugPrint( 4, "AppStop, could not Set Ep Nak, reason = %d\r\n", status );

    }

    // CyU3PDebugPrint( 4, "  AppStop - called UsbSetEpNak, and waited 100 ticks\r\n");

    /* Abort and destroy the video streaming channel */

    /* Reset the channel: Set to DSCR chain starting point in PROD/CONS SCKT; set DSCR_SIZE field in DSCR memory*/

    status = CyU3PDmaMultiChannelReset(&glChHandleUVCStream);

    if( status != CY_U3P_SUCCESS )

    {

        CyU3PDebugPrint( 4, "AppStop, could not reset DMA channel, reason = %d\r\n", status );

    }

    CyU3PThreadSleep(25);

    // CyU3PDebugPrint( 4, "  AppStop - reset DmaMultiChannel\r\n");

    /* Flush the endpoint memory */

    status = CyU3PUsbFlushEp(VIDEOAR_EP_CAMERASTREAM_SWITCHABLE_IN);

    if( status != CY_U3P_SUCCESS )

    {

        CyU3PDebugPrint( 4, "AppStop, could not flush ep switchable in, reason = %d\r\n", status );

    }

    // CyU3PDebugPrint( 4, "  AppStop - called UsbFlushEp\r\n");

    // put the NAK back

    status = CyU3PUsbSetEpNak (VIDEOAR_EP_CAMERASTREAM_SWITCHABLE_IN, CyFalse);

    CyU3PBusyWait (200);

    if( status != CY_U3P_SUCCESS )

    {

        CyU3PDebugPrint( 4, "AppStop, could not Set Ep Nak to false, reason = %d\r\n", status );

    }

    /* Clear the stall condition and sequence numbers if ClearFeature. */

    if (glIsClearFeature)

    {

        status = CyU3PUsbStall ( VIDEOAR_EP_CAMERASTREAM_SWITCHABLE_IN /*EP*/, CyFalse /*stall*/, CyTrue /*clear data toggles*/ );

        glIsClearFeature = CyFalse;

        if( status != CY_U3P_SUCCESS )

        {

            CyU3PDebugPrint( 4, "AppStop, could not set usb stall on switchable in, reason = %d\r\n", status );

        }

    }

    CyU3PDebugPrint( 4, "AppStop, stopped.\r\n" );

    glVideoDmaBuffersCommittedAndNeedingToBeConsumed = 0;

    bGotDmaError = CyFalse;

    bDmaErrorReset = CyTrue;

    gMeasuredFPS = 0;

}

0 Likes

Hello EtWh_2921621​,

Can you please let me know if you are using SDK 1.3.3 or SDK 1.3.4?

Can you please share a screenshot of the CX3 Configuration Utility for me to review?

The error code: 0x47 corresponds to invalid sequence error.

Please refer to the following KBA: Invalid Sequence Error in Multi-Channel Commit Buffer - KBA218830

The cause as well as a workaround for the issue are provided in the above KBA.

Regards,
Yashwant

0 Likes
EtWh_2921621
Level 3
Level 3
First like received

SDK 1.3.4.

Yes, I know I need to reset the DMA. I'm surprised that the article suggests "setting a flag". I am setting an event, which gets picked up by the main thread, not a variable. And I already posted the DMA reset code above. Two things I'm seeing, that might be important:

1. if I print a lot of debug messages in the DMA callback, it hangs more.

2. I wasn't calling DmaMultiChannelSetXfer, GpifSMStart, and SMSwitch.

0 Likes
EtWh_2921621
Level 3
Level 3
First like received

with the addition of those extra calls, I am seeing it hang less. But it still hangs. Currently it just hung when the SendTimer timed out, and it tried to call Stop/Start on the DMA chain. The routines inside the ApplnStart( ) all executed, but the CX3 just sat there not processing frames any longer. No DMA activity.

0 Likes

Hello,

1.)  It is recommended not to print any debug messages in the DMA callback because there is a significant delay introduced because of the CyU3PDebugPrint() API.

It is advised to use either use flags or variable or events to get the notifications of the subroutines and print the respective prints in the for ( ;;) loop.

2. Please add the DmaMultiChannelSetXfer, GpifSMStart and SMSwitch calls in the firmware and test if the firmware hangs.

"Currently it just hung when the SendTimer timed out, and it tried to call Stop/Start on the DMA chain."

=> Can you please let me know what this SendTimer is? And why is it added in the firmware? And if it is waiting on the sensor to send data?

"The routines inside the ApplnStart( ) all executed, but the CX3 just sat there not processing frames any longer. No DMA activity"

=> Can you please let me know how you confirmed that there was no DMA activity?
Are you keeping track of the PROD and the CONS events in the firmware?

Regards,

Yashwant

0 Likes

Hello,


The query has been resolved in the following threads from the customer:
1.) DMA callback - CX3 - don't understand produce vs consume

2.) CX3: moved to 1_3_4 sdk, bulk endpoint stopped working

3.) cx3 clocks

Regards,

Yashwant

0 Likes