第二章:物理层基础——CC引脚功能解析、BMC编码原理、Chunking机制
好,咱们进入第二章。说实话,物理层是很多人学USB PD时最容易跳过的地方。大家总觉得「不就是两根线嘛,有啥好学的?」——嗯,我以前也这么想,直到第一次调不通通信,拿着示波器抓了半天波形,才发现问题出在CC引脚的电平配置上。从那以后,我再也不敢小看物理层了。
这一章,咱们就掰开揉碎了讲三个核心内容:CC引脚到底在干嘛、BMC编码是怎么回事、以及Chunking机制为什么存在。你把这些搞懂了,后面看协议状态机就会轻松很多。
2.1 CC引脚:不只是检测连接
CC引脚,全称是Configuration Channel。很多人以为它只是用来检测有没有插线,其实它的活儿多着呢。
CC引脚的核心职责有三个:
- 检测连接:判断Source和Sink是否已经物理接触
- 识别角色:谁是供电方(Source),谁是受电方(Sink)
- 承载通信:所有PD协议报文都通过CC引脚传输
我刚开始做项目时,有个坑特别容易踩——CC引脚上的电阻配置。Type-C规范里规定了两种电阻:Rp和Rd。Source端要上拉Rp,Sink端要下拉Rd。这个配置一旦搞反,设备根本没法握手。
关键参数速查表:
| 角色 | 电阻类型 | 典型阻值 | 说明 |
|---|---|---|---|
| Source | Rp(上拉) | 10kΩ / 22kΩ / 56kΩ | 不同阻值对应不同电流能力 |
| Sink | Rd(下拉) | 5.1kΩ | 固定值,不能随便改 |
| 电子标记芯片 | Ra(下拉) | ≈1kΩ | 用于识别线缆是否支持PD |
你想想看,如果Source端把Rp焊成了5.1kΩ,会发生什么?——它会以为自己连了个Sink,但实际上CC线上的电压根本不对,通信直接废掉。我曾经帮一个客户排查过这种问题,折腾了两天才发现是BOM表里电阻值写错了。
2.2 BMC编码:为什么PD不用普通的UART?
好,接下来聊BMC编码。BMC的全称是Biphase Mark Coding,双相标记编码。说白了,它是一种自同步的编码方式。
你可能会问:「为什么PD不直接用UART那种NRZ编码?简单又成熟。」——嗯,原因其实很实际:PD通信是在CC线上进行的,而CC线同时还要承担检测连接的任务。如果用普通的NRZ编码,长时间传输连续的0或1时,电平不变,接收端就分不清是数据还是连接状态了。
BMC编码的规则其实很简单:
- 每个bit的起始处,电平一定会翻转一次
- 如果传输的是逻辑1,在bit中间再翻转一次
- 如果传输的是逻辑0,bit中间不翻转
我画个简单的示意图你感受一下:
时钟: _ _ _ _ _ _ _ _
| | | | | | | | | | | | | | | |
数据: 1 0 1 1 0 0 1 0
BMC: __ __ ____ __ ____ __
| || | | || | | || |
‾‾ ‾‾ ‾‾ ‾‾ ‾‾ ‾‾ ‾‾
你看,每个bit的起始处都有翻转,这样接收端就能从信号里提取出时钟,不需要额外的时钟线。这就是自同步的好处。
我的经验:调试BMC信号时,示波器的采样率至少要设到100MS/s以上。BMC的比特率是300kbps,但它的跳变频率会到600kHz。采样率不够的话,你看到的波形全是锯齿,根本没法判断。
2.3 Chunking机制:为什么要把数据切块?
Chunking,翻译过来就是「分块」。PD协议里,一次完整的消息可能很长,比如要传输一个DisplayPort的配置数据。如果一口气发完,接收端的缓冲区可能装不下,或者处理不过来。
Chunking的核心思想:把长消息切成多个小块,每个小块单独发送,接收端收到后确认,再发下一块。
具体来说,PD协议里定义了一个最大数据包大小——默认是260字节。如果消息超过这个长度,就必须分块。每个块的大小不能超过MaxExtendedMsgLen,这个值在Discover Identity等命令里会协商。
Chunking的流程大致如下:
- 发送端计算消息总长度,判断是否需要分块
- 如果需要,把消息切成N个块,每个块加上块序号
- 发送第一个块,等待接收端的GoodCRC确认
- 接收端回复GoodCRC后,发送下一个块
- 所有块发完后,发送一个End消息表示传输完成
我记得有一次调试一个扩展消息的传输,发现接收端老是丢块。查了半天,发现是发送端在发完一个块后,没有等GoodCRC就直接发下一个块了。协议里明确要求:必须等确认才能继续。这个时序问题,用逻辑分析仪一看就清楚了。
注意:Chunking机制只适用于扩展消息(Extended Message)。普通的消息(比如Request、PS_RDY)长度都在26字节以内,不需要分块。别搞混了。
2.4 物理层的时序要求
最后,咱们简单提一下物理层的时序参数。这些数字你不需要死记硬背,但调试时得知道去哪里查。
| 参数 | 符号 | 最小值 | 最大值 | 说明 |
|---|---|---|---|---|
| 比特率 | BR | 270 kbps | 330 kbps | 标称300kbps |
| 上升时间 | tR | — | 300 ns | 10%~90% |
| 下降时间 | tF | — | 300 ns | 90%~10% |
| 位时间 | tBIT | 3.03 μs | 3.70 μs | 1/BR |
这些参数在USB PD规范的第6章里都有详细说明。我个人习惯是把这些关键时序参数打印出来贴在调试台旁边,省得每次都要翻PDF。
好了,物理层的基础就讲到这里。下一章咱们会进入真正的协议层,开始讲状态机是怎么跑的。你先把CC引脚、BMC编码和Chunking这三个概念消化掉,后面会轻松很多。
课后小练习:拿一个Type-C转接板,用万用表量一下CC引脚对地的电阻。如果是Source设备,你应该量到Rp的值;如果是Sink设备,应该是5.1kΩ。试试看,你会发现物理层其实就在你手边。