Skip to content

Commit

Permalink
Hardware description
Browse files Browse the repository at this point in the history
  • Loading branch information
manuelbl committed Nov 19, 2020
1 parent f921196 commit 09a25ce
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 14 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
Artwork/
24 changes: 10 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ Open-source firmware for USB Power Delivery trigger board based on an FUSB302B p

![ZY12PDN board](doc/board.jpg)


## Building

- Clone the project from GitHub
- Open it with Visual Studio Code
- Install the PlatformIO extension
- Click the build icon in the status bar


## Upload

The ZY12PDN board has a 4-pin SWD pads at the bottom. Either solder wires to them or use a 4-pin adapter with pogo pins.
Expand All @@ -22,6 +24,11 @@ Connect the SWD pads with an ST-Link, J-Link or Black Magic Probe to your comput
In most cases, you will need to try twice since the board does not enable the SWD pins quickly enough.


## Hardware

See [Hardware](doc/hardware.md) for a detailled description of the board and its components (incl. schematic).


## Supported PD Messages

- *Capabilities*: The source announces the supported voltages. The sink must immediately request one of the voltages.
Expand All @@ -34,28 +41,17 @@ In most cases, you will need to try twice since the board does not enable the SW
## Notes

- If the event type of the `pd_sink` callback is `callback_event::source_caps_changed`, `request_power()` must be called to request a voltage -- even if it is 5V. Otherwise the source is likely to reset.
- VBUS is directly connected from the USB-C socket to VBUS (+) of the output. So for the board to be more useful, it would probably make sense to add a MOS-FET as a switch further downstream so that power is only turned on once the correct voltage is available. Initially, VBUS will always start with 5V. To control the MOSFET, you have to solder a wire to one of the unused MCU pins.
- The firmware is currently limited to the fixed voltages. Additionally capabilities (variable voltages etc.) can be easily added.
- The firmware does not properly work with Apple's 87W USB-C Power Adapter. It eventually works but the voltage is cut for a short time and reapplied. The firmware reboots and after that is occupied with endless interrupts.
- Using the build flag `-D PD_DEBUG`, debugging output can be enabled. In order to see it, you have to solder a wire to PA2 (USART2 TX pin) and connect it to a serial adapter. The baud rate is 115,200 bps.
- All the code is very timing sensitive. Be very careful with debugging output in the `source_caps_changed` callback. It the debugging output takes too long, the USB power supply will likely reset and even cut the power.
- The FUSB302B chip can monitor VBUS. However, the pin is not connected. So the firmware must derive the voltage from the USB PD messages (mainly *Request* and *PS_RDY*).


## Firmware Mode

The designers have made two decisions that are unfortunate for hackers:

1. They do not use I2C pins of the I2C peripheral.
2. The pin for SWDIO and INTN is shared.

This was probably made to make the board smaller as the resulting traces are very short indeed:

![Traces](doc/traces.jpg)

Challenge 1 is solved with I2C bit-banging.
The SWDIO line is shared with the interrupt line of the USB PD controller. Therefore, uploading firmware is tricky.

Challenge 2 is somewhat trickier. The firmware needs to decide if a debugger is connected or not:
The firmware needs to decide if a debugger is connected or not:

- If a debugger is connected, the FUSB302B is turned off so it releases the SWDIO pin and the SWD has to be enabled.
- If no debugger is connected, the FUSB302B is configured, and it uses the SWDIO to signal interrupts.
Expand All @@ -64,4 +60,4 @@ Currently, SWCLK is initially configured as input with an external interrupt. If

If you know of a better approach to detect a debugger, let me know.

SWD can be used to upload new firmware. But debugging is not possible as in normal operation, the SWDIO pin is used as the interrupt pin.
SWD can be used to upload new firmware. But debugging is not possible as in normal operation the SWDIO pin is used as the interrupt pin.
Binary file added doc/components.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 58 additions & 0 deletions doc/hardware.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Hardware


## Schematic

![Schematic](schematic.svg)

The SWD programming port is available as 4 pads on the bottom side of the board.


## Components

![Components](components.jpg)

| Label | Component | Purpose |
| ----- | --------- | ------- |
| U1 | FUSB302BMPX | USB PD controller |
| U2 | STM32F030F4P6 | Microcontroller |
| U3 | ? | 3.3V voltage regular (LDO), Vin up to 20V |
| D1, D2 | ? | Diode, probably for ESD protection |
| D3 | ? | Schottky diode, reverse voltage protection? |
| C1 | 1µF | Decoupling capacitor at input of LDO |
| C2 | 470nF | Decoupling capacitor at input of LDO |
| C3 | 4.7µF | Decoupling capacitor at output of LDO |
| C4 | 100nF | Decoupling capacitor at VDD/VDDA of MCU |
| C5 | 100nF | Debouncing capactior for button |
| C6 | 100nF | Timing capacitor for reset |
| R1, R2 | 100Ω | Input protection for CC1/CC2 |
| R3 | 2.2kΩ | Pull-up resistor for SDA |
| R4 | 2.2kΩ | Current limiting resistor for blue LED |
| R5 | 5.6kΩ | Current limiting resistor for green LED |
| R6 | 2.2kΩ | Current limiting resistor for red LED |
| SW1 | ? | Tactile button |
| LED1 | ? | RGB LED |
| USBC1 | ? | USB-C receptable |


## Notes

- The USB PD controller has a *VBUS* input to measure and monitor the VBUS voltage. The pin is connected to ground. Therefore, the VBUS monitoring cannot be used.
- The I2C pins of the MCU are PA9 and PA10 for SCL and SDA, respectively. However, the SCL and SDA traces are connected to PA10 and PA9. Thus they are swapped to save board space with short traces (see image below). Therefore, the MCU's I2C peripheral cannot be used. Instead, I2C bit banging must be used.
- The SWDIO pin is connected to both SWDIO and the USB PD controller's interrupt pin, again to achieve short traces (see below). Tricks must be used to ensure firmware can still be uploaded. See below how to revive the board if the trick fails.
- VBUS of the USB-C connector is directly connected to the positive contacts of the output. There is no controllable switch in-between. Therefore, there will always be 5V on the output when the board is initially connected to a power supply, no matter how sophisticated the firmware is. To improve, a MOSFET would need to be connected down-stream and controlled from the MCU.
- There are several unused MCU pins that can be used for different purposes: PA0 thru PA4 and PB1. The firmware can use PA2 for serial output (debugging).

![Traces](traces.jpg)


## Revive Board

If the board can no longer be flashed with the SWD connector on the bottom side because the firmware cannot stop the PD controller from interfering with the SWDIO line, the board can be revive like so:

- Solder a wire to NRST. The easiest location for soldering is capacitor C6 (on the left side of the capacitor in the above image).
- Connect all four SWD pins plus NRST to a debug adapter.
- Use a firmware upload/erase configuration that connects under reset.
- Erase the flash.

I've been succuessful with a J-Link adapter and J-Flash Lite (but not with J-Flash). An ST-Link adapter and the proper configuration might also work if you know how.
5 changes: 5 additions & 0 deletions doc/schematic.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 09a25ce

Please sign in to comment.