Periodic data transfer delay during Isochrnonous transfer using Auto mode DMA

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

cross mob
Anonymous
Not applicable

 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

   

IsocOutEpt->SetXferSize(bufSize);

   

         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;

   

        }

   

while(1){

   

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

   

{  

   

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

   

}

   

else

   

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)

   

                         else

   

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

   

             

   

                         configChangedCounter++;

   

   

   

                        Pin2_DR |= Pin2_MASK; // Make Pin 2 high

   

                

   

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

   

                        USBFS_1_EnableOutEP(EP6);

   

                } 

   

        }

   

        

   

         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; 

   

            else

   

                Pin2_DR |= Pin2_MASK;

   

            

   

            counter++;

   

            

   

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

   

         } 

   

    }

   

 

   

Thanks,

   

 

   

Manuj Sharma

   

 

   

 

   
        
0 Likes
1 Reply
Anonymous
Not applicable

 Hi Manuj,

   

 

   

Can you please share your PSoC project and PC application here?

   

It would be good if you can create a tech support case on our website since this issue might need some dedicated time for debugging.

   

 

   

-Shashank

0 Likes