7 Replies Latest reply on Jul 22, 2020 3:48 AM by AlEr_4025481

    Cyfxgpiftousb example and CYU3P_PIB_ERR_THR0_WR_OVERRUN

    AlEr_4025481

      Hello,

       

      I took basic cyfxgpiftousb example from c:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\basic_examples\ and added CyU3PPibRegisterCallback to the sources to see if there is some events happen during GPIF to DMA transfer. I was surprised a lot when I saw in output CYU3P_PIB_ERR_THR0_WR_OVERRUN errors.

       

      debug initialized
      USB event: 11 0
      About to connect to USB host
      USB event: 0 1
      CY_U3P_USB_EVENT_CONNECT detected
      CyFxApplnInit complete
      USB event: 4 1
      USB event: 8 0
      USB event: 5 1
      GpifToUsbDmaCallback: 32768 bytes commited
      GpifToUsbDmaCallback: 32768 bytes commited
      GpifToUsbDmaCallback: 32768 bytes commited
      GpifToUsbDmaCallback: 32768 bytes commited
      CYU3P_PIB_ERR_THR0_WR_OVERRUN
      CYU3P_PIB_ERR_THR0_WR_OVERRUN
      

       

      As I think these error happen while IN_DATA action trying to work during DMA buffers are switching. Am I right? If so, how can I pause the data input process until next buffer will be ready? My modified source code is attached.

        • 1. Re: Cyfxgpiftousb example and CYU3P_PIB_ERR_THR0_WR_OVERRUN
          AlEr_4025481

          Just modified again source code above closer to my real task. I switched GPIF state machine to master async mode with one RD output. All I need at this moment is collecting 16-bit words with automatically RD strobing. As I see CYU3P_PIB_ERR_THR0_WR_OVERRUN still happens.

          2020-07-21_11-49-49.png

          2020-07-21_11-49-04.png

           

          debug initialized
          USB event: 11 0
          About to connect to USB host
          CyFxApplnInit complete
          USB event: 2 0
          USB event: 0 0
          CY_U3P_USB_EVENT_CONNECT detected
          USB event: 4 0
          USB event: 6 1
          USB event: 4 0
          USB event: 6 1
          USB event: 5 1
          GpifToUsbDmaCallback: 32768 bytes commited
          CYU3P_PIB_ERR_THR0_WR_OVERRUN
          GpifToUsbDmaCallback: 32768 bytes commited
          CYU3P_PIB_ERR_THR0_WR_OVERRUN
          GpifToUsbDmaCallback: 32768 bytes commited
          CYU3P_PIB_ERR_THR0_WR_OVERRUN
          GpifToUsbDmaCallback: 32768 bytes commited
          CYU3P_PIB_ERR_THR0_WR_OVERRUN
          
          • 2. Re: Cyfxgpiftousb example and CYU3P_PIB_ERR_THR0_WR_OVERRUN
            AlEr_4025481

            Well, my brain damage continues. I modified state machine as shown below and replaced CyU3PDmaChannelConfig_t by CyU3PDmaMultiChannelConfig_t. It looks like CYU3P_PIB_ERR_THR0_WR_OVERRUN finally gone, but DMA commit errors happen.

            2020-07-21_15-36-39_LBL.png

            My DMA multi channel config:

            CyU3PDmaMultiChannelConfig_t dmaMCfg;
                dmaMCfg.size  = 1024;
                dmaMCfg.count = 1;
                dmaMCfg.validSckCount = 2;
                dmaMCfg.prodSckId[0] = CY_U3P_PIB_SOCKET_0;
                dmaMCfg.prodSckId[1] = CY_U3P_PIB_SOCKET_1;
                dmaMCfg.consSckId[0] = CY_FX_EP_CONSUMER_SOCKET;
                dmaMCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
                dmaMCfg.prodHeader = 0;
                dmaMCfg.prodFooter = 0;
                dmaMCfg.consHeader = 0;
                dmaMCfg.prodAvailCount = 0;
                dmaMCfg.notification = CY_U3P_DMA_CB_CONS_SUSP | CY_U3P_DMA_CB_PROD_EVENT;;
                dmaMCfg.cb = GpifToUsbDmaMultiCallback;
            

             

            My GpifToUsbDmaMultiCallback:

            void
            GpifToUsbDmaMultiCallback (
                    CyU3PDmaMultiChannel *chHandle, /* Handle to the DMA channel. */
                    CyU3PDmaCbType_t      type,     /* Callback type.             */
                    CyU3PDmaCBInput_t    *input)    /* Callback status.           */
            {
                uint8_t index = 0;
                CyU3PDmaBuffer_t buf_p;
                CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
            
            
                CyU3PDebugPrint (4, "GpifToUsbDmaMultiCallback called\r\n");
            ...
                        buf_p.buffer[0x0000] = DataSignature++;
                        buf_p.buffer[buf_p.count - 1] = DataSignature++;
            ...
            }
            

             

            Debug output:

            debug initialized
            USB event: 11 0
            About to connect to USB host
            CyFxApplnInit complete
            USB event: 2 0
            USB event: 0 0
            CY_U3P_USB_EVENT_CONNECT detected
            USB event: 4 0
            USB event: 6 1
            USB event: 4 0
            USB event: 6 1
            USB event: 5 1
            GpifToUsbDmaMultiCallback called
            GpifToUsbDmaMultiCallback: 1024 bytes commited, index = 0
            GpifToUsbDmaMultiCallback: 1024 bytes commited, index = 1
            GpifToUsbDmaMultiCallback called
            CyU3PDmaMultiChannelCommitBuffer failed, index = 0, Error code = 71
            CyU3PDmaMultiChannelCommitBuffer failed, index = 1, Error code = 71
            

             

            First 1024 bytes received with wrong signature (must be 0x0000 at the beginning and 0x0001 at the end):

            2020-07-21_16-07-23.png

            So now my questions are:

            1. Why buffer commit errors happen?

            2. Why DataSignature at the beginning and at the end of the buffer is incorrect?

            • 3. Re: Cyfxgpiftousb example and CYU3P_PIB_ERR_THR0_WR_OVERRUN
              AlEr_4025481

              I'm totally stuck! Error code 71 means CY_U3P_ERROR_INVALID_SEQUENCE (invalid function call sequence). Can't imagine what exactly I'm doing wrong...

              • 4. Re: Cyfxgpiftousb example and CYU3P_PIB_ERR_THR0_WR_OVERRUN
                HemanthR_06

                Hi,

                 

                Please use the debug library which is posted in post number 11 of commit error and back flow error in UVC AN75779 and test

                (Note: This library is just for debug purpose and should not be considered as standard release)

                In your firmware, make changes to PROD_EVENT handling in GpifToUsbDmaMultiCallback as below:

                 

                if (type == CY_U3P_DMA_CB_PROD_EVENT)

                    {

                        /* Since this is a many to one channel, there can be a case where one producer

                         * is faster than the other out of sequence produce events. This means that

                         * we have to check for buffers with all producer sockets. In this case there

                         * are two producers and so loop twice or until there are valid buffers. */

                        for (index = 0; index < 2; index++)

                        {

                            status = CyU3PDmaMultiChannelGetBuffer (chHandle, &buf_p, CYU3P_NO_WAIT);

                            if (status != CY_U3P_SUCCESS)

                            {

                            CyU3PDebugPrint (4, "GetFail\r\n");

                                /* This can be a valid case. Just break. */

                                break;

                            }

                 

                 

                            else

                            {

                            buf_p.buffer[0x0000] = DataSignature++;

                            buf_p.buffer[buf_p.count - 1] = DataSignature++;

                 

                 

                            /* 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. */

                            status = CyU3PDmaMultiChannelCommitBuffer (chHandle, buf_p.count, 0);

                            if (status != CY_U3P_SUCCESS)

                            {

                            CyU3PDebugPrint (4, "CyU3PDmaMultiChannelCommitBuffer failed, index = %d, Error code = %d\r\n", index, status);

                            } else

                            CyU3PDebugPrint (4, "GpifToUsbDmaMultiCallback: %d bytes commited, index = %d\r\n", buf_p.count, index);

                            }

                        }

                 

                 

                        /* Increment the counter. */

                        //glDMARxCount++;

                    }

                }

                 

                Please, also note that, it is not recommended to place DebugPrints in dmacallbacks. (You can do it now just for testing)

                 

                In multi channel, the dma buffers should be filled and emptied in a pingpong fashion.

                 

                Regards,

                Hemanth

                • 5. Re: Cyfxgpiftousb example and CYU3P_PIB_ERR_THR0_WR_OVERRUN
                  AlEr_4025481

                  Hi Hemanth,

                   

                  Thanks a lot for your reply! I have done as you said, placed libcyfxapi.a to c:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\fw_lib\1_3_4\fx3_debug\ and switched to debug build. My GpifToUsbDmaMultiCallback now includes:

                   

                      if (type == CY_U3P_DMA_CB_PROD_EVENT)
                      {
                          /* Since this is a many to one channel, there can be a case where one producer
                           * is faster than the other out of sequence produce events. This means that
                           * we have to check for buffers with all producer sockets. In this case there
                           * are two producers and so loop twice or until there are valid buffers. */
                          for (index = 0; index < 2; index++)
                          {
                              status = CyU3PDmaMultiChannelGetBuffer (chHandle, &buf_p, CYU3P_NO_WAIT);
                              if (status != CY_U3P_SUCCESS)
                              {
                                   CyU3PDebugPrint (4, "GetFail\r\n");
                                   /* This can be a valid case. Just break. */
                                   break;
                              } else {
                  
                              buf_p.buffer[0x0000] = DataSignature++;
                              buf_p.buffer[buf_p.count - 1] = DataSignature++;
                  
                              /* 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. */
                              status = CyU3PDmaMultiChannelCommitBuffer (chHandle, buf_p.count, 0);
                              if (status != CY_U3P_SUCCESS)
                              {
                                   CyU3PDebugPrint (4, "CyU3PDmaMultiChannelCommitBuffer failed, index = %d, Error code = %d\r\n", index, status);
                              } else
                                   CyU3PDebugPrint (4, "GpifToUsbDmaMultiCallback: %d bytes commited, index = %d\r\n", buf_p.count, index);
                              }
                          }
                  

                   

                  My debug output as soon as code started:

                  debug initialized
                  USB event: 11 0
                  About to connect to USB host
                  CyFxApplnInit complete
                  USB event: 2 0
                  USB event: 0 0
                  CY_U3P_USB_EVENT_CONNECT detected
                  USB event: 4 0
                  USB event: 6 1
                  USB event: 4 0
                  USB event: 6 1
                  USB event: 5 1
                  GpifToUsbDmaMultiCallback called
                  GpifToUsbDmaMultiCallback: 1024 bytes commited, index = 0
                  GpifToUsbDmaMultiCallback: 1024 bytes commited, index = 1
                  GpifToUsbDmaMultiCallback called
                  GetFail
                  

                   

                  Every time I receive 1024 bytes from 0x81 bulk EP three lines are add:

                  GpifToUsbDmaMultiCallback called
                  GpifToUsbDmaMultiCallback: 1024 bytes commited, index = 0
                  GetFail
                  

                   

                  Data signature in the buffers increments correctly: 0x0000-0x0001, 0x0002-0x0003 and so on.

                  • 6. Re: Cyfxgpiftousb example and CYU3P_PIB_ERR_THR0_WR_OVERRUN
                    HemanthR_06

                    Hi,

                     

                    Yes, the above logs are as expected. GetFail which is seen in line 17 of debug output is because both the buffers of the channel are committed to USB. GetFail in line 3 of last snippet is because only 1 buffer is made available by PIB block with data to commit to USB.

                     

                    FYI:

                    1. Assume that dmaMCfg.count is 2 -> in which case socket 0 will have 2 buffers (name it buffer1 , buffer2) and socket 1 will have 2 buffers (name it buffer3, buffer4). Total 4.

                    2. Let's say the following are filled -> buffer1, buffer2

                    3. In this case, first call to CyU3PDmaMultiChannelGetBuffer() will pass which would give buffer1 to commit to USB. But next call for CyU3PDmaMultiChannelGetBuffer() would fail as expects buffer3 next -> this is the ping pong requirement which I mentioned in my last post. -> CyU3PDmaMultiChannelGetBuffer() will not succeed even though buffer2 is full instead it now looks at socket1's buffer.

                     

                    Regards,

                    Hemanth

                    • 7. Re: Cyfxgpiftousb example and CYU3P_PIB_ERR_THR0_WR_OVERRUN
                      AlEr_4025481

                      Hi Hemanth,

                       

                      thanks for your explanation, it's very helpful for me. Later I plan to attach FPGA with a counter on data bus, to be sure that buffers are switching correctly and received data is monotonic.

                       

                      At this moment I think this thread can be closed.