1 2 Previous Next 19 Replies Latest reply on Nov 19, 2019 3:47 AM by RashiV_61

    CX3 image data add leader and trailer

    haxu_299926

      I want to receive the date ,and first send a leader package, then a data package, and then a trailer package as the end. Similar to UVC header, but UVC header is not an independent buffer,I need the leader and trailer an  independent buffer.How can I implement this operation?How to get an empty dmabuffer,use the getbuffer api?

        • 1. Re: CX3 image data add leader and trailer
          RashiV_61

          Hello,

           

          Please let me know the size of the leader and trailer data.

          Why do you need an independent buffer for that?

           

          Regards,

          Rashi

          • 2. Re: CX3 image data add leader and trailer
            haxu_299926

            Hi,Rashi,

             

            the size of the leader is 52bytes and the trailer is 32bytes,I want to send the leader and trailer independent,not to send the buffer contains the leader and the valid image datas.

            leader packet

            data packt

            ...

            date packet

            trailer packet

            In the example of cycx3_uvc_ov5640, the CyCx3UvcAppDmaCallback function,when the type equal CY_U3P_DMA_CB_PROD_EVENT,it getbuffer and add the UVC header ,and then commit the buffer to consumer. it always in use of the same buffer.

            I want to send the leader packet when the frame start and send the trailer packet when the frame end, but I can't modify the GPIF statemachine,so I can't catch the point of the frame start. for that, I think whether I can send the leader packet when I received the first image date  buffer in the  CyCx3UvcAppDmaCallback function ,but I don't have the empty buffer.and how to get a new buffer,to use getbuffer?and then use the commitbuffer to send?

             

            I don't know whether you understand my problem,and do you have some good suggestions?

            • 3. Re: CX3 image data add leader and trailer
              RashiV_61

              Hello,

               

              I understand.

              As the DMA channel is created between the GPIF  (producer) and the USB (consumer) block. The modifications to the DMA buffer can be done in the DMA call back. Independent buffer cannot be added to the DMA buffers from the DMA callback.

               

              There are some possibilities when you want to add leader and trailer buffer:

               

              - The USB 3.0 will allow endpoint size as 16 x 1024 bytes. So when you will send only 52 bytes (leader buffer), it would be committed as a short packet. So in that micro frame instead of 16KB only 52 bytes will be sent. This will reduce the data throughput of your application.

               

              - If you can have FPGA between the Camera and CX3, then you can add these trailer and leader within FPGA and stream the data through CX3.

               

              - There is an option to configure the DMA channel in the overriding mode but it would be quite  complex. You can go through the API supporting this mode from the FX3APIguide. Please let me know if any queries on that.

               

               

              Regards,

              Rashi

              • 4. Re: CX3 image data add leader and trailer
                haxu_299926

                Hi,Rashi,

                 

                I don't want to use the FPGA between the Camera and CX3,because the reason I chose the cx3 is to reduce costs.

                and I can't reduce the data throughput of your application,so the method 1 and 2 seems to be Infeasible.

                I have read the FX3APIguide,but I still don't know  how to configure the DMA channel in the overriding mode, Can you give me an example?

                • 5. Re: CX3 image data add leader and trailer
                  RashiV_61

                  Hello,

                   

                  If you wan to go for DMA channel override mode, there will be reduction in data throughput.

                  As the leader is having 52 bytes and the total buffer size would be 16 KB, hence there would be a short packet committed to the host. This would effect the data throughput as you will be sending only 52 bytes instead of 16 KB in one micro fframe

                   

                  If you don't want to change the data throughput, I would suggest to send the leader and trailer along with the Frame data and then filter it out in the host application.

                   

                  Please let me know if you still go for DMA Override mode.

                   

                  Regards,

                  Rashi

                  • 6. Re: CX3 image data add leader and trailer
                    haxu_299926

                    Hi,Rashi,

                          I can't accept reduce the data throughput,Can I modify the gpif of the cx3?Can I create a new DMA channel for sending header and trailer packets?

                          Can I use the CyU3PDmaMultiChannelSetupSendBuffer,send the header packet?

                    • 7. Re: CX3 image data add leader and trailer
                      RashiV_61

                      Hello,

                       

                      - CyU3PDmaMultiChannelSetupSendBuffer API is used when DMA channel is in Override mode. The description of this API mentions it in FX3APIGuide.

                       

                      -Creating a DMA channel for sending the header and trailer is possible. But the endpoints used would be different. The host application should be programmed such that it would take the data from different endpoints. Synchronization of the Leader /Trailer need to be done with original data. This would need lot of changes.

                       

                      - CX3 has fixed GPIF state machine. I will let you know if we could help you on this.

                       

                      Regards,

                      Rashi

                       

                      • 8. Re: CX3 image data add leader and trailer
                        haxu_299926

                                                

                         

                        Hi,Rashi,

                             It seems that Creating a DMA channel for sending the header and trailer is Unworkable.Do you have another method to solve this problem? How do I know frame start,and first send the leader packet and then send the data packet

                        • 9. Re: CX3 image data add leader and trailer
                          haxu_299926

                          Hi,Rashi,

                           

                                 Can I change the DMA channel of the stream to MANUAL IN and MANUAL OUT MODE,I try to modify this ,but I found the function CyU3PDmaChannelCreate return error,the error code is ERROR_BAD_ARGUMENT

                          • 10. Re: CX3 image data add leader and trailer
                            RashiV_61

                            Hello,

                             

                            Can you share the snapshot of the DMA channel configuration that you are passing to CyU3PDmaChannelCreate function?

                             

                            For example:

                                     dmaCfg.size  =32768;

                                       dmaCfg.count = 2;

                                       dmaCfg.prodSckId = CY_FX_PRODUCER_USB_SOCKET;

                                       dmaCfg.consSckId =CY_U3P_CPU_SOCKET_CONS ;

                                       dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;

                                       // Enabling the callback for produce event.

                                       dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT;

                                      dmaCfg.cb =CyFxBulkSrcSinkDmaCallback1;

                                       dmaCfg.prodHeader = 0;

                                       dmaCfg.prodFooter = 0;

                                       dmaCfg.consHeader = 0;

                                       dmaCfg.prodAvailCount = 0;

                             

                             

                                       apiRetStatus = CyU3PDmaChannelCreate (&glChHandleSlFifoUtoP,

                                       CY_U3P_DMA_TYPE_MANUAL_IN, &dmaCfg);

                             

                            Regards,

                            Rashi

                            • 11. Re: CX3 image data add leader and trailer
                              haxu_299926

                              Hi,Rashi,

                               

                                      I change the DMA channel of the stream to MANUAL IN and MANUAL OUT MODE.

                              now I can create the dma channel successful,when I try to commit the dmabuffer to the consume, I can't catch the packet in the bushound,and then the second time get the buffer from the channel of glChHandleStreamOut,it will return the error of 0x45,the first time return is success.Can you tell me the problem of my code ,thank you very much!

                              the code is as follow:

                              In the function CyCx3UvcApplnInit:

                               

                                   stInDmaCfg.size                 = CX3_UVC_STREAM_BUF_SIZE;

                                   stInDmaCfg.count                = CX3_UVC_STREAM_BUF_COUNT;

                                   stInDmaCfg.consHeader           = 0;

                                   stInDmaCfg.consSckId            = CY_U3P_CPU_SOCKET_CONS;

                                   stInDmaCfg.prodSckId            = CX3_PRODUCER_PPORT_SOCKET_1;

                                   stInDmaCfg.dmaMode              = CY_U3P_DMA_MODE_BYTE;

                                   stInDmaCfg.notification         = CY_U3P_DMA_CB_PROD_EVENT;

                                   stInDmaCfg.cb                   = CyCx3UvcAppDmaCallback;

                                   stInDmaCfg.prodHeader           = 0;

                                   stInDmaCfg.prodFooter           = 0;

                                   stInDmaCfg.consHeader           = 0;

                                   stInDmaCfg.prodAvailCount       = 0;

                               

                               

                                   status = CyU3PDmaChannelCreate (&glChHandleStreamIn,

                                  CY_U3P_DMA_TYPE_MANUAL_IN , &stInDmaCfg);

                                   if (status != CY_U3P_SUCCESS)

                                   {

                                    CyU3PDebugPrint (4, "\n\rAppInit.....:DmaMultiChannelCreate Err = 0x%x", status);

                                   }

                                   CyU3PThreadSleep(100);

                               

                               

                                   stOutDmaCfg.size                 = CX3_UVC_STREAM_BUF_SIZE;

                                   stOutDmaCfg.count                = 1;

                                   stOutDmaCfg.consHeader           = 0;

                                   stOutDmaCfg.consSckId            = CY_U3P_UIB_SOCKET_CONS_1;

                                   stOutDmaCfg.prodSckId            = CY_U3P_CPU_SOCKET_PROD;

                                   stOutDmaCfg.dmaMode              = CY_U3P_DMA_MODE_BYTE;

                                   stOutDmaCfg.notification         = CY_U3P_DMA_CB_CONS_EVENT;

                                   stOutDmaCfg.cb                   = CyCx3UvcAppDmaCallback;

                                   stOutDmaCfg.prodHeader           = 0;

                                   stOutDmaCfg.prodFooter           = 0;

                                   stOutDmaCfg.consHeader           = 0;

                                   stOutDmaCfg.prodAvailCount       = 0;

                               

                               

                                   status = CyU3PDmaChannelCreate (&glChHandleStreamOut,

                                  CY_U3P_DMA_TYPE_MANUAL_OUT , &stOutDmaCfg);

                                   if (status != CY_U3P_SUCCESS)

                                   {

                                    CyU3PDebugPrint (4, "\n\rAppInit,,,,,:DmaMultiChannelCreate Err = 0x%x", status);

                                   }

                                   CyU3PThreadSleep(100);

                               

                               

                              /* DMA callback function to handle the produce and consume events. */

                                  void

                              CyCx3UvcAppDmaCallback (

                                      CyU3PDmaChannel   *chHandle,

                                      CyU3PDmaCbType_t  type,

                                      CyU3PDmaCBInput_t *input

                                      )

                              {

                                  CyU3PDmaBuffer_t DmaBuffer;

                                  CyU3PDmaBuffer_t DmaOutBuffer;

                                  CyU3PReturnStatus_t status = CY_U3P_SUCCESS;

                                  CyU3PDebugPrint (4, "\n\CyCx3UvcAppDmaCallback:type  = 0x%x",type);

                                  if (type == CY_U3P_DMA_CB_PROD_EVENT)

                                  {

                                      /* This is a produce event notification to the CPU. This notification is

                                       * received upon reception of every buffer. The buffer will not be sent

                                       * out unless it is explicitly committed. The call shall fail if there

                                       * is a bus reset / usb disconnect or if there is any application error. */

                               

                               

                                      /* Disable USB 3.0 LPM while Buffer is being transmitted out*/

                                      if ((CyU3PUsbGetSpeed () == CY_U3P_SUPER_SPEED) && (doLpmDisable))

                                      {

                                          CyU3PUsbLPMDisable ();

                                          CyU3PUsbSetLinkPowerState (CyU3PUsbLPM_U0);

                                          CyU3PBusyWait (200);

                               

                               

                                          doLpmDisable = CyFalse;

                              #ifdef RESET_TIMER_ENABLE

                                          CyU3PTimerStart (&UvcTimer);

                              #endif

                                      }

                               

                               

                                      status = CyU3PDmaChannelGetBuffer(&glChHandleStreamIn, &DmaBuffer, CYU3P_WAIT_FOREVER);

                               

                               

                                      status = CyU3PDmaChannelGetBuffer(&glChHandleStreamOut, &DmaOutBuffer, CYU3P_NO_WAIT);

                                     // CyU3PDebugPrint (4, "\n\CyCx3UvcAppDmaCallback:status2  = 0x%x",status);

                                //      while (status == CY_U3P_SUCCESS)

                                      {

                                   

                                /* Commit Buffer to USB*/

                                CyU3PMemCopy(DmaOutBuffer.buffer, DmaBuffer.buffer, DmaBuffer.count);

                               

                               

                              // status = CyU3PDmaChannelDiscardBuffer(&glChHandleStreamIn);

                              // if(status != CY_U3P_SUCCESS)

                              // {

                              // CyU3PDebugPrint(1,"\r\n CyU3PDmaChannelDiscardBuffer failed error = %x",status);

                              // //CyFxAppErrorHandler(stat);

                              // }

                               

                               

                                status = CyU3PDmaChannelCommitBuffer (&glChHandleStreamOut, (DmaBuffer.count), 0);

                                    //   CyU3PDebugPrint (4, "\n\CyCx3UvcAppDmaCallback:status  = 0x%x,0x%x",status, *(uint8_t *)DmaOutBuffer.buffer);

                                if (status != CY_U3P_SUCCESS)

                                {

                                  CyU3PEventSet(&glCx3Event, CX3_DMA_RESET_EVENT,CYU3P_EVENT_OR);

                                //   break;

                                }

                                else

                                {

                                glDMATxCount++;

                                glDmaDone++;

                                }

                                          }

                                        //  glActiveSocket ^= 1; /* Toggle the Active Socket */

                                       //   status = CyU3PDmaChannelGetBuffer(chHandle, &DmaBuffer, CYU3P_WAIT_FOREVER);

                                      }

                                  }

                                  else if(type == CY_U3P_DMA_CB_CONS_EVENT)

                                  {

                               

                               

                                  glDmaDone--;

                                      /* Check if Frame is completely transferred */

                                      glIsStreamingStarted = CyTrue;

                                      if((glHitFV == CyTrue) && (glDmaDone == 0))

                                      {

                                          glHitFV = CyFalse;

                               

                               

                                          glDMATxCount=0;

                              #ifdef RESET_TIMER_ENABLE

                                          CyU3PTimerStop (&UvcTimer);

                              #endif

                               

                               

                                         // if (glActiveSocket)

                                              CyU3PGpifSMSwitch(CX3_INVALID_GPIF_STATE, CX3_START_SCK1,

                                                      CX3_INVALID_GPIF_STATE, ALPHA_CX3_START_SCK1, CX3_GPIF_SWITCH_TIMEOUT);

                              //           // else

                                           //   CyU3PGpifSMSwitch(CX3_INVALID_GPIF_STATE, CX3_START_SCK0,

                                           //          CX3_INVALID_GPIF_STATE, ALPHA_CX3_START_SCK0, CX3_GPIF_SWITCH_TIMEOUT);

                              //

                                          CyU3PUsbLPMEnable ();

                                          doLpmDisable = CyTrue;

                              //#ifdef RESET_TIMER_ENABLE

                                          CyU3PTimerModify (&UvcTimer, TIMER_PERIOD, 0);

                              //#endif

                                      }

                                  }

                              }

                              • 12. Re: CX3 image data add leader and trailer
                                RashiV_61

                                Hello,

                                 

                                Please let me know the reason for using Manual IN and Manual OUT channel.

                                Assuming that you want to implement DMA Override Mode, you don't need MANUAL IN and MANUAL OUT channel. You can use the MANY_TO_ONE_ MANUAL_DMA channel and override it using CyU3PDmaChannelSetupSendBuffer API

                                 

                                Please refer to the firmware in this thread How to send debug data out an existing dma channel  (USBUART example in the FX3 SDK) (refer attachment)

                                You can understand how to use a DMA channel in Override mode. You can also refer to C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\basic_examples\cyfxflashprog which uses CyU3PDmaChannelSetupSendBuffer and CyU3PDmaChannelSetupRecvBuffer API (DMA override mode)

                                 

                                From your previous response:

                                I can't catch the packet in the bushound,and then the second time get the buffer from the channel of glChHandleStreamOut,it will return the error of 0x45,the first time return is success.

                                >> The error 0x45 is the timeout error which occurs when the DMA buffer is not ready either FULL/EMPTY. Also,  the GPIF state machine is configured for two producer sockets and the DMA channel you created consists of one producer socket. I am not able to understand the logic behind the code in CyCx3UvcAppDmaCallback.

                                The header and trailer should be given by the CPU and not GPIF socket and then that buffer should be sent to USB socket.

                                 

                                According to your application, DMA override mode would work fine.

                                 

                                Please make it clear which method would you like t use to send a separate buffer for Header and trailer. Is it the DMA override mode?

                                 

                                Regards,

                                Rashi

                                 

                                 

                                • 13. Re: CX3 image data add leader and trailer
                                  haxu_299926

                                  Hi,Rashi,

                                         Thank you very much for your reply.I tried  the DMA override mode like the example that you reply with me.but I met a problem:

                                  I modify the  CyCx3UvcAppDmaCallback function,now I can send the packet using the CyU3PDmaMultiChannelSetupSendBuffer,but  then I want to use the CyU3PDmaMultiChannelSetXfer function as your example ,but it return  error code 0x43.and the next package can't send out,

                                  the dma channel seem to be abnormal.I don‘t hnow why?
                                          status = CyU3PDmaMultiChannelGetBuffer(chHandle, &DmaBuffer, CYU3P_NO_WAIT);
                                          while (status == CY_U3P_SUCCESS)
                                          {
                                              /* Add Headers*/
                                              if(DmaBuffer.count < CX3_UVC_DATA_BUF_SIZE)
                                              {
                                                  CyCx3UvcAddHeader ((DmaBuffer.buffer - CX3_UVC_PROD_HEADER), CX3_UVC_HEADER_EOF);
                                                  glHitFV = CyTrue;
                                                  glFrameCount = 0;
                                              }
                                              else
                                              {

                                   

                                                          CyCx3UvcAddHeader ((DmaBuffer.buffer - CX3_UVC_PROD_HEADER), CX3_UVC_HEADER_FRAME);

                                                   if(glFrameCount == 0)
                                                   {
                                                      buf_p.buffer = trailer;
                                                      buf_p.status = 0;
                                                      buf_p.size    = 52;
                                                      buf_p.count   = 52;

                                                   CyU3PDmaMultiChannelReset (chHandle);
                                                      status =CyU3PDmaMultiChannelSetupSendBuffer(chHandle, &buf_p, 0);
                                                      if(status != 0)
                                                      {  

                                                                CyU3PDebugPrint(4,"\n\CyCx3UvcAppDmaCallback: status = %x\n", status);
                                                      }

                                                      CyU3PBusyWait(1000);
                                                      status =  CyU3PDmaMultiChannelSetXfer(chHandle,0,0);
                                                    if (status != CY_U3P_SUCCESS)
                                                   {
                                                          CyU3PDebugPrint(4,"\n\CyU3PDmaMultiChannelSetXfer: status = %x\n", status);
                                                         break;
                                                   }
                                          }

                                          glFrameCount = 1;
                                         }

                                   

                                   

                                  • 14. Re: CX3 image data add leader and trailer
                                    RashiV_61

                                    Hello,

                                     

                                    Apologies. I shared the wrong firmware

                                    Please let me know DMA channel type that you are using

                                    The 0x43 error occurs when the DMA channel is not in configured state. CyU3PDmaMultiChannelSetXfer can only be called when DMA channel id in configured state. CyU3PDmaMultiChannelSetupSendBuffer  sets the DMA channelstate to DMA override. This is the reason for the error. That means you can't call CyU3PDmaMultiChannelSetXfer after CyU3PDmaMultiChannelSetupSendBuffer

                                     

                                    Can you not put this API in the callback function and instead create a different function to  send the leader and trailer.

                                     

                                    If this doesn't work, please share the firmware i.e " .c" files you are working on

                                     

                                    Regards,

                                    Rashi

                                    1 2 Previous Next