
分类
技术干货
【源码简析】基于CH32X035的USBPD报文嗅探器
717
1
2
0
简介
简介:更新时间:2025-08-08 09:30:36
> 硬件部分:https://oshwhub.com/zhoulv2012/mps-simple-digital-display-power
一、USB PD协议与CC线基础简介
1. USB PD通信概述
- USB Power Delivery (USB PD) 定义在Type-C接口的CC(Configuration Channel)线上,使用BMC编码实现全双工数字通信(电压最大可达20V,电流最高5A及以上)。
- 通信基于消息包,每个消息包由消息头(Message Header)、数据对象(Data Object, 4字节一组)、以及CRC校验组成。
- 消息类型包括控制消息(Control Message,如GoodCRC)、数据消息(Data Message,如Source Capabilities)、扩展消息(Extended Message)等。
- USB PD使用SOP(Start Of Packet)码区分通信的通道类型(SOP0主端口通信、SOP1电缆通信、SOP2电缆子通信等)。
2. CC线功能和电气连接
- USB Type-C接口共有两个CC线(CC1与CC2),PD通信在被插入的CC线(对应正插或反插)进行,另外一条CC线空闲。
- CC线通过电压电平检测区分角色:
- **Rp(Pull-up)**端接于Source侧,代表源设备,输出1.0V左右电压。
- **Rd(Pull-down)**端接于Sink侧,代表受电设备,通过下拉电阻拉低电压。
- 通过不同电平组合,双方判定连接状态、方向、角色以及电流能力。
- CC线还支持辅助模式检测,如Audio Accessory、Debug Accessory。
- 电压门限(如0.2V、0.66V、1.23V等)代表不同的检测梯度,硬件通过比较器检测。
二、USB PD通信监测方案架构(基于usbpd_sniffer.c + usbpd_cc.c)
1. 系统初始化(参考 usbpd_sniffer_init())

- GPIO初始化:设置CC线对应的GPIO输入模式。
- USB PD硬件模块初始化:配置寄存器使能DMA、IRQ等硬件功能,准备接收PD数据包。
- 定时器启动:定时周期调用检测CC线状态,实现动态监听CC1或CC2。
- 初次CC线检测:根据电压层级判断当前有效CC线。
2. CC线连接状态检测(结合usbpd_cc.c)

- 主动通过
usbpd_sink_check_cc_connect()检测CC1和CC2信号电平,检查是否存在连接及哪个线有效。 - 每500次定时器中断调度调用
usbpd_sniffer_periodic_switch()进行切换监听CC线。

- 根据
detect_cc_voltage_level()测量CC线电压,判断当前角色:- Open(无连接)
- Sink (Rd电阻)
- Source (Rp电阻)
- Audio/Debug模式或无效状态。
> 小结:CC线电压状态决定USB PD链路物理层是否有效,也是监听通道切换关键。
3. USB PD数据抓包
- 中断触发:USBPD硬件模块接收完PD报文,触发
USBPD_IRQHandler()中断。 - 数据复制:中断中拷贝硬件接收到的USB PD数据包到软件环形缓冲
pd_packet_queue。


- 队列管理:通过维护
pd_queue_head,pd_queue_tail控制环形队列进出。
4. 报文解析(结合usbpd_parse_packet()和usbpd_sink_protocol_analysis())

- 消息头解码:
- 提取消息类型(控制 / 数据 / 扩展)
- 获取数据对象数量
- 协议版本、角色、消息ID等。
- 数据对象解析:
- 解析Source Capabilities,Battery Capabilities,Request Data Object等。
- 对PDO(Power Data Object)的类型细致解析(固定、变量、APDO等)。
- 输出电压、电流等关键参数。
- 控制消息处理:
- GoodCRC、Accept、PS_RDY、Soft Reset等状态机管理。
- 扩展消息处理:
- EPR(Extended Power Range)相关消息解析。
- 打印输出:
- 通过串口打印解析结果,辅助调试和分析。
5. 协议状态维护
- 根据报文内容更新协议状态机,如是否进入EPR模式,是否已确认电源准备好。
- 维持消息ID,处理应答和重传。
三、结合代码流程总结图
+---------------------------+
| 硬件初始化 | <-- usbpd_sniffer_init()
+---------------------------+
|
v
+---------------------------+
| 定时器周期检测CC线 | <-- timer3中断 + usbpd_sniffer_periodic_switch()
| 决定监听CC1或CC2 |
+---------------------------+
|
v
+---------------------------+
| USBPD中断: 接收新数据包 | <-- USBPD_IRQHandler()
| 放入软件队列缓冲区 |
+---------------------------+
|
v
+---------------------------+
| 主任务处理队列数据 | <-- usbpd_sniffer_process_queue()
+---------------------------+
|
v
+---------------------------+
| 解析消息内容 | <-- usbpd_parse_packet(), usbpd_sink_protocol_analysis()
+---------------------------+
|
v
+---------------------------+
| 更新协议状态机 |
| 打印解析结果 |
+---------------------------+
四、USB PD CC线电气连接细节深入剖析
1. CC线的基本结构和作用
USB Type-C插头内有两根CC线(CC1、CC2),只会有一根实际参与通信(取决于插头插入方向),另一根处于悬空或闲置状态。
- 这两根线由上下游设备两端分别接入上拉电阻 (Rp) 或 下拉电阻 (Rd),以实现设备角色识别和电流能力协商。
- CC线上还承载数据通信信号:USB PD协议(BMC调制编码)通过CC线传输数据信息。
2. 电气连接状态定义
| CC线电压状态 | 说明 | 设备角色判定 |
|---|---|---|
| Open (<0.2V) | CC线上无连接,悬空或未匹配 | 无连接 |
| Rd 电平 (约0.2~0.4V) | 代表负载端(Sink)连接,带下拉电阻 | 表明该CC线连接到 Sink (受电设备) |
| Audio/Debug (约0.4~0.8V) | 附加状态,兼容音频或调试附件模式 | 附加功能线模式 |
| Rp 电平 (约0.8~1.6V) | 表示源端(Source)连接,带上拉电阻 | 表明该CC线连接到 Source (上游设备) |
| Invalid (>1.8V) | 电压异常或硬件故障 | 不应出现,可能需排查 |
> 注意:以上电压数值为参考范围,具体数值依芯片及方案设计略有不同。
3. 采样和比较实现(代码核心)
在代码usbpd_cc.c的detect_cc_voltage_level()实现中,电压检测通过硬件比较器测量:
- 设置比较门限(CC_CMP_22, CC_CMP_66, CC_CMP_123),分别对应约 0.2V、0.66V、1.23V(具体参照 MCU 数据手册或电路设计),依次判断是否超过门限。
- 分别读取各门限对应的
PA_CC_AI输入位,判断电压是否高于对应阈值。 - 依据三档门槛位组合判定CC电平类型。
具体代码示意:
// 示例判断阈值后的电平判定逻辑
if (!above_20)
result = CC_VOLTAGE_OPEN;
else if (above_20 && !above_66)
result = CC_VOLTAGE_RD;
else if (above_66 && !above_123)
result = CC_VOLTAGE_RP;
else if (above_20 && above_66 && above_123)
result = CC_VOLTAGE_INVALID;
else
result = CC_VOLTAGE_AUDIO;
4. 角色和电流能力判定
- Sink端接入
Rd电阻(通常5.1kΩ、Rp定义的下拉),下拉电压水平被源端检测确认,指示Sink设备已连接。 - Source端通过上拉电阻
Rp(可选档位标识电流等级如Default USB、1.5A、3.0A)输出相应电压。 - 通过CC线的电压水平,Source能检测Sink端Rd阻值大小,从而获取Sink最大承载电流能力。
这种电压与电阻匹配机制实现了USB Type-C的“角色识别”和“电流能力告知”,进一步配合USB PD协议协商电源参数。
5. CC线多路监听机制
- Type-C接口有两个CC线,物理方向确定后只有一根有效。
- 代码中通过读取两根CC线电压(
usbpd_sink_check_cc_connect())确定当前哪路CC线为有效连接。 - 定时器每500次调用切换检测到的CC线,实现双线监听和动态切换,保证无论插头正插还是反插都能抓包。

示例:
if (ccLine == USBPD_CC1) {
// 使能CC1监听,关闭CC2监听
} else if (ccLine == USBPD_CC2) {
// 使能CC2监听,关闭CC1监听
}
6. CC线电压检测与USB PD消息收发关系
- USB PD数据以BMC编码形式通过CC线发送,需要线路处于有效连接状态(Rp及Rd存在)保证信号质量。
- CC检测确认连接和角色后,USB PD硬件模块才会启动BMC调制解调进行消息收发。
- 抓包代码基于CC线检测驱动USBPD接收模块工作,实现有效协议消息捕获。
五、补充说明:USB PD电气规范标准参考
- USB PD规范和Type-C规范对CC信号定义非常严格,如USB Type-C Spec和USB PD Spec中详细描述。
- CC线定义了默认电流电平(USB Default: 500mA,1.5A,3A等),并结合协商能力动态调整。
- 电气层匹配保证数字信号的完整性和协议可靠运行。
总结
usbpd_cc.c实现了基于GPIO和硬件比较器的CC线电压状态精确检测,结合电压阈值判定连接类型。- 根据不同阈值组合区分Open、Sink(Rd)、Source(Rp),实现连接检测和上下游设备角色识别。
usbpd_sniffer.c利用CC线检测结果动态切换抓包监听线路,并结合USB PD硬件外设和DMA中断实现协议数据包捕获与解析。- 整体系统实现了物理连接监测->协议层抓包->协议状态机维护的完整USB PD通信监测体系。
添加到专辑
0
0
分享
侵权投诉






评论