niazlv/nrf52-eink-price-tag

GitHub: niazlv/nrf52-eink-price-tag

该项目对无文档的廉价电子货架标签进行逆向工程,为 nRF52832 和 SSD1675A 电子纸面板开发了支持 BLE 控制与泛洪 mesh 的开源固件及可移植 C99 显示驱动库。

Stars: 0 | Forks: 0

# nRF52 电子纸标签 这是一款被重新利用的 2.9 英寸黑-白-红 (BWR) 电子货架标签的固件 —— 一颗 nRF52832 芯片,通过 BLE 驱动 SSD1675A 电子纸面板,整个开发过程没有任何厂商文档可供参考。 这些面板是从分类广告网站上花几分钱买来的一堆闲置价格标签,既没有文档、没有 SDK,也没有愿意提供解答的厂商。 这里的所有内容 —— 引脚定义、波形表、刷新模式、流媒体传输路径 —— 都是在工作台上逆向工程得出的,并记录在 [`docs/`](docs/) 中。 关于如何破解这些标签的故事(俄语): [Как я купил кота в мешке: реверс-инжиниринг электронных ценников](https://habr.com/ru/articles/1044406/)。 ## 功能说明 - 在 128×296 黑白红面板上渲染时钟 / 状态 / 屏幕保护界面 - 在经过原始全屏刷新耗时约 9 秒后,通过 BLE 以每帧约 110 ms 的速度向面板流式传输动画和视频 - 通过 Nordic UART Service 接收来自 CLI、桌面 GUI 或[在线 Web 应用](https://pwa.price-tag.sorewa.ru/)的命令 - 通过该 Web 应用进行空中升级(基于 MCUboot,支持双变体签名) - 通过无连接的泛洪 mesh 网络在标签之间中继命令,因此只需一部手机连接即可覆盖整个标签群 ## 核心亮点 - [`lib/`](lib/) —— 显示驱动和绘图代码,作为一个**可移植、无外部依赖的 C99 库**提供。不依赖 Zephyr,也不依赖 nRF SDK:它仅通过六个函数与平台隔离,并提供了针对 Zephyr、Arduino 和 STM32 HAL 的参考移植。 - [`docs/eink-lut-reference.md`](docs/eink-lut-reference.md) —— 通过实验解码出的 SSD1675A 波形表字节级格式:包含 LUT 行语义、RP 重复规则、时序计算公式,以及防止面板出现残影的 DC-balance 算术逻辑。 - [`docs/display-optimization.md`](docs/display-optimization.md) —— 记录了如何将 762 ms 的局部刷新缩短至 112 ms,包括在其中探索过的两条死胡同以及随之而来的老化问题。 ## 仓库结构 ``` lib/ portable library — see lib/README.md eink/ SSD1675A driver, waveform presets, platform ports gfx/ 1-bpp canvas, text, dithering, Game of Life src/ this firmware (Zephyr / nRF Connect SDK) app/ display manager, commands, mesh, auth, persistence, battery ble/ NUS service, advertising, identity examples/ eink_demo/ minimal app built on lib/ alone lut_tester_host/ host tooling: LUT editor GUI, video streamer, DFU, PWA docs/ reverse-engineering write-ups scripts/ build and flashing helpers boards/ board overlays ``` ## 硬件说明 | 部件 | 详情 | | ----- | ------------------------------------------------------------------ | | MCU | nRF52832 (512 KB flash, 64 KB RAM) | | 面板 | SSD1675A 级别, 128×296, 黑/白/红 | | 总线 | 软件模拟的 9-bit SPI (面板将 D/C 位放在帧内部) | | 开发板 | `nrf52dk/nrf52832` 目标平台 | 默认引脚分配(可在构建系统中覆盖 `SSD1675A_PIN_*`): | 信号 | 引脚 | | ------ | --- | | BUSY | 6 | | RST | 7 | | CS | 8 | | CLK | 11 | | MOSI | 12 | | VCC | 19 | ## 构建说明 需要 nRF Connect SDK v3.0.1。如果你的安装路径不在默认位置,请在 Makefile 中指定: ``` make # build + package an OTA image make NCS_DIR=/opt/nordic/ncs/v3.0.1 BOARD=nrf52dk/nrf52832 make flash # west flash make flash-retry # retry until it verifies (flaky SWD) make clean ``` 两个 OTA 变体从同一个源代码树构建 —— 详见 [`Makefile`](Makefile) 中的变体矩阵: ``` make # legacy batch: current layout, default signing key make VARIANT=v2 # v2 batch: own signing key, factory_data partition make release # both, merged into one manifest ``` OTA 大小校验会在发布镜像前中断构建,以防止生成 MCUboot 会接受但静默拒绝切换的镜像。 ### 首次烧录 全新的标签必须通过 SWD 进行一次有线烧录 —— 在此固件刷入之前,没有任何无线访问入口。nRF52832 是一颗 Cortex-M4 芯片,因此任何 CMSIS-DAP 调试器都可以使用;处于 CMSIS-DAP 模式的 WCH-LinkE、原装 ST-Link 或 J-Link 均可胜任,且都不需要安装 Nordic 专用的烧录器。将线焊接到 SWDIO/SWCLK 焊盘上(不同批次的电路板焊盘位置可能有所不同 —— 建议先用万用表确认)。 ``` make flash # west flash, for probes west knows about make flash-openocd # openocd CLI, spawns its own session make flash-gdb # a running OpenOCD on telnet localhost:4444 make flash-retry # keep retrying until it verifies — for flaky SWD contact ``` 提供 `make flash-retry` 的原因是,此类开发板上的弹簧针 (pogo-pin) 接触不太稳定;该命令会重复执行烧录直到校验通过。完成此步骤后,所有后续更新均可通过 BLE 进行。 ## 与标签通信 命令通过 Nordic UART Service 以文本行(如 `MODE:3`、`NUKE:5`、`TIME=…`)或二进制 opcode 帧的形式接收。两者均通过 [`src/app/cmd_opcodes.h`](src/app/cmd_opcodes.h) 中的同一个注册表进行分发,因此每条命令只需实现一次。运行 `HELP` 可列出当前固件支持的所有命令。 ### 通过浏览器 —— 免安装 [`lut_tester_host/web/`](lut_tester_host/web/) 已部署并开放给所有人,访问地址:****。它与本仓库中包含的应用完全相同,具备所有可用功能:支持带抖动算法的图像、文本、动画和视频流传输,内置带有实时图表和 DC-balance 柱状图的 70 字节波形编辑器,支持屏幕保护和显示模式,显示时间、电池和统计信息,以及通过 [`/dfu.html`](https://pwa.price-tag.sorewa.ru/dfu.html) 进行 OTA 升级。 它通过 Web Bluetooth 直接从浏览器与标签通信 —— 主机端无需构建或安装任何内容。**它只能搜索到已经运行了此固件的标签**,因此全新的标签需要先通过 SWD 进行一次有线烧录;标签出厂的原厂固件不会广播任何可供此应用连接的服务。它是一个 PWA,因此加载后即可安装并支持离线使用。界面语言为俄语。 Web Bluetooth 目前支持桌面端和 Android 端的 Chrome、Edge 或 Opera;Safari、iOS 和 Firefox 暂不支持。 这是一个静态资源包,因此你可以在指向它的任意主机上运行 —— `make deploy` 负责发布。 ### 通过终端 ``` pip install -r lut_tester_host/requirements.txt python3 lut_tester_host/lut_tester.py # LUT editor + device control GUI python3 lut_tester_host/vstream_player.py … # stream video to the panel python3 lut_tester_host/dfu_upload.py … # OTA from the command line ``` ## 复用显示代码 编写 `lib/` 的初衷就是使其能够从本仓库中独立提取出来。它不依赖 Zephyr、nRF SDK 或本仓库中的任何其他内容 —— 只需六个函数(`ssd1675a_port.h`)即可完成驱动程序与硬件的对接,并且 `lib/eink/port/` 目录中提供了适用于 Zephyr、Arduino 和 STM32 HAL 的可用实现。 有关移植规范和可直接复制粘贴的示例,请参阅 [`lib/README.md`](lib/README.md)。 ## 许可证 本项目编写的代码采用 MIT 许可证 —— 详见 [`LICENSE`](LICENSE)。 此固件基于 Nordic `peripheral_uart` 示例开发,仍然带有 Nordic 版权声明的文件(`Kconfig`、`prj.conf`、`CMakeLists.txt` 以及 `src/ble/` 的部分内容)按照原标注保持在 `LicenseRef-Nordic-5-Clause` 许可下。`lib/` 目录为原创作品,仅采用 MIT 许可证。
标签:C99, Mesh网络, 云资产清单, 后端开发, 嵌入式固件, 物联网, 电子纸驱动, 蓝牙低功耗, 逆向工具, 逆向工程