This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Does LPC1343 USBCDC example lack flow control when sending from target to host?

When using the NXP/Keil usbcdc example, data appears to be lost when sending large amounts from target to host. Does the Keil usbcore/usbcdc lack flow control, or is this a limitation of the usb cdc specification?

Target: LPC1343
Compiler: gcc
Host: Linux (Ubuntu)

vcomdemo.c V1.02
cdcuser.c V1.10
usbcore.c V1.20
serial.c V1.10

Changes below were made to the usbcdc example, to send an incrementing stream of bytes [0..255].

cat /dev/ttyACM0 > capture
hexdump capture | less

* serial.c *

int ser_Read (char *buffer, const int *length) {
        static int increment = 0;
        buffer[0] = increment++;
        return 1;
}

void ser_AvailChar (int *availChar) {
        return 1;
}

  • Are you implementing the test code correctly?
    For example, this code is nonsense at all.

    void ser_AvailChar (int *availChar) {
            return 1;
    }
    

    The original one is here.

    serial.c (v1.20)
    
    /*----------------------------------------------------------------------------
      check if character(s) are available at the serial interface
     *---------------------------------------------------------------------------*/
    void ser_AvailChar (int *availChar) {
    
      *availChar = SER_BUF_COUNT(ser_in);
    
    }
    

    > Does the Keil usbcore/usbcdc lack flow control, or is this a limitation of the usb cdc specification?

    USB has intrinsic NAK flow control on its hardware, for bulk/interrupt/control transfer.
    If you see any data drop, it occurs on your firmware.
    - For IN endpoint, overwrite to the endpoint buffer causes data drop, before the last transaction complete.
    - For OUT endpoint, validate of the EP before unloading entire packet makes data drop.

    Tsuneo

  • > Are you implementing the test code correctly?
    > For example, this code is nonsense at all.

    The code I presented is to construct a pathological test, and certainly should not be used in application code. Setting ser_AvailChar to always return '1' signals that there is always data available. In ser_AvailChar, a single incrementing byte is sent on each call.

    What I would expect to see in the output file is [0,1,2,3,4,...,255,0,1,2...], repeated as fast as the interface can send and the host can accept.

    However, I do not see this, which returns me to the original question. Does the Keil USBCDC example support flow control? If it does, can someone please demonstrate this under the principles I have presented of sending a test sequence that floods the interface with deterministic data.

  • Correction:

    void ser_AvailChar (int *availChar) {
            *availChar = 1;
    }
    

  • Like Tsuneo "USB_Master" Chinzei predicted...

    "If you see any data drop, it occurs on your firmware."

    Tsuneo, I'm still waiting you write a Book about USB embedded!

    :)

  • > If you see any data drop, it occurs on your firmware.

    Thanks for the confirmation.

    I am using the standard reference code from Keil, in the USBCDC example.
    I believe I have modified the code to produce a deterministic test pattern. Do you disagree with the validity of my change to generate a reliable test pattern? Please do present an alternative.

    I have not tried on Windows, so if the above holds, it could be an issue with the Linux usb cdc driver (2.6.32). Though this is highly unlikely, I am just expressing an assumption needing testing.

    Would appreciate if someone would confirm or disprove my finding, with my changes, or with alterative published steps. The test is to send a high bandwidth test pattern from target to host using a modified Keil USBCDC example reference design. Would also gladly accept any reference code that shows driving (test pattern) data from LPC1343 target to host at the upper limit of the interface.

  • Was an issue with tty handling on Linux.
    To resolve: stty -F /dev/ttyACM0 raw

  • > Was an issue with tty handling on Linux.

    Surely, PC applications may also "drop" data :-)

    Software sniffer shows the culprit, device or PC app.

    usbmon and WireShark on Linux
    biot.com/.../usb-sniffing-on-linux

    Tsuneo