上次,我展示了将现有 PSU 转换为 USB-C 任务的几种方法,并重点介绍了一种将数量众多的 18 V – 20 V 笔记本电脑 PSU 转换为 USB-C 的特定方法。我们剩下的就是为其编写软件,我将解释它是如何工作的。我还发现了一个很酷的 USB-C 秘密,但您必须继续阅读才能了解更多信息。
从上一篇文章来看,我们有一个带有 RP2040 和 FUSB302 组合的主板,它从笔记本电脑砖获取 20 V DC PSU 输入,并且可以将 5 V、20 V 或 0 V 切换到其 USB-C 插座使用 FET。 USB-C 通信固件非常简单,但也有一些注意事项,特别是在安全方面。让我们来看看这些吧!
代码逻辑
默认情况下,VBUS 必须处于非供电状态 – 当 FUSB302 检测到其中一根 CC 线路上存在 5.1 kΩ 下拉电阻时,我们仅提供 5 V 电压。提供 5 V 电压后,我们发送 PSU 功能广告,这种广告是我们在回复 PD 文章中学会解析的那种 – 每当我们收到请求时,我们必须切换到请求的配置文件,将请求的电压轨连接到场效应管。假设设备性能良好,我选择在此设计中不进行任何电流消耗控制,但理论上您应该这样做。添加一个高侧电流传感器并不难,比如来自 Analog Devices 的产品 – 我只是现在不想这样做,特别是考虑到我已经在使用两个暴露的 ADC 引脚来做 Lenovo相反,HP PSU 能力检测,一个用于 VBUS 测量,第四个用于 VIN(20 V 轨)测量 – 这是四个 ADC,与 RP2040 的数量一样多。但是,如果我需要更多 ADC,我可以在下一版本中添加类似 4051 的模拟多路复用器!
我还选择不对电缆 5 A 消耗进行 emarker 检查 – 如果您错过了emarker 文章,emarker 是 USB-C 电缆内部的 IC,其中包含有关电缆功能的数据,包括电缆是否可以承载 5 A 电流。安然无恙。 PSU 应该在提供更高电流的配置文件之前进行这些检查,而我只是还没有研究如何查询 emarker。然而,我可以通过仅检测表明需要 VCONN 的 Ra(1kΩ 下拉)电阻器的存在来相对轻松地检测标记电缆的存在,并据此假设我们对 5 A – 60 W 提供 100 W 支持- 只有电缆中没有标记,除非专门标记为高速电缆。
我没有任何这样的 60W 高速电缆,而且,在您可以向固件添加 emarker 检查之前,您可能不应该在此类设备上使用此类电缆。如果没有 emarker,您必须将宣传的电流限制为 3 A – 值得庆幸的是,像笔记本电脑这样的设备只会消耗其允许的电流。哦,您的主板的 USB-C 插座的额定电流也必须为 5 A:请记住,许多插座的额定电流仅为 3 A。
启动时,我们的代码应该检查连接的 PSU 的功能 – 对于 Dell PSU,您必须读取单线 EEPROM,对于 Lenovo 或 HP PSU,您必须读取从 ID 引脚连接到 GND 或 GND 的电阻器分别使用分压器和 ADC 以及用于保护的齐纳二极管来实现这一点。在我看来,如果没有检测到任何情况,我可以相当安全地假设 3 A 并采用该值 – 能够低于 3 A 的笔记本电脑 PSU 相对较少。然后,我们构建一个包含 PSU 电压和电流能力的 PD 配置文件,并等待下游设备连接到我们的 USB-C 端口。之后,我们定期发送 USB-C 配置文件,并等待请求消息 – 当我们收到该消息时,我们会解析它,对其进行完整性检查,然后回复接受消息。
该 Accept 消息将为我们提供来自设备的 GoodCRC 响应 – 理想情况下,我们仅在收到 20 V 后才提供它,以便我们可以确定设备确实已确认我们即将提供 20 V。然后,我们可以切换从 5 V 到 20 V,并发送 PS_RDY 消息以表明 20 V 可用。
或者,您可以按照我的做法,在短暂延迟后提供电压,而不是等待 GoodCRC – 这偏离了规范,但有延迟就足够了。我们还偏离了规范,因为我们不会在收到请求消息后立即启动“关闭 VBUS”计时器 – 该计时器是 PSU 实施的规范要求,如果您不这样做,它可能会让您陷入困境。在编写自己的 PD 触发代码时不要考虑它,但这里并不是 100% 需要。当然,我们还缺少一些东西来更加符合规范,也许还可以与更多的设备兼容——但它实际上不会造成任何问题!
需要注意的事项
当然,有一些我们不能忽视的安全要求。首先,我们使用 FUSB302B PD 前端,当未通电时,它会对其引脚施加 5.1 kΩ 下拉电阻 – 此功能称为“电池电量耗尽”,这是不言自明的。显然,如果我们想充当 USB-C PSU,则必须禁用上拉电阻,而是启用指示 5 V/1.5 A 配置文件的上拉电阻,作为 USB-C 模拟 PD 信号的一部分。使用 FUSB302 在软件中执行这两项操作都非常简单,但有一个问题 – 如果您在尚未提供 20 V 电压且我们的代码尚未运行时将 USB-C PSU 或双角色端口插入此适配器,它将启动循环。值得庆幸的是,我们可以在软件中检测到这种情况,只需等待 20 V 连接即可。还有 FUSB302T 版本没有启用电池耗尽功能,因此如果您要构建专业的 USB-C PSU 板,则必须使用 302T 版本。我已经购买了一些 301T IC,现在我只需要将它们焊接在 302B 的位置即可。在我们的代码中,我们可以通过读取FUSB302的版本寄存器来区分芯片的-B和-T版本,这很有帮助!
一旦移除 5.1 kΩ 下拉电阻,我们就必须将 VBUS 返回到 0 V 状态,确保在拔掉我们正在供电的设备后,连接器上永远不会保留 20 V 电压。如果在不再检测到设备上拉后仍将 20V 连接到 VBUS,则可能会导致 USB-C 设备的引脚上出现 20V 电压,而当您重新插入时,只有 5V 电压才可以。这是一种安全措施- 您需要使用看门狗计时器的关键点 – 我将研究MicroPython 看门狗实现,确保如果我的代码崩溃,系统将重置为安全状态。
哦,当然,过流保护是非常棒的。为了防止 5 V 电源轨短路,如果您正在供电的设备出现 VBUS 短路,我建议您在 5 V FET 对输入之前使用类似 SY6820 限流开关的开关,将其设置为略高于 1.5答:之前的原理图没有这个,但新原理图有!至于直流输入过流,你可以尝试设置,但我个人更喜欢依赖上游PSU的电流限制,并确保我们的设备不是弱点。此外,如果我们测量 VBUS 和 VDC,并且电阻分压器经过充分校准,我们可以通过测量 VBUS 和 VDC 之间的差异来测量电流,并使用 FET 作为分流器。如果 VDC-VBUS 路径 FET 上的电压超过几伏,则可能值得将其禁用。
逐渐面对现实
即使采取了这些预防措施,代码本身也并不棘手。 FUSB302 为 USB-C 事件提供中断,我们只需对这些中断和 FIFO 中任何传入的 PD 消息做出反应。我编写了一段从列表中构造 USB-C PD 配置文件的代码 – 它只是我们在“回复 PD”文章中编写的 PD 配置文件解析函数,但它将值转换为字节,而不是提取值字节数。由于我已经有了解析代码,因此我添加了一个简短的检查,将新构建的配置文件通过该解析代码并assert()
结果是否匹配!构造 PS_RDY 和 Accept 消息很容易 – 我已经有了一个可以发送任何命令消息的通用函数,这是我根据当时编写的 Request 函数制作的。
我逐渐开发了 PSU 行为循环代码,并在整个开发过程中对其进行了测试,从简单的 USB-C 设备开始进行测试。例如,在测试连接-分离行为和 FUSB302 中断处理的基础知识时,您可以使用具有 5.1K 下拉电阻的随机 USB-C 分线 – 这样,如果您意外提供 20 V 电压,就不会存在烧毁的风险。我已经开始用我的 Pinecil 测试这段代码,因为它是一个相当宽松的 USB-C 设备,因为它的开源 PD 接收器堆栈可以与各种 PD 电源一起工作,尽管有一些怪癖 – 这对于可能具有怪癖和锋利的边缘!它也是一个非常安全的测试设备——它不会关心你是否只在 VBUS 上施加 20 V 电压,而相当多的笔记本电脑会反对这样做,有些甚至可能会产生激烈的反应。
借助 Pinecil,我可以测试所有基础知识 – 连接-分离行为、PD 配置文件发送及其 PD 测试仪功能向我表明,它可以正确识别我的代码创建的所有配置文件!最后的前沿是让这个 PSU 与我的 Framework 笔记本电脑一起工作,因为这就是我开发这个 PSU 的实际目的。当然,第一次尝试并没有成功——框架使用具有适当 USB-C 堆栈的 PD 控制器,并强制执行所有 USB-C 规范的约束,因此需要一些额外的调试。 “回复 PD”文章中的 PD 触发代码特别帮助我消除了与规范的差异 – 我可以将我的 USB-C 接收器代码板插入具有 PD 接收器代码的同一块板上,查看两个 RP2040 的 UART 输出,并将我的主板的 PD 通信与我现有的 USB-C 充电器的通信进行比较。
我发现有两件事似乎让框架的 PD 控制器感到难过。第一个是我在连接后显然太早发送了 PD 广告,这是我在注意到我的 Pinecil 需要大约五秒钟才能与我的 PSU 协商,而与我放置的充电器协商只需要大约一秒钟后发现的大约。看到这一点,我意识到我的第一个广告发送得太早,以至于 Pinecil 无法启动并接收它,并且为似乎即时的谈判进行了调整。修复此问题后,笔记本电脑将正确接收配置文件并请求 20 V,但在将 20 V 电压接入 VBUS 后它将分离。罪魁祸首是我在发送 Accept 和将 20 V 电压放到总线之间没有等待足够的时间 – 增加延迟解决了这个问题。如果我等待 GoodCRC 的回复,会有帮助,但是,当时感觉可以抄近路!
收获研究成果
如果我阅读规格并正确实施所有 PSU 的限制、检查状态机并遵守时间限制等,那将会有所帮助。尽管如此,这款 PSU 却发挥了奇迹,而且我在开发这款电源时几乎不需要检查规格 – 这对我的自尊产生了奇迹!即使将电流增加到 5 A 也很顺利,我只需要确保插入一根 100 W 的电缆,因为配置文件目前是硬编码的。是的,还有待办事项 – 我当前的代码还没有 emarker 检查或笔记本电脑 PSU 功能检查,因此我正在宣传硬编码的 PD 配置文件,而不是像我应该的那样在启动时计算它们。我正在慢慢地处理这些事情,目前,在给定特定笔记本电脑 PSU 和电缆组合的情况下,它足以对我的笔记本电脑进行长期测试。我拥有的第一个 100 W USB-C PSU,是我自己组装的 10 0W PSU,感觉不错。
所有代码都像往常一样使用 MicroPython——这是我对高级修补友好实现的选择。您可以简化代码,移植到 C 并将其放入较小的设备(例如 ATtiny 或 CH32V003)上,因为您只需要一些 GPIO、ADC 和 I2C。这就是您构建一个廉价的改装适配器所需的全部内容,以便将任何 DC PSU 制成 USB-C PSU,其电压大致适合 USB-C 配置文件 – 甚至不符合 USB-C 配置文件!还记得我提到的秘密吗?我在代码中提供了 5 V 和 20 V 配置文件,但我发送的是连接了 19 V PSU 的 20 V 配置文件,因为这就是我手头上的配置文件。这在我的框架上有效,这让我想知道 – 我实际上可以提供多么不标准的电压?我尝试提供 19 V 配置文件,令我惊讶的是,笔记本电脑接受并开始充电 – 功率为 95 W,不少于。这是一个巨大的胜利,极大地增加了我实际上可以使用该板的不同 DC PSU 的数量。
制作电压明显高于 20 V 的自定义配置文件可能不是一个好主意(并不是说我不会很快尝试 21 V 锂离子电池组),但低于 20 V 电压应该没问题!当然,也有一些警告 – 例如,某些 Framework 主板仍然存在15V 处理的硬件错误,需要交换 FET 才能使低于 18V 的电压正常工作。然而,在 FET 交换之后,该 PSU 允许您使用任何高于 15 W 的 10 V – 20 V DC 电源为框架充电 – 您只需传达电压和电流消耗限制;对于其他笔记本电脑,您的里程可能会有所不同,因为这可能取决于 PD 控制器固件。要点是 – 如果您想用四块或五块串联的 18650 电池为框架充电,您只需将它们连接到该板的 VIN,持续测量它们的总电压,并定期重新公布可用电流和电压。当你的电池组电压下降时,就会飞起来。
目前,我计划将此电路封装成几种不同的格式,确保常见类型的直流 PSU 不会被抛弃!此外,考虑到新的 Pi 5需要 PD 握手才能真正接受 5 A、5 V 的电流,本文的工作可能只是帮助您从随机的大型非 PD 5 V PSU 为您的 Pi 供电,而无需对其进行节流。不过,他们可能保留了 5 V GPIO 接头反向供电漏洞,因此我想一旦有人真正研究它,我们就会获得有关 Pi 5 PD 要求的更多详细信息。
这还不是全部 – 与此同时,我的一些朋友一直在修改 USB-C PSU 设计,将我的原理图变成了精彩的电路板!例如,这里有一个来自 [Wificable] 的主板,它是一款 Framework 笔记本电脑扩展卡,可让您使用戴尔和惠普 PSU 作为 USB-C 充电器。将来,我们可以添加对 MagSafe 之类的支持!
这个设计很有趣,它为我提供了一种重复使用一大堆 PSU 的方法,帮助我找到了意想不到的 Framework PD 控制器功能,并且可能会帮助我构建一个非常简单且高效的 USB-C 电源组,以便直接重复使用锂离子电池。除此之外,看起来这张卡本身会带来一些不错的设计!我希望您喜欢这段旅程,就像我喜欢记录它一样,每当您需要探索 USB-C 技术的世界时,希望这些文章能够为您提供帮助。
原文: https://hackaday.com/2023/12/04/usb-c-for-hackers-program-your-own-psu/