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:


But my low-tech eye diagram shows something unexpected:


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


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:


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.

  • \$\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 '16 at 5:35
  • \$\begingroup\$ It's unlikely that the TVS or the charge detector are interfering with the signal like that. I have no clue why the STM32 would exhibit that behavior, though. \$\endgroup\$ – user2943160 Jun 7 '16 at 5:35
  • \$\begingroup\$ That looks like a reflection, but it would have to be on a fairly long cable. Maybe some kind of contention? I think my first debugging action would be to desolder the charger detector and bridge it with a couple of wires. \$\endgroup\$ – The Photon Jun 7 '16 at 5:44
  • 1
    \$\begingroup\$ I would look for the problem somewhere else. This signal looks like transition from driving (1 or 0) to high-Z. \$\endgroup\$ – Gregory Kornblum Jun 7 '16 at 5:55
  • 1
    \$\begingroup\$ Try sampling in the middle of the waveform - the eye diagram looks good enough to decode correctly. \$\endgroup\$ – Andy aka Jun 7 '16 at 7:26

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.

  • 1
    \$\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 '16 at 22:29

This is absolutely perfect FS signal. Apparently the OP probes the signals at device end of the cable. The FS signals are unterminated by USB standard. 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.

  • \$\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 '16 at 22:21

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.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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