ESP32-WROVER + ILI9341: 70% "RuntimeError: Not enough DMA-able memory to allocate display buffer", 30% error-free white screen


ESP32-WROVER with 4MB SPIRAM (TTGO T-Koala) + ILI9341

I’ve looked at the other threads on this subject but no luck following the advice so far.

Following the docs, I built lv_micropython with IDF 4.4.4. I updated the submodules before building.

I then run the following:

import lvgl as lv
from ili9XXX import ili9341
import espidf as esp

disp = ili9341(mhz=10,miso=12, mosi=13, clk=14, cs=4, dc=27, rst=26, spihost=esp.HSPI_HOST)

scr = lv.obj()
btn = lv.btn(scr)
btn.align_to(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text("Hello World!")

About 70% of the time, I get
RuntimeError: Not enough DMA-able memory to allocate display buffer
The rest of the time I get

Double buffer
ILI9341 initialization completed
Enable backlight

In the latter case, the display stays white.

There is nothing different between the two cases - it’s just random. I’m pasting the lines into the serial console manually so perhaps timing variations determine the outcome.

gc.mem_free() reports >4MB free.

Any ideas?

This reports total memory, including SPI-RAM which is not DMAable.

The display driver uses DMA and requires DMAable memory as large as the display buffers.
You can decrease the size of the display buffers by setting the factor argument in ili9341 constructor.
(try 2,4,8,16,32,64, choose the lowest value that works for you.

Setting factor to 8 means that the buffer will be 1/8 of the display and the entire display will be updated in 8 steps. So lower factor values mean faster and smoother display updates, higher values mean lower DMAable memory requirement.

Thanks amirgon.

Setting factor=16 does mostly get rid of the memory error (though I do still get them sometimes.)

Also, I sometimes get

RuntimeError: Failed initializing SPI bus

It seems the driver is unstable.

I have never managed to draw anything to the screen. Can you check my test code above? It is taken from the docs.

I have checked the hardware. The pins are all valid outputs, there is nothing else connected to them, the wiring is correct, and the display is definitely an ILI9341. I have had it working with micro-gui on the same hardware, but I want the more powerful LVGL.

I would very much appreciate any suggestions you may have,


Well, I’m not sure what the problem is, but last time I checked it worked fine on my hardware.

Anyway, you can also try the pure Python driver.
That one does not use DMA and is a pure Python generic driver, so it’s obviously slower, but it worked fine last time I checked.

gc.mem_free reports all available memory, not just DMA memory. if you have an esp32 and not an esp32s3 then you only have a small amount of memory that is DMA memory. When you initialize the display driver add the argument factor=x where x is a multiple of 4.The absolute first thing that needs to be done is that display needs to be initialized.

It’s because of the additional memory use from the repl. If you put the code into a script called and upload that script to the ESP32 you will have no issues with the memory allocation portion so long as you set the driver up first thing.

Thanks guys. I’ll try adding a With factor=16 it appears well behaved even from the REPL, so I guess there’s another problem somewhere.

I’ll capture some oscilloscope traces to see if that sheds some light on it.

I often got this error when I tried to initialize the display again, without hard resetting the ESP32. So I’m my case it worked to hard reset/power off and on the ESP32.