从硬件到驱动简单讲解手机充电 1----USB 和 BC12

1、基础概念、名词

Usb

我们目前的手机主要是通过USB接口充电,这个USB,发布自USB Implementers Forum这个组织,以及历经了USB1.1、2.0、3.0、3.1、3.2、4等等版本,这些协议主要是和速率方面有关,但是市面上的形态主要分为以下几个:TYPE AB、min AB、micro ab,以及我们现在充电的主要接口,USB TYPE C。具体划分我们不细讨论,可以参考:秒懂所有USB接口类型,USB接口大全;Type-A、Type-B、Type-C、miniUSB、microUSB区分 - 知乎 (zhihu.com)

USB TYPEC

跳过无用的概念,我们直接看这个接口

image.png

image.png

通过接口图,我们可以发现,TYPEC的引脚,都是成对出现的,并且物理位置是相对的,这就实现了我们的使用中,使用TYPEC的情况下正反插都不会影响工作的原因。

咱们今天将一对比较重要的引脚:

DP、DM,这是USB信号的差分,接下来会就其充电相关的知识做介绍。(其他方面俺不会!)

BC12以及switch charger

我们先讲一般非PD的充电,就是最常见的线材,一头A口一头C口的那种。

在充电器和手机插入之后,会有专门的芯片去处理信号,并判定这个USB的工作状态,这种芯片分为俩个派类,第一种是集成在手机SOC中的PMIC(电源管理芯片),一般大部分的旗舰平台都是采取这个方案,第二种就是单独外挂的charger,比较典型的的厂商是TI(德州仪器)、SGM(圣邦微)、SC(南芯)等。这种芯片内部会根据USB插入时的芯片BC12的结果,判定插入的类型,并根据驱动设置相关的充电参数。

那什么是BC12,他的全称是battery charging ,就是一个USB官方发布的充电规范,他将USB的类型分为以下三种:

USB2.0协议规定外设从USB充电器抽取电流的最大值为500mA,500mA的电流限制无法满足日益增长的快充需求。因此,BC1.2引入了充电端口识别机制,主要包括以下几个USB端口类型:

1.标准下行端口(SDP)

SDP端口支持USB协议,一般用于传输数据,最大电流500mA

2.专用充电端口(DCP)

DCP不支持数据协议,支持快充,可以提供大电流,我们日常的充电器就是这种。

3.充电下行端口(CDP)

CDP既可以支持数据传输,也可以支持快充。

那他具体是怎么区分的?

找了一张图image.png

我们可简单的理解一下(因为这个部分基本上是芯片自发的行为,抓波形一般只用于debug)

1、VBUS有效检测

2、数据链接检测

3、首测检测,判断是数据口还是充电口,这个过程会拉DM(D+)到0.6V,然后看DP电压,如过小于参考电压则认为他是SDP,否则就是CDP和DCP之一。

4、二次检测

同样的,这里将DP(D-)拉高至0.6V,然后检测DM的电压,如果小于规定的参考电压则端口是CDP,如果大于规定的参考电压说明端口是DCP。

还是找了一张网图:

image.png

接下来回到芯片,我们的芯片以及驱动是如何处理的呢?

刚才提到过,芯片会自己读取BC12的结果并保存在寄存器中,当充电器插入的时候,会产生中断,我们可以在软件中注册中断,并在中断中读取状态寄存器,根据USB插入的类型设置最基本的充电参数(例如SDP只要500MA)。以我们最常见的TI BQ25601为例

image.png

image.png

例如我们最常用的充电器,就会上传为CDP的类型,然后上层驱动就会根据这个属性来设置电流,这里还包含了power_supply架构是如何运作的。

有兴趣的小伙伴可以参考内核代码(目前比较多的是4.19 5.10)的PSY去学习一下,这里我就鸽了,下次有机会再具体讲。放一下目录:

supply - drivers/power/supply - Linux source code (v4.19.303) - Bootlin

这篇主要是对手机充电的一个基本讲解,其实就是摸鱼的时候写了一点,目前我也只是做了一年这行,大火看个乐子,图片来自互联网,如果侵权请联系删除。

接下来我放点小工具

开源内核:https://elixir.bootlin.com/

如何让代码在word里面好看:CodeInWord|在word中优雅展现的代码|代码高亮|word中插入代码|代码格式化(鱼排好像这个用不了)

摸了!