CH558 OS Switch

在 Hackaday 上看到了 Hardware boot selection switch 这个项目,作者用 STM32 模拟出一个 U 盘,通过读取硬件开关的状态返回不同的内容,从而让 grub2 启动不同的系统。

最近 STM32 涨价涨得太厉害,一片 F103 也要几十块钱。有同学推荐了国产的 CH558 ,价格只需要两三块钱,于是入手了 CH558T 来尝试一下。手边有很多没用掉的 SSOP20 转接板,所以买了这种封装的芯片。

转接板上的 CH558

国产单片机的最大劣势就是生态不好。厂商能提供一份 Datasheet 和几个糊出来的示例程序,剩下的资料就要靠各种论坛上搜了,不过也不一定能搜得到。arm 架构的也许有 CMSIS 用?像这种 51 改造的 8 位单片机,基本就是直接操作寄存器了。 CH558 和 CH559 的硬件规格大致相同,网络上有 CH559 模拟 U 盘的程序下载,但那份程序里状态机貌似写的有些问题,在 Windows 下对一些错误的容忍度比较高,不过在我的电脑开机时, BIOS 读取信息时就会卡死,还是需要动手改造一下再用。

USB 协议比较好的参考资料就是 usb.org 上的各种文档。由于很多细节涉及到硬件上的操作,还是建议结合他人的程序深入理解。首先把 usb 和电脑的基础沟通部分做好,让 endpoint 能够正常通信,再去把 Mass Storage Class 的状态机写出来。我使用的是 Bulk-Only Transport + SCSI Transparent Command ,要写好 BBB 的操作和 SCSI 命令的处理。最后把文件系统的相应函数写好,可以用 FAT12 这样简单的文件系统减少负担。一次写一层,每一层都用相应的工具进行检验调试。

成果

读取 GPIO 是非常简单的,因为只在开机时读取一次 GPIO 状态,所以也完全不用考虑滤波的问题。

最后还是要吐槽一下,如果让我重新来过,我就去用 rpi pico 或 esp32 做。 Pico SDK 里面的 raw usb device 示例中,都有一堆库函数在做底层的操作,如果想偷懒还可以直接用 TinyUSB 写好的 MSC 代码。 ESP32 部分型号不支持 USB 功能,用 risc-v 处理器的可能示例比较少,也需要再留意一下。如果非要用 CH558 ,建议用 LQFP48 封装的版本。 SSOP20 的版本有些蛮重要的引脚被砍掉了,比如 UART0 。 UART1 没被砍,但操作起来竟然和 UART0 是不一样的。