lvgl-micropython / lvgl_micropython

LVGL module for MicroPython
MIT License
62 stars 19 forks source link

how to make firmware #6

Closed kk8900 closed 6 months ago

kk8900 commented 6 months ago

Compilation environment: ESP-IDF V5.0.4 Micropython V1.22 Use the following command? make USER_C_MODULES=~/esp/micropython/examples/usercmodule/lvgl_micropython/micropython.cmake

kdschlosser commented 6 months ago

you need to use this command.

If you are compiling for say an esp32-s3 with 8mb of octal spi ram.

python3 make.py esp32 mpy_cross submodules clean BOARD=ESP32_GENERIC_S3 VARAINT=SPIRAM_OCT

That will take care of downloading everything that is needed in order to get it to compile. It will handle collecting ESP-IDF, LVGLv9.0, MicroPython 1.22 and any other libraries/modules that are used to build.

The only thing it doesn't handle is installing gcc,

As of now compiling has only been tested using Linux/WSL. Compiling on Windows is a pain to get working right and I have not messed with it and I don't know if I will. I may not because of WSL being available for people running Windows 10 or higher.

I do want to note if you pass any additional arguments like -deploy or setting the port in which to deploy to those will be passed to make and will work like it did before when using make directly.

When you compile is should also be faster than it has been in the past. How fast all depends on the number of cores/threads your CPU has. It compiles in about 15 seconds on my machine. (32 logical processors)

kk8900 commented 6 months ago

you need to use this command.

If you are compiling for say an esp32-s3 with 8mb of octal spi ram.

python3 make.py esp32 mpy_cross submodules clean BOARD=ESP32_GENERIC_S3 VARAINT=SPIRAM_OCT

That will take care of downloading everything that is needed in order to get it to compile. It will handle collecting ESP-IDF, LVGLv9.0, MicroPython 1.22 and any other libraries/modules that are used to build.

The only thing it doesn't handle is installing gcc,

As of now compiling has only been tested using Linux/WSL. Compiling on Windows is a pain to get working right and I have not messed with it and I don't know if I will. I may not because of WSL being available for people running Windows 10 or higher.

I do want to note if you pass any additional arguments like -deploy or setting the port in which to deploy to those will be passed to make and will work like it did before when using make directly.

When you compile is should also be faster than it has been in the past. How fast all depends on the number of cores/threads your CPU has. It compiles in about 15 seconds on my machine. (32 logical processors)

Thank you for your guidance.But I have the following problems when make firmware. keyboard_framework.py doesn't exist. How to solve it?

Traceback (most recent call last): File "/home/le/lvgl/lvgl_micropython/make.py", line 139, in mod.build_manifest(target, SCRIPT_DIR, frozen_manifest) File "/home/le/lvgl/lvgl_micropython/builder/esp32.py", line 252, in build_manifest generate_manifest(script_dir, manifest_path, frozen_manifest) File "/home/le/lvgl/lvgl_micropython/builder/init.py", line 57, in generate_manifest raise RuntimeError(f'File not found "{file}"') RuntimeError: File not found "/home/le/lvgl/lvgl_micropython/driver/frozen/indev/keyboard_framework.py"

kdschlosser commented 6 months ago

I will fix that. I will have it done by the end of today.

Bigmaxmafia commented 6 months ago

I will fix that. I will have it done by the end of today.

No solution?

straga commented 6 months ago

I am tested with master micropythin and esp-idf v5.1.2 now work C spi_bus, if add heap_caps and use python spi_bus from https://github.com/bdbarnett/mpdisplay work.

Try by self for buidl: for testing.

micropythonv and esp-idf

mpy_cross and micropython configure as standart build and esp-idf

board for lvgl

## sdkconfig.base
    CONFIG_FREERTOS_INTERRUPT_BACKTRACE=n
    CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=4096

## manifest.py
    Not add yey, copy later direct to board

## mpconfigport.h
    define MICROPY_PY_MACHINE_I2S (0)

submodules

cd to dir lvgl_micropython:
    git submodule update --init lib/pycparser
    git submodule update --init lib/lvgl

heap_caps if needed

## in ext_mod rename to heap_caps
add to ext_mod/micropython.cmake
    include(${CMAKE_CURRENT_LIST_DIR}/heap_caps/micropython.cmake)

v build create

lvgl_micropython/build -> crate file lvgl_header.h

#include "{Absolute path from root}/lvgl_micropython/lib/lvgl/lvgl.h"
#include "{Absolute path from root}/lvgl_micropython/lib/lvgl/src/lvgl_private.h"

Build from standart micropython.

make -j 9 LV_PORT=esp32 LV_CFLAGS="-DLV_KCONFIG_IGNORE=1" BOARD=STRAGA_CORE_SPIRAM USER_C_MODULES=~/Documents/dev_iot/opt/upy/cmodules/lvgl/lvgl_micropython/micropython.cmake

kdschlosser commented 6 months ago

I am trying to remove the need for having the heap_caps module all together. the allocation of the frame buffers would be handled by the display drivers themselves. The reasoning for this is the rgb bus which is actually a panel driver and not really a bus driver.

straga commented 6 months ago

I know, but now after init display over C SPI driver, board reboot. That my side only.

martyy665 commented 6 months ago

Isn't the reboot similar to issue #5 (e.g., a similar stack dump)?

straga commented 6 months ago

Yep. same.

cheops commented 6 months ago

small typo in VARIANT keyword and has been changed to BOARD_VARIANT``

python3 make.py esp32 mpy_cross submodules clean BOARD=ESP32_GENERIC_S3 VARAINT=SPIRAM_OCT
python3 make.py esp32 mpy_cross submodules clean BOARD=ESP32_GENERIC_S3 BOARD_VARIANT=SPIRAM_OCT
kk8900 commented 6 months ago

small typo in VARIANT keyword and has been changed to BOARD_VARIANT``

python3 make.py esp32 mpy_cross submodules clean BOARD=ESP32_GENERIC_S3 VARAINT=SPIRAM_OCT
python3 make.py esp32 mpy_cross submodules clean BOARD=ESP32_GENERIC_S3 BOARD_VARIANT=SPIRAM_OCT

Can this command make firmware ok?

kdschlosser commented 6 months ago

While the firmware does compile for some strange reason it needs to be run a second time to be successful. I am not sure where the issue is stemming from with that.

The proper build command is going to be

python3 make.py esp32 mpy_cross submodules clean BOARD=ESP32_GENERIC_S3 BOARD_VARIANT=SPIRAM_OCT

There is a glitch somewhere I have yet to locate and it causes you to have to compile it a second time in order for it to work. For some reason the submodules for the ESP32 port in micropython never get added. Running the command a second time will install the rest of the submodules that are needed.

that needs to be used only for the first time compiling. After that you can use

python3 make.py esp32 clean BOARD=ESP32_GENERIC_S3 BOARD_VARIANT=SPIRAM_OCT

I am also having an issue with reboots when the bus drivers have their init method called. I know this issue exists for the RGB bus drivers, I am not sure it is an issue with the I80 or the SPI driver as well. I did locate a code issue with the RGB driver that would cause this kind of a problem. I have not yet tested the change to see if it is fixed and I will be doing that at some point within the next day or so.

The most recent changes that were made to the bus drivers was due to the API not being uniform across the drivers. I want the user to only need to change small amounts of code in order to change displays. The way LVGL v9.0 has been coded changing displays is able to be done at runtime and not compile time. This allows for faster development. I have been working on SDL drivers that follow the same API as the bus drivers so a user can easily develop on a desktop and upload the source files for the code they have written and they would be off and running.

The goal is to have the API work like this.

import sys
import lvgl as lv
import lcd_bus

if sys.platform == 'linux':
    data_bus = lcd_bus.SDLBUS(
        lcd_bus.SDLBus.WINDOW_BORDERLESS | lcd_bus.SDLBus.WINDOW_ALWAYS_ON_TOP
    )

    import sdl_display

    display = sdl_display.SDL(
        data_bus=data_bus,
        display_width=480,
        display_height=320,
    )

else:
    data_bus = lcd_bus.SPIBus(
        dc=2,
        host=1,
        sclk=5,
        freq=80000000,
        mosi=13,
        miso=12,
        cs=-1
    )

    import st7796

    display = st7796.ST7796(
        data_bus=data_bus,
        display_width=480,
        display_height=320,
        reset_pin=23,
        power_pin=24,
        backlight_pin=26,
        color_space=lv.COLOR_FORMAT.RGB565,
        rgb565_byte_swap=True
    )

The same code used when developing on the desktop can simply be uploaded to an MCU and it will run.

The trick here is to allow customization of the size of the frame buffers if the user wants to be able to do that.

import sys
import lvgl as lv
import lcd_bus
from micropython import const

_WIDTH = const(480)
_HEIGHT = const(320)
_BUFFER_SIZE = const(480 * 320 * 2)

if sys.platform == 'linux':
    data_bus = lcd_bus.SDLBUS(
        lcd_bus.SDLBus.WINDOW_BORDERLESS | lcd_bus.SDLBus.WINDOW_ALWAYS_ON_TOP
    )
else:
    data_bus = lcd_bus.SPIBus(
        dc=2,
        host=1,
        sclk=5,
        freq=80000000,
        mosi=13,
        miso=12,
        cs=-1
    )

buf1 = bus.allocate_buffer(_BUFFER_SIZE, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_DMA)
buf2 = bus.allocate_buffer(_BUFFER_SIZE, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_DMA)

if sys.platform == 'linux':
    import sdl_display

    display = sdl_display.SDL(
        data_bus=data_bus,
        display_width=_WIDTH,
        display_height=_HEIGHT,
        frame_buffer1=buf1,
        frame_buffer2=buf2,
    )

else:
    import st7796

    display = st7796.ST7796(
        data_bus=data_bus,
        display_width=_WIDTH,
        display_height=_HEIGHT,
        frame_buffer1=buf1,
        frame_buffer2=buf2,
        reset_pin=23,
        power_pin=24,
        backlight_pin=26,
        color_space=lv.COLOR_FORMAT.RGB565,
        rgb565_byte_swap=True
    )

The bump in handling this is the RGB bus driver. This is because the RGB driver is not a bus driver in the ESPIDF. It is a panel driver. I am not sure as to why it was made this way but it is causing me some grief with how to deal with the returned values from allocate_buffer. Doing this with the other drivers is not an issue because the bus driver doesn't create the buffers where as the RGB driver does and it only does it once the driver has been initialized which gets done in the python display driver framework.

kdschlosser commented 6 months ago

I want the user to be able to hot plug the displays if they wanted to without having to reboot or needing to upload code.

kk8900 commented 6 months ago

I tried to drive the display screen of ili9341, but it failed. I couldn't import libraries such as espidf and ili9XXX. How to solve it?

from espidf import VSPI_HOST
from ili9XXX import ili9341
from xpt2046 import xpt2046
kdschlosser commented 6 months ago

This is NOT the same thing as lv_micropython. How it works is completely different.

You need to upload the driver from the drivers/display folder or you need to bake it into the firmware by using the "DISPLAY={driver_name}" argument when compiling. Replacing {driver_name} with the file name you want to compile into the firmware (without the ".py")..

Once you have the driver placed onto the MCU then you need to initialize the data bus. The data bus is the connection type you are using to connect the display to the MCU.

most displays connect using SPI, so this would be how to go about it. You are going to need to set the pin numbers to whatever they need to be set to for your display. If there is no connection for any og the things then simply remove it

import lcd_bus
import ili9341
import lvgl as lv

bus = lcd_bus.SPIBus(
    dc=5,
    sclk=10,
    mosi=12,
    miso13,
    cs=14
)

display = ili9341.ILI9341(
    data_bus=bus,
    display_width=320,
    display_height=480,
    reset_pin=15,
    power_pin=16,
    backlight_pin=17,
    color_space=lv.COLOR_FORMAT.RGB565,
    rgb565_byte_swap=True
)

display.set_power(1)
display.set_rotation(lv.DISPLAY_ROTATION._90)
display.init()
display.set_backlight(100)
hathi59 commented 5 months ago

Hi, I tried like described above. But the driver is demanding a huge amount of memory. MPY: soft reboot Traceback (most recent call last): File "", line 32, in File "display_driver_framework.py", line 185, in init MemoryError: memory allocation failed, allocating 1073554936 bytes

The displaydriver is ili9341 with a 320x240 display. What could be wrong here? The Init sequence is: import lcd_bus import ili9341 import lvgl as lv from micropython import const

bus = lcd_bus.SPIBus( host=1, dc=2, sclk=14, mosi=13, miso=12, freq = const(40000000), cs=15 )

display = ili9341.ILI9341( data_bus=bus, display_width=320, display_height=240,

#frame_buffer1 = b,
#frame_buffer2 = b1,
#reset_pin=15,
#power_pin=16,
backlight_pin=21,
color_space=lv.COLOR_FORMAT.RGB565,
rgb565_byte_swap=True

) lv.init() display.set_power(1) display.set_rotation(lv.DISPLAY_ROTATION._90) display.init() display.clear()

display.set_backlight(1)

hathi59 commented 5 months ago

I forgot to tell: I built a firmware with color_depth = 16 on ESP32 Port for a simple ESP32- WROOM

kdschlosser commented 5 months ago
File "display_driver_framework.py", line 185, in init
MemoryError: memory allocation failed, allocating 1073554936 bytes

Not at line 185.. you are probably using an old version. I suggest cloning the repo again and compiling using the latest code.

kdschlosser commented 5 months ago

and leave the color depth at 32

hathi59 commented 5 months ago

Sorry, it didn't succeed. After initialization and starting REPL on Thonny there was a reboot after typing:

import lvgl as lv b = lv.obj() Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.

Core 1 register dump: PC : 0x4018a851 PS : 0x00060030 A0 : 0x8018aa8b A1 : 0x3ffd0340
A2 : 0x00000000 A3 : 0x00038000 A4 : 0x00000001 A5 : 0x3ffdf3b0
A6 : 0x3ffc45d4 A7 : 0x00000985 A8 : 0x00000000 A9 : 0x3ffd0320
A10 : 0x3ffd18f0 A11 : 0x00000000 A12 : 0x00000040 A13 : 0x3ffd4210
A14 : 0x00000000 A15 : 0x00000004 SAR : 0x0000001e EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000010 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0x00000000

Backtrace: 0x4018a84e:0x3ffd0340 0x4018aa88:0x3ffd0360 0x40158269:0x3ffd0380 0x401581c8:0x3ffd03b0 0x400fca88:0x3ffd03f0 0x400fb744:0x3ffd0430 0x400e3af2:0x3ffd0470 0x400d5705:0x3ffd04b0 0x40196f75:0x3ffd04f0 0x400d5ddd:0x3ffd0510 0x400e3b36:0x3ffd0560 0x40195a49:0x3ffd0590 0x40196f75:0x3ffd05b0 0x40197039:0x3ffd05d0 0x40086659:0x3ffd05f0 0x40190158:0x3ffd0690 0x40196f75:0x3ffd06e0 0x40196f8a:0x3ffd0700 0x401a3552:0x3ffd0720 0x401a36ec:0x3ffd07b0 0x401aaf7e:0x3ffd0800

ELF file SHA256: 025098cce59becac

Rebooting... ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0030,len:4728 load:0x40078000,len:14888 load:0x40080400,len:3368 entry 0x400805cc MicroPython v1.22.2-dirty on 2024-04-04; Generic ESP32 module with ESP32 Type "help()" for more information.

I have no idea why