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.

LM4F USB Handshake issue

Hi,

I have some questions concerning the USB Core in the LM4F120H5QR. In my current development I want to use the USB device funtion, but now I have problems with the acknowledge after the setup request. I correctly receive the GET_Descriptor request, so the PHY and the USB core appear to work just fine. To meet the USB2.0 a handshake is required. There for I write 0xD2 into the FIFO0 register and set the transmit packet ready bit in CSRL0. Then the handshake has been transmitted I write the requested descriptor into the FIFO and set the transmit packet ready bit and DATAEND bit. I expect the next interrupt to be the transmit complet interrupt but it isn't. Instead I get an USB reset.

My conclusion the handshake fails in some way because the next packet is only in parts or not transmitted.

  1. Does the USB core transmit handshakes on its own at any time? In this case the handshake is transmitted twice and the USB reset is an reaction due to this failure
  2. Is there any possibility to check how many bytes I have written into the transmit fifo? This would be very helpful for debugging
  3. Did I miss any important information in the USB2.0 specs and in the datasheet in my description of the problem?

Thank you for your help,

Regards Jannis

  • Jannis,

      As you probably know, USB is a rather complex protocol and there are many, many areas where you will have problems unless you are very, very careful. From your post, I sounds to me as if you are writing a driver that calls the low level USB driver (in driverlib) directly rather than using the USB Library that we provide. I would very strongly recommend that you verify the operation of your device using the USB Library first then, if necessary, optimize the code and cut out sections you do not need. We've done a lot of work in the USB Library and spent a lot of time making sure that it behaves as the standard requires. By writing to the low level driver, you are putting yourself in a position where you need to redo all this work and make all these discoveries again!

      In answer to your specific questions:

    1. Yes, the core sends the handshakes automatically in response to code actions. You don't need to explicitly send ACK, NACK, STALL, etc. Just call the appropriate USB API to indicate how you want the request handled (for example, USBDevEndpointDataAck() or USBDevEndpointStall().

    2. I'm not aware of any way to check the current FIFO level for an IN endpoint FIFO. You would have to track this yourself based on the number of bytes you wrote to it. For an OUT endpoint, calling USBEndpointDataAvail() will tell you how much data is available to be read.

    3. My copy of the USB 2.0 specification is 622 pages long so no doubt there's something in there that's been missed :-) Seriously, though, I think your problem here is that you are trying to write the handshake when the hardware is also sending it automatically.

    If you are keen to continue working on your own stack rather than using USBLib, I would recommend you look through the device-side code in usblib/device/usbdenum.c since this should give you a pretty good insight into how requests are handled and how the software must interact with the USB peripheral. Start by looking at USBDeviceIntHandlerInternal() and work your way up from there.

  • Thanks Will. 

    I know that my question is quite unusal, I also don't use the driverlib provided in the stellaris ware. Why? This implementation is only for educational purpose there it is necesarry to deal with the, as you said, very complex protocol of USB. Due to that I can't use the great usblib provided by TI because I need to work at the lowest possible level. I already read the documentation to the usblib and had a look at enum.c and the included headers. Unfortunately I couldn't found the source code or a documentation concerning the function MAP_USBDevEndpointDataAck which is used in the driverlib which would solve my question. 

    You mentioned that the APIs manualy send the handshake. Am I right that the hardware implementation of the USB un the LM4F series does not automaticly send any handshake? (I may failt to explain what I mean with USB core. In this case I mean the hardware implementation decribed in the datasheet in the USB section.)

    Regards Jannis

  • Jannis,

      I'm fairly sure that the hardware automatically sends NACK until you tell it explicitly to ACK the last transaction. You'll find the source for the functions I mentioned in driverlib/usb.c (the low level USB driver layer). USBLib makes calls to this driver.

      Good luck!

    Dave

  • durchgebrannt said:
    couldn't find the source code or a documentation concerning the function MAP_USBDevEndpointDataAck

    Look again w/in file "usb.c" but for, "USBDevEndpointDataAck()."  That MAP prefix is a signal which orders the use of ROM based code - but that same code is visible w/in usb.c.  (minus that MAP signal prefix)

    Dave gives very good advice - much will be revealed to you - made very much clearer - by your seriously reviewing the code mechanics w/in StellarisWare.  Working in this manner - from "known good, well tested, efforts of skilled others" - you speed, ease & enhance the likelihood of your "own creation" succeeding...  (i.e. you'll learn pertinent register usage, register relationships, sequencing, etc...)  Pity that this exploitation is either poorly recognized - or improperly rejected...

    And - just as Dave Wilson said - w/in usb.c appears...

    //*****************************************************************************
    void
    USBDevEndpointDataAck(unsigned long ulBase, unsigned long ulEndpoint,
                          tBoolean bIsLastPacket)
    {

    Function you failed to find thus is very much, "Present & accounted for..."  

    Very often, "investigative skills" and/or "desire to simplify" - appear surprisingly sub-optimal - for those targeting, "educational purpose."  And - in the "real world" - those skill-sets have substantial value...

  • Hi, 

    I found the primariy failure in my concept. Obviously I wasn't able to read the datasheet carefully enough. i skiped the very important part in the OUT transaction description there the functionality of the RXRDY bit is decribed. In this part is also mentioned that the usb controller automaticly sends the acknoledge (ACK) then this bit is cleared.  

    --> the function in USB.c gave me the important hint, there for thanks a lot.  ;)

    Regards Jannis