4. 角色定义与切换

USB Type-C接口的物理层支持正反插,但真正决定供电方向和数据传输主从关系的,是CC(Configuration Channel)逻辑与PD(Power Delivery)协议中的角色机制。在Type-C系统中,每个端口并非固定不变的角色,而是可以在Source(供电方/数据主机)、Sink(受电方/数据设备)以及DRP(双角色端口)之间动态切换。理解角色定义与切换机制,是进行嵌入式USB-C产品设计、固件开发以及排障的基础。本章将深入剖析角色定义、Try.SRC/Try.SNK的硬件级策略、角色切换的触发条件,以及PD协议中通过显式控制消息完成角色协商的完整过程。

Type-C 角色定义与切换机制总览 角色定义 Source 供电/DFP Sink 受电/UFP DRP (双角色端口) 初始角色由CC电阻决定 Try.SRC / Try.SNK 硬件/固件级偏好策略 切换触发条件 • 插入/拔出事件 (CC1/CC2电平变化) • 角色请求 (DR_Swap / PR_Swap) • 电源能力协商 (PD Contract) • 错误恢复 (Error Recovery) • 策略引擎决策 (Policy Engine) • VBUS 检测与放电完成 所有切换必须经过 PD 协商 PD 角色协商流程 1. 物理层连接 (CC 检测) 2. 发送 DR_Swap / PR_Swap 3. 接收 Accept / Reject 4. PS_RDY (电源就绪) 5. 新角色生效 (重新枚举) 角色切换状态机(简化) Source 供电/主机 DRP 检测 CC 电平采样 Sink 受电/设备 Try.SRC 偏好 Source 插入 CC 判定 PR_Swap 角色切换完成 → 重新进行 PD 协商 → 新角色生效 注:Try.SRC 仅在 DRP 端口上有效,用于解决“双 DRP 对接”时的角色竞争问题

上图展示了Type-C角色体系的整体框架。从左侧的角色定义出发,中间是触发切换的各类事件,右侧是PD协议中的协商流程,底部则是角色切换的简化状态机。在实际工程中,角色切换并非简单的电平翻转,而是涉及硬件电阻配置、CC逻辑状态机、PD协议策略引擎以及系统软件(如Linux USB gadget/host驱动)的协同工作。下面我们将分模块详细展开。

4.1 角色定义:Source、Sink与DRP的硬件基础

4.1.1 核心原理:CC电阻与角色绑定

Type-C端口的角色在物理层由CC1/CC2引脚上的下拉/上拉电阻决定。根据USB Type-C规范,一个端口作为Source时,其CC引脚必须连接上拉电阻Rp(典型值56kΩ至36kΩ,取决于支持的电流能力);作为Sink时,CC引脚连接下拉电阻Rd(5.1kΩ)。DRP端口则通过交替切换Rp和Rd来探测对端角色。这种电阻配置是硬件层面的“初始角色声明”,在PD协议启动之前,系统就已经通过CC引脚的电压比较确定了基本连接关系。

角色CC引脚配置典型电阻值默认数据角色典型应用
Source (DFP)上拉 Rp56kΩ (0.5A) / 22kΩ (1.5A) / 10kΩ (3A)Host (DFP)充电器、PC主机、HUB上行口
Sink (UFP)下拉 Rd5.1kΩDevice (UFP)手机、外设、HUB下行口
DRP交替 Rp/Rd切换周期约 50-100ms初始随机/策略决定笔记本、平板、双角色设备
Try.SRC先 Rp,后交替同DRP偏好 Host支持对外供电的笔记本
Try.SNK先 Rd,后交替同DRP偏好 Device主要作为外设的平板

4.1.2 判断方法:如何识别端口角色

在调试中,可以通过测量CC引脚对地电压快速判断角色:Source的CC电压约为0.25V至0.6V(取决于Rp和Rd的分压),Sink的CC电压约为0.2V至0.4V(当对端为Source时)。更准确的方法是使用逻辑分析仪抓取CC引脚的波形——DRP端口会呈现周期性的高低电平变化,而固定角色端口则保持稳定电平。对于支持PD的设备,还可以通过读取PDO(Power Data Object)消息来确认当前角色。

经验提醒:在PCB设计时,建议在CC1/CC2引脚预留测试点(TP),并串联0Ω电阻以便调试时断开。实际项目中,很多角色切换异常问题都源于CC电阻焊接错误或走线过长导致的分压偏差。

4.1.3 案例拆解:双DRP设备对接的角色竞争

考虑两台笔记本通过Type-C直连的场景。两台设备均为DRP,初始状态都在交替发送Rp和Rd。当检测到对端时,双方可能同时尝试成为Source,导致角色冲突。此时,Try.SRC机制发挥作用:如果一台设备配置了Try.SRC(例如联想笔记本默认启用),它会在检测到连接后先尝试以Source角色启动,发送Source Capabilities消息。如果对端是普通DRP,会响应Sink请求,从而完成角色分配。若两台设备都配置了Try.SRC,则通过PD协议中的“DRP角色优先级”和随机退避算法解决竞争。

4.1.4 常见误区:DRP不等于自动切换

很多开发者误以为DRP端口会自动协商出最优角色。实际上,DRP只是提供了角色切换的可能性,真正的角色确定需要PD协议层的策略引擎参与。例如,一个DRP充电宝连接DRP手机时,充电宝的策略引擎会优先尝试成为Source以对外供电,而手机的策略引擎可能优先尝试成为Sink以充电。如果双方策略冲突,则通过PD的DR_Swap消息进行协商。此外,Try.SRC/Try.SNK并非强制功能,而是可选策略,由产品定义决定。

4.2 Try.SRC与Try.SNK:硬件级角色偏好策略

4.2.1 核心原理:解决DRP竞争的策略

Try.SRC和Try.SNK是USB Type-C规范中定义的DRP端口可选行为。其核心思想是:在DRP的CC探测阶段,先以特定角色(Source或Sink)尝试连接,如果在一定时间(通常为120ms)内未成功,则切换为普通DRP交替模式。这种机制显著减少了双DRP对接时的角色协商时间,并让产品能够表达“我更喜欢当供电方”或“我更喜欢当受电方”的意图。

4.2.2 操作流程:Try.SRC的时序分析

// 伪代码:Try.SRC 状态机
State: Try.SRC
  1. 设置 CC 为上拉 Rp (Source 模式)
  2. 等待 tTrySrc (约 120ms)
  3. 检测 CC 电压:
     - 若检测到 Rd (对端为 Sink) → 进入 Source 模式
     - 若检测到 Rp (对端为 Source) → 进入 Sink 模式
     - 若无连接 → 切换为普通 DRP 交替模式
  4. 进入 PD 协商阶段

在硬件实现上,Try.SRC需要MCU或Type-C控制器在CC探测阶段精确控制上拉/下拉电阻的切换时序。例如,使用FUSB302或TUSB320等控制器时,可以通过I2C寄存器配置Port Role为Try.SRC,硬件会自动完成上述时序。

4.2.3 实战场景:笔记本与扩展坞的角色匹配

某款笔记本设计为Try.SRC,扩展坞设计为Try.SNK。当两者连接时:笔记本先以Source角色上拉Rp,扩展坞先以Sink角色下拉Rd,双方立即匹配成功,无需经过DRP交替周期。整个识别过程在50ms内完成,用户体验良好。如果扩展坞也配置为Try.SRC,则双方都会先尝试Source,导致约120ms的等待后,才进入DRP交替模式,最终通过PD协商决定角色。这个案例说明,产品定义时需明确角色偏好,以减少协商延迟。

4.2.4 总结复盘:Try.SRC的代价

Try.SRC虽然加快了角色确定,但存在一个潜在问题:如果设备A是Try.SRC,设备B是普通DRP,A会先以Source身份发送电源能力,B作为Sink接受。但如果B实际上需要对外供电(例如B是带电池的显示器),则后续需要通过PR_Swap(电源角色交换)来反转角色。这增加了协议交互的复杂度。因此,Try.SRC更适合明确知道对端是Sink的场景,如笔记本连接手机。

4.3 角色切换触发条件与PD协商流程

4.3.1 核心原理:从物理层到协议层的触发链

角色切换的触发条件分为三类:物理层事件(CC引脚电平变化、VBUS插拔)、协议层请求(DR_Swap、PR_Swap、VCONN_Swap)、策略层决策(电量管理、外设枚举需求)。所有触发最终都会汇聚到PD协议的状态机中,通过显式控制消息(Control Messages)完成协商。

4.3.2 判断方法:角色切换的完整流程

  1. 检测阶段:CC逻辑检测到对端连接,确定初始角色(Source/Sink/DRP)。
  2. 能力声明:Source发送Source_Capabilities(PDO列表),Sink发送Sink_Capabilities或请求。
  3. 协商阶段:双方通过Request/Accept/PS_RDY消息建立电源契约(Power Contract)。
  4. 角色交换:若需要切换,发起方发送DR_Swap或PR_Swap,接收方回复Accept或Reject。
  5. 切换执行:双方交换角色后,重新进行PD协商,并复位USB数据总线(重新枚举)。

4.3.3 案例拆解:PR_Swap(电源角色交换)实战

场景:一台支持PD的显示器(初始为Sink,从笔记本取电)连接一台手机(初始为Source,对外供电)。用户希望显示器反向给手机充电。此时,显示器策略引擎发起PR_Swap请求。具体过程如下:

步骤发起方消息接收方响应说明
1显示器PR_Swap手机回复 Accept手机同意交换电源角色
2显示器PS_RDY手机检测到电源就绪显示器准备开始供电
3手机PS_RDY显示器确认手机准备开始受电
4双方重新协商新PDO交换显示器作为新Source发送能力
5USB总线复位重新枚举数据角色也随电源角色切换

这个案例中,关键点是PS_RDY消息必须在VBUS电压稳定后发送。如果显示器在VBUS尚未达到5V时就发送PS_RDY,手机可能因欠压而进入保护状态。实际调试中,我们曾遇到因PS_RDY发送过早导致手机充电反复重启的问题,最终通过增加VBUS放电完成检测和延时解决。

4.3.4 常见误区:数据角色与电源角色的耦合

在PD协议中,电源角色(Source/Sink)和数据角色(DFP/UFP)是独立协商的,但通常默认耦合。例如,PR_Swap会同时交换电源角色和数据角色(除非使用DR_Swap单独交换数据角色)。很多初学者混淆这一点,导致在实现DR_Swap时错误地改变了电源方向。正确做法是:DR_Swap仅交换数据角色(Host/Device),电源角色保持不变;PR_Swap则同时交换两者。在USB4和Thunderbolt模式下,角色交换还涉及Alternate Mode的重新协商,复杂度更高。

风险提示:在角色切换过程中,VBUS必须经历“放电-重新上电”的过程。如果系统没有正确实现VBUS放电(Discharge)路径,可能导致端口损坏或对端设备误检测。设计时务必在VBUS上预留放电电阻(如1kΩ至2kΩ)和MOS管控制。

4.4 PD协议中的角色协商机制

4.4.1 核心原理:显式控制消息与策略引擎

PD协议使用基于BMC(双相标记编码)的物理层,通过CC引脚传输数据包。角色协商主要依赖以下控制消息:DR_Swap(数据角色交换)、PR_Swap(电源角色交换)、VCONN_Swap(VCONN电源交换)、Get_Source_Capabilities等。这些消息由策略引擎(Policy Engine)生成,经过协议层封装,最终由物理层发送。策略引擎是决定“何时发起交换”的智能模块,通常由固件实现。

4.4.2 操作流程:DR_Swap的报文交互

// DR_Swap 报文序列 (以Sink发起为例)
Sink → Source: DR_Swap (数据角色交换请求)
Source → Sink: Accept (接受)
Source → Sink: PS_RDY (电源就绪,表示切换准备完成)
Sink → Source: PS_RDY (确认)
// 之后双方交换数据角色,USB总线复位,重新枚举

值得注意的是,DR_Swap的发起方可以是任意角色。例如,一个UFP(设备)可以主动请求成为DFP(主机),这在USB OTG场景中很常见。协议规定,收到DR_Swap的一方必须在tReceiverResponse(约15ms)内回复Accept或Reject。如果超时,发起方会重试或放弃。

4.4.3 案例拆解:手机与PC的DR_Swap实现

某Android手机通过Type-C连接PC,初始状态为UFP(设备)。用户开启“USB共享网络”功能,需要手机成为DFP(主机)以枚举PC的网卡。此时,手机固件发起DR_Swap请求。PC的Type-C控制器(如Intel Titan Ridge)收到请求后,其策略引擎判断当前无其他USB设备占用,回复Accept。随后,PC的USB角色从Host切换为Device,手机从Device切换为Host。整个过程耗时约200ms,期间USB总线断开重连。这个案例中,PC端必须支持角色切换,否则会回复Reject,手机只能保持UFP角色。

4.4.4 总结复盘:角色协商的失败模式

  • 超时无响应:对端未在15ms内回复Accept/Reject,发起方应重试3次后放弃。
  • PS_RDY丢失:切换过程中PS_RDY消息因干扰丢失,导致状态机卡死。需实现超时重传机制。
  • 策略冲突:双方同时发起DR_Swap,协议规定由端口角色优先级决定(Source优先)。
  • 硬件不支持:部分Type-C控制器(如仅支持Source的充电芯片)无法响应PR_Swap,需在固件中屏蔽该功能。
工程建议:在固件开发中,建议将角色切换状态机设计为独立模块,并通过事件回调通知上层应用。例如,在Linux内核中,typec_class驱动会发送typec_switch_role事件,供USB gadget/dual-role驱动处理。务必在切换前保存当前USB配置,切换后恢复,避免枚举失败。

综上所述,Type-C的角色定义与切换机制是一个从硬件电阻配置到协议层协商的多层次系统。Source/Sink/DRP定义了端口的物理能力,Try.SRC/Try.SNK提供了角色偏好策略,而PD协议则通过显式控制消息实现了动态协商。在实际产品开发中,需要根据应用场景合理选择角色策略,并充分测试各种切换路径,尤其是异常场景(如切换中拔出、对端无响应等)。掌握这些机制,是构建稳定、高效的USB-C系统的基础。