updated doc for epd

This commit is contained in:
2026-04-04 21:44:16 -04:00
parent 74b3e01556
commit 9269e3b873
+60 -51
View File
@@ -1,62 +1,71 @@
# EPD Reference Driver — GDEY075T7 (UC8179)
# EPD Implementation Reference — GDEY075T7 (UC8179)
## Source
**Repository:** [ekosboard/firmware](https://github.com/ekosboard/firmware)
**File:** [`src/components/EPD/driver/epd_GDEY075T7.c`](https://github.com/ekosboard/firmware/blob/main/src/components/EPD/driver/epd_GDEY075T7.c)
This document describes the current working state of the UC8179 E-Paper driver as implemented in `components/EPD/epd.cpp`.
## Panel Info
- **Controller:** UC8179
- **Panel:** GDEY075T7 (Good Display 7.5" B/W, 800×480)
- **Platform:** ESP-IDF (native SPI)
- **Grayscale:** 4-level support present but marked as "NOT TESTED"
- **Controller:** UC8179 (Good Display)
- **Panel:** GDEY075T7 (7.5" B/W, 800×480)
- **Platform:** ESP-IDF (Native SPI2 Host)
- **Status:** **Fully Operational** (B/W and 4-Level Grayscale)
## Hardware Interface
### BUSY Pin Polarity
- **Logic:** LOW = Busy, HIGH = Idle
- **Wait loop:** `while (gpio_get_level(BUSY) == 0) { vTaskDelay(5); }`
### SPI Configuration
- **Host:** `SPI2_HOST`
- **Clock:** `SPI_FREQUENCY` (2MHz typically for EPD)
- **Mode:** SPI Mode 0
- **Transfer Size:** Chunked into 4096-byte buffers to avoid DMA limits and task watchdogs.
## Key Implementation Details
### BUSY Pin Polarity
- **Reference driver:** HIGH = Busy, LOW = Idle
- **⚠️ Our board is INVERTED:** LOW = Busy, HIGH = Idle
- Wait loop polls `gpio_get_level(BUSY) == 0` to detect idle (reference)
- Our code uses `== 0` to wait while busy (opposite meaning, same code pattern)
### Data Polarity & VCOM (0x50)
We use `0x29` for VCOM and Data Interval:
- **VBD:** `00` (Floating/Black border?)
- **N2OCP:** `1` (Auto-copy NEW data to OLD data after refresh)
- **DDX:** `01` (Data Polarity: 0=Black, 1=White)
- **Note:** In our 4-gray unpacking, we send `~output_byte`, effectively inverting the logic to match the panel's expectation for the LUTs used by the UC8179.
### Clear Screen (White)
- Writes `0xFF` to **both** old (0x10) and new (0x13) data layers
- `0xFF` = White, `0x00` = Black
### Refresh Management
The driver tracks refresh history to prevent ghosting or panel damage:
- **Full Refresh:** Required every 5 fast refreshes or after 24 hours.
- **Fast Refresh (B/W):** Optimized waveforms via `0xE5` -> `0x5A`.
- **4-Gray Refresh:** Optimized waveforms via `0xE5` -> `0x5F`.
### Display Image
- Writes `0x00` to old data layer (0x10) — assumes previous state was black
- Writes actual image data to new data layer (0x13)
## Grayscale Mapping (4-Level)
The input is a packed 2bpp bitmap (4 pixels per byte). We unpack this into two sequential data layers: **Old (0x10)** and **New (0x13)**.
| Gray Level | Input Bits (2bpp) | Old Layer (0x10) | New Layer (0x13) | Final Value (Inverted) |
| :--- | :--- | :--- | :--- | :--- |
| **White** | `11` | 1 | 1 | `00` (Low) |
| **Gray 1** | `10` | 0 | 1 | `10` |
| **Gray 2** | `01` | 1 | 0 | `01` |
| **Black** | `00` | 0 | 0 | `11` (High) |
*Note: The hardware logic for 4-gray on UC8179 drives the pixels based on the difference between the Old and New layers over multiple sub-frames.*
## Driver State Machine
### Initialization (Full)
1. **Hardware Reset:** RST Low (10ms), RST High (10ms).
2. **Power Setting (0x01):** `0x07, 0x07, 0x3f, 0x3f`.
3. **Booster Soft Start (0x06):** `0x17, 0x17, 0x28, 0x17`.
4. **Power On (0x04):** Wait 100ms + Busy Idle.
5. **Panel Setting (0x00):** `0x1F` (800x480, KW Mode).
6. **Resolution (0x61):** `800×480`.
7. **VCOM (0x50):** `0x29, 0x07`.
### Fast Mode Adjustments
- **Booster (0x06):** `0x27, 0x27, 0x18, 0x17` (Stronger drive for fast transitions).
- **Fast Mode Enable (0xE0):** `0x02`.
- **Timing (0xE5):** `0x5A` (B/W) or `0x5F` (4-Gray).
### Sleep Sequence
1. `0x50` with `0xF7` — VCOM and data interval setting before sleep
2. `0x02` — Power Off
3. Wait for BUSY idle
4. `0x07` + `0xA5` — Deep Sleep
### Init Sequence (Full Refresh)
1. Hardware reset (RST low 10ms, high 10ms)
2. `0x01` — Power Setting: VGH=20V, VGL=-20V, VDH=15V, VDL=-15V, VDHR=4.2V
3. `0x06` — Booster Soft Start: 0x17, 0x17, 0x28, 0x17
4. `0x04` — Power On + 100ms delay + wait busy
5. `0x00` — Panel Setting: `0x1F` (KW B/W mode)
6. `0x61` — Resolution: 800×480
7. `0x15` — DUSPI disabled
8. `0x50` — VCOM: 0x10, 0x07
9. `0x60` — TCON: 0x22
10. `0xE3` — PWS: 0x22
### Fast Refresh
- `0xE0``0x02` (enable fast mode)
- `0xE5``0x5A` (fast refresh timing)
### Partial Update
- Uses `0x91` (partial in) / `0x92` (partial out) + `0x90` (resolution setting)
- Writes `~data` (inverted) to old layer to force transitions
- Sets `0x50``0x21` (N2OCP disabled) for partial mode
### 4-Level Grayscale
- Requires different booster settings: `0x27, 0x27, 0x18, 0x17`
- `0xE5``0x5F` for grayscale timing
- Data encoding: 2 bits per pixel (0xC0=white, 0x00=black, 0x80=gray1, 0x40=gray2)
- Old layer and new layer encode different bit planes, both inverted (`~temp3`)
1. **VCOM pre-sleep (0x50):** `0xF7`.
2. **Power Off (0x02):** Wait for Busy Idle.
3. **Deep Sleep (0x07):** `0xA5` (Check code).