4
\$\begingroup\$

I have designed a USB device around an STM32F105. It is USB 2.0 Full Speed CDC device configured as a Virtual COM Port using ST's USB Library. It uses the STM32's built-in PHY, and runs at 12 Mbps.

I'm sending data in 254-byte packets. Occasionally (averaging 1 in 17000 packets) the host computer receives bad data. It is generally constrained to a single byte in the packet.

So I'm looking at the signals using a Tektronix TDS2025 O-scope (200 Mhz).


Most of the transitions look great:

USB1


But my low-tech eye diagram shows something unexpected:

Eye


I managed to trap one of the bad waveforms, which looks like this:

USB2


What might be causing this? I'm not sure where to start looking.

When I first plug in the device, the enumeration takes place successfully, and the eye diagram looks clean. But once I open the COM Port (using PuTTY, Hercules, or my custom java software), the glitches show up. I'm using a Lenovo Thinkpad with Windows 7.

Here is a picture of the layout:

PCB

The TVS IC is an NXP PRTR5V0U2F, and the Charger Detector is a TI BQ24392.

The USB traces travel about an inch on the back side of the board, then they come back up and connect directly to the microcontroller's USB pins. They are impedance controlled and appropriately length-matched to each other.

I'm probing from the USB connector's solder pads to the ground point which I've labeled on the picture. The probe had a short ground spring, not a long alligator clip.

If more data would help, please let me know. Also, this is my first USB device, and my first eye diagram test. If you see something wrong with my setup or assumptions, please let me know.

\$\endgroup\$
13
  • 1
    \$\begingroup\$ 2.2R as series resistor for your data lines seem pretty low to me. Can you confirm it's 2.2R and not 22R as I would expect it to? Do you have a reference design where you took this from? Also, can you confirm that you at least tried to route the usb signal lines with the same length and an approximate 50Ohms? \$\endgroup\$
    – Tom L.
    Jun 7, 2016 at 5:35
  • 1
    \$\begingroup\$ I would look for the problem somewhere else. This signal looks like transition from driving (1 or 0) to high-Z. \$\endgroup\$
    – user76844
    Jun 7, 2016 at 5:55
  • 1
    \$\begingroup\$ The reflection (wherever it may be) is going into a lower impedance (reflection is out of phase). I would suggest that the two different looking signals are the two different signalling directions. \$\endgroup\$ Jun 7, 2016 at 6:46
  • 1
    \$\begingroup\$ Those resistors are probably the series termination required by the USB specification. According to spec, they should be around 16R-33R (2.2 is definitely too small) to account for the different usb cable impedance. This may cause issues but they probably wouldn't show like what you actually see (they should be more consistent). I would consider changing them anyway. \$\endgroup\$
    – Tom L.
    Jun 7, 2016 at 7:24
  • 1
    \$\begingroup\$ Try sampling in the middle of the waveform - the eye diagram looks good enough to decode correctly. \$\endgroup\$
    – Andy aka
    Jun 7, 2016 at 7:26

3 Answers 3

5
\$\begingroup\$

It doesn't look like this is a hardware problem. The stepped wavform looks either like a reflection is happening or this is at the transition when the host and device switch sender and receiver roles. In any case, the signal looks plenty good enough to be decoded properly.

It would help if you put the trigger of your scope somewhere on the screen. With the trigger being off-screen, you may get more apparent jitter than is really on any one bit.

You need to look at your software carefully. Most likely you have a bug somewhere that corrupts or misses or adds a byte when a particular corner case happens. This could be, for example, during contention for the FIFO when it is one byte short of full or something. If the FIFO is being accessed by both interrupt and foreground code, then this is exactly the kind of hard to find problem you expect when the lockout logic isn't quite right.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Thanks, Olin. It did turn out to be a software bug. ST's USB library stuffs the outbound queue one byte at a time (Buffer[index] = data; index++;). When I built my own function I did it this way: Buffer[index++] = data; Apparently the USB process would (very occasionally) take place after the index incremented but before the data was written. \$\endgroup\$
    – bitsmack
    Jul 24, 2016 at 22:29
7
\$\begingroup\$

This is absolutely perfect FS signal. Apparently the OP probes the signals at device end of the cable. The FS signals are unterminated at FAR END by USB standard, unlike in high-speed mode. All incoming signals (host-driven) are fine, since they are measured at destination point. However, when the device drives back an occasional handshake packet (short ACK or NAK or else), the driver hits the transmission line. Half-ampiltude signal (shouder) gets developed until the reflection from host end comes back. This is absolutely normal behavior of signals on unterminated transmission line. As I see, the round-trip delay is about 20ns, or 10ns one-way. This tells that the cable in use is about 2m long, or a standard 6ft cable. If the OP would probe the bus at host end, he would see an opposite picture. Just my 2c.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Excellent, Ali, thank you! This is what I was looking for. Sorry that I have already accepted a different answer... \$\endgroup\$
    – bitsmack
    Jul 26, 2016 at 22:21
  • \$\begingroup\$ Why do you say USB Full-Speed is "unterminated by USB standard"? USB 1.1 says "A full-speed USB connection is made through a shielded, twisted pair cable with a characteristic impedance (Z0) of 90Ω ±15% and a maximum one-way delay of 26ns. The impedance of each of the drivers (ZDRV) must be between 28Ω and 44Ω i.e. within the grey area in Figure 7-3. … For a CMOS implementation, the driver impedance will typically be realized by a CMOS driver with an impedance significantly less than this resistance with a discrete series resistor making up the balance" \$\endgroup\$
    – endolith
    May 26, 2023 at 16:29
  • 1
    \$\begingroup\$ @endolith, USB Full-speed mode does not have 45Ω termination on far-end. The text you quoted describes the near-end (driver) end. I am correcting the answer with this detail. \$\endgroup\$ May 26, 2023 at 23:00
  • 1
    \$\begingroup\$ @endolith, it is bidirectional, but only "half-duplex". When the host drives the line, its impedance is expected to be 45+45Ω at the driver end . The other end, however, is unterminated and therefore produces 2x reflection. When the device drives, the situation is mirrored - host end is unterminated (Tx drivers are off), the device drives with 45+45. \$\endgroup\$ May 28, 2023 at 18:36
  • 1
    \$\begingroup\$ @endolith - Yes. \$\endgroup\$ Jun 1, 2023 at 2:47
2
\$\begingroup\$

I'm sending data in 254-byte packets. Occasionally (averaging 1 in 17000 packets) the host computer receives bad data. It is generally constrained to a single byte in the packet.

Do you use a FIFO? If so, check your source code: There are bad FIFO examples out there that actually allow reading a "bad" byte.

The "bad waveform" is still within spec. You probably see a reflection when the PC sends data. This will be better when using a hub or using desktop PC backside ports, and worse on front side ports that are connected by longer cables inside a PC.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.