1. PD协议概述与协商流程简介
USB PD(Power Delivery)这玩意儿,说白了就是让USB口能跑大功率、能调电压、还能换方向传输的协议。早些年我们用USB 2.0充电,5V/0.5A,充个手机都要半天。后来快充百花齐放,各家搞各家的协议,乱得很。PD的出现,就是想一统江湖。
我个人刚开始接触PD时,觉得它就是个「充电协议」。后来踩了坑才发现——它更像一套源端和受电端之间的动态协商机制。你想想看,一个Type-C口插上去,怎么知道对面要5V还是20V?要1A还是5A?谁做主?谁让步?这些全是靠PD协议里一串一串的报文来回“谈判”搞定的。
1.1 为什么需要PD协商?
传统USB充电是固定的:Source只管输出5V,Sink能吸多少就吸多少。但到了高功率场景(笔记本65W、显示器100W),这种「一刀切」就不行了。如果直接输出20V给只支持5V的设备,轻则烧保护,重则冒烟。
所以PD引入了协商的概念。每次连接,Source和Sink先交换能力描述符,再选一个双方都支持的电压/电流组合。我在项目里见过不少「不协商直接拉高电压」的设计,结果……嗯,板子上的DCDC直接炸了。
1.2 PD协议的层叠结构
PD协议不是铁板一块,它分了好几层。我习惯用这张表来跟团队新人解释:
| 层 | 功能 | 关键内容 |
|---|---|---|
| 物理层 | 差分信号传输,载波检测,比特流收发 | BMC编码,4b5b转换 |
| 协议层 | 报文封装、重传、超时、CRC校验 | GoodCRC,MessageID,Retry |
| 策略层 | 电源角色、VDM、协商状态机 | PR_Swap,DR_Swap,VDM_REQ |
| 应用层 | 供应商自定义命令、调试命令 | DP Alt Mode,PCIe Tunneling |
不过呢,咱们这门课重点盯的是策略层和应用层——尤其是描述符的定位。因为绝大多数PD协商失败,问题都出在描述符内容写错了,或者角色策略打架了。
1.3 一次完整的协商流程
我把它拆成5步。你记着这5步,后面所有调试都围着它们转:
- 连接检测:CC引脚上拉/下拉电阻出现,Source检测到Sink接入。
- 能力宣告:Source发送
Source_Capabilities(SRC_CAP)报文,告诉Sink自己支持哪些PDO。 - 请求选择:Sink从收到的PDO里挑一个最合适的,发送
Request报文(含RDO)。 - 接受切换:Source接受请求,回复
Accept,随后切换电压/电流,最后发PS_RDY表示准备好了。 - 正常供电:双方进入稳定供电模式,期间可发起VDM或角色互换。
1.4 几个关键概念你得先知道
- PDO(Power Data Object):电压/电流对。Source的每个PDO描述一个供电能力,比如5V/3A、9V/3A、15V/3A、20V/5A。
- RDO(Request Data Object):Sink给Source的请求,里面指明要哪个PDO,以及最大电流、操作电流、标志位(Unchunked/Chunked、USB通信能力等)。
- 角色(Role):Source是供电方,Sink是受电方。但PD支持角色互换——Source可以变成Sink,Sink也可以变成Source(PR_Swap)。这个互换也是通过描述符协商的。
- VDM(Vendor Defined Message):供应商自定义报文。用来做Alt Mode、固件升级等。VDM也依赖描述符里的VID/PID匹配。
1.5 描述符在PD协商中的核心地位
你可能会问:既然PD有完整的状态机和报文,为什么还要单独提「描述符定位」?
因为PD协议虽然标准,但芯片实现、线缆、设备端往往各有“私货”。举个例子,我手头一个案子,Source的SRC_CAP里PDO顺序是:5V→9V→15V→20V。Sink按标准顺序挑15V,结果发现15V那组PDO的电压容差写成了±10%(标准是±5%)。Source却按自己的容差输出15V,Sink这边的过压保护直接触发。这就是描述符数据本身有问题,跟协商流程无关——你拿逻辑分析仪看报文,每一帧都是正确的,但数值不对。
所以这门课的核心就是:当PD协商出了问题,如何通过分析描述符里的数据,快速定位到问题根源。我会带你从最简单的SRC_CAP解析开始,一路深入到RDO、VDM、Chunking、以及叠了多路Alt Mode的复杂场景。
好了,这章先给你搭个架子。后面我们就要一头扎进描述符的具体字段里了。嗯,准备好你的十六进制编辑器吧。