From 763ba34110fe7328ec96161d268454ccf69269a2 Mon Sep 17 00:00:00 2001 From: Stanislav N Mikhailov Date: Sun, 5 Apr 2026 00:21:12 +0300 Subject: [PATCH] Add ILI9341 backend and fix orientation/color settings --- Examples/Thermometr/CMakeLists.txt | 4 +- src/core/display_driver.c | 68 +++++++++++++++++++++++++++--- src/core/display_driver.h | 1 + 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/Examples/Thermometr/CMakeLists.txt b/Examples/Thermometr/CMakeLists.txt index 9134ab6..235290f 100644 --- a/Examples/Thermometr/CMakeLists.txt +++ b/Examples/Thermometr/CMakeLists.txt @@ -41,7 +41,9 @@ set(DISPLAY_PIN_CS 13) set(DISPLAY_PIN_DC 12) set(DISPLAY_PIN_RST 11) set(DISPLAY_PIN_BL 10) -set(DISPLAY_TYPE DISPLAY_TYPE_ST7789) +# Available values: DISPLAY_TYPE_ST7789, DISPLAY_TYPE_ILI9341 +set(DISPLAY_TYPE "DISPLAY_TYPE_ILI9341" CACHE STRING "Display controller backend") +set_property(CACHE DISPLAY_TYPE PROPERTY STRINGS DISPLAY_TYPE_ST7789 DISPLAY_TYPE_ILI9341) # Pass display mapping into display backend without editing engine sources. target_compile_definitions(display_engine PUBLIC diff --git a/src/core/display_driver.c b/src/core/display_driver.c index 4feeda5..9d3c458 100644 --- a/src/core/display_driver.c +++ b/src/core/display_driver.c @@ -4,8 +4,6 @@ #include "pico/stdlib.h" #include "hardware/spi.h" -#if DISPLAY_TYPE == DISPLAY_TYPE_ST7789 - static inline void display_send_command(uint8_t cmd) { gpio_put(DISPLAY_PIN_DC, 0); @@ -27,7 +25,7 @@ static inline void display_send_data_u8(uint8_t data) display_send_data_bytes(&data, 1); } -static inline void st7789_set_window(uint16_t width, uint16_t height) +static inline void display_set_window(uint16_t width, uint16_t height) { uint16_t x_end = (width > 0) ? (uint16_t)(width - 1u) : 0u; uint16_t y_end = (height > 0) ? (uint16_t)(height - 1u) : 0u; @@ -46,6 +44,8 @@ static inline void st7789_set_window(uint16_t width, uint16_t height) display_send_data_bytes(window, sizeof(window)); } +#if DISPLAY_TYPE == DISPLAY_TYPE_ST7789 + void display_driver_panel_init(uint16_t width, uint16_t height) { gpio_set_function(DISPLAY_PIN_MOSI, GPIO_FUNC_SPI); @@ -80,7 +80,7 @@ void display_driver_panel_init(uint16_t width, uint16_t height) display_send_command(0x3A); /* COLMOD */ display_send_data_u8(0x55); /* RGB565 */ - st7789_set_window(width, height); + display_set_window(width, height); display_send_command(0x21); /* INVON */ display_send_command(0x29); /* DISPON */ @@ -89,18 +89,74 @@ void display_driver_panel_init(uint16_t width, uint16_t height) void display_driver_begin_frame_transfer(uint16_t width, uint16_t height) { - st7789_set_window(width, height); + display_set_window(width, height); display_send_command(0x2C); /* RAMWR */ gpio_put(DISPLAY_PIN_DC, 1); gpio_put(DISPLAY_PIN_CS, 0); } -void display_driver_end_frame_transfer(void) +#elif DISPLAY_TYPE == DISPLAY_TYPE_ILI9341 + +void display_driver_panel_init(uint16_t width, uint16_t height) { + gpio_set_function(DISPLAY_PIN_MOSI, GPIO_FUNC_SPI); + gpio_set_function(DISPLAY_PIN_SCK, GPIO_FUNC_SPI); + + gpio_init(DISPLAY_PIN_CS); + gpio_init(DISPLAY_PIN_DC); + gpio_init(DISPLAY_PIN_RST); + gpio_init(DISPLAY_PIN_BL); + gpio_set_dir(DISPLAY_PIN_CS, GPIO_OUT); + gpio_set_dir(DISPLAY_PIN_DC, GPIO_OUT); + gpio_set_dir(DISPLAY_PIN_RST, GPIO_OUT); + gpio_set_dir(DISPLAY_PIN_BL, GPIO_OUT); + gpio_put(DISPLAY_PIN_CS, 1); + gpio_put(DISPLAY_PIN_DC, 1); + gpio_put(DISPLAY_PIN_BL, 0); + + gpio_put(DISPLAY_PIN_RST, 0); + sleep_ms(50); + gpio_put(DISPLAY_PIN_RST, 1); + sleep_ms(50); + + display_send_command(0x01); /* SWRESET */ + sleep_ms(150); + display_send_command(0x11); /* SLPOUT */ + sleep_ms(150); + + /* + * ILI9341 uses a different MADCTL layout than ST7789 for practical panel + * orientations; this value keeps 320x240 landscape without mirror and BGR. + */ + display_send_command(0x36); /* MADCTL */ + display_send_data_u8(0b11101000); + + display_send_command(0x3A); /* PIXFMT */ + display_send_data_u8(0x55); /* RGB565 */ + + display_set_window(width, height); + + display_send_command(0x20); /* INVOFF */ + display_send_command(0x29); /* DISPON */ + gpio_put(DISPLAY_PIN_BL, 1); +} + +void display_driver_begin_frame_transfer(uint16_t width, uint16_t height) +{ + display_set_window(width, height); + display_send_command(0x2C); /* RAMWR */ + + gpio_put(DISPLAY_PIN_DC, 1); + gpio_put(DISPLAY_PIN_CS, 0); } #else #error "Unsupported DISPLAY_TYPE. Add implementation in src/core/display_driver.c." #endif + +void display_driver_end_frame_transfer(void) +{ + gpio_put(DISPLAY_PIN_CS, 1); +} diff --git a/src/core/display_driver.h b/src/core/display_driver.h index 563ed88..fafd909 100644 --- a/src/core/display_driver.h +++ b/src/core/display_driver.h @@ -4,6 +4,7 @@ /* Display type identifiers used by DISPLAY_TYPE. */ #define DISPLAY_TYPE_ST7789 1 +#define DISPLAY_TYPE_ILI9341 2 #ifndef DISPLAY_TYPE #define DISPLAY_TYPE DISPLAY_TYPE_ST7789