Times-Z/GeekMagic-Open-Firmware
GitHub: Times-Z/GeekMagic-Open-Firmware
为GeekMagic系列ESP8266小屏设备提供完整的开源替代固件,包含ST7789显示驱动、WiFi配置、Web管理界面和OTA刷写能力。
Stars: 76 | Forks: 8
# Geekmagic 开源固件
[](https://github.com/Times-Z/GeekMagic-Open-Firmware/releases)
[](https://github.com/Times-Z/GeekMagic-Open-Firmware/actions)
[](https://github.com/Times-Z/GeekMagic-Open-Firmware/actions)
[](LICENSE)
## 目录
- [重要信息](#important-information)
- [拆解](#teardown)
- [屏幕硬件配置](#screen-hardware-configuration)
- [显示器规格](#display-specifications)
- [引脚接线](#pin-wiring)
- [重要配置详情](#important-configuration-details)
- [屏幕工作原理](#how-the-screen-works)
- [初始化序列](#initialization-sequence)
- [通信协议](#spi-communication-protocol)
- [绘制到屏幕](#drawing-to-the-screen)
- [颜色格式](#color-format)
- [下一步是什么 ?](#whats-next)
- [固件](#plateformio-firmware)
- [安装指南](#installation-guide)
- [许可证](#license)
- [支持](#support)
## 重要信息
**警告:我对您的设备变砖不承担任何责任。刷机风险自负**
**我建议在做任何事情之前,先对您的 flash 进行完整的[备份](backup/readme.md)**
**我已经上传了我的出厂备份(cube 版本为 7.0.17,small tv 版本为 9.0.40);这可能会有用。备份已经过测试和验证,可以正常工作**
## 拆解
- **MCU**: ESP8266
- **LCD 控制器**: ST7789 (RGB565)
- **外壳**: 3D 打印
Cube & TV Disassembly
## 屏幕硬件配置
### 显示器规格
- **控制器**: ST7789
- **分辨率**: 240x240 像素
- **颜色格式**: RGB565 (16位色)
- **接口**: SPI (Serial Peripheral Interface)
- **SPI 速度**: 40 MHz (80 MHz 是可能的,但不稳定且超出了数据手册规格)
- **旋转**: cube 显示器为倒置,small tv 为正常
### 引脚接线
small TV 和 cube 的接线是相同的
显示器使用以下 GPIO 引脚连接到 ESP8266:
| 功能 | GPIO 引脚 | 描述 |
| ------------- | -------- | ----------------------------------------------------- |
| **MOSI** | GPIO 13 | SPI 主输出从输入 (数据从 ESP8266 到屏幕) |
| **SCK** | GPIO 14 | SPI 时钟 |
| **CS** | GND | 片选,永久连接到 GND |
| **DC** | GPIO 0 | 数据/命令选择 (低电平=命令, 高电平=数据) |
| **RST** | GPIO 2 | 复位引脚 |
| **背光** | GPIO 5 | 背光控制 (低电平有效) |
### ESP8266 开发板接线示例
对于常见的 ESP8266 开发板,例如 NodeMCU 或 ESP-12E 开发板,按如下方式连接 TFT 模块:
| TFT 引脚 | ESP8266 GPIO | 常见开发板标签 | 备注 |
| -------------- | ------------ | ---------------------- | ------------------------------------------ |
| **GND** | GND | GND | 地线 |
| **VCC** | 3V3 | 3V3 | 从 3.3V 为显示器供电 |
| **SCL / SCK** | GPIO 14 | D5 | SPI 时钟 |
| **SDA / MOSI** | GPIO 13 | D7 | 从 ESP8266 到显示器的 SPI 数据 |
| **DC** | GPIO 0 | D3 | 数据/命令选择 |
| **RES / RST** | GPIO 2 | D4 | 显示器复位 |
| **BLK** | GPIO 5 | D1 | 可选背光控制,见下方备注 |
如果您的模块没有 **CS** 引脚,或者 **CS** 已经在 PCB 上拉低,则不需要额外的片选接线。
许多 1.3" ST7789 模块在 **BLK** 悬空时会保持背光启用。在这种情况下,屏幕根本不需要连接 **BLK** 即可工作。如果您希望通过固件控制背光,请将 **BLK** 连接到 GPIO 5。
请注意,**GPIO 0** 和 **GPIO 2** 是 ESP8266 的启动引导引脚。此接线与固件使用的原始硬件相匹配,但如果您的模块在复位期间将任一线路拉至错误电平,ESP8266 可能无法启动。
Pin Wiring Diagram (exact same for small tv) && NodeMCU working
### 重要配置详情
**片选 (CS) 极性**:此板子将显示器的 CS 永久连接到 GND。
**SPI 模式**:SPI 模式 3 (CPOL=1, CPHA=1)
**数据/命令引脚**:低电平为命令,高电平为数据
**背光**:低电平有效控制 - 将 GPIO 5 置为低电平以打开背光,置为高电平以关闭背光
## 屏幕工作原理
### 初始化序列
固件通过 `lcdEnsureInit()` 函数初始化显示器,该函数执行以下步骤:
1. **背光激活**:GPIO 5 被配置为输出,并根据 `LCD_BACKLIGHT_ACTIVE_LOW` 配置进行驱动(通常驱动为低电平以打开背光)
2. **SPI 总线初始化**:硬件 SPI 初始化为:
- 时钟速度:由 `LCD_SPI_HZ` 定义(通常为 40 MHz)
- 模式:由 `LCD_SPI_MODE` 定义(此显示器需要模式 3)
3. **硬件复位序列**:RST 引脚 (GPIO 2) 按以下时序切换:
- 置高 → 等待 120ms → 置低 → 等待 120ms → 置高 → 等待 120ms
4. **显示控制器初始化**:通过 `lcdRunVendorInit()` 执行供应商特定的初始化序列,其中包括:
- 退出睡眠 (0x11),延迟 120ms
- Porch 设置 (0xB2),参数为:HS=0x1F, VS=0x1F, Dummy=0x00, HBP=0x33, VBP=0x33
- 撕裂效应 (0x35) 设置为 OFF (0x00)
- 内存访问控制/MADCTL (0x36) 设置为默认 (0x00)
- 颜色模式 (0x3A) 设置为 16 位 RGB565 (0x05)
- 电源控制设置:
- Power B7 (0xB7) = 0x00
- Power BB (0xBB) = 0x36
- Power C0 (0xC0) = 0x2C
- Power C2 (0xC2) = 0x01
- Power C3 (0xC3) = 0x13
- Power C4 (0xC4) = 0x20
- Power C6 (0xC6) = 0x13
- Power D0 (0xD0) = 0xA4, 0xA1
- Power D6 (0xD6) = 0xA1
- Gamma 校正 (0xE0, 0xE1) 使用预定义曲线(各 14 个字节)
- Gamma 控制 (0xE4) = 0x1D, 0x00, 0x00
- 显示反转 (0x21)
- 显示开启 (0x29)
- 列地址设置 (0x2A):0x00 到 0xEF
- 行地址设置 (0x2B):0x00 到 0xEF
- RAM 写入命令 (0x2C)
5. **初始化后**:
- 延迟 10ms 以稳定显示器
- 应用显示旋转(通过配置的 `getLCDRotationSafe()`)
- 屏幕填充为黑色,文本颜色设置为白色
### SPI 通信协议
ST7789 通过 SPI 进行通信,具有以下信号处理:
1. **时钟**:SCK (GPIO 14) - 以配置的频率 (40 MHz) 驱动 SPI 时钟
2. **数据**:MOSI (GPIO 13) - 将命令字节或像素数据从 ESP8266 传输到显示器
3. **片选**:CS 永久连接到 GND(始终处于活动状态)
4. **数据/命令模式**:DC 引脚 (GPIO 0) 指示数据类型:
- DC = 低电平:接下来是命令字节
- DC = 高电平:接下来是像素/参数数据
显示器需要 **SPI 模式 3** (CPOL=1, CPHA=1),这在初始化序列中已明确配置。
### 绘制到屏幕
固件使用 **Arduino_GFX 库**配合自定义的 ST7789 显示器驱动程序。绘图操作通过全局 `g_lcd` 实例进行管理:
1. **文本渲染**:
- 通过 `lcdDrawTextWrapped()` 实现,提供自动换行支持
- 自动换行算法处理空格、制表符和换行符
- 文本大小按整数倍数缩放(大小为 1 时,每个字符为 6×8 像素)
- 支持带有可配置字符和行数限制的自动换行
2. **图形基元**:
- 通过 `DisplayManager::getGfx()` 直接访问 Arduino_GFX API
- 矩形填充:`fillRect(x, y, width, height, color)`
- 全屏填充:`fillScreen(color)`
- 直接 SPI 写入在 `beginWrite()` 和 `endWrite()` 调用之间进行批量处理
3. **GIF 播放**:
- 通过 `Gif` 类实例 `s_gif` 进行管理
- 支持带可选持续时间限制的全屏 GIF 播放
- 可随时通过 `DisplayManager::stopGif()` 停止
4. **性能优化**:
- **硬件 SPI**:使用 ESP8266 的硬件 SPI 外设 (40 MHz) 进行高效传输
- **批量写入**:命令和数据在 `beginWrite()`/`endWrite()` 调用之间进行批量处理
- **Yield 调用**:在长时间操作期间调用 `yield()` 以防止看门狗超时
- **直接流式传输**:GIF 帧直接流式传输,无需中间缓冲
### 颜色格式
显示器使用 **RGB565** (16位) 颜色编码:
- **红色通道**:5 位 (位 15-11)
- **绿色通道**:6 位 (位 10-5)
- **蓝色通道**:5 位 (位 4-0)
此格式提供 65,536 种不同的颜色,是 ST7789 显示器的标准格式。
**常见颜色常量**(定义在 DisplayManager.h 中):
- 黑色:`0x0000`
- 白色:`0xFFFF`
- 红色:`0xF800`
- 绿色:`0x07E0`
- 蓝色:`0x001F`
- 青色:`0x07FF`
- 品红色:`0xF81F`
- 黄色:`0xFFE0`
等等...
## 下一步是什么 ?
好的,现在我们有了一个可以工作的最小固件。
我非常喜欢 ESP 设备,也非常喜欢使用 ESP-IDF 进行开发,所以我计划~~如果可能的话(我还没有检查过兼容性,我对这个世界还是新手)~~创建一个在功能上接近原始固件的固件,但当然是完全开源的 \o/
由于 ESP IDF 与 esp8266 不兼容,我打算在 [plateformIO](https://platformio.org/) 的基础上构建固件
至少,这就是这个项目
## PlateformIO 固件
这是我想要改进的“真正”固件,包含整洁且可靠的代码
### 技术栈
| 组件 | 技术 / 库 | 主要角色 |
| ----------------- | ------------------------------------------------------------------------ | --------------------------------------- |
| 微控制器 | ESP8266 (esp12e) | 主要硬件平台 |
| 构建环境 | PlatformIO | 项目管理、构建、上传 |
| 框架 | Arduino Framework | ESP8266 的软件基础 |
| 文件系统 | LittleFS | 本地存储 LittleFS |
| 图形显示 | Arduino_GFX 库 | ST7789 显示器管理 (SPI, RGB565) |
| Web UI (前端) | [Pico.css](https://picocss.com/docs), [Alpine.js](https://alpinejs.dev/) | 极简的 Web 用户界面 |
## 安装指南
要在的 GeekMagic 设备上使用开源固件,请按照以下步骤操作:
### 1. 克隆仓库
```
git clone https://github.com/Times-Z/GeekMagic-Open-Firmware.git
```
### 2. 配置 JSON 文件
```
cp data/config-{hellocubic|smalltv}.example data/config.json
```
您可以编辑此 JSON 文件来配置您的固件,例如通过修改 `wifi_ssid` 和 `wifi_password` 使您的设备连接到您的网络
注意:config.json 中的 Wi-Fi 凭据和 API token 在首次启动时会迁移到 EEPROM “安全存储”中。之后,这些凭据将从 config.json 中删除
**配置选项:**
- `wifi_ssid`:您的 WiFi 网络名称
- `wifi_password`:您的 WiFi 密码
- `api_token`:用于 API 身份验证的 Bearer token
- `lcd_rotation`:显示器旋转设置
- `ntp_server`:用于时间同步的 NTP 服务器
已存储机密的安全性:
- 所有敏感值(API 密钥、wifi 凭据、token 等)都使用设备唯一的混淆方案存储在 EEPROM 中
- 混淆密钥是使用 SHA-256 从 ESP8266 的 MAC 地址、芯片 ID 和盐(可在代码中的[此处](./src/main.cpp#L41)进行配置)派生而来的
- JSON 负载在写入 EEPROM 之前会与此派生密钥进行异或 (XOR) 运算,并在读取时进行反混淆
- 这使得从另一台设备上的原始 flash 转储中恢复机密,或者在只有部分硬件知识的情况下恢复机密变得困难得多
局限性:
- 这不是真正的加密,不提供硬件支持的安全性,也不能防范拥有完全设备访问权限的坚定攻击者
- 公开的盐不是机密;如果攻击者知道盐、MAC 和芯片 ID,他们就可以重建密钥
- 没有安全元件或防篡改机制
**不要指望能防范坚定的攻击者以保持机密性**
警告:如果盐、芯片 ID 或 MAC 地址发生变化,EEPROM 安全存储将被清空并重置,以确保不会发生数据泄露
### 3. 构建固件和文件系统
要构建固件,您可以使用容器、Docker 或使用 [PlateformIO](https://docs.platformio.org/en/latest/core/installation/methods/installer-script.html) 自行构建
```
pio run && pio run --target buildfs
# 或使用 devcontainer aliases
build && buildfs
# 或 docker
./scripts/build-with-docker.sh
```
生成的文件将位于:
```
.pio/build/esp12e/
```
### 4. 刷入固件
有两种可能的刷入方法:
- **OTA (Over-The-Air)** – 无需先决条件
- **USB** – 需要一个 USB 转 TTL 转换器来连接到 ESP
### OTA 刷入
刷入分两步进行
#### 步骤 1:刷入固件
前往:
```
http://{your_geekmagic_ip}/update
```
这是原始固件的更新端点。上传 `firmware.bin` 文件
完成此步骤后,设备将重新启动。根据型号不同,屏幕方向可能正确也可能不正确——这是正常现象
此时,仅刷入了固件。文件系统(配置、Web 应用程序)仍需要刷入
#### 步骤 2:刷入文件系统
固件将创建一个具有以下凭据的 Wi‑Fi 接入点:
- **SSID:** `GeekMagic`
- **密码:** `$str0ngPa$$w0rd`
连接到此接入点并前往:
```
http://192.168.4.1/legacyupdate
```
从那里,选择并使用 `littlefs.bin` 文件刷入文件系统
设备重新启动后,设置即完成!
## 许可证
本项目基于 **GPLv3 许可证** 授权 - 详情请参见 [LICENSE](LICENSE) 文件
## 支持
- 发现了错误或有疑问?[开启一个 Issue](https://github.com/Times-Z/GeekMagic-Open-Firmware/issues)
Cube & TV Disassembly
Pin Wiring Diagram (exact same for small tv) && NodeMCU working
**用 ❤️ 制作**
如果您觉得这个项目有用,请在 [GitHub 上给我们点 Star](https://github.com/Times-Z/GeekMagic-Open-Firmware.git)!
这个项目花了我很多时间!
标签:C++, ESP32, Geekmagic, HelloCubic, IoT, LCD屏幕, PlatformIO, SmallTV, SPI通信, 屏幕驱动, 嵌入式开发, 开源固件, 开源硬件, 数据擦除, 智能小电视, 智能硬件, 极客, 桌面摆件, 物联网, 硬件DIY, 硬件控制
