espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.37k stars 7.21k forks source link

st7789 lcd show me incorrect color (IDFGH-9055) #10459

Open hyu7000 opened 1 year ago

hyu7000 commented 1 year ago

Answers checklist.

IDF version.

v5.0 7f5ecbe

Operating System used.

Windows

How did you build your project?

VS Code IDE

If you are using Windows, please specify command line type.

CMD

Development Kit.

ESP32s3 wroom 1 devkit

Power Supply used.

USB

What is the expected behavior?

when i set color to display on st7789 LCD, LCD display correct color.

What is the actual behavior?

when i set color to display on st7789 LCD, LCD display incorrect color.

if Blue(0x001F) was set, lcd show Green. if Red(0xF800) was set, lcd show Blue. if Green(0x07E0) was set, lcd show Red.

Steps to reproduce.

  1. Step create example project : lcd_tjpgd_example_main

  2. Step add 'esp_lcd_panel_invert_color(panel_handle,true);' after 'ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_ON_LEVEL));'

  3. Step disable these code //ESP_ERROR_CHECK(pretty_effect_init());

// while (1) { // // Set driver configuration to rotate 180 degrees each time // ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, is_rotated, is_rotated)); // Display // display_pretty_colors(panel_handle); // is_rotated = !is_rotated; // }

  1. Step add this code in last

uint16_t num[100]; for(int i = 0; i < 100; i++) { num[i] = 0xF800; } esp_lcd_panel_draw_bitmap(panel_handle, 0, 100, 24, 103, &num);

Debug Logs.

No response

More Information.

when i use Adafruit_ST7789 lib, my st7789 lcd was display with correct color. color type is RGB565

suda-morris commented 1 year ago

I think some ST7789 needs to call esp_lcd_panel_invert_color(panel_handle,true); but some do not. So doesn't the issue exist when you call or not call the "invert color" function?

hyu7000 commented 1 year ago

@suda-morris when i didn't call esp_lcd_panel_invert_color(panel_handle, true);, lcd displayed a completely different color such as magenta, cyan, yellow.

in default example project, this code is not include.

suda-morris commented 1 year ago

is the rgb_endian set to LCD_RGB_ENDIAN_BGR or LCD_RGB_ENDIAN_RGB in your project?

hyu7000 commented 1 year ago

@suda-morris yes if LCD_RGB_ENDIAN_RGB was set.

Blue(0x001F) -> Green. Red(0xF800) -> Blue. Green(0x07E0) -> Red.

and if LCD_RGB_ENDIAN_BGR was set.

Blue(0x001F) -> Green. Red(0xF800) -> Red. Green(0x07E0) -> Blue.

only red is correct.

i don't understand why Red is only correct;

kriegste commented 1 year ago

There are two factors that have to be taken care of: Endianess (little or big) and order (RGB or BGR). So in total there are 4 ways to represent a color (RGB little endian, RGB big endian, BGR little endian, BGR big endian). And only 1 will look right.

hyu7000 commented 1 year ago

@kriegste in esp-idf document, it explained that esp32s3 a little-endian chip.

is there funtion to change factor(endian)?

kriegste commented 1 year ago

In my code I just swapped the bytes in my color constants.

Try 0x1F00, 0x00F8 and 0xE007.

hyu7000 commented 1 year ago

@suda-morris i just try it.

if LCD_RGB_ENDIAN_RGB was set.

0x1F00 -> Blue 0x00F8 -> Red 0xE007 -> Green

if LCD_RGB_ENDIAN_BGR was set.

0x1F00 -> Red 0x00F8 -> Blue 0xE007 -> Green

I had an idea during the test.

my guess is this. The first five bit of 16-bit are Blue. The last six bit of 16-bit are green. The middle five of 16-bit are Red. (in LCD_RGB_ENDIAN_RGB)

So i get pink number(0xFB9E) and change it to suit my guess. 0xFB9E (0b1111'1011'1001'1110) -> 0xF7DC (0b1111011111011100)

then lcd show me pink color. but i don't understand why?

and my guess is not clear.

kriegste commented 1 year ago

The change in endianess causes this: 0bRRRRRGGGGGGBBBBB -> 0bGGGBBBBBRRRRRGGG (with the lower 3 green bits on the left)

When I first came across the issue, I struggled just like you. I ended up testing each bit separately. Then I saw that endianess was the problem.

hyu7000 commented 1 year ago

@kriegste Did you use esp32s3 chip, too?

kriegste commented 1 year ago

No. ESP32.

Dan-Albrecht commented 1 year ago

@hyu7000, I was having the exact same problem as you (how I found this thread):

if Blue(0x001F) was set, lcd show Green. if Red(0xF800) was set, lcd show Blue. if Green(0x07E0) was set, lcd show Red.

The problem for me was fixed for me by setting the swap_color_bytes bit in esp_lcd_panel_io_i80_config_t. Such as in this example.

kriegste commented 1 year ago

There is no swap_color_bytes flag for st7789. So maybe this would be the feature request here?

Dan-Albrecht commented 1 year ago

There is no swap_color_bytes flag for st7789. So maybe this would be the feature request here?

I certainly don't have that request. I'm accessing the device via I80 and part of the initialization chain of calling esp_lcd_new_panel_st7789 has you building an esp_lcd_panel_io_i80_config_t which has that setting.

Perhaps you're using a different protocol that is missing this? You'd need to specify.

kriegste commented 1 year ago

The OP refers to the tjpgd example. This is what I based my code on, too. In the example, there is no esp_lcd_panel_io_i80_config_t. https://github.com/espressif/esp-idf/blob/master/examples/peripherals/lcd/tjpgd/main/lcd_tjpgd_example_main.c#L137

Dan-Albrecht commented 1 year ago

So with esp_lcd_panel_io_spi_config_t looks like maybe the octal_mode flag might have some promise. Don't have the hardware so cannot test. The only other one that I'd play with is lsb_first, but docs aren't clear if the B is bit or byte.

weilian1977 commented 1 year ago

关注一下

viteo commented 8 months ago

see https://docs.espressif.com/projects/esp-idf/en/v5.1/esp32s3/api-reference/peripherals/spi_master.html#transactions-with-integers-other-than-uint8-t

use SPI_SWAP_DATA_TX(0xF800, 16);

image

I'm using union and swap u.data when assign to backbuffer

typedef union
{
    uint16_t data;
    struct
    {
        unsigned red:5;
        unsigned green:6;
        unsigned blue:5;
    } c;
    struct
    {
        uint8_t lsb;
        uint8_t msb;
    } d8;
} color;