How to add driver (FT81x) from LV_PORT_ESP32 to LV_MICROPYTHON

Hello,
is there any way to add a specific display driver(in c) from LV_PORT_ESP32 to LV_MICROPYTHON (of course port ESP32)?

I’ve tried a lot and spent much time, but I think there are some steps that I don’t understand… Now I want to start all over again and hope for your support. - I want to do myself, but I need a common thread.

How is the rough procedure? Do you have some hints for me? Are there some tools?

Thank you :slightly_smiling_face:

https://github.com/lvgl/lv_port_esp32

https://github.com/lvgl/lv_micropython

There are two steps:

  • Make FT81x compile and link in lv_micropython esp32 port.
    You can either change esp32 Makefile to include the driver sources, or just copy them somewhere under lvgl/src/ directory.
  • Register FT81x_init and FT81x_flush as Micropython functions. The quickest way would be to include FT81x.h in lvgl.h or one of its included headers (such as lv_conf.h).
    That would make them available under the lvgl module.

How far did you get?

Thank you for your answer!

I have tried it with your hints. Here are my steps:

  • copied folders lv_port_esp32/components/lvgl
    and lv_port_esp32/components/lvgl_esp32_drivers
    in lv_micropython/lib/lv_bindings/lvgl

  • inserted #include "src/lvgl_esp32_drivers/lvgl_touch/FT81x.h"
    in lv_micropython/lib/lv_bindings/lvgl/lvgl.h

  • inserted #define CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X
    in lv_micropython/lib/lv_bindings/lvgl/src/lvgl_esp32_drivers/lvgl_helpers.h
    because “#error "No display controller selected"”

  • executed /lv_micropython/ports/esp32$ make

Result:

ParseError
LVGL-GEN build-GENERIC/lvgl/lv_mpy.c
Traceback (most recent call last):
  File "../../lib/lv_bindings/gen/gen_mpy.py", line 225, in <module>
    ast = parser.parse(s, filename='<none>')
  File "/home/jt/lv_micropython/lib/lv_bindings/gen/../pycparser/pycparser/c_parser.py", line 149, in parse
    return self.cparser.parse(
  File "/home/jt/lv_micropython/lib/lv_bindings/gen/../pycparser/pycparser/ply/yacc.py", line 331, in parse
    return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
  File "/home/jt/lv_micropython/lib/lv_bindings/gen/../pycparser/pycparser/ply/yacc.py", line 1199, in parseopt_notrack
    tok = call_errorfunc(self.errorfunc, errtoken, self)
  File "/home/jt/lv_micropython/lib/lv_bindings/gen/../pycparser/pycparser/ply/yacc.py", line 193, in call_errorfunc
    r = errorfunc(token)
  File "/home/jt/lv_micropython/lib/lv_bindings/gen/../pycparser/pycparser/c_parser.py", line 1844, in p_error
    self._parse_error(
  File "/home/jt/lv_micropython/lib/lv_bindings/gen/../pycparser/pycparser/plyparser.py", line 67, in _parse_error
    raise ParseError("%s: %s" % (coord, msg))
pycparser.plyparser.ParseError: ../../lib/lv_bindings/lvgl/src/lvgl_esp32_drivers/lvgl_tft/../lvgl_tft/disp_driver.h:69:45: before: *
make: *** [../../py/py.mk:47: build-GENERIC/lvgl/lv_mpy.c] Error 1
make: *** Deleting file 'build-GENERIC/lvgl/lv_mpy.c'

What do you mean? What cause this error?

Thanks for help!

The error suggests that one of your files has a syntax error in it or at least something the Python C parser can’t understand.

I don’t think you need to copy components/lvgl since lvgl already exists under lv_bindings.
Adding lvgl_esp32_drivers is supposed to be enough.

Did you notice that lv_bindings has its own lv_conf.h configuration file, which is different from lv_conf.h of lv_port_esp32?

You might need to create a new “lv_conf.h” which is a combination of both.
The lv_port_esp32 version depends on kconfig and probably configures your display driver parameters (such as SPI parameters).
The lv_bindings version contains some important definitions, specifically related to reusing Micropython Garbage Collector in LVGL.

There is actually a problem with including FT81x.h in lvgl.h.
FT81x.h itself already includes lvgl.h so it can’t be included from lvgl.h.
This is probably the source of the error you are seeing:

    raise ParseError("%s: %s" % (coord, msg))
pycparser.plyparser.ParseError: ../../lib/lv_bindings/lvgl/src/lvgl_esp32_drivers/lvgl_tft/../lvgl_tft/disp_driver.h:69:45: before: *

It complains about a type that is defined in lvgl, but still undefined at this point in code after preprocessing.

To work around this, the simplest solution is not to include FT81x.h in lvgl.h.
Instead, you can add some extern to the functions you need.

Something like that:

extern void disp_driver_init(void);
extern void disp_driver_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);

You can add this to lv_conf.h if you want, instead of lvgl.h.

One more thing worth noting:
The steps I’m describing here are the “quick and dirty” way to achieve what you want, but is not the regular way we develop drivers for Micropython.
One of the disadvantages of this “quick and dirty” method is that if you want to change some display parameters (such as the display interface pins, SPI configuration etc.) you would have to rebuild the firmware.

The “right” way to develop a Micropython driver, which requires a bit more effort, is to change the driver such that it receives all parameters on runtime. That allows the same firmware use the driver in different configurations, and provide the configuration in the Micropython script. This is how existing LVGL micropython drivers (such as ili9XXX) are designed.