1 Reply Latest reply on Nov 28, 2014 7:27 AM by shashank.rebbapragada

    Periodic data transfer delay during Isochrnonous transfer using Auto mode DMA


       I am transferring data from a WIndows 8 PC to a PSoC 5LP board connected to PC thrugh USB 2.0.


      The host application, written in VC++, sends data in a loop to PSoC over an Isochronous OUT EP (EP6) using XferData() API call.


      ISOC OUT EP (EP6) is configured with maximum packet size of 1023 bytes. The firmware uses Auto Mode DMA to transfer data from OUT EP SRAM to local buffer (array).


      The main loop in host application is:


      bufSizeMultiplier = 8;


      maxPktSize = IsocOutEpt->MaxPktSize; // Max packet size of the ISOC OUT EP (configured to be 1023 bytes)


      bufSize = maxPktSize * bufSizeMultiplier;  // Buffer size (bufSize) is 8 times the Max packet size of the ISOC OUT EP




               XferDataBuffer = new UCHAR[bufSize]; // Allocate the buffer (array) of size bufSize


      // Initialize the buffer with some dummy data


      for (i = 0; i < bufSize; i++) {


      xferDataBuffer[i] = i;






      if ((IsocOutEpt->XferData(xferDataBuffer, bufSize))) // Transfer the buffer data to PSoC




      //   printf("Sender: XferData succeeded\n");






      printf("Sender: XferData failed\n");





      The firmware code uses USBFS_1_ReadOutEP() call to initialize and configure the DMA whenever  the device configuration changes (in our case, it just changes once in the begining, so this call is executed only once in the begining). In subsequent loops, firmware waits until the OUT buffer is full, and then re-arms the EP6 OUT end point using USBFS_1_EnableOutEP() call.




      In order to see the time taken by the DMA operations, we use two GPIO pins of PSoC. Pin 1 is toggled (between high(1) and low(0)) only when the configuration changes and pin 2 is toggled every time before checking the EP buffer to be full and re-arming the EP6 OUT end point. The value (signals) on these pins are monitored using Oscilloscope. Since in our program runs, the configuration just changed only once in the begining, Pin1 becomes high and stays high forever (see the yellow signal in enclosed images).




      However, we noticed following behavior for Pin 2: Signal on Pin2 toggles bewteen High and Low 4 times (with duration of nearly 1 millisec), and then stays low for nearly 5 to 6 millisec. The signal then again becomes high and toggles between high and low values 4 times, and then remain low for nearly 5-6 millisec. This pattern repeats indefinitely: After every block of 4 transitions (between high and low), the signal remains low for 5-6 millisec. To me, this suggests that the DMA transfer operation is periodically interrupted for 5-6 millisec, which leads to a periodic delay in data transfer. Enclosed image 1 shows the signal pattern when the program starts; image 2 shows it at a later duration.




      Can somebody suggest what could be the problem? Is any spurious interrupt is periodically occuring which is disrupting DMA transfer? If yes then how to check/handle/disable such interrupt? Or, am I doing something wrong in my application and/or firmware code?


      The main loop of the firmware is as follows:




              counter = 0;


      for (;;) {


                  if (USBFS_1_IsConfigurationChanged() != 0)   // Executes only once in the begining in our case




                       AltSettingNumber = USBFS_1_GetInterfaceSetting(0);


                       if (AltSettingNumber == 1) // Our confguration uses Alternate Interace 1 for OUT EP6




                               if (configChangedCounter % 2 == 0)


                                      Pin1_DR |= Pin1_MASK;  // Make Pin 1 high   (Shown in yellow color in enclosed images)




                                      Pin1_DR &= ~Pin1_MASK; // Make Pin 1 low








                              Pin2_DR |= Pin2_MASK; // Make Pin 2 high




                              USBFS_1_ReadOutEP(EP6, &Isochronous_OUT_Buffer1[0], BUFSIZE);      // Configure DMA










               if (AltSettingNumber == 1)




                  // Alternately make Pin-2  high(1) or low (0) based on even or odd counter value


                  if (counter % 2 == 0)


                      Pin2_DR &= ~Pin2_MASK; 




                      Pin2_DR |= Pin2_MASK;








                  // Wait to OUT buffer to become full


                  while (USBFS_1_bGetEPState(EP6) != USBFS_1_OUT_BUFFER_FULL){}


                  USBFS_1_EnableOutEP(EP6);   // Rearm EP6 OUT EP












      Manuj Sharma