开发者文档

通过 SPI Bridge,把它当作一块稳定的外部单色信息屏。

显示模型

DS5 对外不是裸 LCD,也不是 i8080 面板透传。外部主机只需要发送统一的逻辑画面,DS5 固件会在内部转换到实际屏幕。

尺寸 184 × 126
刷新方式 整帧刷新
坐标方向 产品正向坐标

外部主机不要自行按设备倒放方向旋转画面。固件会根据设备设置处理物理屏幕旋转。

供电

DS5 可以通过 USB Type-C 供电,也可以通过接口 Pin 1 供电。使用 Pin 1 供电时,屏幕不需要再接 USB Type-C。

接线

DS5 侧当前以 V3 硬件为准。外部主机可以是任意支持 SPI mode 0 的 MCU 或开发板;下表里的 GPIO 只是测试 sketch 的默认引脚,可以按你的主机硬件修改。

测试 sketch 默认引脚 DS5 信号 方向
GPIO10 SPI_CS host -> DS5
GPIO11 SPI_SCK host -> DS5
GPIO12 SPI_MOSI host -> DS5
GPIO13 HOST_DET host -> DS5
GPIO14 BUSY_OUT DS5 -> host
GND GND 共地

SPI 是单向数据流,不使用 MISO。建议先使用 1 MHz SPI 时钟。确认稳定后再提高频率。发送新包前必须等待 BUSY_OUT 为低电平。

SPI Protocol v1

一个 SPI transaction 就是一个完整 DS5 packet。协议不支持把一个 packet 拆成多个 CS 窗口。

CS low
  32-byte header
  optional payload
CS high

SPI 参数

模式 SPI mode 0,CPOL = 0,CPHA = 0
位序 MSB first
响应 无 MISO 响应,错误通过 DS5 串口诊断查看
流控 BUSY_OUT 高电平表示 DS5 忙

Header

Offset Size 字段 说明
04magicASCII D5SP
41version固定为 1
51header_size固定为 32
61command命令 ID
71format画面格式,或 0
82seq主机序号
102flags命令参数
122width通常为 184
142height通常为 126
162stride每行字节数
182reserved0必须为 0
204payload_lenpayload 字节数
244payload_crc32payload CRC32
284header_crc32header 前 28 字节 CRC32

所有多字节整数都是 little-endian。CRC32 使用标准 CRC-32/ISO-HDLC。

命令

ID 名称 Payload 说明
0x01 HELLO 进入或保持 SPI Bridge 模式
0x10 FRAME_FULL 整帧 framebuffer 显示一帧完整画面
0x11 CLEAR flags & 0x000F 清屏
0x12 EXIT_BRIDGE 退出 bridge,回到本机应用
0x20 RESET_STREAM 清除协议错误状态

画面格式

ID 名称 支持屏幕 Stride Payload
0x01 MONO1 全部 23 2898 bytes
0x02 GRAY2 P2 46 5796 bytes
0x03 GRAY4 P2 92 11592 bytes

MONO1

0 表示白,1 表示黑。每个字节保存 8 个像素,LSB first。

byte_index = y * 23 + x / 8
bit_index  = x & 7

GRAY4

0 表示白,15 表示黑。每个字节保存 2 个像素,低 nibble 在前。

byte_index = y * 92 + x / 2
low nibble  = x + 0
high nibble = x + 1

样例代码

仓库里包含一个 Arduino host 示例,默认引脚适合我们测试时使用的开发板;如果你使用其他主机,只需要保留协议和 DS5 侧信号,调整 SPI 初始化和引脚定义即可。

测试流程:

  1. 打开 DS5 串口,输入 spi bridge status,确认设备支持 SPI Bridge。
  2. 按上面的接线表连接外部主机和 DS5。
  3. 如有需要,修改样例代码里的主机引脚定义。
  4. 把样例 sketch 刷入外部主机,开始发送测试画面。

测试过程中再次查看 spi bridge status,正常情况下可以看到 helloframes 计数增加。

最小发送流程

  1. 拉高 HOST_DET
  2. 发送一个或多个 HELLO packet。
  3. 等待 BUSY_OUT 为低。
  4. 发送完整 FRAME_FULL packet。
  5. 每次发送下一帧前,继续等待 BUSY_OUT 为低。