USB发展已经非常多的年头了,最近做东西要做到关于PD Source的产品,这里就大致看看PD是什么,怎么工作,这里所理解的,基本都是目前标准上的部分内容罢了,想了解更详细,还是得自己看标准.
USB PD依赖USB C口,具体来说是依赖CC线,而其他接口是提供不了CC线的.
全功能的Type-C可以支持USB2.0/USB3.0/USB3.1/DP等等,DP是通过SBU通信的,上面的图已经很清楚,而实现PD事实上也可以是PD Only的插头定义,只是比较少见,可能成本差距不大,做的人就少吧.另外全功能也比较少见,因为必须加E-Mark芯片来识别线材,并且Source通过下拉电阻识别后,通过其中一个CC引脚提供VCONN进行后续的配置.既然这里讨论PD,就暂时不考虑其传输能力,只考虑供电能力,即Power Role,那么就只分为Sink和Source,哪怕他是个Sink Host(吃电但是他还是个USB Host).
正常的线缆中,CC引脚并不是短一起的,其中一个CC用于通信,另一个CC悬空或提供VCONN,其中Source会上拉Rp到5V,Sink会下拉Rd到地,这里看到Source除了提供上拉到5V,还可以切换到提供VCONN,也是前面说到过的,简单地说,Source可以检测Rd是否存在确定Sink是否存在,Sink可以检测Rp确定供电能力,但是这毕竟还是不够,所以就引入PD协议.
Sink也可以检测VBus是不是有VSafe 5V判断Source是否存在,同时检测CC引脚中谁被上拉决定当前通信链路,比如可能数据线只在其中一侧也是有可能的,需要通过一些MUX手段切换.当然,这已然是基于电阻各种采集来判断,也可以引入PD协议来进一步配置.
具体靠电阻判断,用多大电阻这里就不细说了.
引入PD协议,解决上面如果设备是DRP(Dual Role Power),既可以做Source也可以做Sink,结果大家互相切换Rp/Rd,或者各种沟通不良,而PD其实相当简单,毕竟也没什么数据流.撇开VDM/DAM/音频模式,CC引脚就是PD通信用的了.
PD链接后就会等待SRC_CAP发送他的支持的电源Profile,如果没发送,就会每隔一秒发送一次复位,五次都还没发送,可以认定他不是PD Source.
如果收到SRC_CAP,要进入PD_Save_Adapter_SrcCap保存收到的Capacity.等下再分析这个函数,滞后申请Index 2的Profile,如果发送成功,就进入STA_RX_ACCEPT_WAIT.这个ACCPET应该在500ms内能完成.
ACCEPT_WAIT和PS_RDY_WAIT放一起判断了,要是500ms没等来,就软复位这条线,软复位成功,则模式没变,失败则硬复位,硬复位后就等于回到一开始,这些一般都是遇不上的.
复位逻辑.
如果下面收到信息,收到ACCPET报文,就会等RDY报文,如果收到RDY不问,那么全部OK了.
除此之外,在PD这里可以响应其他报文,但是这里暂时不研究,比如VDM,不要又像走入USB协议研究那样了.
谁来推动第一个STA_SRC_CONNECT呢,那就是主程序每5毫秒进一次的Det.
他检测插入,并决定谁是通信线.那说完了Sink,Source的过程就基本是对应过来了.角色就变成了自己是发送SRC_CAP,并实际提供供电,当然Det也有所改变,如果CC1/CC2对方有拉高,那么对方也是Source,这样肯定不能继续提供服务,除非自己是DRP.
被SINK链接,赶紧发送SRC_CAP.
当然这里可能还会被请求DEF_TYPE_GET_SRC_CAP_EX,具体看请求中是不是要扩展的PD 3.0数据,是的话,发送扩展的供电能力信息,这个内容包含在PD_Rx_Buf[ 0 ] & 0x1F中.
不管有没有请求扩展,接着收到Request处理.
这里大致基本分析完成,现在再深入一步看.PD数据包他应该长什么样,数据包看起来是Header + Data.
所以这个函数把前两个字节部分内容填写了,其中Message Type分为Data和Control两种,Control类型的消息后面没有Data.比如SOFT RESET就是Control消息.
所有Control信息.
而内容就很多了,比如请求供电的PDO.
在代码上如此表现,另外电流可以不申请满,比如SRC_CAP提供2000mA,你申请500mA,按理说有部分Source会过流切断保护你.
其他数据包也是这么分析,可以看官方手册.
https://www.usb.org/document-library/usb-power-delivery
另外实测发送5V 5A的SRC_CAP,树莓派5也是不会承认的,可能他用的是某种私有协议吧.