Saturday, January 17, 2015

USB interfacing for AVR microcontrollers

Since the release of V-USB, dozens of projects have been made that allow an AVR to communicate over USB.  USB data signals are supposed to be in the range of 2.8 to 3.6V, so there are two recommended ways to have an AVR output the correct voltage.  One is to supply the AVR with 3.3V power, and the other is to use 5V power but clip the USB data signal using zener diodes.  Most implementations of V-USB, like USBasp, use the zener diodes.  I'll explain why using a 3.3V supply should be the preferred method.

Pictured above is a capture of D- line on a chinese USBasp, showing one of the 1kHz SE0 idle pulses.  The idle voltage is close to the 2.8V limit because this particular USBasp uses a 2.2K pullup resistor to +5V.  Using a 1.5K pullup as is recommended on the V-USB site puts it closer to 3.2V, which is the high voltage level from the host.

To determine how the signal is read by the AVR, we can look at the ATmega8A input threshold graphs at section 28.8 of the datasheet.
The graph indicates with a 5V supply, any voltage over 2.65V will be read as a logic "1".  The next graph in the datasheet shows any voltage below 2.4V will be read as a logic "0".  Since signals from the host transition between 0 and 3.2V and not 5V, the AVR will interpret low signals as being longer than high signals.  With a fall time of about 115ns, the signal will drop to 2.4V (logic low) in about 29ns.  With a rise time of about 100ns, the signal will rise above 2.65V from 0V in about 83ns.  At 1.5mbps, both high and low bits should last 667ns, but instead a low bit will last 721ns and a high bit will last only 612ns.  This 18% difference in bit times reduces the margin of error V-USB has to work with.

With a 3.3V supply voltage to the AVR, the low signal will last almost 670ns, and the high will last a little more than 663ns, for a timing difference of just under 1%.  Besides significantly improving signal timing, using a 3.3V supply simplifies the USB interface circuit.  Obviously the zener diodes are no longer needed.  Additionally, the 68Ohm resistors which limit the current from the AVR through the zener diodes, are no longer necessary either.

An alternative to using a 3.3V regulator, which is described on the V-USB site, is to use 2 diodes in series to provide a drop of about 1.6V.  My preference is to use a medium-power red LED like the BR5379K, which doubles as a power LED.  At 5mA, the current draw of an ATmega8A running at 12Mhz and 3.6V, the BR5379K has a voltage drop of about 1.65V.  It has a maximum current of 50mA; more than enough to drive something like a nRF24l01+ module in addition to the AVR.


  1. Or just use a uC with a proper USB interface, there are plenty on the market for prices comparable (or even cheaper) with the AVR chips.

    I have used V-USB before and while it sort-of works, it is an enormous pain in the backside - it is only low speed, so there is only a small buffer than can be transferred per packet. What is worse, it is electrically marginal - your solution with the LED or LDO will be problematic if there is a significant voltage drop on the USB cable - the USB specs has the USB voltage as 5+-0.25V, that gives 4.75V in the worst case. Add any voltage drop and your circuit is going to be unreliable, especially when connected to unpowered hubs. From this point of view the zeners recommended in the V-USB documentation are better, at the cost of the signal integrity.

    The correct solution would be using a buck-boost DC-DC converter, which is more expensive, more complex and takes up more space on the board.
    Oh and don't get me started on the requirements of USB Suspend ...

    If I need USB on a small micro these days I am rather going to PIC18F14k50, 25k50 and similar. Or an STM32F103x series - a much more powerful chip than an AVR and for essentially the same price. All of these have hardware full speed USB transciever, the PICs are 3.3V devices with a built-in 3.3V LDO, so can be directly powered from the USB bus voltage and don't need another regulator. And they are 5V tolerant, so no problem interfacing them neither.

    1. Jan, the PIC and STM parts you mentioned are still more than 2x the price of the cheapest AVRs. The attiny88 is on special at Newark for only 42c. The cheapest price I can find for the PIC18F14k50 in small quantities is over $1 on the Chinese grey market.

      I agree the red LED isn't the best solution when connected to a hub, though it will still provide over 3V when supplied 4.75V. A cheap LDO like the AMS1117 that is already used on many USBasp designs has a typical dropout of 1.1V, meaning a stable 3.3V supply can be had without resorting to a much more expensive buck-boost circuit.

    2. If I remember, correctly, 12MHz @ 3.3V is grossly outside of spec on the attiny88. The atmgea168PB (or 88PB, when that is available) would probably be a better choice, since it has a 10MHz rating @ 2.7V and a 20Mz rating @ 4.5V. As far as I recall, there is a graph somewhere in the datasheet showing a linear relationship between these two points, making 12Mhz @ 3.3V within spec. But 42c is quite cheap, wow, it's cheaper than the Attiny13A's I got in China!

      As noted below, I have used the Mic5205 (150ma) to great succes. It is quite cheap also, and have a much lower dropout. There are probably many alternatives in that range.

    3. You're right about 3.3V being out of spec for the tiny88 @12Mhz, however like other AVRs, in practice, they work fine at lower voltages. Atmel even gives a power consumption curve for 8Mhz down to 1.8V (datasheet figure 23-3), so if it works at 8Mhz with 1.8V, 12Mhz at 3.3V should be a no-brainer. If I finish the 8Mhz USB code I started last year then it all becomes moot though. For dropout under 1V, the Mic5205 does look like a nice option.

    4. I haven't actually tried the QFN parts yet, as I still have a couple extra t88-au's. I may get a few on my next newark order if only to practice my fine soldering skills. I'm comfortable with 0.8mm qfp's and 0805 parts now, so 0.5mm is the next challenge.

  2. Ralph, thanks for a nice analysis. I am guessing that the 2.2kohm pull-up version is from my HandyStick design? I think I got it from some of the user designs on the v-usb site, and it is a more common value than 1.5k, so I went for it. How mistaken I was :-). When I use rev1 boards, I will be sure to use 1.5kohm instead.

    However, I also prefer running at 3.3V, which I have done on my not-yet-published rev2. It was mainly for aesthetics, and I realised that adding a small voltage regulator (Mic5205) and some caps wasn't so much of a BOM-cost increase, and also allowed the board to be run on 3 or 4 AA batteries in a pinch (and still have a constant voltage). I am glad to see that it has a dramatic effect on timing.

    However, the design on the v-usb sites shows the two 68R resistors, even though they are running at a lower voltage (using two diodes in series): . Are you certain that they are only there for limiting the current for the zeners? The design guidelines in the Atmega16u2 datasheet recommends series resistors as well (22 ohm, though).

    I really need to get an oscilloscope, and I would have caught this!

    However, I have been thinking of exploring chips with real USB interfaces, but they are usually much more expensive. I have been using Atmegas from china (yeah, I know). But the new cheaper edition, the Atmega168PB, cuts the price drastically (on Mouser), making the regular Atmegas cheaper than an STM32 with USB.

    1. Niels, the 2.2k pullup is on a LC Tech USBasp. It's from the standard schematic Thomas Fischl has on his site. If I'm going with an LDO I prefer something beefier than a 78l05 or Mic5205, hence my preference for the AMS1117. It takes more board space, but it provides enough power for wireless modules like the new esp8266.

      I can think of 2 reasons to keep series resistors:
      1) slew rate control for RF mitigation. Without the resistors it won't be any worse than 12mbps full speed which has no slew rate control, so if you are OK with the RF levels from full speed, you can forgo the slew rate control on low speed.
      2) Short protection. If the data line is shorted when the AVR is outputting a 1, the series resistors will protect the AVR.
      In my experience (and from other people's comments), the AVRs are very tough and a dead short with 5V supply won't kill them. With a 3.3V supply there's even less chance you'll kill it. All the USBasp designs I have use a polyfuse on the Vbus line, so further reducing the chance of damage. With the red LED, it acts like a ~100mA fuse.

      I'm very pleased with my DS1054Z. You should check out the EEVblog review, or just go and buy one because there really is no competition in the under $500 range.

      I too have noticed the 168PB, and home the 328PB follows soon.

    2. Oh man.. series resistors are here for impedance matching. USB spec says 90 ohm. From the AVR pin output voltage-current graph you can assume pin output impedance of 25 ohm. So 68 is making it up to 90.

    3. Now that you mention it, I remember the impedance matching in the spec. It's there to mitigate signal reflections, but at low speed it's rather insignificant; over a 1m USB cable it takes less than 10ns for the reflection to return.
      Also at lower voltages the driver strength drops a bit; at 3.3V the output impedance is a little over 30 ohms.