
## 1 USB与USB PD
由于USB的内容经过这么多年的发展,内容非常多,本篇文章并不能完整的介绍,仅能简单的提供一些资料以供诸君了解。
USB,全称为Universal Serial Bus(通用串行总线),是一种快速、灵活的总线接口。它是为了解决日益增加的PC外设与有限的主板插槽和端口之间的矛盾而制定的一种串行通信标准。
USB一般常用的就是USB2.0、USB3.0,而USB3.0还包括Gen 1和Gen2。同时,支持设备(例如iPhone X)的快速充电而使其倍受青睐。通过称为Power Delivery(PD)。
### **1.1 USB PD1.0**
USB PD1.0就要是对之前USB BC技术的整合,其传输功率从之前的7.5W提高到了最大100W,输出电压最高达到20V,最大电流达到5A。当一个USB用电设备通过USB接口连接到USB主机后,其初始功率为10W (5V / 2A),但是通过功率规格选定之后,可以进行传输功率转换,可选的传输功率有18W,36W,60W或者100W。
早其的USB PD技术使用的是VBUS进行PD协议的传输协商的,这样做的目的是为了不影响Type-A/B接口中数据线(D+,D-)上的数据传输。
如下图,在USB PD通信中,是将24MHz的FSK通过cAC-Coupling耦合电容耦合到VBUS上的直流电平上的,而为了使24MHz的FSK不对Power Supply或者USB Host的VBUS直流电压产生影响,在回路中同时添加了zIsolation电感组成的低通滤波器来过滤掉FSK信号。

但是,由于PD信号与电源以及USB数据之间的信号完整性等问题,这次尝试效果并不是很好。而且根据USB-IF的规范,只有当线缆一端是Type-A口,另一端是Type-B口的时候,才允许功率传输,这样不但限制了功率的双向传输,而且实现功率双向传输也变得非常复杂。
### **1.2 USB PD2.0**
USB PD2.0规范的发布是基于Type-C接口实现的,VBUS电压可以在5V,9V,15V和20V之间切换。
USB PD2.O规范奠定了现代USB PD技术的基础,具有划时代意义。
Type-C是一种接口规范,默认最大支持5V/3A。Type-C接口带有专用的通信线,即CC(channel configure)线。CC线可以传输USB PD协议,同时支持DRP (dual role port) type C接口,可以在电源和负载之间进行角色转换,进而支持功率双向传输。USB PD2.0借助Type-C接口进行功率传输,有效的解决了上述问题。
随着Type-C接口规范的发布,USB-IF将USB PD升级到了2.0版本。BUS电压根据需求在5V,9V,15V和20V之间切换。

### **1.3 USB PD3.0**
USB PD3.0是目前USB PD的最新版本。其最大的特点是可编程性,使用USB PD技术走向了更加智能化,更加精细化的操作。
在PD2.0的基础上,PD3.0增加了PPS(programmable power supply)功能,BUS电压能够以20mV/step进行调整,电流限值能够以50mA/step进行调整。电压电流细分调整可以优化电力传输策略,让power变得更加智能化。
USB PD2.0规定多大的功率就应该输出哪几个档位电压。举例来说,如果输出功率为45W那么就应该输出5V/9V/15V@3A,而不需要出现20V这个电压。另外,PD3.0功率规则也是类似,只是增加了可变输出电压档位。

## 2 USB 新一代接口:TypeC
TYPE-C是一种硬件线缆接口,该接口主要用于数据传输和对使用了该接口的设备进行供电。

同时,Type-C作为一种接口规范,默认最大支持5V/3A。Type-C接口带有专用的通信线,即**CC (channel configure)线**。CC线可以传输USB PD协议,同时支持DRP (dual role port) type C接口,可以在电源和负载之间进行角色转换,进而支持功率双向传输。USB PD2.0借助Type-C接口进行功率传输,有效的解决了上述问题。

可以看到,TypeC接口`VBUS`和`GND`都存在四个触点,可以提供更大的电流。
四组`USB 3.0`数据通道`RX1PN` `RX2PN` `TX1PN` `TX2PN`,提供了高达40Gbps的数据交互能力。
两组`USB 2.0`数据通道`D1PN`、`D2PN`,支持USB2.0的D+/D-数据引脚。
另外的引脚包括`CC1`,`CC2`,`SBU1`,`SBU2`作为设备沟通和音频转接的功能使用。
### **2.1 SBU**
SBU1/SBU2 主要是用于音频应用,将TYPE-C用于传输模拟音讯。

### **2.2 CC**
TypeC最大的创新在于多了`CC1`、`CC2`引脚,CC PIN是PD的沟通接口,主要是负责两边Device的电源及数据协议格式的握手工作。在CC PIN上的走的是`Bi-phase Mark Code(BMC)`通信界面,BMC是one–wire传输接口,在TYPE-C PD传输速度被规定在`300K±10%`,传输格式如下图,每一个bit都需要在准位上先做一次转向,当DATA为1时需要在一个单位时间内高低准位各转向一次,当DATA为0时则转向后需保持一个单位时间长度。

信号线封包格式则是包含了Sync、Start of Packet(SOP)、Header、Data、CRC、End of Packet(EOC)…等。
其中`SOP`又分为`SOP`、`SOP'`、`SOP''`三种,分别对应到不同的目标设备:
- `SOP`:缆线对面的设备
- `SOP'`:缆在线较靠近自己的E-Marker
- `SOP''`:缆在线较远离自己的E-Marker

此时,应该大家都会有一个问题~~(可能也不算大问题,毕竟大家用`16P TypeC`都是直接下拉`5.1KΩ`)~~
> 既然是`one-wire接口`为何需要两根PIN?
这是因为TYPE-C并没有正反之分,所以当两设备对接后,才会决定由哪一个脚位去做`BMC`数据传输。
此时另一个脚位则会变成所谓的`VCONN PIN`,用来做为另一个电源的输出,主要是用来供电给TYPE-C缆在线`E-marker IC`使用。

如图,图上的彩线模拟了TypeC公对公线材内部的电路。
反接时,A5-B5连接,`CC->CC2`;正接时,A5-A5连接,`CC->CC1`。
由于TYPE-C两头都一样,没有方向性,所以在对接前并不会有电源输出,数据主从也尚未定义。在PD的规范内,针对装置对接,定义了三个电阻来进行对接的识别。
`Rp`:做为下行设备`DFP`需要在CC脚位上上拉一个`Rp`电阻。Rp电阻允许有三种阻值(上拉5V时,10K/22K/56K),这三种阻值也同时初步的宣告了下行设备`DFP`在对接的初期允许的电流。
此时CC线经分压电阻后电压大约`1.68V(10K)`/ `0.92V(22K)`/ `0.41V(56K)`。

`Rd`:做为上行设备`UFP`时需要在CC脚位上下拉一个`Rd`电阻`5.1K`。
`Ra`:在缆线中的`E-Marker IC`需要下拉一个`Ra`电阻`1K`。

例如对于本次开源设计的`CH543` PD控制器来说,芯片在CC1,CC2的管脚上内部设置了下拉电阻。在设计时就可以减少物料的成本。

### **2.3 4b5b编码器解码器**
TYPE-C PD供电协议信号是通过线缆CC1进行传输的,但数据的发送与接收方在信号进行传输过程中传递的并不是原始数据,而是处理过的数据。
- 对于数据发送方,需要对原始数据进行4b5b的编码,再通过BMC编码器,然后再通过CC1引脚进行传输。

- 对于数据接收方,需要执行发送方的逆操作,即先进行BMC解码,然后再4b5b的解码。

PD供电协议编码格式是4b5b,即把4位的数据(0x0-0xf)编码成5位,其编码对照表见下图:
| 名称 | 4b | 5b Symbol | 描述 |
| -------- | ------ | --------- | ----------------- |
| 0 | 0 | 11110 | hex data 0 |
| 1 | 1 | 1001 | hex data 1 |
| 2 | 10 | 10100 | hex data 2 |
| 3 | 11 | 10101 | hex data 3 |
| 4 | 100 | 1010 | hex data 4 |
| 5 | 101 | 1011 | hex data 5 |
| 6 | 110 | 1110 | hex data 6 |
| 7 | 111 | 1111 | hex data 7 |
| 8 | 1000 | 10010 | hex data 8 |
| 9 | 1001 | 10011 | hex data 9 |
| A | 1010 | 10110 | hex data A |
| B | 1011 | 10111 | hex data B |
| C | 1100 | 11010 | hex data C |
| D | 1101 | 11011 | hex data D |
| E | 1110 | 11100 | hex data E |
| F | 1111 | 11101 | hex data F |
| Sync-1 | K-code | 11000 | Startsynch #1 |
| Sync-2 | K-code | 10001 | Startsynch #2 |
| RST-1 | K-code | 111 | Hard Reset #1 |
| RST-2 | K-code | 11001 | Hard Reset #2 |
| EOP | K-code | 1101 | EOP End Of Packet |
| Reserved | Error | 0 | Shall Not be used |
| Reserved | Error | 1 | Shall Not be used |
| Reserved | Error | 10 | Shall Not be used |
| Reserved | Error | 11 | Shall Not be used |
| Reserved | Error | 100 | Shall Not be used |
| Reserved | Error | 101 | Shall Not be used |
| Sync-3 | K-code | 110 | Startsynch #3 |
| Reserved | Error | 1000 | Shall Not be used |
| Reserved | Error | 1100 | Shall Not be used |
| Reserved | Error | 10000 | Shall Not be used |
| Reserved | Error | 11111 | Shall Not be used |
如上图,根据上面的编码状态,可以组成一些常用的功能序列。
#### **2.3.1 硬件复位 hard Reset**
硬件复位信令是为了被物理层识别而发送的一组有序字节。
硬复位信号顺序集定义为:`RST-1 K,RST-1 K,RST-1 K,RST-2 K`。
硬件复位的功能是对接口和线缆进行复位。
| K-code | number K-code in code table |
| ------ | --------------------------- |
| 1 | RST-1 |
| 2 | RST-1 |
| 3 | RST-1 |
| 4 | RST-2 |
#### **2.3.2 线缆复位 Cable Reset**
电缆复位信令是一组有序的字节,发送的目的是将其识别为嵌入到PHY层的控制消息。
电缆复位信号顺序集定义为以下K代码序列:`RST-1,Sync-1,RST-1,Sync-3`。
线缆复位用于对线缆进行复位。
| K-code | number K-code in code table |
| ------ | --------------------------- |
| 1 | RST-1 |
| 2 | Sync-1 |
| 3 | RST-1 |
| 4 | Sync-3 |
电缆复位信号只能由DFP发送。电缆线缆复位序列用于重置电缆插头,无需硬重置端口。电缆复位信号发出后,电缆插头的状态应等同于电缆插头的电源循环。
#### **2.3.3 包序列开始 Start of Packet Sequence (SOP)**
`SOP`是一个有序的集合。
`SOP`序列集定义为:`Sync-1,Sync-1 ,Sync-1,Sync-2` 。
`SOP`用于数据包的开始标识,在**发送给接口的信号中**使用。
| K-code | number K-code in code table |
| ------ | --------------------------- |
| 1 | Sync-1 |
| 2 | Sync-1 |
| 3 | Sync-1 |
| 4 | Sync-2 |
#### **2.3.4 Start of Packet Sequence Prime (SOP')**
`SOP'`的有序集定义为:`Sync-1,Sync-1 ,Sync-3 ,Sync-3` 。
`SOP'`用于数据包开始标识,在**发送给线缆的信号**中使用。
| K-code | number K-code in code table |
| ------ | --------------------------- |
| 1 | Sync-1 |
| 2 | Sync-1 |
| 3 | Sync-3 |
| 4 | Sync-3 |
#### **2.3.5 Start of Packet Sequence Double Prime (SOP'')**
`SOP''`有序集定义为以下K代码序列:`Sync-1、Sync-3、Sync-1、Sync-3`。
`SOP''`用于数据包开始标识,在发送给线缆的信息中使用,如果线缆中有两个供电协议通讯单元,则一个通过`SOP`通讯,另一个用`SOP''`通讯。
| K-code | number K-code in code table |
| ------ | --------------------------- |
| 1 | Sync-1 |
| 2 | Sync-3 |
| 3 | Sync-1 |
| 4 | Sync-3 |
### **2.4 PD通讯消息格式**

消息定义为以下格式:
- `Preamble`:信息编码为呈现“`0`”和“`1`”的交替序列。
- `SOP*`:可能包含三种SOP格式:`SOP、SOP'、SOP''`,
- 帧头`Header`:,消息头包括2`byte`,总共16位。这里展示的是控制和数据消息的`Header`,控制消息的`Header`暂时不做介绍。并且对于SOP'和SOP''消息,这里仅仅简单提到。
| 位 | 名称 | 说明 |
| :---- | :----------------------------------------------------- | -----------------------------------------------------------: |
| 15 | `Extended` | 此消息是否为扩展类型 |
| 14-12 | `Number of Data Objects` 数据个数 | 后面数据的个数,每个数据是4byte。对于非扩展数据,此字段的值为0~7 |
| 11-9 | `Message Id`消息ID | 消息ID,每发送一次,增加一次 |
| 8 | `Port Power Role` 接口供电角色 / Cable Plug 线缆或接口 | 对于`SOP`信息,代表接口的供电角色 / 对于`SOP'`或`SOP''`信息,代表此消息是接口发送的还是线缆发送的 |
| 7-6 | `Specification Reversion`规范版本 | 此消息的当前版本 |
| 5 | `Port Data Role` 接口通讯功能角色 / Reserved | 对于`SOP`消息代表接口的功能角色 / 对于`SOP'`和`SOP''`保留 |
| 4-0 | `Message Type`消息类型 | 消息类型 |
```c
/* Header */
typedef struct {
// Extended 1 0
// NDO 3
// MsgID 3
// PortPwrRole 1 0:Sink 1:Source
// SpecRev 2 01 Rev2.0
// PortDataRole 1 0:UFP 1:DFP
// MessageType 5
UINT8 PortPwrRole:1;
UINT8 MsgID:3;
UINT8 NDO:3;
UINT8 Extended:1;
UINT8 MsgType:5;
UINT8 PortDataRole:1;
UINT8 SpecRev:2;
} _Msg_Header_Struct;
```
- 数据`Byte 0-n`:PD定义了两种消息类型,分别为控制、数据消息(`Control Messages Or Data Messages`)和扩展消息(`Extend Messages`)。
- `CRC`:用于保护数据帧头和数据,应该在传输完帧头和数据之后立即被合并。PD数据当中的CRC是32bit,多项式为`04C1 1DB7h`,初始值为 `FFFF FFFFh`。

- `EOP`上文已经介绍,这里不再详细描述。其中仅`SOP*`和`EOP`的长度为`4b5b编码`之后的长度。
## 3 USB PD DFP/UFP协商流程
### **3.1 PD 通讯流程**
发送方发送信息给接收方后,接收方收到消息并确认无误(CRC是否正确)后,应向发送方回复`GoodCRC`以表示自己正确无误地收到发送方发过来的消息,发送方收到`GoodCRC`后表示该消息发送成功,否则发送方等待超时(0.9~1.1ms),重新发送原消息。
消息重试发送最多两次重试,如果重试三次发送方都未收到`GoodCRC`,则认为消息发送失败。
所有的消息发送都是由发送和GoodCRC回复组成。

当供电设备和耗电设备通过TYPE-C接口一旦连接后,就进入了供电协商的过程。

- 当耗电方和供电方通过TYPE-C线缆连接之后,一端为供电方,另一端为耗电方。此时供电方默认提供的电压是5V.
- 此时耗电方通过CC1上的电压获取供电方默认的供电电流能力。
- 供电方向耗电方发送`Source_Capabilites`数据信息。
- `Source_Capabilites`信息的数据部分描述了代但发方提供的所有供电能力,如`5V/3A、9V/3A`等。
- 耗电方收到之后,解析供电方的供电能力,然后请求自己需要的供电。
- 如耗电方的电源需求是`9V/2A`,耗电方解析到供电方有`9V/3A`的供电能务,能满足要求,然后耗电方向供电方发送`Request`消息请求`9V/2A`的供电能力
- 供电方收到请求之后,会判断是否可以满足对方的请求。
- 如果满足,供电方会发送`Accept`信息,在`Accept`发送成功之后,供电方操作`VBUS`提供请求的供电,然后发送`PS_Rdy`告诉耗电方已提供请求的供电。如果不满足,则供电方会回复`Reject`表示请求的供电不满足。
若是在`耗电方`工作过程中想改变工作供电,协商的流程如下:

- 耗电方根据前面民到的`Source_Capabilites`数据信息选掼其它的电压和电流。
- 耗电方发送`Request`消息请求需要的供电。
- 如果满足,供电方会发送`Accept`信息,在`Accept`发送成功之后,供电方操作`VBUS`提供请求的供电,然后发送`PS_Rdy`告诉耗电方已提供请求的供电。如果不满足,则供电方会回复`Reject`表示请求的供电不满足。
另外一种`供电方`改变工作供电的,则是由供电方提出:

- 供电方重新向耗电方发送`Source_Capabilites`数据信息。
- `Source_Capabilites`信息的数据部分描述了供电方提供的所有供电能力。
- 耗电方收到之后,解析供电方的供电能力,然后请求自己需要的供电。
- 供电方收到请求之后,会判断是否可以满足对方的请求。
- 如果满足,供电方会发送`Accept`信息,在`Accept`发送成功之后,供电方操作`VBUS`提供请求的供电,然后发送`PS_Rdy`告诉耗电方已提供请求的供电。如果不满足,则供电方会回复`Reject`表示请求的供电不满足。
> **DRP角色的切换流程暂不在本文的叙述范围之内。**
### **3.2 CH543 C代码解析**
本例以`UFP供电协商`为例。
```c
switch(Union_Header->HeaderStruct.MsgType)
{
case SourceCap: //PD:接收到Source_Capabilites的数据信息
PD_PHY_STAT.SendingRequest = 1;
break;
case Accept: //PD:接收到Accept的数据信息
break;
case PS_RDY: //PD:接收到PS_RDY的数据信息
break;
...
...
default :
//
break;
}
mDelayuS(25);
PD_PHY_STAT.SendingGoodCRC = 1; //置发送GoodCRC标志位
PD_PHY_TX_GoodCRC(); //回复GoodCRC
```
## 4 USB AltMode模式协商流程
### **4.1 AltMode 交替模式通讯流程**

- 当具有DP功能的设备通过Type-C线缆连接上之后,一端是DP主 机,另一端是DP设备。
- DP主机如果不是下行端口(DFP),会进行通信角色切换成下行端口。
> 当PD快充在CC线上完成后,主机将会对设备发送VDM类请求,即当`Message Type`消息类型为`Vendor_Defined(0_1111b)`时。
>
> VDM消息包含三种格式:`Header + VDM Header + 消息内容`,Header详情见上。
>
> VDM Header的结构体构成如下:
>
> 
>
> 消息内容根据Header的Command来进行构造,详细还是到官网查看spec。
- DP主机发送`Discover Identity`信息获取连接设备的信息。
- DP设备回复`Discover IdentityACK`信息,包含自己的设备信息。
- DP主机发送`Discover SVIDs`信息获取连接设备支持的厂商SVID列表。
- DP设备端回复`Discover SVIDs ACK`信息,包含自己支持的SVIDG列表。
- DP主机收到回复后,发送`Discover Modes`获取DP设备的模式信息。此信息的数据头使用DP的VID,表示获取支持的DP模式的列表。
- DP设备回复`Discover Modes ACK`信息,包含自己的模式列表。
- DP主机收到回复后,解析收到的所有模式,并从中选取一个合适的模式,作为Enter MODE的参数发送给对方。
- DP投备收到,进入D模式,开始工作有DP模式
- DP主机发送`EnterMode`成功后,也开始工作为DP模式
- Dp主机发送`DpstasUpdate`信息设置DP设备的状态
- DP设备回复`Dpstas Update ACK`信息,包括DP上行端口功能连接状态(UIPD)和DP显示设备连接状态(HPD Staus)
- 如果DP上行端口功能(UFPD)已经连接,DP主机发送`DP Confgure`配置设备端DP通信信号。如果DP显示设备已经连接,则开始 进行DP通信
- 如果DP上行端口功能没有连接,DP主机等待Attention信息报告 连接变化
- DP设备会通过Atention通知自己的状态变化。
- 当收到Atention指示DP上行端口功能已经连接时,DP主机通过 DPConfigure配置DP通信信号。
- 如果DP显示设备没有连接,DP主机等待Auention信息报告连接 变化
- DP设备会通过Auenion通知自己的状态变化。
- 当收到Atention指示DP显示设备已经连接(HPDState)时,开始进行DP通信。
Source&Sink端`退出DP模式`的流程在一般应用中用不到。这里不进行描述。
### **4.2 CH543 C代码解析**
```c
switch(Union_Header->HeaderStruct.MsgType)
{
case SourceCap: //PD:接收到Source_Capabilites的数据信息
PD_PHY_STAT.SendingRequest = 1;
break;
case Request:
MsgID++;
// 需要先验证请求是否可行,OK的话操作ISINK进行修改 ,然后在450ms内PS_RDY
PD_PHY_STAT.SendingAccept = 1;
break;
case Accept: //PD:接收到Accept的数据信息
break;
case Reject:
break;
case PS_RDY: //PD:接收到PS_RDY的数据信息
break;
case GetSrcCap:
MsgID++;
PD_PHY_STAT.SendingSourceCap = 1;
break;
case GetSinkCap:
MsgID++;
PD_PHY_STAT.SendingSinkCap = 1;
break;
case SourceCap_VDM:
Recv2 = Union_Header->HeaderStruct.SpecRev; //获取版本号
Union_VDM_Hdr = (_Union_VDM_Hdr *)&PD_RX_BUF[2];
switch(Union_VDM_Hdr->VDMHdrStruct.Command)
{
case 1: //DP:Discover Identity请求
MsgID++;
PD_PHY_STAT.SendingACK_Disc_Ident = 1;
break;
case 2: //DP:Discover SVIDs请求
MsgID++;
PD_PHY_STAT.SendingACK_Disc_SVID = 1;
break;
case 3: //DP:Discover Modes请求
MsgID++;
PD_PHY_STAT.SendingACK_Disc_Mode = 1;
break;
case 4: //DP:Enter Mode请求
MsgID++;
PD_PHY_STAT.SendingACK_Enter_Mode = 1;
break;
case 16: //0x10
PD_PHY_STAT.SendingACK_DP_Stat_Pos_1 = 1;
MsgID++;
break;
case 17: //0x11
PD_PHY_STAT.SendingACK_DP_Configure_Pos_1 = 1;
MsgID++;
break;
}
break;
default :
//
break;
}
mDelayuS(25);
PD_PHY_STAT.SendingGoodCRC = 1; //置发送GoodCRC标志位
PD_PHY_TX_GoodCRC(); //回复GoodCRC
```
## 5 工程介绍
CH543内置了USB Power Delivery控制器和PD BMC PHY收发器。支持 USB type C、BC、PD2.0、PD3.0,支持12V高压电源。CH543内置了USB主机控制器和收发器,支持全速和低速USB Host主机和USB Device设备。

CH543 内置的PD通讯时需要的BMC编解码、4B5B编解码、CRC校验也都有集成,这样的话用CH543实现一个PD通讯就比较简单了。CC端口不需要额外的下拉电阻,减少BOM成本。

- 板载一个拨动开关,可以设置成2lane DP+2lane USB3.2或4lane DP,如果笔记本的DP协议是DP 1.4,可以使用2lane跑4K60Hz,并不需要4对差分线来传递数据。
- MUX采用的VL171,支持DP1.4,上一个工程使用的是CH9445,同样也支持,后续可以更换。
- 以DP输出1080P144Hz为例,此时使用`2 lane`的DP:

### 注意事项:
- 使用2lane程序时,需要插上DP输出画面才可以使用`USB SSTX SSRX`,之后看情况重新整理代码~~(有一个小虫,最近无空抓了)~~
- 使用4lane程序时,讲拨码开关拨到`4L`处,此时USB功能失效,无法使用,`TypeC`全力以`4lane`输出`DP1.4`
## 6 项目进度
| 日期 | 记录 |
| :---------- | :-------------------------- |
| 2023/01//25 | 打板,生成V1,等待SMT及焊接 |
| 2023/02/04 | 焊接完成,编写程序 |
| 2023/02/09 | release V1程序,不包括USB3.2,等待USB座子到货焊接 |
| 2023/02/20 | release V2程序,包括USB3.2 |
## 7 图集






122
166
收藏到专辑