PD快充 - fusb302驱动调试笔记

文章详细介绍了FUSB302作为USBType-C控制器的功能,如何通过PD协议控制电源适配器的输出,并讨论了其在Linux系统中的驱动移植过程,包括设备树配置、Makefile编写以及遇到的问题和解决方案。此外,还提到了与bq25720充电管理IC的配合使用,以实现充电过程的管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、fusb302介绍

Fusb302是可编程的USB Type-C控制器,支持识别各种USB 设备和对应的状态;且支持最高100W的PD协议。

Fusb302用CC1/CC2引脚与typeC电源适配器通信,通过PD协议来设置电源适配器的输出电压和电流,从而达到控制充电电压电流,实现快充的目的。

说白了,就是通过 PD协议 控制电源适配器,从VBUS输出不同功率的电源(最高100W)。

 二、fusb302引脚功能

引脚

功能

CC1/CC2

主要用来 PD协议通信 或 其他:

1)探测USB连接,区分正反面,区分DFP和UFP的主从关系

2)配置Vbus,有USB Type-C和USB Power Delivery两种模式

3)配置Vconn,当线缆里有芯片的时候,一个cc传输信号,一个cc变成供电Vconn,用来给线缆里的芯片供电(3.3V或5V);

4)如果CC通道连接其他配置,如连接音频配件、DP、PCIE时,CC通道配置是不同的。

VBUS

VBUS为电源适配器提供的用来给电池充电的总线电源,USB PD协议可配置电压和电流,最大100W,如:20V 5A

VCONN

当线缆里有芯片的时候,一个cc传输信号,一个cc变成供电Vconn,用来给线缆里的芯片供电(3.3V或5V)

INIT_N

中断输出,当有事件发生时,用于通知处理器读取I2C寄存器数据。如:插入/拔出typeC,INIT_N都会拉低一下。

SCL、SDA

I2C时钟、数据引脚

介绍:

1、主从

SRC:Source,供电端如:充电器。

SNK:Sink,受电端如:手电筒。

2、DFP、UFP、DRP用途解析

① DFP:Source,下行端口,可以理解为一个Host,DFP作为source给VBUS和vcon供电的,简单理解为一个提供电源的设备,如:电源适配器。

② UFP:Sink,上行端口,可以理解为Device,UFP可以理解为受电端口,DFP为供电端口,UFP从VBUS中取电,并可提供数据。典型设备如:U盘、移动硬盘。

③ DRP:双角色端口,DRP既可以做DFP(Source)又可以做UFP(Sink),也可以在DFP和UFP间动态切换,典型设备是:笔记本电脑、充电宝。

充电宝为UFP(Sink)的应用:电源适配器给充电宝充电。

充电宝为DFP(Source)的应用:充电宝给手机或其他设备充电。

三、fusb302驱动移植及修改方法

与供应商沟通,原厂前期只提供了mcu的代码没提供linux的。因此移植瑞芯微的板子里的fusb302驱动到酷芯平台。

1、将fusb302驱动编译成.ko,并加载

1)设备树dts添加子节点,fusb302挂载 i2c3上

&i2c3 {
         status = "okay";
         fusb0:fusb30x@22 {
                 compatible = "fairchild,fusb302";
                 reg = <0x22>;                                    //设备地址
                 int-n-gpios = <&porta0 4 GPIO_ACTIVE_HIGH>;     //GPIO_A0_4
                 status = "okay";
         };
};

引脚配置如下:

i2c 和 gpio 引脚

 2)Makefile

KERN_DIR = /home/dongao/share/kernel/linux-linaro-stable-lsk-v4.9-17.07  #内核路径

all:
    make -C $(KERN_DIR) ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- M=`pwd` modules 

clean:
    make -C $(KERN_DIR) ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- M=`pwd` modules clean
    rm -rf modules.order

obj-m    += fusb302.o

3)加载并测试

删除没有定义的 extcon相关函数。

$ make                                //ubuntu下编译生成 fusb302.ko

$ insmod fusb302.ko        //ARM板加载驱动

发现问题:

问题1:probe() 中的 devm_extcon_dev_allocate() 函数会失败。

 解决方法:内核配置 extcon。

问题2:酷芯提供的内核的 drivers\extcon\extcon.c 中的 extcon_info[] 没有定义 EXTCON_USB_VBUS_EN

解决方法:按照rk内核的extcon.c文件,extcon_info[]数组添加 EXTCON_USB_VBUS_EN 如下。

struct __extcon_info {
    unsigned int type;
    unsigned int id;
    const char *name;

} extcon_info[] = {
    ...
/* 2022-08-22 donga add */
       [EXTCON_USB_VBUS_EN] = {
                .type = EXTCON_TYPE_USB,
                .id = EXTCON_USB_VBUS_EN,
                .name = "USB_VBUS_EN",
        },
    ...
}

问题3:正常运行probe()后,插上typec电源适配器后,发现电源适配器不停的发送 Hard Rest。

分析原因:PD协议对实时性要求比较高,fusb302收到适配器适配器的cap自动返回GoodCRC之后,要在15ms内发送request,不然电源适配器会发送HardReset命令。rk平台主频高,每个打印信息也只消耗1ms左右,而酷芯为900M主频,每个打印信息都间隔10ms左右。因此没来得及发送request。

解决方法:见修改驱动源码。

借用一张网图,描述PD协议交互过程:

 2、修改驱动源码

修改方向:发送完GoodCRC后,会触发 INTERRUPTB_GCRCSENT 中断,状态机中尽量减少不需要的分支。

 

 之后,经过多次HardRest,某次及时request进入正常充电。(此时代码不稳定,我想要每次都能立刻request进入正常充电)。继续调试代码。

同时,测试typeC拔出时,应该能产生INIT_N中断。示波器测INIT_N脚,确实有拉低的动作,奇怪为什么没有运行中断处理函数?

原因:驱动代码中断配置成 IRQF_ONESHOT | IRQF_TRIGGER_LOW 模式,中断处理函数中关中断,工作队列再开中断。之后就无法触发了。(如果不关开中断,可以一直触发)。这个问题找厂家协助处理中。。。

测试发现下降沿触发不会出现这样的问题,因此对代码作出修改,改为 IRQF_TRIGGER_FALLING 模式加载驱动时,还需判断 type-C插入状态。

如下:

3、验证fusb302驱动,结合bq25720 充电管理IC

fusb302只是控制typeC电源适配器的VBUS脚输入的电压和电流。充电还需要充电管理IC,这里为 bq25720(驱动方法看相关文档)。

如:项目中fusb302控制电压适配器VBUS输出为 9V 3A,再通过 bq25720 限制到 8V 2A(实际看功率,要比VBUS的功率小),最终给电池充电。

 硬件环境:

 

 PD快充流程:

1)fusb302 原理图

2)加载驱动

$ insmod fusb302.ko                 //ARM板加载fusb302.ko驱动

$ insmod bq25720_charger.ko //ARM板加载bq25720_charger.ko驱动

3)逻辑分析仪采集CC1/2 PD协议通信过程

Sink发送Soft_Rest信号

 Sink请求

 

至此,每次插上type-c充电时,电流计能检测到 9V 2.2A左右。与我代码里设置的值一致。

附上源码:https://download.csdn.net/download/hinewcc/87589264

USB PD(Power Delivery)协议是一种由 USB-IF 组织制定的电源传输技术,旨在通过 USB Type-C 接口实现更高功率的电力传输和灵活的电源管理[^1]。其工作原理基于通信协商机制,允许设备之间动态地协商电压和电流参数以满足不同设备的需求。具体来说,USB PD 协议通过使用可编程电源(Programmable Power Supply, PPS)技术,在电过程中调整输出电压和电流,从而优化电效率并减少热量产生[^2]。 从技术规范的角度来看,USB PD 协议能够使标准的 USB Type-C 接口提供的最大功率提升至 100W,这远高于传统的 5V/2A(即 10W)。此外,随着版本的发展,例如 USB PD3.1 版本,支持的功率输出进一步增加,使得该技术不仅适用于智能手机和平板电脑等小型移动设备,也适合笔记本电脑等高功耗设备[^4]。 在应用场景方面,USB PD 协议因其广泛的兼容性和高效的能源利用而被广泛应用。它被用于各种便携式电子设备中,包括但不限于智能手机、平板电脑、笔记本电脑以及一些外设如显示器和打印机。由于其标准化的特点,USB PD 成为了跨品牌和跨设备类型之间统一电解决方案的理想选择[^3]。 ```python # 示例代码:模拟一个简单的PD协商过程 class PDPowerNegotiator: def __init__(self): self.supported_profiles = [5, 9, 15, 20] # 支持的电压档位 V def negotiate_power(self, requested_voltage): if requested_voltage in self.supported_profiles: print(f"协商成功: 设置电压为 {requested_voltage}V") else: closest_profile = min(self.supported_profiles, key=lambda x:abs(x-requested_voltage)) print(f"协商失败: 请求的电压不可用。建议设置电压为最接近的 {closest_profile}V") negotiator = PDPowerNegotiator() negotiator.negotiate_power(18) # 尝试协商18V ```
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值