Almost any voltage with QC



Kicad 8 projects and Arduino code : QC_Fab.zip

QickCharge using tiny412

The QuickCharge protocol lets you “negociate” voltage through USB on smart power supplies.

This page is a short documentation about my journey testing QuickCharge capabilities. I did it for myself and mainly for learning purposes.

I like things small and efficient. This is why this project is ATTiny412-based. (could actually be even smaller/simpler processor). The board was redesigned to make it very “Fab-able”.

Long story short (TL;DR;)

The code was written to be as compatible as possible :

All the “fast chargers” tested so far are compatible, even when only declared as PD (not explicitely QC) - read dedicated section to know the difference. However, some appeared to be CLASSA only (12V max) when used with QC even though they can deliver up to 20V when used in PD mode. Also, some were able to ramp up to 20V in continuous mode but not as QC2.0 standard voltage (asking for 19.9V will to the trick, for example). Strange.

The QC protocol

The CHY103 datasheet provide a good overview about the QC3 protocol : handshake and voltage selection. Voltages are selected based on three voltage levels applied to D+/D- pins :

  • 0V
  • 0.6V
  • 3.3V

CHY100 datasheet specifies voltage thresholds of 0.325V and 2V, so 0.6V is a safe (and generally documented) value for the “intermediary” voltage.

The QC protocol in brief :

QC2.0 voltages :

D+ D- Output
0.6V GND 5V
3.3V 0.6V 9V
0.6V 0.6V 12V
3.3V 3.3V 20V

QC3.0 addition :

D+ D- Output
0.6V 3.3V enter continous mode
0.6V 0.6V (glitch) Decrease 0.2V
3.3V (glitch) 3.3V Increase 0.2V

After each glitch, the signals must return to “coutinous mode” (D+ = 0.6V, D-=3.3V). Glitches are 5ms in this code.

A more detailed explaination about the protocol and the code is documented in the arduino code commented head section.

The board

The schematic is pretty simple (USB only view) :

  • D+ 0.6V voltage is realized by a resistor bridge (R1 and R2) when the corresponding pin is set as an input. When set as an output, the pin imposes its own voltage that can be 0V = LOW (actually never used) or 3.3V = HIGH
  • D- 0.6V is realized by the ADC (code will automatically select available internal reference). Instead of changing the ADC value to get the 0V or 3.3V, we simply set the pin as a digital output when needed.
  • two 1k resistors protect the lines in case something goes wrong

The full schematic includes :

  • a 10k (or reasonably close, not critical) potentiometer - RV1 - to provide a selectable input readable by an analog pin
  • a resistor bridge (R6 and R7) to divide the VBUS voltage by 11 : we’ll do the more complex maths later. (see notes about ADC on the sense pin)
  • a 3.3V regulator and its capacitor : this value has been chosen to ease the output voltages values on D+/D-
  • and of course our cute and lovely little atTiny412 and its UPDI access for programming

Before you go further, I strongly recommend that you have a look at the code and know your goal as you might not want to populate the entire board depending on your usage.

I packed everything together. And I still use thick traces [min 0.64mm, usually more, especially on power lines]. Thick traces are easier to mill (with more than reasonable 0.5mm clearance), more robust and handle more current and force. So why would we wear out our bits removing more copper?

This is my very first test of 3D printing (and actually just using) a stencil. All I did was to export the “Mask” layer as SVG, removed the big connectors (USB and OUTPUT) and made it 3D with a three-line code in OpenSCAD. It was printed in PETG (for robustness, but could have been PLA) with a 0.25mm nozzle on a Prusa MK3S. Slowing down (@~70%) the printer gave good results.

I taped it slightly, put some paste and spread the solder paste with a spatula.

Well. Yeah, ok : this is ugly. Probably too thick stencil : there is too much solder paste. But looks at the right place and as long as the solder joins by capilarity, it should be good. I had ordered a hot plate (the PCB is so small it will entirely fit on a MHP430), but couldn’t really wait to get it, so I used a hot air gun. Discovered that I had to provide a fair air flow to melt it.

These are the components placed before being soldered. Tight package is cool. But not that easy to place the components without moving the previous ones.

I would have expect a little bit better result and had to remove the USB connector because some paste was short-circuiting the GND anv VBUS underneath, but all the rest was ok.

Hero video

And this is working just great!

Notes and comments

An arduino library exists but doesn’t take advantage of DAC and will be more resources/hardware/pins-consuming.

“Indication” LED

I added an “indication” led that lets me have a very rough idea of the voltage : with a 10k resistor the led will be very shy at 5V and be more visible when approaching 20V. This value might be adapted for ClassB. (3k3 or 4k7 probably are good values for ClassB, I didn’t test)

Stronger power lines

I put a quite thick solder cover on the power lines between my USB connector and output terminal block. This is because I want to make sure that my traces will handle high currents without resistance. It makes my board uglier but more reliable.

Resistor divider, ADC timing and maths

R6 = 47k and R7 = 4k7 form a resistor divider by a factor 11 : those values were chosen to ease components list (10x multiples are very common in stocks) and let VBUS reach 20V (or more) safely :

Using high impedance resistance devider will sink less current but will maybe require small ADC timing adjustments and/or parallel small capacitor (e.g. 100nF in parallel with R7) to avoid noise on the sensing pin.

This voltage sensor is used as a feedback.

Getting the value in dcV from the voltage divider requires some maths :

So we should compute a 11x33/1023 ~= 0.355 multiplication to get the actual voltage in dcV from the ADC conversion. This is achieved by approximating 0.355 by ( 1 + 1/2 - 1/16 - 1/32 + 1/64) / 4, that is “quite” easy to compute with limited computational resources. This code complexification is the (not-that-high-)price to pay for high code compatibility and versatility on a chip with limited resources.

“Universal” UPDI access

I put a “double” foot print on the board to reach the UPDI pin : you can either solder a 2 pins 2.54mm SMD header to get your GND-UPDI contacts, or solder a unique through hole pin. This last solution gives more robustness for testing purposes and will work fine if you connect your GND reference into the terminal block (or if you’re connected to a USB port with the same GND reference).

I actually solder a UPDI connector for testing purposes only. On my end board I usually simply program my code by pressing a wire on the UPDI pad and leave it unpopulated.

Drilled USB connector versions

I added a drilled USB connector version. I’m not a huge fan of using those, especially for power-related boards or testing purposes.

Wide power regions

I intentionally created wide power regions on the top : this allows one to solder wires instead of populating with a terminal block connector.

QuickCharge (QC) VS Power Delivery (PD)

Quick Charge and Power Delivery stand out as two prominent players, each with distinct features and specifications.

Quick Charge is often associated with Qualcomm Snapdragon-powered devices, while Power Delivery is more commonly found in a wide array of devices due to its open standard nature.

While both technologies aim to provide rapid charging, Power Delivery offers broader compatibility and versatility, especially with the rise of USB Type-C as a universal standard. However, Quick Charge remains popular for its efficiency and fast-charging capabilities in Qualcomm-powered devices. My choice of investigating QC is essentially linked to the USB connector (see below).

Quick Charge

Quick Charge, developed by Qualcomm, utilizes a protocol that typically relies D+ and D- pins of USB Type-A or Type-C connectors. This also means that those communication lines are not available for actual USB communication when Quick Charge is used.

So :

*

(img credit Simon Eugster on wikipedia )

Power Delivery

On the other hand, Power Delivery (PD) is an open standard established by the USB Implementers Forum (USB-IF). It operates using the USB Type-C connector, which supports a versatile array of functions beyond charging, such as data transfer and video output. PD can negotiate power delivery between devices, allowing for a range of voltages and currents, through the additional USB wires/lines (. This flexibility makes it suitable for various devices, from smartphones to laptops and beyond.

So :

*

(img credit Chindi.ap on wikipedia )

Conclusion

This - very - small board allows me to get - almost - any voltage using very minimalistic hardware and works on most smart power supply. Playing around with my different chargers let me know more about their real (and sometimes surprising) characteristics. When all I need is 12V, I now can get it easily on - almost? - any charger (even external batteries).

This gives me food for thought about my box of “chargers I keep just in case” I need a specific voltage…

Is it about to become old XX’s century stuffs?

Files

Kicad 8 projects and Arduino code : QC_Fab.zip