GPIF-to-Isochronous behavior?

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

cross mob
Anonymous
Not applicable

I'm trying to use the FX3 to be a sort of logic analyzer/digitizer, and as such I'm trying to get it to load 16-bit data off of the GPIF bus at 100 MHz.  I've played around with the isochronous tests and my computer seems to have plenty of headroom.  Even in the basic configuration, I can get 256 MB/sec without any hiccups directly into my PC-side application.

As soon as I try hooking up the GPIF bus, things come to a screeching slowdown.  I start getting tons of CYU3P_PIB_ERR_THR0_WR_OVERRUN faults and the data rate goes to 8 MB/sec -- though it appears I have my state machine set up correctly as I am getting good data off the GPIF bus! It looks like it's correctly synchronously operating.

Additionally, if I use the Streamer.exe application it chokes up when initializing... Though once started it runs nice and cool.

Some places I may be getting snagged at, so I'm including them:

     pibClock.clkDiv      = 4;
     pibClock.clkSrc      = CY_U3P_SYS_CLK;
     pibClock.isHalfDiv   = CyFalse;
     pibClock.isDllEnable = CyFalse;
     apiRetStatus = CyU3PPibInit (CyTrue, &pibClock);
     if (apiRetStatus != CY_U3P_SUCCESS)
     {
         CyU3PDebugPrint (CY_FX_DEBUG_PRIORITY, "P-port Initialization failed, Error Code=%d\r\n", apiRetStatus);
         CyFxAppErrorHandler (apiRetStatus);
     }

Setting up the system for the 400 MHz bus:

     ///Confusing but seems to set it up so the SYS_CLK can be 400 MHz. from https://community.cypress.com/thread/21688    
     CyU3PSysClockConfig_t clkCfg = {
                             CyTrue,
                             2, 2, 2,
                             CyFalse,
                             CY_U3P_SYS_CLK
     };
     status = CyU3PDeviceInit (&clkCfg);

Configuring the GPIF and DMA

      CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof (epCfg));
      epCfg.enable   = CyTrue;
      epCfg.epType   = CY_U3P_USB_EP_ISO;
      epCfg.burstLen = (usbSpeed == CY_U3P_SUPER_SPEED) ? (CY_FX_ISO_BURST) : 1;
      epCfg.streams  = 0;     epCfg.pcktSize = size;     epCfg.isoPkts  = isoPkts;

      /* Consumer endpoint configuration */
      apiRetStatus = CyU3PSetEpConfig(CY_FX_EP_CONSUMER, &epCfg);
      if (apiRetStatus != CY_U3P_SUCCESS)
      {
          CyU3PDebugPrint (4, "CyU3PSetEpConfig failed, Error code = %d\n", apiRetStatus);
          CyFxAppErrorHandler (apiRetStatus);
      }

      /* Flush the endpoint memory */
     CyU3PUsbFlushEp(CY_FX_EP_CONSUMER);
      /* Only the EP needs to be configured with the correct parameters. The DMA channel can always be prepared
        to allow the greatest bandwidth possible.      */
     dmaCfg.size = ((size + 0x0F) & ~0x0F);
     if (usbSpeed != CY_U3P_FULL_SPEED)
     {
         dmaCfg.size *= CY_FX_ISO_PKTS;
     }

      /* Multiply the buffer size with the burst value for performance improvement. */
//    dmaCfg.size          *= CY_FX_ISO_BURST; //XXX CNL This should be DMA_OUT_BUF_SIZE shouldn't it?
      dmaCfg.size           = DMA_IN_BUF_SIZE;
      dmaCfg.count          = CY_FX_ISOSRC_DMA_BUF_COUNT;
      dmaCfg.prodSckId      = CY_FX_PRODUCER_PPORT_SOCKET; // Was CY_U3P_CPU_SOCKET_PROD; XXX CNLohr
      dmaCfg.consSckId      = CY_FX_EP_CONSUMER_SOCKET;
      dmaCfg.dmaMode        = CY_U3P_DMA_MODE_BYTE;
      dmaCfg.notification   = CY_U3P_DMA_CB_CONS_EVENT;
      dmaCfg.cb             = 0;  //CyFxIsoSrcDmaCallback; XXX CNL
      dmaCfg.prodHeader     = 0;
      dmaCfg.prodFooter     = 0;
      dmaCfg.consHeader     = 0;
      dmaCfg.prodAvailCount = 0;
      //apiRetStatus = CyU3PDmaChannelCreate (&glChHandleIsoSrc, CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaCfg); XXX CNL
      apiRetStatus = CyU3PDmaChannelCreate (&glChHandleIsoSrc, CY_U3P_DMA_TYPE_AUTO, &dmaCfg);
      if (apiRetStatus != CY_U3P_SUCCESS)
      {
         CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
         CyFxAppErrorHandler(apiRetStatus);
      }

      apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleIsoSrc, CY_FX_ISOSRC_DMA_TX_SIZE);
      if (apiRetStatus != CY_U3P_SUCCESS)
      {
         CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer Failed, Error code = %d\n", apiRetStatus);
         CyFxAppErrorHandler(apiRetStatus);
      }
      /* Start the GPIF state machine which will read and write data to/from SRAM whenever requested */
      apiRetStatus = CyU3PGpifSMStart (START, ALPHA_START);
      if (apiRetStatus != CY_U3P_SUCCESS)
      {
          CyU3PDebugPrint (CY_FX_DEBUG_PRIORITY, "CyU3PGpifSMStart Failed, Error code = %d\r\n", apiRetStatus);
          CyFxAppErrorHandler (apiRetStatus);
      }

You can see I've pretty much shamelessly ripped off the Iso test... I will probably go back and rewrite cause there's other features I want to add don't want to start from something that's not working.

#define CY_FX_ISOSRC_DMA_TX_SIZE        (0)             /* DMA transfer size is set to infinite */
#define CY_FX_ISOSRC_THREAD_STACK       (0x1000)        /* Application thread stack size */
#define CY_FX_ISOSRC_THREAD_PRIORITY    (8)             /* Application thread priority */
#define CY_FX_ISOSRC_PATTERN            (0xAA)          /* 8-bit pattern to be loaded to the source buffers. */

/* Endpoint and socket definitions for the bulkloop application */
/* Note: For USB 2.0 the endpoints and corresponding sockets are one-to-one mapped
          i.e. EP 1 is mapped to UIB socket 1 and EP 2 to socket 2 so on */

#define CY_FX_EP_CONSUMER               0x83    /* EP 3 IN */
#define CY_FX_EP_CONSUMER_SOCKET        CY_U3P_UIB_SOCKET_CONS_3    /* Socket 3 is consumer */

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

#define CY_FX_ISOSRC_DMA_BUF_COUNT      (4)     /* Number of buffers in the DMA channel. (Now applied to GPIF) */
#define CY_FX_ISO_PKTS                  (2)     /* Number of bursts per microframe. */
#define CY_FX_ISO_BURST                 (16)    /* Number of packets per burst. */ 

//Below here is from the fast_gpif2 stuff based on SRAMMASTER
#define DMA_IN_BUF_SIZE                         (1024)  /* Size of DMA buffer used for SRAM to USB transfer. */
#define CY_FX_PRODUCER_PPORT_SOCKET             (CY_U3P_PIB_SOCKET_0)           /* GPIF Socket 0 is producer. */

There's still a lot I don't understand, like exactly how to start/stop the DMA to/from the GPIF bus... And I want to try to make a more complicated option with it to allow it to send data slower if desired, but, if I can't get it to operate at 100 MHz, I may abandon the project.

FIRST EDIT: Sorry, seems this thing ate my formatting.... I'm trying to fix it.

0 Likes
1 Solution
Anonymous
Not applicable

Yay! Found the problem.  I was using the wrong value when setting up the DMA buffer size.  It was using a size significantly smaller than the 32,768 I intended to use.

Now, I'm on CRUISE CONTROL FOR COOL getting 200,736,768 bytes per second!

Wonder why it's not exactly 200,000,000 but I'm cool.

View solution in original post

0 Likes
1 Reply
Anonymous
Not applicable

Yay! Found the problem.  I was using the wrong value when setting up the DMA buffer size.  It was using a size significantly smaller than the 32,768 I intended to use.

Now, I'm on CRUISE CONTROL FOR COOL getting 200,736,768 bytes per second!

Wonder why it's not exactly 200,000,000 but I'm cool.

0 Likes