9 Replies Latest reply on Dec 8, 2017 1:52 AM by hppc

    Trying to use the FX3 to capture images from OnSemi image sensor

    tlbrkt_2409941

      Trying to use the FX3 to capture images from OnSemi image sensor and have few questions - could not find answer in the docs or forums.   I use the image sensor in trigger mode, so need to read only 1 image upon request.  The image size is known. For example: the buffer size of monochromatic image of 768X768 pixels is 768X768X2 = 1179648 bytes (16 bits per pixel)   I use a GPIF to USB bulk manual channel to capture the image.   Knowing this size:  What should be the buffer size associated with the channel? (i now use size of 16*1024)  What should be the number of buffers allocated to the channel (I use 4)  What should be the packet size (I use 1024)   When capturing images of 512X512 it works well.  But when capturing images of 768X768 and bigger, the received buffer is made of 15-20 last lines of the previous image, and the rest are lines of the currently captured image.  There is some sync problems between the captured and received buffers.Can anyone help with this?

        • 1. Re: Trying to use the FX3 to capture images from OnSemi image sensor
          hppc

          Can you share the firmware source code. Are you using AN75779 example firmware?

          • 2. Re: Trying to use the FX3 to capture images from OnSemi image sensor
            tlbrkt_2409941

            Did not use the AN75779 because I use a triggered image (only one image at a time that is generated upon request)

            I edited the simple GpifToUSB example.

             

            ==================This is the very simple DmaCallback:============================

             

            void

            GpifToUsbDmaCallback (

                    CyU3PDmaChannel   *chHandle,

                    CyU3PDmaCbType_t   type,

                    CyU3PDmaCBInput_t *input)

            {

            // uint8_t high,low;

            uint8_t i=0;

            #ifdef STREAMING_MANUAL

                if (type == CY_U3P_DMA_CB_PROD_EVENT)

                {

                     /*Change few pixels to black */

                     for(i=0; i<50; i++)

                     {

                        input->buffer_p.buffer[7680+i] = 0;

                      }

                    CyU3PDmaChannelCommitBuffer (chHandle, input->buffer_p.count, 0);

                }

                if (type == CY_U3P_DMA_CB_CONS_EVENT)

                {

                    /* Data transfer has been started. Enable the LPM disable loop. */

                    gDoLpmDisable = CyTrue;

                }

            #endif

            }

             

            ==================== This is the header with the relevant definitions. ======================

             

            #include "cyu3types.h"

            #include "cyu3usbconst.h"

            #include "cyu3externcstart.h"

             

             

            #define CY_FX_GPIFTOUSB_DMA_TX_SIZE        (0)                       /* DMA transfer size is set to infinite */

            #define CY_FX_GPIFTOUSB_THREAD_STACK       (0x1000)                  /* Bulk loop application thread stack size */

            #define CY_FX_GPIFTOUSB_THREAD_PRIORITY    (8)                       /* Bulk loop application thread priority */

            #define CY_FX_GPIFTOUSB_PATTERN            (0xAA)                    /* 8-bit pattern to be loaded to the source buffers. */

             

             

            /* Endpoint and socket definitions for the bulk source sink application */

             

             

            #define CY_FX_EP_CONSUMER               0x83    /* EP 3 IN */

            #define CY_FX_EP_CONSUMER_SOCKET        CY_U3P_UIB_SOCKET_CONS_3    /* Socket 1 is consumer */

            #define CY_FX_GPIF_PRODUCER_SOCKET      CY_U3P_PIB_SOCKET_0

             

             

            /* Burst mode definitions: Only for super speed operation. The maximum burst mode

            * supported is limited by the USB hosts available. The maximum value for this is 16

            * and the minimum (no-burst) is 1. */

             

             

            /* Burst length in 1 KB packets. Only applicable to USB 3.0. */

            #ifndef CY_FX_EP_BURST_LENGTH

            #define CY_FX_EP_BURST_LENGTH           (16)

            #endif

             

             

            /* Size of DMA buffers used by the application. Tried many values*/

            /*****

            #ifndef CY_FX_DMA_BUF_SIZE

            #define CY_FX_DMA_BUF_SIZE            (28800) // (26912) (16384) //(32768) (16384)

            #endif

            *******/

             

             

            /* Number of DMA buffers to be used on the channel. */

            #ifndef CY_FX_DMA_BUF_COUNT

            #define CY_FX_DMA_BUF_COUNT             (4)

            #endif

             

             

            /* Parameters for loop-back function. */

            #define CY_FX_EP_LOOP_OUT               (0x02)

            #define CY_FX_EP_LOOP_IN                (0x82)

            #define CY_FX_LOOP_PRODUCER_SOCK        CY_U3P_UIB_SOCKET_PROD_2

            #define CY_FX_LOOP_CONSUMER_SOCK        CY_U3P_UIB_SOCKET_CONS_2

             

             

            #ifndef  STREAMING_MANUAL

            #define  STREAMING_MANUAL (1)

            #endif

             

            ............

            • 3. Re: Trying to use the FX3 to capture images from OnSemi image sensor
              hppc

              To ensure that the GPIF and DMA buffers are in sync, the DMA reset mechanism can be used after each transfer. Please check the AN75779 example for DMA reset procedure. Also as no control signals are used, there is no need for any actual device connectivity on the GPIF II interface when using gpiftousb example. How are you make sure that the data sampling is proper? How is the GPIF-II project modified? Please check the Slave FIFO GPIF interface attached with the app note AN65974 - Designing with the EZ-USB® FX3™ Slave FIFO Interface.

              • 4. Re: Trying to use the FX3 to capture images from OnSemi image sensor
                tlbrkt_2409941

                Like in the AN75779, the  the GPIF reads the image data only when Frame and Line signals are on. The image contains a total of about 1M bytes. It starts only after specific request, and only 1 image is sent from the sensor. The first image is correct, but some how, the first few bytes of the  next image that is initiated and read only few seconds after, contains some data of the prev image. What do you mean by "reset procedure"?

                • 5. Re: Trying to use the FX3 to capture images from OnSemi image sensor
                  hppc

                  In the AN75779 CyFxUvcApplnStop function, the DMA channel and endpoint is cleared which will remove any previous image data already sampled. I am attaching the code corresponding to this. 

                   

                      /* Disable the GPIF state machine. */

                      CyU3PGpifDisable (CyFalse);

                      streamingStarted = CyFalse;

                      glDmaResetFlag = CY_FX_UVC_DMA_RESET_EVENT_NOT_ACTIVE;

                   

                   

                      /* Place the EP in NAK mode before cleaning up the pipe. */

                      CyU3PUsbSetEpNak (CY_FX_EP_BULK_VIDEO, CyTrue);

                      CyU3PBusyWait (125);

                   

                   

                      /* Reset and flush the endpoint pipe. */

                      CyU3PDmaMultiChannelReset (&glChHandleUVCStream);

                      CyU3PUsbFlushEp (CY_FX_EP_BULK_VIDEO);

                      CyU3PUsbSetEpNak (CY_FX_EP_BULK_VIDEO, CyFalse);

                      CyU3PBusyWait (125);

                   

                  Similarly in the CyFxUvcApplnStart the channel will be set ready for transfer.

                  • 6. Re: Trying to use the FX3 to capture images from OnSemi image sensor
                    tlbrkt_2409941

                    Thanks for the info.

                    I believe that there should be a way to receive the images without resting or clearing the buffers.

                    It is weird that  everything works fine if image size is up to 512X512X16 bits. Can not understand what goes wrong when receiving bigger images.

                    Can you help and tell where can I find a good documentation that explains the following:

                    • In what way the buffers are managed when a large stream of data is received from the GPIF?
                    • What are the rolls of the DMA buffer / buffer count? (Why not one big buffer)?
                    • What effect has the buffer size as requested by the Host? Should it be in any relation to the DMA buffer size / count?

                    Tried to read about these, but could not find good documentation.

                    • 7. Re: Trying to use the FX3 to capture images from OnSemi image sensor
                      hppc

                      AN75779 contains explanation of how the buffers are managed when a large stream of data is received from the GPIF. Also it is explained how to select a DMA buffer size to optimize USB throughput. Also you can go through FX3 programmers manual and FX3 TRM for more details which are available along with SDK.

                      With the current settings, this should work, but we need to conform the GPIF state machine is fine. Can you share the GPIF state machine. We can check how the data state machine is switching back to start receiving the new buffer.

                      • 8. Re: Trying to use the FX3 to capture images from OnSemi image sensor
                        tlbrkt_2409941

                        GPIF-SM.jpg

                        Please see the above image for the state machine as designed for the project.

                         

                        Regarding the documentation of the AN75779:

                        This is a quote from the "Ping Pong DMA buffers paragraph:

                         

                        A socket takes a finite amount of time (up to a

                        few microseconds) to switch from one DMA Descriptor to another after it fills or empties a DMA buffer. The socket will

                        not be able to transfer any data while this switch is in progress.

                         

                        The way I understand it, when the DMA buffer which I set its size in the 

                        #define CY_FX_DMA_BUF_SIZE is filled, the system drained it (to where?, and what is the CY_FX_DMA_BUF_COUNT ? ).

                        Anyway, as you can see, I use a buffer size of 28800 (count = 4), and so this switching must happen when I receive a 512X512X16 bits (262,164 bytes). As I mentioned before, everything works fine when receiving these images. But when changing to 768X768X16 images, there is an unexplained data that accumulated from prev. images. That is received at the beginning of each new incoming image.

                        I must understand more about what happens when a buffer is filled, and can not find good documentation for that.

                         

                         

                         

                        • 9. Re: Trying to use the FX3 to capture images from OnSemi image sensor
                          hppc

                          Since your state machine is using a single socket, the buffer switching will come into consideration. CY_FX_DMA_BUF_SIZE provides the buffer size allocated to the socket and the CY_FX_DMA_BUF_COUNT is the number of such buffers the DMA can queue. From the above mentioned firmware settings, it will queue 4 buffers of 16KB size.i.e, Once your 16KB gets filled the buffer will switch to next one(4 is the count used). This buffer switching happens multiple times in transferring a single frame as frame size is much higher than buffer size.

                           

                          Since you use only a single producer socket, there will be a delay in buffer switching when the buffer is getting filled. This buffer switching delay is around 100us. To avoid this we use two producer sockets in AN75779 and switch the sampling thread(thread switch wont have delay) between the two sockets.

                           

                          Now for 512x512x16 frame size and 16KB buffer size, exactly 16 lines(16x512x2 bytes) will be packed in each buffer. Here the horizontal blanking must be helping to hide the delay. In case of 768x768x16 frame size, the first buffer will be full with 10 full lines and a half line. Then the buffer switching delay will cause losing some lines of data. This can be a reason the higher resolution is not working proper. Still I wonder how the first frame is received properly.

                           

                          What is the horizontal blanking time in 512x512x16 and 768x768x16 frame size? Also can you try keeping a buffer size multiple of lines for 768x768x16 and check whether this is helping.