8 Replies Latest reply on Oct 29, 2020 12:09 AM by YashwantK_46

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

    EtWh_2921621

      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

        • 1. Re: Frames received by CX3, but not sent to PC. Why?
          EtWh_2921621

          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.

          • 2. Re: Frames received by CX3, but not sent to PC. Why?
            YashwantK_46

            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

            • 3. Re: Frames received by CX3, but not sent to PC. Why?
              EtWh_2921621

              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;

              }

              • 4. Re: Frames received by CX3, but not sent to PC. Why?
                YashwantK_46

                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

                • 5. Re: Frames received by CX3, but not sent to PC. Why?
                  EtWh_2921621

                  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.

                  • 6. Re: Frames received by CX3, but not sent to PC. Why?
                    EtWh_2921621

                    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.

                    • 7. Re: Frames received by CX3, but not sent to PC. Why?
                      YashwantK_46

                      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

                      • 8. Re: Frames received by CX3, but not sent to PC. Why?
                        YashwantK_46

                        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