Times-Z/GeekMagic-Open-Firmware

GitHub: Times-Z/GeekMagic-Open-Firmware

为GeekMagic系列ESP8266小屏设备提供完整的开源替代固件,包含ST7789显示驱动、WiFi配置、Web管理界面和OTA刷写能力。

Stars: 76 | Forks: 8

# Geekmagic 开源固件 [![最新发布](https://img.shields.io/github/v/release/Times-Z/GeekMagic-Open-Firmware?label=Latest%20Version&color=c56a90&style=for-the-badge&logo=star)](https://github.com/Times-Z/GeekMagic-Open-Firmware/releases) [![主分支构建状态](https://img.shields.io/github/actions/workflow/status/Times-Z/GeekMagic-Open-Firmware/.github/workflows/ci.yml?branch=main&label=Pipeline%20Status%20main&style=for-the-badge&logo=star)](https://github.com/Times-Z/GeekMagic-Open-Firmware/actions) [![开发分支构建状态](https://img.shields.io/github/actions/workflow/status/Times-Z/GeekMagic-Open-Firmware/.github/workflows/ci.yml?branch=develop&label=Pipeline%20Status%20develop&style=for-the-badge&logo=star)](https://github.com/Times-Z/GeekMagic-Open-Firmware/actions) [![许可证: GPLV3](https://img.shields.io/badge/License-GPLV3-yellow.svg?style=for-the-badge)](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)
HelloCubic Lite Showcase HelloCubic Lite Showcase
open firmware showcase working on both hellocubic and smalltv
## 重要信息 **警告:我对您的设备变砖不承担任何责任。刷机风险自负** **我建议在做任何事情之前,先对您的 flash 进行完整的[备份](backup/readme.md)** **我已经上传了我的出厂备份(cube 版本为 7.0.17,small tv 版本为 9.0.40);这可能会有用。备份已经过测试和验证,可以正常工作** ## 拆解 - **MCU**: ESP8266 - **LCD 控制器**: ST7789 (RGB565) - **外壳**: 3D 打印
Cube Disassembly Cube Disassembly
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 可能无法启动。
Pinout Diagram NodeMCU working
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)
**用 ❤️ 制作** 如果您觉得这个项目有用,请在 [GitHub 上给我们点 Star](https://github.com/Times-Z/GeekMagic-Open-Firmware.git)! 这个项目花了我很多时间!
标签:C++, ESP32, Geekmagic, HelloCubic, IoT, LCD屏幕, PlatformIO, SmallTV, SPI通信, 屏幕驱动, 嵌入式开发, 开源固件, 开源硬件, 数据擦除, 智能小电视, 智能硬件, 极客, 桌面摆件, 物联网, 硬件DIY, 硬件控制