CYUSB3014 freezes during Slave FIFO transfer

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

cross mob
lock attach
Attachments are accessible only for community members.
DeSa_1285516
Level 1
Level 1
5 replies posted 5 sign-ins 5 likes given

Our setup gets data from the fast ADC which is connected to FPGA. FPGA through CYUSB3014 working in SuperSpeed mode and
send data to the PC. We use slightly modernized SlaveFifo synchronous firmware from AN65974 (cyfxslfifosync.c and cyfxslfifosync.h have been attached).
Usually data transmitted fine but sometimes USB controller freezes - FPGA has data to sent but libusb_bulk_transfer() reads
0 bytes with timeout error (timeout variable in libusb_bulk_transfer sets to 200 ms). The freeze could be overcome with the help of libusb_reset_device() function
from PC. After that, libusb_bulk_transfer() works fine until next freeze.

From the primary analysis it seems that the freeze is due to the fact that the callback function of the producer event (CyFxSlFifoPtoUDmaCallback) is not called.
Probably the freeze happens when the PC tries to read data when the endpoint buffer in the CYUSB3014 is partially filled.
In a case when initially no data on FPGA (FIFO buffer is empty) all works fine and no freeze are observed after data becomes available.

PC OS: x86_64 Ubuntu Linux 18.04.4 LTS
libusb 1.0.21-2
CYUSB3014 connected to USB 3.0 port on PC.

Is it possible to prevent the freezes without libusb_reset_device() call?

0 Likes
1 Solution

Hello,

We use FLAGB (active LOW) as a watermark flag to determine when the DMA buffer is empty, and then FPGA starts to fill the DMA buffer and fills it until FLAGA is LOW (ready). Please notice, that the FPGA fills the DMA buffer four times by 4 KB, whenever an event by outside signal occurs, and then PC reads from CYUSB3014 16 KB.

>> Please monitor Flag A (DMA Ready flag) from the FPGA. When FLAG A is high i.e. the DMA buffer is empty, the FPGA should start writing the data to DMA buffers of FX3.

>>FLAG B (DMA watermark flag) is generally monitored by the Master to know when the FPGA should stop the data transfer. This can be configured to indicate the partially empty/full status of a socket. A watermark value must be selected such that the flag is asserted when the number of 32-bit words that may be read or written is less than or equal to the watermark value.

This API CyU3PGpifSocketConfigure (0,CY_U3P_PIB_SOCKET_0,6,CyFalse,1); is used to configure the watermark value of FLAG B. The fourth parameter of this API is CyFalse which means the flag will be set when the socket contains less data than the watermark.

watermark * (32/bus width) - 4 = 6 - 4 = 2. In this case, the FLAG B will be asserted LOW when the DMA buffer is almost filled and only 2 data words (32 bit in this case) space is empty in the DMA buffer. This will indicate to the master that the DMA buffer is about to fill and the data transfer should be stopped after 2 clock cycles (i.e. SLWR should be pulled HIGH). So, FPGA is expected to write 2 data words after FLAG B is asserted LOW.

The application note AN65974 also makes use of the same Flag configuration. The DMA ready flag (FLAG A) is monitored for starting the data transfer to FX3 and DMA watermark flag is used to stop the data transfer.

Please let me know if any queries on this

Regards,

Rashi

Regards,
Rashi

View solution in original post

11 Replies
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello,

Please let me know how many bytes of data are transferred from FPGA to FX3.

From the primary analysis, it seems that the freeze is due to the fact that the callback function of the producer event (CyFxSlFifoPtoUDmaCallback) is not called.

>>This indicates that the DMA buffer (16KB) if STREAM_IN_OUT macro is enabled.

In the files that you have shared, I found that only one DMA buffer is being used for the DMA channel. Please confirm if the data from FPGA is sent only when the FLAG A (DMA_READY) is HIGH(ready). Also, if the data sent from the FPGA is not 16KB i.e. if the data is short packet then the PKTEND signal should be asserted by the FPGA to wrap the partially filled buffer and then commit to USB in the CyFxSlFifoPtoUDmaCallback.

Probably the freeze happens when the PC tries to read data when the endpoint buffer in the CYUSB3014 is partially filled.

>> We can check if there is a DMA buffer that needs to be consumed by USB. If all the DMA buffers are empty and producer events are not triggered then the FX3 has nothing to send to the host. If the host requests for data in this case the timeout error can be seen.

Also, please let me know the reason for using 4100 as the watermark value. The watermark flags are generally used to stop the data transfer    CyU3PGpifSocketConfigure (0,CY_U3P_PIB_SOCKET_0,4100,CyFalse,1);

Please share the UART debug prints when the issue is seen.

To track the DMA buffers register for CONS event

dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;

    /* Enabling the callback for produce event. */

    dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_CONS_EVENT;

    dmaCfg.cb = CyFxSlFifoPtoUDmaCallback;

and then track the CY_U3P_DMA_CB_CONS_EVENT in the CyFxSlFifoPtoUDmaCallback using a varaible and getthe UART prints in the

void

CyFxSlFifoPtoUDmaCallback (

        CyU3PDmaChannel   *chHandle,

        CyU3PDmaCbType_t  type,

        CyU3PDmaCBInput_t *input

        )

{

........

if (type == CY_U3P_DMA_CB_CONS_EVENT)

    {

       glDMATxCount_PtoU++;

}

SlFifoAppThread_Entry(){

.......

CyU3PThreadSleep (1000);

        if (glIsApplnActive)

        {

            /* Print the number of buffers received so far from the USB host. */

            CyU3PDebugPrint (6, "Data tracker: buffers received: %d, buffers sent: %d, buffers_consumed : %d.\n\r",

                    glDMARxCount, glDMATxCount,glDMATxCount_PtoU );

        }

Please enable the above debug print in the firmware to track the DMA buffer consumed and produced

Regards,

Rashi

Regards,
Rashi

Thank you for the fast response.

In the files that you have shared, I found that only one DMA buffer is being used for the DMA channel. Please confirm if the data from FPGA is sent only when the FLAG A (DMA_READY) is HIGH(ready). Also, if the data sent from the FPGA is not 16KB i.e. if the data is short packet then the PKTEND signal should be asserted by the FPGA to wrap the partially filled buffer and then commit to USB in the CyFxSlFifoPtoUDmaCallback.

We use FLAGB (active LOW) as a watermark flag to determine when the DMA buffer is empty, and then FPGA starts to fill the DMA buffer and fills it until FLAGA is LOW (ready). Please notice, that the FPGA fills the DMA buffer four times by 4 KB, whenever an event by outside signal occurs, and then PC reads from CYUSB3014 16 KB.

Also, please let me know the reason for using 4100 as the watermark value. The watermark flags are generally used to stop the data transfer    CyU3PGpifSocketConfigure (0,CY_U3P_PIB_SOCKET_0,4100,CyFalse,1);

4100 has been chosen according to the equation from AN65974 (page 18, section 9.3): watermark * (32/bus width) - 4 = 4100 - 4 = 4096 32-bit words we should then write (16 KB DMA buffer). What we’ve done incorrectly, do you mean? How else FPGA should check if the DMA buffer empty?

Please share the UART debug prints when the issue is seen.

To track the DMA buffers register for CONS event

Unfortunately on the board we have only JTAG for debugging CYUSB3014. I could increment the counter in case of CY_U3P_DMA_CB_CONS_EVENT event (as you suggest) and write it to the input->buffer_p on CY_U3P_DMA_CB_PROD_EVENT event and then read it to the PC.

0 Likes

Hello,

We use FLAGB (active LOW) as a watermark flag to determine when the DMA buffer is empty, and then FPGA starts to fill the DMA buffer and fills it until FLAGA is LOW (ready). Please notice, that the FPGA fills the DMA buffer four times by 4 KB, whenever an event by outside signal occurs, and then PC reads from CYUSB3014 16 KB.

>> Please monitor Flag A (DMA Ready flag) from the FPGA. When FLAG A is high i.e. the DMA buffer is empty, the FPGA should start writing the data to DMA buffers of FX3.

>>FLAG B (DMA watermark flag) is generally monitored by the Master to know when the FPGA should stop the data transfer. This can be configured to indicate the partially empty/full status of a socket. A watermark value must be selected such that the flag is asserted when the number of 32-bit words that may be read or written is less than or equal to the watermark value.

This API CyU3PGpifSocketConfigure (0,CY_U3P_PIB_SOCKET_0,6,CyFalse,1); is used to configure the watermark value of FLAG B. The fourth parameter of this API is CyFalse which means the flag will be set when the socket contains less data than the watermark.

watermark * (32/bus width) - 4 = 6 - 4 = 2. In this case, the FLAG B will be asserted LOW when the DMA buffer is almost filled and only 2 data words (32 bit in this case) space is empty in the DMA buffer. This will indicate to the master that the DMA buffer is about to fill and the data transfer should be stopped after 2 clock cycles (i.e. SLWR should be pulled HIGH). So, FPGA is expected to write 2 data words after FLAG B is asserted LOW.

The application note AN65974 also makes use of the same Flag configuration. The DMA ready flag (FLAG A) is monitored for starting the data transfer to FX3 and DMA watermark flag is used to stop the data transfer.

Please let me know if any queries on this

Regards,

Rashi

Regards,
Rashi

We suppose that if FLAGA is HIGH then it indicates that the DMA buffer is NOT FULL yet, but NOT EMPTY, is not it?

Are there any differences from the flag usage in comparison with FX2LP?

0 Likes

Hello,

As per AN65974, Flag A is DMA Ready flag which indicates the status of the buffer. FLAG A will be HIGH when the DMA buffer is Empty and ready to take the Data from FPGA.

Please refer to the FPGA master state machine in section 11.4.2 which shows FLAG A is monitored first and the state switches towards stream_in_write state.

If you are writing short packets or ZLP to FX3, please refer section11.4.4 and 11.4.5

As per AN61345 for FX2LP, the watermark flags are not being used.

Regards,

Rashi

Regards,
Rashi

We have fixed the issue with flags, but the freezes of the USB controller stay.

We have checked the counter of CY_U3P_DMA_CB_PROD_EVENT and CY_U3P_DMA_CB_CONS_EVENT with the changes in source

code of CyFxSlFifoPtoUDmaCallback():

if (type == CY_U3P_DMA_CB_PROD_EVENT)
{

        input->buffer_p.buffer[8] = glDMATxCount & 0x000000ff;
        input->buffer_p.buffer[9] = (glDMATxCount & 0x0000ff00) >> 8;
        input->buffer_p.buffer[10] = (glDMATxCount & 0x00ff0000) >> 16;
        input->buffer_p.buffer[11] = (glDMATxCount & 0xff000000) >> 24;

        input->buffer_p.buffer[12] = glDMATxCount_PtoU & 0x000000ff;
        input->buffer_p.buffer[13] = (glDMATxCount_PtoU & 0x0000ff00) >> 8;
        input->buffer_p.buffer[14] = (glDMATxCount_PtoU & 0x00ff0000) >> 16;
        input->buffer_p.buffer[15] = (glDMATxCount_PtoU & 0xff000000) >> 24;

        status = CyU3PDmaChannelCommitBuffer (chHandle, input->buffer_p.count, 0);
        if (status != CY_U3P_SUCCESS)
        {
            CyU3PDebugPrint (4, "CyU3PDmaChannelCommitBuffer failed, Error code = %d\n", status);
        }


        /* Increment the counter. */
        glDMATxCount++;
}

if (type == CY_U3P_DMA_CB_CONS_EVENT)

{
        glDMATxCount_PtoU++;
}

Always (in normal work and after unfreeze with reset) the glDMATxCount is equal to the glDMATxCount_PtoU.

As mentioned above the FPGA fills the DMA buffer four times by 4 KB, whenever an trigger event by an outside signal occurs.

The outside signals which trigger the writing of 4 KB usually go one by one with an interval of about 1 ms.

We have performed the test: when the first trigger comes we write 4 KB and then immediately 3 times duplicate this first 4 KB to the DMA buffer (to fill all 16 KB).

So we did not wait for the other 3 triggers. In the case all works fine - we did not observe freezes of the controller.

What is the possible  reason for such freezes?

0 Likes

Hello,

The outside signals which trigger the writing of 4 KB usually go one by one with an interval of about 1 ms.

We have performed the test: when the first trigger comes we write 4 KB and then immediately 3 times duplicate this first 4 KB to the DMA buffer (to fill all 16 KB).

So we did not wait for the other 3 triggers. In the case all works fine - we did not observe freezes of the controller.

>>Please let me know which trigger are you referring to in this description.

What is the possible  reason for such freezes?

>> Please share the UART debug prints when the freeze is seen and also when the freeze is not seen

Regards,

Rashi

Regards,
Rashi
0 Likes

Hello,

Please let me know which trigger are you referring to in this description.

>>>I talk about the trigger in FPGA. The trigger occurs when the ADC output exceeds the threshold.

Please share the UART debug prints when the freeze is seen and also when the freeze is not seen.

>>>Sorry, but the UART signals are not available in our board.

0 Likes

Hello,

Please let me know how are the signals SLWR and SLCS handled along with the trigger from the FPGA.

Also, let me know how is the data being read from the FX3 to USB host. Is it through control Center?

If yes, what error is thrown by the control center when the freeze is seen.

The outside signals which trigger the writing of 4 KB usually go one by one with an interval of about 1 ms.

>> Is the CY_U3P_DMA_CB_PROD_EVENT and CY_U3P_DMA_CB_CONS_EVENT seen in this case?

After how many DMA buffers is the freeze seen?

Regards,

Rashi

Regards,
Rashi
0 Likes

SLCS is constantly 0 (active). Initially SLWR is 1. The trigger flag is being monitored, and then FIFOADDR is asserted «00», after that, with the delay of three PCLK cycles, SLWR is asserted to 0.

We read data to PC with the help of libusb_bulk_transfer() in cycle

the call looks like

r = libusb_bulk_transfer(usb_h, IN_EP, buf, USB3_BUFSIZE, &transferred, timeout);

where USB3_BUFSIZE is equal to 16384 and timeout is equal to 200.

When controller freezes libusb_bulk_transfer return error code LIBUSB_ERROR_TIMEOUT with transferred equals to 0.

Is the CY_U3P_DMA_CB_PROD_EVENT and CY_U3P_DMA_CB_CONS_EVENT seen in this case?

After how many DMA buffers is the freeze seen?

When controller freezes no CY_U3P_DMA_CB_PROD_EVENT or CY_U3P_DMA_CB_CONS_EVENT events occur.

The occurrence of freezes seem to be partially random. It depends on the number of triggers.

When trigger rate is about 100 per second 1-2 freezes occur on acquisition time of 100 s.

0 Likes

Hello,

Thank you for the details.

As you mentioned that

When controller freezes no CY_U3P_DMA_CB_PROD_EVENT or CY_U3P_DMA_CB_CONS_EVENT events occur. When CY_U3P_DMA_CB_PROD_EVENT are not seen this means that FX3 has not received the data. And if the data is not received if the host asks for the data libusb_bulk_transfer it will throw timeout error.

Please confirm if the data is being written to FX3. If the DMA buffer size is 16KB, CY_U3P_DMA_CB_PROD_EVENT will trigger if the 16 KB buffer is completely filled or if a short packet is sent from FPGA (i.e. data(bytes) <16KB) then PKTEND signal needs to be asserted to wrap the buffer. Please refer to AN65974 is short packet is being sent by FPGA

Please probe the interface signals PCLK,SLCS, SLWR, PKTEND, FPGA trigger and share the traces.

Regards,

Rashi

Regards,
Rashi
0 Likes