Esp32-p4 10.1in MIPI DSI Display Mandelbrot/Julia
Posted: Mon Sep 21, 2026 10:56 am
I have an esp32-p4 and for a while I've attempted to get the MIPI DSI display (interface) working with the 10.1in display. Recently I finally cracked it 
I used the esp32-s3 fcdx file - I've just noticed that Martin has posted a guide to the fcdx file - so I might attempt a real 'p4' one - but for now I just increased the maximum clock speed to 360MHz in the s3 file (if you are lucky you might have a board which supports 400MHz?) I then set 360MHz as the clock speed in build -> options.
Initially I attempted to draw the Graves-Stokes equation - but it was very slow (hours). So I reverted to a Mandelbrot set and then added Julia sets... Note that the p4 has a FPU - so I use floating point rather than fixed point integer (as in the s3 version)
Create the program - attempt to compile which will fail then from a command line (framework_dir/export - I used v5.5 of the espressif tools) - cd to the program directory (or 'build' directory) and do:
Note that lvgl 9.6.0 is now available - and this should work but the configuration settings are different.
In serial flasher config - set flash size to 16MB (or to suit your board)
In compiler options - set optimisation level to 'optimise for performace'
In component config:
In esp PSRAM - turn on support for external PSRAM (and set speed to 80MHz)
In ESP System Settings - I increased the stack size to 65536
In LVGL - depending on version - select use minimum config (not in 9.6) and
In Memory and Standard Library -> select use malloc
Operating system -> Select FreeRTOS
sprintf functions -> change to C
In Text & Font settings -> Built in Fonts -> add 30 point and increase the default font size (I used 18 point)
In Examples -> disable build
In Demos -> Disable build
edit (notepad) sdkconfig and set
CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y
cd main
mkdir include
notepad CmakeLists.txt
add include to the INCLUDE_DIRS
Add the attached code.h and code.c files to the include directory.
Then recompile (I used idf.py -p COMn -b 921600 flash - but you can do so from within Flowcode)
The user interface needs a little work - but you can drag an area to magnify, or tap to change to Julia. (the dropdown - which should be full width - can also be used to toggle)
The hard part was avoiding the WDT issues - I use esp_wdt_task_deinit() to remove the WDT on the render task...
I pulled the display code from the WaveShare demo - which draws coloured bars - then alll that is needed for LVGL is a callback to copy data to the display. Here I set the clock to 20MHz - at 80MHz I think the display is working at 60Hz refresh (I got issues here - so reduced the speed - but in other samples managed to get 80MHz working - see code.c)
The LVGL code is a mix of 'design tool' and hand-coded. My main aim was to test the display (rendering is just a retro bonus) - so didn't worry too much about converting to FC - I might play with getting the display manager component to work.
You can zoom by dragging a rectangle around the area of interest - or tap to calculate the Julia set at a point (when in Mandelbrot mode)
Martin
I used the esp32-s3 fcdx file - I've just noticed that Martin has posted a guide to the fcdx file - so I might attempt a real 'p4' one - but for now I just increased the maximum clock speed to 360MHz in the s3 file (if you are lucky you might have a board which supports 400MHz?) I then set 360MHz as the clock speed in build -> options.
Initially I attempted to draw the Graves-Stokes equation - but it was very slow (hours). So I reverted to a Mandelbrot set and then added Julia sets... Note that the p4 has a FPU - so I use floating point rather than fixed point integer (as in the s3 version)
Create the program - attempt to compile which will fail then from a command line (framework_dir/export - I used v5.5 of the espressif tools) - cd to the program directory (or 'build' directory) and do:
Code: Select all
idf.py set-target esp32p4
idf.py add-dependency "waveshare/esp_lcd_jd9365_10_1^2.0.0"
idf.py add-dependency "espressif/esp_lcd_touch_gt911^1.2.1"
idf.py add-dependency "lvgl/lvgl^9.5.0~1"
Note that lvgl 9.6.0 is now available - and this should work but the configuration settings are different.
Code: Select all
idf.py menuconfigIn compiler options - set optimisation level to 'optimise for performace'
In component config:
In esp PSRAM - turn on support for external PSRAM (and set speed to 80MHz)
In ESP System Settings - I increased the stack size to 65536
In LVGL - depending on version - select use minimum config (not in 9.6) and
In Memory and Standard Library -> select use malloc
Operating system -> Select FreeRTOS
sprintf functions -> change to C
In Text & Font settings -> Built in Fonts -> add 30 point and increase the default font size (I used 18 point)
In Examples -> disable build
In Demos -> Disable build
edit (notepad) sdkconfig and set
CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y
cd main
mkdir include
notepad CmakeLists.txt
add include to the INCLUDE_DIRS
Code: Select all
idf_component_register(SRCS "esp-project.c"
INCLUDE_DIRS "" "include")Then recompile (I used idf.py -p COMn -b 921600 flash - but you can do so from within Flowcode)
The user interface needs a little work - but you can drag an area to magnify, or tap to change to Julia. (the dropdown - which should be full width - can also be used to toggle)
The hard part was avoiding the WDT issues - I use esp_wdt_task_deinit() to remove the WDT on the render task...
I pulled the display code from the WaveShare demo - which draws coloured bars - then alll that is needed for LVGL is a callback to copy data to the display. Here I set the clock to 20MHz - at 80MHz I think the display is working at 60Hz refresh (I got issues here - so reduced the speed - but in other samples managed to get 80MHz working - see code.c)
The LVGL code is a mix of 'design tool' and hand-coded. My main aim was to test the display (rendering is just a retro bonus) - so didn't worry too much about converting to FC - I might play with getting the display manager component to work.
You can zoom by dragging a rectangle around the area of interest - or tap to calculate the Julia set at a point (when in Mandelbrot mode)
Martin