Inkplate 5v2 partial refresh fails (I2S DMA timeout — line not sent)

I’m using the Inkplate5v2 with the Soldered Inkplate ESPHome custom component (https://github.com/SolderedElectronics/Soldered-Inkplate-ESPHome/tree/main).

I noticed my custom .yaml code stopped working after 1-2 hours or so. It was a lot of “ghosting” on the screen and when i opened the logs it was full of errors saying “[E][inkplate:588]: I2S DMA timeout — line not sent” many time per second.

I first assumed this had something to do with my .yaml but i later did a test with the example code on github “inkplate5v2_partial.yaml” and got the same issue. I let the code run with the log window open in ESPHome Builder and it also failed after 1-2 hours with the same spamming error message.

...
[17:50:14.461][E][inkplate:588]: I2S DMA timeout — line not sent
[17:50:14.461][E][inkplate:588]: I2S DMA timeout — line not sent
[17:50:14.461][E][inkplate:588]: I2S DMA timeout — line not sent
[17:50:14.461][E][inkplate:588]: I2S DMA timeout — line not sent
[17:50:14.463][E][inkplate:588]: I2S DMA timeout — line not sent
...

With the occasional

[17:50:14.356][W][component:421]: display took a long time for an operation (3986 ms), max is 2550 ms
[17:50:14.445][W][inkplate:148]: display_partial() skipped — busy (state 2)

I ran it twice, and both tests failed after roughly 1–2 hours with the same I2S DMA timeout errors.

Here is the exact code i used for reference:

esphome:
  name: inkplate5v2-partial
  friendly_name: Inkplate 5 V2 Partial
  on_boot:
    priority: -100
    then:
      - component.update: my_inkplate5

esp32:
  framework:
    type: esp-idf
  variant: esp32

external_components:
  - source:
      type: git
      url: https://github.com/SolderedElectronics/Soldered-Inkplate-ESPHome.git
      ref: main

psram:
  mode: quad
  speed: 40MHz

# ============================================================
# WIFI / API / OTA
# ============================================================

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

api:
  encryption:
    key: !secret inkplate5v2__encryption_key

ota:
  - platform: esphome
    id: ota_inkplate5v2
  
logger:
  baud_rate: 115200
  hardware_uart: UART0

i2c:
  id: i2c_bus
  sda: GPIO21
  scl: GPIO22
  frequency: 100000

pca6416a:
  id: inkplate_pcal
  i2c_id: i2c_bus
  address: 0x20

display:
  platform: inkplate
  model: inkplate5v2
  id: my_inkplate5
  i2c_id: i2c_bus
  address: 0x48
  pca6416a_id: inkplate_pcal
  update_interval: never
  lambda: |-
    it.fill(COLOR_OFF);
    it.filled_rectangle(0, 0, 1280, 720, COLOR_ON);
    it.filled_rectangle(10, 10, 1260, 700, COLOR_OFF);

interval:
  - interval: 10s
    then:
      - lambda: |-
          static bool state = false;
          state = !state;
          id(my_inkplate5).filled_rectangle(400, 260, 400, 200,
              state ? COLOR_ON : COLOR_OFF);
          id(my_inkplate5).display_partial();


I also did a test (~8h) without any partial refreshes in the code that did not fail.

Has anyone seen this issue before? Could it be related to the partial-refresh implementation?

Inkplate 5v2 and Inkplate 10 boards have a known issue with the onboard TPS chip when using partial updates for extended periods of time. The only way to fix it is to power down the board and power it on again.
You could either do that or use full refresh updates.

Thank you for your reply! So in other words you can’t use the partial refresh with the 5v2 board if you plan to use it longer than an hour or so? I must say I really like the board so far, but that’s a bit disappointing.

An update from my side. I did some digging and found this pull request in ESPhome [Inkplate] Refactor component and add support for all B&W Inkplates by franFodor · Pull Request #17179 · esphome/esphome · GitHub .
I thought the review comment from Copilot sounded similar to what I had found so I tried implementing the change copilot suggested: [Inkplate] Refactor component and add support for all B&W Inkplates by franFodor · Pull Request #17179 · esphome/esphome · GitHub .
Replaced:
uint32_t deadline = esp_timer_get_time() + 5000; // 5 ms max per line

with:
int64_t deadline = esp_timer_get_time() + 5000; // 5 ms max per line

I have no idea if there are other issues related to the TPS chip on the board but the same example code has been running for 8+ hours after the fix (still running), and that good enough for me!

You got partial update running for 8+ hours after that fix?

8 hours and 23 minutes now (still going)!

Another update.
After about 12 hours (not exactly sure when it first started) i got this

[16:27:25.461][W][inkplate:253]: TPS65186 power-good timeout (pg=0xA0, missing=0x5A)
[16:27:25.480][D][inkplate:584]: state 1 → 2
[16:27:25.949][D][inkplate:584]: state 2 → 3
[16:27:26.291][D][inkplate:584]: state 3 → 0
[16:27:45.144][D][inkplate:584]: state 0 → 1
[16:27:45.465][W][inkplate:253]: TPS65186 power-good timeout (pg=0xA0, missing=0x5A)
[16:27:45.479][D][inkplate:584]: state 1 → 2
[16:27:45.947][D][inkplate:584]: state 2 → 3
[16:27:46.289][D][inkplate:584]: state 3 → 0

And the display stopped updating.
I’m guessing this is the TPS chip issue you where referring to @fran?

Yeah that must be it, unfortunately that is hardware bound and there is not much software side we can do. The only way to fix is it to replug the board.