This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

OMAP-L13X USB 2.0 UNDERRUN and FIFONOTEMPTY errors

Other Parts Discussed in Thread: OMAP-L138, OMAPL138

Hello,

I've some problems with the USB2.0.
I'm using a LOGIC PD L138 eXperimenter board with the following versions
on the ARM side of the OMAP-L138:
- CCS Version 4.2.1.00004 (with GEL files for the eXperimenter board)
- SYS/BIOS 6.30.03.46

Implemented is a virtual COM port (usbser.sys) on my Laptop (Windows XP Professional, SP3).
The two bmAttributes for the endpoint descriptors (EP1 IN and EP1 OUT) within the configuration descriptor are set to "Bulk".
Enumeration for high speed is OK.

When sending one message from the Laptop to the OMAPL138 for the first time, I got the correct answer.
When I now resend the exact same message, the OMAPL138 receives this message correct, however on the Tx side of the OMAPL138 I got the UNDERRUN and FIFONOTEMPTY errors.

The flow and OMAPL138 register setting is as follows:
Send 10 bytes from Laptop to OMAPL138 (via LabVIEW):
INTMASKEDR = 0x00000200 (EP1 Rx Interrupt)
Set INDEX to 1
RXCSR      = 0x00000001 (RXPKTRDY)
RXCOUNT    = 0x0000000A (10 bytes received as expected)
Read 10 bytes from FIFO1 (read the correct bytes)
Clear RXPKTRDY (RXCSR &= ~USB20_PERI_RXCSR_RXPKTRDY)

Send back 8 bytes from OMAPL138 to Laptop:
Set INDEX to 1
TXCSR      = 0x00002004 (MODE Tx / UNDERRUN ?????)
Clear UNDERRUN (TXCSR &= ~USB20_PERI_TXCSR_UNDERRUN)
Write 8 bytes to FIFO1
Set TxPktRdy (TXCSR |= USB20_PERI_TXCSR_TXPKTRDY)
All 8 bytes are correct receive by the Laptop (LabVIEW)

INTMASKEDR =0x00000002 (EP1 Tx Interrupt)
Set INDEX to 1
TXCSR      = 0x00002004 (MODE Tx / UNDERRUN ?????)
Clear UNDERRUN (TXCSR &= ~USB20_PERI_TXCSR_UNDERRUN)
Post semaphore that Tx is over

Send same 10 bytes as above  from Laptop to OMAPL138 (via LabVIEW):
INTMASKEDR = 0x00000200 (EP1 Rx Interrupt)
Set INDEX to 1
RXCSR      = 0x00000001 (RXPKTRDY)
RXCOUNT    = 0x0000000A (10 bytes received as expected)
Read 10 bytes from FIFO1 (read the correct bytes)
Clear RXPKTRDY (RXCSR &= ~USB20_PERI_RXCSR_RXPKTRDY)

Set INDEX to 1
TXCSR      = 0x00002000 (MODE Tx)
Write 8 bytes to FIFO1
Set TxPktRdy (TXCSR |= USB20_PERI_TXCSR_TXPKTRDY)
Nothing received by the Laptop (LabVIEW)!!!

INTMASKEDR =0x00000002 (EP1 Tx Interrupt)
Set INDEX to 1
TXCSR      = 0x00002002 (MODE Tx / FIFONOTEMPTY ?????)

======================================================

After an USB reset from Host, the FIFOs are set to the following values:
INDEX      (0x01E0040E) = 1
RXFIFOSZ   (0x01E00463) = 0x16   (double buffering: 1024 bytes)
TXFIFOSZ   (0x01E00462) = 0x16   (double buffering: 1024 bytes)
RXFIFOADDR (0x01E00466) = 0x0008 (start addr. 64)
TXFIFOADDR (0x01E00464) = 0x0088 (start addr. 1088, i.e. 1024 + 64)
RXMAXP     (0x01E00414) = 0x0200 (512 byte max payload)
TXMAP      (0x01E00410) = 0x0200 (512 byte max payload)

======================================================

I can see the UNDERRUN / FIFONOTEMPTY when using hyperterm.
I also tried to use two different endpoints (EP1 IN / EP2 OUT), no success.

Has anybody an idea what could be wrong?

Thanks,
Frank

  • Hello,

    anybody there from TI?

    I'm thankful for any help.

    Thanks,

    Frank

  • Frank

    Tx Underrun error will be set when host sends read request (IN token) to device and device has no data to send. Hence this is not an issue.

    From your explanation i understand that the first TX from device was successful but the second TX is not happening. Can you have cleared the endpoint interrupt status and EOI to controller.

    Regards

    Ravi B

  • typo error.

    Please check the interrupt status for TX  has been cleared. And also the TXCSR (0x2002) shows that TXFIFONOTEMPTY and why TXPKTRDY bit was not set?

    Regards

    Ravi B

  • Hello Ravi,

    thanks.

    I installed an USB sniffer and observed, that the problem is at the end of enumeration. I'll upload a screen-shot (OMAPL138_USB_Sniffer.jpg ).

    After the Laptop is sending the SetControlLineState request (wValue set to 0) it immediatley sends an Bulk IN request for current configuration 01, Interface 00, Endpoint addr 81 and a Bulk OUT request for current configuration 01, Interface 00, Endpoint addr 00.
    This BULK OUT Endpoint addr is not defined, Bulk OUT addr. should be 01!

    Below are the definitions for my Device descriptor and my Configuration descriptor.

    Do you have any ideas why the Laptop is doing this?
    Anything wrong in my descriptors?

    const unsigned char deviceDesc[18] =
    {
     0x12,                                      // bLength (Size of the Descriptor in Bytes (18 bytes))
     TYPE_DEVICE_DESCRIPTOR,                    // bDescriptorType (0x01)
     0x00,                                      // bcdUSB USB Version 2.0 (low byte)
     0x20,                                      // bcdUSB USB Version 2.0 (high byte)
     0x02,                                      // bDeviceClass
     0x00,                                      // bDeviceSubclass
     0x00,                                      // bDeviceProtocol
     0x40,                                      // bMaxPacketSize 64 Bytes (Maximum Packet Size for Zero Endpoint)
     0x9E,                                      // idVendor  (Vendor ID (Assigned by USB Org)) (low byte)
     0x0F,                                      // idVendor  (Vendor ID (Assigned by USB Org))
     0x00,                                      // idProduct (Product ID (Assigned by Manufacturer)) (low byte)
     0xFA,                                      // idProduct (Product ID (Assigned by Manufacturer))
     0x00,                                      // bcdDevice (Device Release Number) (low byte)
     0x01,                                      // bcdDevice (Device Release Number) (high byte)
     0x01,                                      // iManufacturer (Index of string descriptor describing manufacturer)
     0x02,                                      // iProduct (Index of string descriptor describing product)
     0x03,                                      // iSerialNumber (Index of string descriptor describing the device’s serial number)
     0x01                                       // bNumberConfigurations (Number of possible configurations)
    };

    unsigned char cfgDesc[32] =
    {
     // configuration descriptor
     0x09,                                      // bLength
     TYPE_CONFIGURATION_DESCRIPTOR,             // bDescriptorType (0x02)
     0x20,                                      // wTotalLength (low byte)
     0x00,                                      // wTotalLength (high byte)
     0x01,                                      // bNumInterfaces
     0x01,                                      // bConfigurationValue
     0x00,                                      // iConfiguration String Index
     0xC0,                                      // bmAttributes Self-Powered, No Remote Wakeup
     0x00,                                      // bMaxPower, 0 mA
     // interface descriptor
     0x09,                                      // bLength
     TYPE_INTERFACE_DESCRIPTOR,                 // bDescriptorType (0x04)
     0x00,                                      // bInterface Number
     0x00,                                      // bAlternateSetting
     0x02,                                      // bNumEndpoints
     0x02,                                      // bInterfaceClass (Vendor specific)
     0x02,                                      // bInterfaceSubClass
     0x00,                                      // bInterfaceProtocol
     0x00,                                      // iInterface String Index
     // endpoint descriptor
     0x07,                                      // bLength
     TYPE_ENDPOINT_DESCRIPTOR,                  // bDescriptorType (0x05)
     0x81,                                      // bEndpoint Address EP1 IN
     0x02,                                      // bmAttributes - Bulk
     0x00,                                      // wMaxPacketSize (low byte)
     0x02,                                      // wMaxPacketSize (high byte)
     0x01,                                      // bInterval
     // endpoint descriptor
     0x07,                                      // bLength
     TYPE_ENDPOINT_DESCRIPTOR,                  // bDescriptorType (0x05)
     0x01,                                      // bEndpoint Address EP1 OUT
     0x02,                                      // bmAttributes - Bulk
     0x00,                                      // wMaxPacketSize (low byte)
     0x02,                                      // wMaxPacketSize (high byte)
     0x01                                       // bInterval
    };

    Thanks,
    Frank

  • Hello Ravi,

    I figured out my problem:

    need another configuration descriptor, similar as described on the following web page:

    http://www.st.com/mcu/modules/Splatt_Forums/downloadtemp/Virtual_Com_Port.txt

    According to this page, an additional IN endpoint (addr 0x82) with transfer typ Interrupt is needed.
    When I look into sprufm9h.pdf chapter 2.7.1.3 Peripheral Mode: Interrupt Transactions, it is stated:
    "Tx endpoints in the USB controller have one feature for Interrupt IN transactions that they do not support in Bulk IN transactions. In Interrupt IN transactions, the endpoints support continuous toggle of the data toggle bit.
    This feature is enabled by setting the FRCDATATOG bit in the PERI_TXCSR register (bit 11). When this bit is set, the controller will consider the packet as having been successfully sent and toggle the data bit for the endpoint, regardless of whether an ACK was received from the host."

    Q: Do I need to set this bit for my virtual COM port application?

    By the way, I had opened nearly two weeks ago a ticket (see link below), but did not receive any update from TI up to now.

    http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/p/120686/429596.aspx#429596

    Can you have a look?

    Thanks,
    Frank

  • Hello Ravi,

    can you please have a look to my question (marked Q:)?

    Thanks,

    Frank

  • Hi Frank,

    As shown in the function that I posted in your the other post, I did not use FRCDATATOG feature for the Interrupt IN endpoint, the code is commented out.

    But, I still can send and receive data with my virtual COM port without that. Again, I did not use double-buffering.

    rgds,

    kc Wong

  • Hallo kc Wong,

    thanks for your two replies.

    Frank

  • Hi Frank,

    Since you are using LOGIC PD L138 eXperimenter board also, I would like to check with you, did you see the issue I see ...

    During enumeration in high speed, the GetDescriptor(String iSerialNumber) and GetDescriptor(String iProduct) requests sent by host are ignored. USB Controller HW does not generate ACK for the SETUP packet of these requests, and HW also does not generate interrupt to firmware for these requests.

    Thus, host never successful obtain product ID and the serial number of my device.

    http://e2e.ti.com/support/embedded/f/354/t/123362.aspx

    rgds,

    kc Wong

  • Hello kc Wong,

    have a look at the following thread, here are examples from Zegeye Alemu for string descriptors:

    http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/p/29276/101773.aspx?PageIndex=11

    On my kit it is working for high speed.

    Frank

  • Hi Frank,

    Thanks for reply.

    In my case, the USB Contoller HW does not even generate interrupt for these requests, so the firmware has no way to handle the request.

    But, I found out the value of wLength in the SETUP packet will make a difference. If the host sends GetDescriptor (String iSerialNumber) request with wLenght=256, then the HW is able to generate the ACK, and interrupt the firmware. But, during enumeration, the host always sends request with wLength=255. This is in the Windows USB driver, no way to change this.

    Anyway, thanks for checking. Good that it is working on your kit.

    rgds,

    kc Wong