Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Downloadable standard builds? #26

Open
TecDroiD opened this issue Apr 10, 2024 · 21 comments
Open

Downloadable standard builds? #26

TecDroiD opened this issue Apr 10, 2024 · 21 comments

Comments

@TecDroiD
Copy link

As far as I understand, you already build lvgl_micropython automatically for several computer architectures.
Sadly, I can't build it and don't understand why. I suppose that I have some environment, your automatic builder has.

Is it possible to make them downloadable, at least for esp32 and esp32s3 architectures?

@kdschlosser
Copy link
Collaborator

It's broken at the moment and I am working on getting it fixed. This project is still very much under development and is in an alpha test state and is going to have problems.

What are you wanting to compile for it for? What display, touch screen and MCU?

@TecDroiD
Copy link
Author

I need it for those yellow chinese boards. ESP32-S3 with an 800/480 ST7262 TFT and GT911 touch: https://de.aliexpress.com/item/1005005100043791.html

@kdschlosser
Copy link
Collaborator

The build should be fixed now. Those yellow Chinese boards can be fickle to get going depending on the bus type that is being used.

@TecDroiD
Copy link
Author

TecDroiD commented Apr 10, 2024 via email

@kdschlosser
Copy link
Collaborator

what is the display IC model number?
What is the bus connection between the ESP32 and the display IC?

@TecDroiD
Copy link
Author

that's what i'm currently trying to figure out. I suppose it's ST7262. But for the last few days, I couldn't download the files from jcnz1688.com. As far as I know, it supports parallel, I2C and SPI. Sadly, without Schematic's, I don't know which pins are used and connected where.. In worst case, i'll have to "ring" them out..

@kdschlosser
Copy link
Collaborator

kdschlosser commented Apr 11, 2024

OH... it doesn't matter. It's an RGB display. So the display IC is moot anywho.

This is the command line you want to use to build it.

python3 make.py esp32 mpy_cross submodules clean BOARD=ESP32_GENERIC_S3 BOARD_VARIANT=SPIRAM_OCT DISPLAY=rgb_display INDEV=gt911

At the end of the built it will tell you how to flash the MCU. make sure you run BOTH commands when flashing. The first command erases the memory and the second writes the firmware. for the second command you are going to have to change the -b 921600 to -b 460800 this is because of the lower grade UART IC that was used.

@kdschlosser
Copy link
Collaborator

Here is some test code you can run. This should have all of the correct pinouts set for your MCU

from micropython import const  # NOQA
import i2c


_WIDTH = const(800)
_HEIGHT = const(480)

_CTP_SCL = const(9)
_CTP_SDA = const(8)
_CTP_IRQ = const(4)

_SD_MOSI = const(11)
_SD_SCK = const(12)
_SD_MISO = const(13)

_LCD_FREQ = const(13000000)
_PCLK_ACTIVE_NEG = const(0)

_HSYNC_PULSE_WIDTH = const(10)
_HSYNC_BACK_PORCH = const(10)
_HSYNC_FRONT_PORCH = const(10)

_VSYNC_PULSE_WIDTH = const(10)
_VSYNC_BACK_PORCH = const(10)
_VSYNC_FRONT_PORCH = const(20)

_PCLK = const(7)
_HSYNC = const(46)
_VSYNC = const(3)
_DE = const(5)
_DISP = const(-1)
_BCKL = None
_DRST = None
_DPWR = None

I2C_BUS = i2c.I2CBus(
    scl=_CTP_SCL,
    sda=_CTP_SDA,
    freq=400000,
    use_locks=False
)

_DATA15 = const(10)  # B7
_DATA14 = const(17)  # B6
_DATA13 = const(18)  # B5
_DATA12 = const(38)  # B4
_DATA11 = const(14)  # B3
_DATA10 = const(21)  # G7
_DATA9 = const(47)  # G6
_DATA8 = const(48)  # G5
_DATA7 = const(45)  # G4
_DATA6 = const(0)  # G3
_DATA5 = const(39)  # G2
_DATA4 = const(40)  # R7
_DATA3 = const(41)  # R6
_DATA2 = const(42)  # R5
_DATA1 = const(2)  # R4
_DATA0 = const(1)  # R3

import lcd_bus  # NOQA


bus = lcd_bus.RGBBus(
    hsync=_HSYNC,
    vsync=_VSYNC,
    de=_DE,
    disp=_DISP,
    pclk=_PCLK,
    data0=_DATA0,
    data1=_DATA1,
    data2=_DATA2,
    data3=_DATA3,
    data4=_DATA4,
    data5=_DATA5,
    data6=_DATA6,
    data7=_DATA7,
    data8=_DATA8,
    data9=_DATA9,
    data10=_DATA10,
    data11=_DATA11,
    data12=_DATA12,
    data13=_DATA13,
    data14=_DATA14,
    data15=_DATA15,
    freq=_LCD_FREQ,
    hsync_front_porch=_HSYNC_FRONT_PORCH,
    hsync_back_porch=_HSYNC_BACK_PORCH,
    hsync_pulse_width=_HSYNC_PULSE_WIDTH,
    hsync_idle_low=False,
    vsync_front_porch=_VSYNC_FRONT_PORCH,
    vsync_back_porch=_VSYNC_BACK_PORCH,
    vsync_pulse_width=_VSYNC_PULSE_WIDTH,
    vsync_idle_low=False,
    de_idle_high=False,
    pclk_idle_high=False,
    pclk_active_low=_PCLK_ACTIVE_NEG,
    disp_active_low=False,
    refresh_on_demand=False
)

buf1 = bus.allocate_framebuffer(_WIDTH * _HEIGHT * 2, lcd_bus.MEMORY_SPIRAM)
buf2 = bus.allocate_framebuffer(_WIDTH * _HEIGHT * 2, lcd_bus.MEMORY_SPIRAM)

import lvgl as lv  # NOQA
import rgb_display  # NOQA

lv.init()

display = rgb_display.RGBDisplay(
    data_bus=bus,
    display_width=_WIDTH,
    display_height=_HEIGHT,
    frame_buffer1=buf1,
    frame_buffer2=buf2,
    reset_pin=_DRST,
    reset_state=rgb_display.STATE_HIGH,
    power_pin=_DPWR,
    power_on_state=rgb_display.STATE_HIGH,
    backlight_pin=_BCKL,
    backlight_on_state=rgb_display.STATE_HIGH,
    color_space=lv.COLOR_FORMAT.RGB565,
    rgb565_byte_swap=True
)

display.set_power(True)
display.init()
display.set_backlight(100)


import time  # NOQA
import gt911  # NOQA

indev = gt911.GT911(I2C_BUS)

scrn = lv.screen_active()
scrn.set_style_bg_color(lv.color_hex(0x000000), 0)

slider = lv.slider(scrn)
slider.set_size(500, 75)
slider.center()


while True:
    time.sleep_ms(1)
    lv.tick_inc(1)
    lv.task_handler()

If you have a problem with the touch not working properly lemme know I will tell you how to fix it.

@TecDroiD
Copy link
Author

TecDroiD commented Apr 11, 2024

Wellllll... sadly, these pinouts aren't correct. But... I could download the correct documentation zip from jncz1688... (5.0inch_ESP32-8048S050.zip) hopefully...
if so, this should be correct

bus = lcd_bus.RGBBus(
			hsync=const(39),
			vsync=const(41),
			de=const(40),
			disp=const(-1),
			pclk=const(42),
			data0=const(45),
			data1=const(48),
			data2=const(47),
			data3=const(21),
			data4=const(14),
			data5=const(5),
			data6=const(6),
			data7=const(7),
			data8=const(15),
			data9=const(16),
			data10=const(4),
			data11=const(8),
			data12=const(3),
			data13=const(46),
			data14=const(9),
			data15=const(1),
			)

but sadly, display stays black.. even if I try something like
scr.set_style_bg_color(lv.color_hex(0xafafaf), 0)

@kdschlosser
Copy link
Collaborator

kdschlosser commented Apr 11, 2024

Those pinouts are for the exact board you are using.
#20

@kdschlosser
Copy link
Collaborator

Try the cod exactly as I had it and see what happens. I am pretty sure those are the correct pinouts and the correct hsync and vsync settings.

@TecDroiD
Copy link
Author

TecDroiD commented Apr 11, 2024

this one worked #20 (comment)
next is getting the gt911 working..
...
...
edit: works!
I got the feeling that there is some minimal (or extremely fast) flickering.. well, i'll experiment with it a little.

@kdschlosser
Copy link
Collaborator

Are you using double buffering?

@kdschlosser
Copy link
Collaborator

kdschlosser commented Apr 11, 2024

If you are saying this code works...

import time, micropython
micropython.mem_info()

import lcd_bus
display_bus = lcd_bus.RGBBus(
    hsync = 39,
    vsync = 41,
    de = 40,
    disp = -1,
    pclk = 42,  # to TFT DCLK
    data0  = 8,  data1  = 3,  data2  = 46, data3  = 9,  data4  = 1,  # B
    data5  = 5,  data6  = 6,  data7  = 7,  data8  = 15, data9  = 16, data10 = 4,  # G
    data11 = 45, data12 = 48, data13 = 47, data14 = 21, data15 = 14,  # R
    freq = 12000000,
    hsync_front_porch = 8,
    hsync_back_porch = 8,
    hsync_pulse_width = 4,
    hsync_idle_low = True,
    vsync_front_porch = 8,
    vsync_back_porch = 8,
    vsync_pulse_width = 4,
    vsync_idle_low = True,
    de_idle_high = False,
    pclk_idle_high = False,
    pclk_active_low = True,
    disp_active_low = False,
)

import rgb_display
import lvgl as lv
display = rgb_display.RGBDisplay(
    data_bus = display_bus,
    display_width = 800,
    display_height = 480,
    backlight_pin = 2,
    color_byte_order = rgb_display.BYTE_ORDER_BGR,
    color_space = lv.COLOR_FORMAT.RGB565,
)

display.init()
display.set_backlight(100)

scrn = lv.screen_active()
scrn.set_style_bg_color(lv.color_hex(0x000000), 0)

slider = lv.slider(scrn)
slider.set_size(200, 50)
slider.center()

while True:
    time.sleep_ms(1)
    lv.tick_inc(1)
    lv.task_handler()

change it to this

from micropython import const  # NOQA
import i2c


_WIDTH = const(800)
_HEIGHT = const(480)

_CTP_SCL = const(20)
_CTP_SDA = const(19)

_LCD_FREQ = const(13000000)
_PCLK_ACTIVE_NEG = const(1)

_HSYNC_PULSE_WIDTH = const(4)
_HSYNC_BACK_PORCH = const(8)
_HSYNC_FRONT_PORCH = const(8)

_VSYNC_PULSE_WIDTH = const(4)
_VSYNC_BACK_PORCH = const(8)
_VSYNC_FRONT_PORCH = const(8)

_PCLK = const(42)
_HSYNC = const(39)
_VSYNC = const(41)
_DE = const(40)
_DISP = const(-1)
_BCKL = const(2)
_DRST = None
_DPWR = None

I2C_BUS = i2c.I2CBus(
    scl=_CTP_SCL,
    sda=_CTP_SDA,
    freq=400000,
    use_locks=False
)

_DATA15 = const(14)  # B7
_DATA14 = const(21)  # B6
_DATA13 = const(47)  # B5
_DATA12 = const(48)  # B4
_DATA11 = const(45)  # B3
_DATA10 = const(4)  # G7
_DATA9 = const(16)  # G6
_DATA8 = const(15)  # G5
_DATA7 = const(7)  # G4
_DATA6 = const(6)  # G3
_DATA5 = const(5)  # G2
_DATA4 = const(1)  # R7
_DATA3 = const(9)  # R6
_DATA2 = const(46)  # R5
_DATA1 = const(3)  # R4
_DATA0 = const(8)  # R3

import lcd_bus  # NOQA


bus = lcd_bus.RGBBus(
    hsync=_HSYNC,
    vsync=_VSYNC,
    de=_DE,
    disp=_DISP,
    pclk=_PCLK,
    data0=_DATA0,
    data1=_DATA1,
    data2=_DATA2,
    data3=_DATA3,
    data4=_DATA4,
    data5=_DATA5,
    data6=_DATA6,
    data7=_DATA7,
    data8=_DATA8,
    data9=_DATA9,
    data10=_DATA10,
    data11=_DATA11,
    data12=_DATA12,
    data13=_DATA13,
    data14=_DATA14,
    data15=_DATA15,
    freq=_LCD_FREQ,
    hsync_front_porch=_HSYNC_FRONT_PORCH,
    hsync_back_porch=_HSYNC_BACK_PORCH,
    hsync_pulse_width=_HSYNC_PULSE_WIDTH,
    hsync_idle_low=True,
    vsync_front_porch=_VSYNC_FRONT_PORCH,
    vsync_back_porch=_VSYNC_BACK_PORCH,
    vsync_pulse_width=_VSYNC_PULSE_WIDTH,
    vsync_idle_low=True,
    de_idle_high=False,
    pclk_idle_high=False,
    pclk_active_low=_PCLK_ACTIVE_NEG,
    disp_active_low=False
)

buf1 = bus.allocate_framebuffer(_WIDTH * _HEIGHT * 2, lcd_bus.MEMORY_SPIRAM)
buf2 = bus.allocate_framebuffer(_WIDTH * _HEIGHT * 2, lcd_bus.MEMORY_SPIRAM)

import lvgl as lv  # NOQA
import rgb_display  # NOQA

lv.init()

display = rgb_display.RGBDisplay(
    data_bus=bus,
    display_width=_WIDTH,
    display_height=_HEIGHT,
    frame_buffer1=buf1,
    frame_buffer2=buf2,
    reset_pin=_DRST,
    reset_state=rgb_display.STATE_HIGH,
    power_pin=_DPWR,
    power_on_state=rgb_display.STATE_HIGH,
    backlight_pin=_BCKL,
    backlight_on_state=rgb_display.STATE_HIGH,
    color_space=lv.COLOR_FORMAT.RGB565,
    rgb565_byte_swap=True
)

display.set_power(True)
display.init()
display.set_backlight(100)


import time  # NOQA
import gt911  # NOQA

indev = gt911.GT911(I2C_BUS)

scrn = lv.screen_active()
scrn.set_style_bg_color(lv.color_hex(0x000000), 0)

slider = lv.slider(scrn)
slider.set_size(500, 75)
slider.center()


while True:
    time.sleep_ms(1)
    lv.tick_inc(1)
    lv.task_handler()

@TecDroiD
Copy link
Author

TecDroiD commented Apr 11, 2024

looks good to me. Short question. how is the color defined? my former experiment gave a blue slider, now it's yellow. I suppose its the byte order which was set to BGR in the former code. which one is right?

@kdschlosser
Copy link
Collaborator

delete this line from the code

    rgb565_byte_swap=True

@TecDroiD
Copy link
Author

that way it's usable. thank you.

@kdschlosser
Copy link
Collaborator

which code are you using? If you are using the code I gave you 2-3 posts back try removing the byte swap and tell me what it comes out as.

@TecDroiD
Copy link
Author

thats what i meant :) removing the byte swap in the double buffering code (#26 (comment)) gives me plausible colors :)

@kdschlosser
Copy link
Collaborator

kdschlosser commented Apr 11, 2024

There are many things that can effect the color when dealing with an RGB display. It could be the data pin assignments, it could be the color format that is passed to LVGL, to could be byte swapping and lastly it could be the order of the colors.

When dealing with RGB565 this gets a bit tricky. With RGB565 it is literally as it states, 5 bits for reg 6 bits for green and 5 bits for blue. The least signifigant bits are the ones that get cut off. If you change the color order from RGB to BGR you get this..

                    byte 1                |                byte 2
         ===================================================================
RGB      r3, r4, r5, r6, r7, g2, g3, g4   |   g5, g6, g7, b3, b4, b5, b6, b7

BGR      b3, b4, b5, b6, b7, g2, g3, g4   |   g5, g6, g7, r3, r4, r5, r6, r7

now if we "byte swap that you end up with this.

                    byte 1                |                byte 2
         ===================================================================
RGB      g5, g6, g7, b3, b4, b5, b6, b7   |   r3, r4, r5, r6, r7, g2, g3, g4

BGR      g5, g6, g7, r3, r4, r5, r6, r7   |   b3, b4, b5, b6, b7, g2, g3, g4 

Technically speaking when using an RGB display the number of pins is equal to the color depth being used. That is because each pin represents one bit of the color depth. IF and I am really stressing the IF here. IF the board manufacturer has proper documentation and they have mapped the pin to bit color properly then you should only have to instruct the driver of the color depth being used.

I have found that when using a 16 lane (pin) RGB display that this is not always the case. For whatever reason the documentation has the pin order messed up. Using the rgb565 byte swap corrects this problem. the byte swapping typically has to be done for SPI and I8080 connections and this is because of a difference in processor design between the MCU and the display driver IC and to correct the problem the frame buffer needs to be iterated over having the bytes flip flopped for each pixel. What I did for the 16 lane RGB displays was flip flopping the pins instead. This improves performance because the frame buffer doesn't have to be iterated over.

BGR is almost never used for RGB displays. As the name suggests for the RGB display the byte order is going to be RGB. The color format in LVGL needs to be set to RGB565 if the connection is 16 lanes. If the colors are not right when doing that then try setting the rgb565 byte swap to True. That would need to be done because of poor documentation which is not all that surprising to see from a Chinese manufacturer. This "glitch" in the documentation comes from the hardware designers not communicating with the people that write the documentation. If the display deals in MSB byte order but the MCU deals in LSB byte order you end up with this flip flop not being taken into account. The datasheet for the display refers to the pins as R0, R1, R2... etc and when connected to the MCU those same labels are when get used when they really shouldn't.

Make sense?

@TecDroiD
Copy link
Author

well, yes. thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants