A couple of months ago I got myself a new Dell P2720DC monitor. Along the HDMI and DisplayPorts inputs, it also has a USB Type-C port which serves multiple purposes.
The -C port can be used a display input, as the input of the built-in USB Hub and it can also charge devices with up 65W of power using the USB Power Deliver 3.0 standard.
With my previous monitor I used a cheap HDMI switch, and as I also use this monitor with multiple PC I stared to look for a similar switch for USB Type-C. I was interested in one that is capable switching at least two USB Type-C input, and is also supports USB PD pass-trough.
It turns out that they are very few switches for USB Type-C on the market. An those available are like super expensive, the cheapest being like > $100.
Then, I thought it wort to see if I could design a inexpensive USB Type-C switch for myself. Bellow is what I came up with.
ConceptThe goal of the project was to design a KVM style USB 3.x Type-C Switch, with the following features:
- two USB 3.x Type-C "Input" and one "Output" port
- switching of all four USB 3.x SuperSpeed differential pairs
- switching of the USB 2.0 HighSpeed differential pairs
- switching of the Configuration (CC) and Sideband use (SBU) channels
- switching the VBus rails, with USB Power Delivery pass-through support up to the full power range of 100W (20V @ 5A)
- reasonable cost
The main use case of the device is to use it as KVM switch, with an USB Type-C Monitor connected to "Output" port, while two PC-s/Laptop-s at the two "Input" ports.
Input devices like a mouse and keyboard that can be connected to the built-in USB Hub of Monitor. The PC/Laptop side then can use the USB Type-C connection for display, charging or just as plain USB hub connection.
Other use case are also possible. There is no actual restriction on what type of devices can be connected on the "Input" / "Output" sides. The switch should be able to handle most of the USB Type-C devices.
Electrical DesignThe USB Type-C Switch was designed in KiCad, with the schematics being done in Eeschema
The schematics is structured using hierarchical sheets. The main sheet contains 3 x USB Type-C receptacles and 4 x sub-sheets:
The 4 sub-sheets contains implementation of the following mostly independent features:
- USB 3.x Signal Switching
- USB 2.0, SBU and CC Signal Switching
- Power Switching and Supplies
- Control
The USB Type-C receptacles are 24 pin versions. This is needed so that USB 3.1 & USB 3.2 functionality can be fully supported.
The Ground signal an Shield of the USB connectors are tied together using a RC filter consisting of a resistor (100k) and a capacitor (100n).
> USB 3.x Signal SwitchingThe USB 3.x standards a capable of data rates of 5 to 20 Gbps. This is achieved by using up to 2 receive (RX) and 2 transmit (TX) differential data signals operation at frequencies of up to 5 GHz, and data rates up to 10 Gbps.
Switching signals operating at such a high speed is not as straight forward. Standard analog switches does not usually handle frequencies that high.
It turn out there are a couple of multiplexer / multiplexer IC-s on the market designed to switch USB 3.x differential signal pairs. These are used in different gadgets to route the USB 3.x data signals, based on the orientation of the USB Type-C port.
However, these IC-s are basically high speed analog switches, so we should be also able to use them to switch USB 3.x data signals coming from two different USB connector.
To switch the 4 differential pairs, I used two FUSB340 IC-s from ON Semiconductor. Each of these is capable to switch 2 differential pairs working at up to 10 Gbps.
Each channel in the switches is used to route one of the 4 x USB 3.x differential pairs. The positive and negative signals are sometimes swapped (the USB 3.x standard allows this) for better routing on the PCB.
> USB 2.0 & SBU & CC Signal SwitchingSwitching USB 2.0 signals is much easier. There are a couple of relatively low cost analog switches capable of switching 480 Mbps signals.
I ended up using the NL3S588 IC switch from ON Semiconductor. The same is used to switch the sideband use SBU1 and SBU2 signals,
Finding suitable switching IC for the CC signals was a little bit trickier. The CC lines are used for Type-C connector orientation detection, but also for powering IC's of active cables. For this reason the switch needs to work at voltages up to 5V, and it also needs to be capable to handle a moderate amount of current.
After some research, I decided to go with the DG2788ADN from Vishay, which is a relatively high bandwidth (338 MHz) switch capable of handling signals with up to 5V and 300mA.
> Power Switching & SuppliesIn the power section there were two things to deal with.
First, the VBus rails of the USB Type-C connectors need to be switched. With the introduction of USB PD 3.0 the USB Type-C cables can be used to deliver up to 100W of power. These means the VBus can work at voltages of 5 to 20V, with maximum current of 5A.
To handle this I used two UCS3205 bidirectional load switches from Microchip, one chip at each input port. The UCS3205 is a bidirectional load switch designed for USB PD applications, and is capable to handle voltages from 5 to 22, maximum current of 5A, and has an on state resistance 30 mΩ.
The switching IC-s and the microcontroller needs power. This is supplied by a power supply with 3 stages.
First the VBus rail of the 3 USB Type-C ports is combined into a single voltage source using 3 Stocky diodes. The 5-20V is then converted down to 5V using a switching regulator, implemented with an AP63205 IC. Then the 5V regulated further down to 3.3V using the AZ1117C LDO regulator.
To detect when cable connected to the USB Type-C ports, the VBus line of each port is sensed using a voltage divider.
> ControlThe control logic of the switch will be realized with a a ATSAMD21E15B micro controller, with ARM Cortex-M0+ core running at up to 48MHz.
The chip has a good number of digital an analog inputs. These are used to control the switch IC-s, to handle a push button input, drive 3 LED-s and to handle the analog VBus sense lines.
The chip also has an USB 2.0 interface. I tied the USB 2.x data lines of one input port to the USB inputs of the ATSAMD21E15B. Normally these inputs will be disabled, but at some point it could be used to implement management / configuration functionality over one the USB ports.
The chip is programmed using through a standard 10 pin JTAG / SWD connector. I plan to program it using the Arduino IDE. The Arduino Zero uses a chip from the same family (ATSAMD21G18), so it should not be too hard make it work.
PCB DesignAfter the schematic was mostly done, the next step was to start designing the PCB.
As the design contains many high speed differential signals, I decided to go with a 4-layer PCB.
I also thought to try with a 2-layer PCB to lower the cost, but when I seen that the 4-layer boards are now just $5 for 5 pieces at JLCPCB it was really a no-brainer to go with 4-layer.
The two inner layers are solid ground planes, while the outer layers are used to route the signals. This way the impedance controlled traces needed by the high speed signal lines are much easier to implement.
As this is an open-source project, JLCPCB offered to sponsor the PCB-s for this project. :)
> High Speed SignalsI started laying out the PCB-s by roughly placing the three USB Type-C connectors and the two FUSB340 IC-s involved in the USB 3.x signal routing. Next, I routed the USB 3.x differential traces, ignoring everything else.
The USB 3.x signals were routed on both the top and bottom planes. To be able to use both sides of the board, I deliberately chosen an USB Type-C receptacles that has one set of signals as through hole pins (B side) and other set of signals (A side) as SMD legs.
As I mentioned earlier the USB 3.x differential signals, and event the USB 2.0 ones, needs to be routed as impedance matched traces. The impedance of the traces for USB need to be 45Ω for a single trace, 90Ω total for a differential pair.
Controlled impedance in 4-layer PCB-s can be done with a technique called micro-strip routing. This works by routing signals on the external layers, over solid ground planes implemented in the inner layers.
Knowing the dimensions and characteristics of the PCB and its layers, the signal impedance can be controlled by selecting the right trace width and spacing.
JLCPBC offers two stack-ups for controlled impedance PCB-s: JLC7628 and JLC2313. After we selected which one we like, there is a calculator that can be used to determine the correct trace width and spacing.
I decided to go with JLC7628, and I ended up using traces of 0.2 mm with a spacing of 0.125 mm (aprox. 5 and 8.1 mils).
After we dial in these values in the Board Setup, we are ready to route the differential pairs. KiCad has some nice tools to do this.
There are a couple of important things to keep in mind when routing high speed differential signals. The most important ones would be:
- avoid corners, especially the 90° one, use two 45° when needed
- use as few vias as possible, and GND stitching vias to connect the two ground planes
- the length of the two signals traces in the pair must be matched
- keep the clearance of ~ 1mm around the high speed differential traces
Here are some example of how to apply the above rules:
After the USB 3.x signals were done, I routed the USB 2.0 ones.
> PowerThe next step was to lay out the power sections.
The hardest part was to extract the VBus rails from the area of the USB Type-C receptacles. The VBus rails will carry a maximum of 5A, so they need to be relatively wide, while the space around the USB Type-C receptacles is very limited.
I decided to place the two power switches right along the USB Type-C receptacles. This way only one VBus trace needs to be routed to the other side of the board
Here is what I end up with:
The VBus trace is 1.25mm wide in most places. In the section that crosses the board the trace is 2.5mm, and it is also backed by a ~5mm wide pour.
The power supply section is located in the bottom of the board, far away from the high speed signal traces.
As the maximum continuous current on the 5V and 3.3V lines should be < 10 mA, the trace width are I used are relatively small: 0.3 - 0.5 mm
The last step was to route the remaining SBU and CC signal lines, and as well the control lines for the micro-controller, and the switching IC-s and LED-s.
This turned out to be a good amount of signals, so to be able to route them I ended up to re-route / adjust the existing high-speed signal a couple of times.
The micro-controller is placed at the top of the board, right above the USB 2.0 switch:
The SBU anc CC switches are placed at the bottom:
The SBU1 and SBU2 lanes are routed as 0.2 mm traces. As in some application the SBU lines are used as USB data lines, I decided to match the length of the two lines.
The CC lines are routed as 0.25 mm traces, to be able to comfortably carry 300mA of current if needed.
After this the PCB design was mostly done. Here is what I ended up with:
- top layer
- bottom layer
- inner layers
The next step was to double check the design in PCBNew, and to generate the Gerber files needed for PCB manufacturing.
This Gerber files can be generated from the Plot menu. PCB manufactures usually have guides with the exact settings to be used.
It is recommended to load the Gerber files to GerbView, and double-check everything looks fine:
After this we are ready to order the PCB from the manufacturer. As JLCPCB offered to sponsor the PCB for this project, I ordered the PCB order from them.
The 4-layer PCB-s with impedance control starts at $5 for 5 pcs at JLCPCB, so I would have probably ordered from them anyway.
As the components used are pretty fine pitch I decided to also add EING surface finish. This cost $15.20:
The manufacturing of the PCB-s took about 4-5 days, so I got the PCB-s about 1.5 weeks after ordering.
They come out nice:
I also decided to order some SMT Stencils:
The smallest sheet size was 38 * 28 cm, which looks like a little bit huge compared to the 5 x 5 cm board. We will see how I will be able to use them.
SoftwareThe firmware of the device was built in Arduino IDE, using a custom board definition. The ATSAMD21E15 MCU on the board is very similar to the ATSAMD21G18 used in the Arduino Zero, so creating a custom board definition was easy:
The software logic of the switch is relatively straight forward. It basically a state machine with 3 states:
- OFF / Idle - all ports & signals are disconnected
- ON Port 1 - OUT port is connected to IN1 port
- ON Port 2 - OUT port is connected to IN2 port
The changes between the states are triggered either by a button press, or by VBUS voltage detection on ports indicating a device was connected.
The switch between the two ON states is made with a short delay to ensure the power and data signals were properly disconnected before making the new connection.
Assembly and TestingAlong the the PCB-s, I also needed to order parts for the project. These where mostly ordered from DigiKey, with a couple of them from LCSC and Farnell.
For testing purposes, I ordered from AliExpress two USB PD 3.0 power supplies rated up to 100W, and also some USB Type-C PD trigger circuits and breakout boards:
As soon as these parts arrive, I will start assembling the board. I plan to test out the features of the board one-by-one, starting with synthetic test and then continuing with real life scenarios.
> AssemblyI started the assembly with the power supply and micro-controller sections, along with a single USB Type-C port.
Unfortunately, the AP63205 switching regulator IC-s I selected for the 5V rail got out stock both at DigiKey and Farnell, so I needed to wait a couple of months for it. For testing I ended up mocking the 5V supply to be provided externally:
The next step was to connect an SWD Debugger and if the micro-controller was detected. Fortunately it was, started testing the all the inputs and outputs by simple Arduino sketches uploaded to the board.
Then I continued with soldering all the USB Type-C connectors, and checking all the connections using a multimeter, and USB Type-C cable and breakout boards:
The rest of the components were mounted on the board one by one. This allowed each of the functions to be tested individually.
> ValidationAlthough the USB Type-C Switch is a simple device, it still quite a bit of functionality that needs to be working:
.. I created this table:
The power supplies section was validated using an oscilloscope:
The signal routing check were done using a Waveform Generator and an Oscilloscope. A 1 MHz sine wave was injected into the different signals of an USB Type-C cable. After the signal passed through the switch, it was measured using an oscilloscope:
Along
There are the bugs and mistakes I found during assembly and testing:
- USB 2.0 Data Signals (+ and -) were swapped on the Out port - I fixed this by cutting the original traces, and replacing them with some patches made from thin coated wire:
- No Power where are the connection are USB Type-C devices connected are in PD idle state - looks like in the next version we will need to add pull down resistors to the CC1 / CC2 lines. These also need to switchable ON / OFF, and 5V on CC1 / CC2 should by default activate the pull-down resistors. This could be achievable with a circuit like bellow:
- Labels of the R17 and R18 resistors were swapped on the silk-screen - these are resistor for the voltage sensing divider, and I ended up populating the swapped on the board - it is fixed in the KiCad project
- SEL line for USB 3.x switching is inverted in Software - this is just a Software bug, so it was an easy fix
Here are some of the references I used in this project:
- Routing USB 3.x Type-C Signals (StackExchange.com, Electronic Engineering)
- USB 3.x Type-C Switch (KVM type) - Design Review (Element14 Community)
Cheers! :)
Comments
Please log in or sign up to comment.