Public Access
The datasheet (docs/datasheet, Planar 020-0354-00A) is now stated as the source of truth. Two-bit mode is PS1 jumper 2 (DCONFIG) removed (Table 3), not a generic "mode jumper". The README timing table now lists the Table 5/6 limits beside our values, and the notes add T1-T8, the 8 ns setup/hold from Figure 4 and the input levels from Table 4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
63 lines
3.0 KiB
Markdown
63 lines
3.0 KiB
Markdown
# Notes
|
|
|
|
- Plan: https://claude.ai/code/artifact/3b9eda11-a87e-4eea-bbb9-e6454e558991
|
|
- Datasheet: [datasheet/EL512.256-H3 FRB.pdf](datasheet/EL512.256-H3%20FRB.pdf)
|
|
|
|
## Approach
|
|
|
|
I2S0 in 8-bit parallel (LCD) mode with a circular DMA descriptor chain. Each DMA byte
|
|
is one VCLK period:
|
|
|
|
| Bit | Signal |
|
|
|-----|--------|
|
|
| 0 | VID (even columns) |
|
|
| 1 | TVID (odd columns) |
|
|
| 2 | HS |
|
|
| 3 | VS |
|
|
|
|
The I2S0 BCK output drives VCLK. ENABLE (GPIO 25) and _LOWPWR (GPIO 26) are plain GPIO.
|
|
|
|
I2S0 setup (`EL512Panel::startI2S()`), following bitluni's ESP32Lib 8-bit mode:
|
|
|
|
- Clock: PLL_D2_CLK 160 MHz / `clkm_div_num` 32, `tx_bck_div_num` 1 -> 5 MHz, one byte
|
|
per BCK period.
|
|
- `lcd_en`, `lcd_tx_wrx2_en`, `tx_bits_mod` 8, `tx_fifo_mod` 1, `tx_chan_mod` 1,
|
|
`tx_right_first`. With this setup each 32-bit DMA word goes out as bytes 2, 3, 0, 1,
|
|
so `encodeRow()` stores clock c at `c ^ 2`.
|
|
- Stream bits 0..3 -> `I2S0O_DATA_OUT16_IDX` + n; BCK -> VCLK (`INVERT_VCLK` flips it).
|
|
- 18 descriptors of up to 15 lines (4080 bytes) each, looped; `eof` set once per frame.
|
|
|
|
## From the datasheet
|
|
|
|
The datasheet is the source of truth for everything in this section and wins over any
|
|
other doc, comment or the plan.
|
|
|
|
- Two-bit parallel mode is selected by removing jumper 2 (DCONFIG) of pin strip PS1
|
|
(Table 3; factory default has jumpers 1 and 2 fitted). Even columns on VID, odd
|
|
columns on TVID, numbered from the left as seen by the viewer; 256 VCLKs per row.
|
|
- VCLK is active on the rising edge and should be kept running.
|
|
- HS envelopes the pixels of a row: the visible pixels are the last 512 (two-bit mode:
|
|
last 256 clocks) before HS falls. The number of VCLKs during HS high should be even.
|
|
- The topmost row is the first HS high time ending after the rising edge of VS. Only
|
|
the rising edge of VS is used; VS high/low time is at least 1 VCLK (T2).
|
|
- Table 5: front porch T1 >= 100 µs, HS setup to VS T4 >= 1 VCLK, HS hold from VS
|
|
T5 >= 3 µs, HS low T6 >= 4 VCLK, HS period T8 >= 50 µs, VS 70 Hz typ / 75 Hz max.
|
|
- Figure 4 / Table 6: VID, TVID, HS and VS need 8 ns setup and 8 ns hold around the
|
|
rising VCLK edge; VCLK period >= 33 ns (30 MHz max).
|
|
- Inputs are HCT compatible with pull-ups (Table 4: high >= 2 V, low <= 0.8 V,
|
|
abs. max Vcc1 + 0.5 V). ENABLE and _LOWPWR are on J2 and pulled high internally.
|
|
|
|
## Open items
|
|
|
|
- [x] Implement `EL512Panel::startI2S()` (I2S0 LCD mode, clock dividers for 5 MHz,
|
|
GPIO matrix routing, circular `lldesc_t` chain).
|
|
- [x] Handle the 8-bit LCD-mode byte-pair swap in `encodeRow()`.
|
|
- [ ] Check on a scope: VCLK is 5 MHz on GPIO 18, HS is 256 clocks high / 16 low
|
|
(54.4 us period), VS is one line high per 14.2 ms frame, data changes on the
|
|
falling VCLK edge, VS/HS setup and hold (T4/T5). Unconfirmed until then: the
|
|
DATA_OUT16 base and the `^ 2` byte order. HS edges sit on word boundaries, so a
|
|
wrong order does not show on HS; on the panel it shuffles pixels in groups of 8
|
|
(a 1-pixel line at x = 0 lands at x = 4).
|
|
- [ ] Tear-free updates (double buffer or swap at VS).
|
|
- [ ] Unit test for `encodeRow()`.
|