Support for gamma curves

This commit is contained in:
Ken Van Hoeylandt 2026-07-13 23:42:37 +02:00
parent f31103882d
commit d2889b2d3d
9 changed files with 39 additions and 0 deletions

View File

@ -53,6 +53,10 @@ properties:
type: int type: int
default: 10 default: 10
description: Size of the internal SPI transaction queue description: Size of the internal SPI transaction queue
gamma-curve:
type: int
default: 1
description: Gamma curve preset index [0,3], sent via the MIPI DCS GAMSET (0x26) command at bring-up
pin-dc: pin-dc:
type: phandles type: phandles
required: true required: true

View File

@ -24,6 +24,8 @@ struct Ili9341Config {
uint32_t bits_per_pixel; uint32_t bits_per_pixel;
uint32_t pixel_clock_hz; uint32_t pixel_clock_hz;
uint8_t transaction_queue_depth; uint8_t transaction_queue_depth;
// Gamma curve preset index [0,3], sent via the MIPI DCS GAMSET (0x26) command at bring-up.
uint8_t gamma_curve;
struct GpioPinSpec pin_dc; struct GpioPinSpec pin_dc;
struct GpioPinSpec pin_reset; struct GpioPinSpec pin_reset;
bool reset_active_high; bool reset_active_high;

View File

@ -13,6 +13,7 @@
#include <esp_err.h> #include <esp_err.h>
#include <esp_lcd_io_spi.h> #include <esp_lcd_io_spi.h>
#include <esp_lcd_panel_commands.h>
#include <esp_lcd_panel_io.h> #include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_ops.h> #include <esp_lcd_panel_ops.h>
#include <esp_lcd_ili9341.h> #include <esp_lcd_ili9341.h>
@ -25,6 +26,11 @@
#define GET_CONFIG(device) (static_cast<const Ili9341Config*>((device)->config)) #define GET_CONFIG(device) (static_cast<const Ili9341Config*>((device)->config))
// Maps gamma-curve devicetree index [0,3] to the MIPI DCS GAMSET (0x26) parameter value. Mirrors
// the deprecated HAL's EspLcdSpiDisplay::setGammaCurve() (Drivers/EspLcdCompat) - note the
// non-linear mapping, not index+1.
static const uint8_t GAMMA_CURVE_VALUES[4] = { 0x01, 0x04, 0x02, 0x08 };
struct Ili9341Internal { struct Ili9341Internal {
esp_lcd_panel_io_handle_t io_handle; esp_lcd_panel_io_handle_t io_handle;
esp_lcd_panel_handle_t panel_handle; esp_lcd_panel_handle_t panel_handle;
@ -140,6 +146,7 @@ static error_t start(Device* device) {
ok = ok && (!config->swap_xy || esp_lcd_panel_swap_xy(internal->panel_handle, true) == ESP_OK); ok = ok && (!config->swap_xy || esp_lcd_panel_swap_xy(internal->panel_handle, true) == ESP_OK);
ok = ok && ((!config->mirror_x && !config->mirror_y) || esp_lcd_panel_mirror(internal->panel_handle, config->mirror_x, config->mirror_y) == ESP_OK); ok = ok && ((!config->mirror_x && !config->mirror_y) || esp_lcd_panel_mirror(internal->panel_handle, config->mirror_x, config->mirror_y) == ESP_OK);
ok = ok && (!config->invert_color || esp_lcd_panel_invert_color(internal->panel_handle, true) == ESP_OK); ok = ok && (!config->invert_color || esp_lcd_panel_invert_color(internal->panel_handle, true) == ESP_OK);
ok = ok && (config->gamma_curve >= 4 || esp_lcd_panel_io_tx_param(internal->io_handle, LCD_CMD_GAMSET, &GAMMA_CURVE_VALUES[config->gamma_curve], 1) == ESP_OK);
ok = ok && esp_lcd_panel_disp_on_off(internal->panel_handle, true) == ESP_OK; ok = ok && esp_lcd_panel_disp_on_off(internal->panel_handle, true) == ESP_OK;
if (!ok) { if (!ok) {

View File

@ -49,6 +49,10 @@ properties:
type: int type: int
default: 10 default: 10
description: Size of the internal transaction queue description: Size of the internal transaction queue
gamma-curve:
type: int
default: 1
description: Gamma curve preset index [0,3], sent via the MIPI DCS GAMSET (0x26) command at bring-up
pin-reset: pin-reset:
type: phandles type: phandles
default: GPIO_PIN_SPEC_NONE default: GPIO_PIN_SPEC_NONE

View File

@ -23,6 +23,8 @@ struct St7789I8080Config {
bool bgr_order; bool bgr_order;
uint32_t pixel_clock_hz; uint32_t pixel_clock_hz;
uint8_t transaction_queue_depth; uint8_t transaction_queue_depth;
// Gamma curve preset index [0,3], sent via the MIPI DCS GAMSET (0x26) command at bring-up.
uint8_t gamma_curve;
struct GpioPinSpec pin_reset; struct GpioPinSpec pin_reset;
bool reset_active_high; bool reset_active_high;
// Optional reference to this display's backlight device, NULL if none. // Optional reference to this display's backlight device, NULL if none.

View File

@ -12,6 +12,7 @@
#include <tactility/log.h> #include <tactility/log.h>
#include <esp_err.h> #include <esp_err.h>
#include <esp_lcd_panel_commands.h>
#include <esp_lcd_panel_io.h> #include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_ops.h> #include <esp_lcd_panel_ops.h>
#include <esp_lcd_panel_st7789.h> #include <esp_lcd_panel_st7789.h>
@ -24,6 +25,11 @@
#define TAG "ST7789I8080" #define TAG "ST7789I8080"
#define GET_CONFIG(device) (static_cast<const St7789I8080Config*>((device)->config)) #define GET_CONFIG(device) (static_cast<const St7789I8080Config*>((device)->config))
// Maps gamma-curve devicetree index [0,3] to the MIPI DCS GAMSET (0x26) parameter value. Mirrors
// the deprecated HAL's EspLcdSpiDisplay::setGammaCurve() (Drivers/EspLcdCompat) - note the
// non-linear mapping, not index+1.
static const uint8_t GAMMA_CURVE_VALUES[4] = { 0x01, 0x04, 0x02, 0x08 };
namespace { namespace {
// Panel bring-up commands beyond esp_lcd_panel_init()'s generic ST7789 sequence: gate/porch/power // Panel bring-up commands beyond esp_lcd_panel_init()'s generic ST7789 sequence: gate/porch/power
@ -179,6 +185,7 @@ static error_t start(Device* device) {
ok = ok && (!config->swap_xy || esp_lcd_panel_swap_xy(internal->panel_handle, true) == ESP_OK); ok = ok && (!config->swap_xy || esp_lcd_panel_swap_xy(internal->panel_handle, true) == ESP_OK);
ok = ok && ((!config->mirror_x && !config->mirror_y) || esp_lcd_panel_mirror(internal->panel_handle, config->mirror_x, config->mirror_y) == ESP_OK); ok = ok && ((!config->mirror_x && !config->mirror_y) || esp_lcd_panel_mirror(internal->panel_handle, config->mirror_x, config->mirror_y) == ESP_OK);
ok = ok && (!config->invert_color || esp_lcd_panel_invert_color(internal->panel_handle, true) == ESP_OK); ok = ok && (!config->invert_color || esp_lcd_panel_invert_color(internal->panel_handle, true) == ESP_OK);
ok = ok && (config->gamma_curve >= 4 || esp_lcd_panel_io_tx_param(internal->io_handle, LCD_CMD_GAMSET, &GAMMA_CURVE_VALUES[config->gamma_curve], 1) == ESP_OK);
ok = ok && esp_lcd_panel_disp_on_off(internal->panel_handle, true) == ESP_OK; ok = ok && esp_lcd_panel_disp_on_off(internal->panel_handle, true) == ESP_OK;
if (!ok) { if (!ok) {

View File

@ -53,6 +53,10 @@ properties:
type: int type: int
default: 10 default: 10
description: Size of the internal SPI transaction queue description: Size of the internal SPI transaction queue
gamma-curve:
type: int
default: 1
description: Gamma curve preset index [0,3], sent via the MIPI DCS GAMSET (0x26) command at bring-up
pin-dc: pin-dc:
type: phandles type: phandles
required: true required: true

View File

@ -24,6 +24,8 @@ struct St7789Config {
uint32_t bits_per_pixel; uint32_t bits_per_pixel;
uint32_t pixel_clock_hz; uint32_t pixel_clock_hz;
uint8_t transaction_queue_depth; uint8_t transaction_queue_depth;
// Gamma curve preset index [0,3], sent via the MIPI DCS GAMSET (0x26) command at bring-up.
uint8_t gamma_curve;
struct GpioPinSpec pin_dc; struct GpioPinSpec pin_dc;
struct GpioPinSpec pin_reset; struct GpioPinSpec pin_reset;
bool reset_active_high; bool reset_active_high;

View File

@ -13,6 +13,7 @@
#include <esp_err.h> #include <esp_err.h>
#include <esp_lcd_io_spi.h> #include <esp_lcd_io_spi.h>
#include <esp_lcd_panel_commands.h>
#include <esp_lcd_panel_io.h> #include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_ops.h> #include <esp_lcd_panel_ops.h>
#include <esp_lcd_panel_st7789.h> #include <esp_lcd_panel_st7789.h>
@ -25,6 +26,11 @@
#define GET_CONFIG(device) (static_cast<const St7789Config*>((device)->config)) #define GET_CONFIG(device) (static_cast<const St7789Config*>((device)->config))
// Maps gamma-curve devicetree index [0,3] to the MIPI DCS GAMSET (0x26) parameter value. Mirrors
// the deprecated HAL's EspLcdSpiDisplay::setGammaCurve() (Drivers/EspLcdCompat) - note the
// non-linear mapping, not index+1.
static const uint8_t GAMMA_CURVE_VALUES[4] = { 0x01, 0x04, 0x02, 0x08 };
struct St7789Internal { struct St7789Internal {
esp_lcd_panel_io_handle_t io_handle; esp_lcd_panel_io_handle_t io_handle;
esp_lcd_panel_handle_t panel_handle; esp_lcd_panel_handle_t panel_handle;
@ -140,6 +146,7 @@ static error_t start(Device* device) {
ok = ok && (!config->swap_xy || esp_lcd_panel_swap_xy(internal->panel_handle, true) == ESP_OK); ok = ok && (!config->swap_xy || esp_lcd_panel_swap_xy(internal->panel_handle, true) == ESP_OK);
ok = ok && ((!config->mirror_x && !config->mirror_y) || esp_lcd_panel_mirror(internal->panel_handle, config->mirror_x, config->mirror_y) == ESP_OK); ok = ok && ((!config->mirror_x && !config->mirror_y) || esp_lcd_panel_mirror(internal->panel_handle, config->mirror_x, config->mirror_y) == ESP_OK);
ok = ok && (!config->invert_color || esp_lcd_panel_invert_color(internal->panel_handle, true) == ESP_OK); ok = ok && (!config->invert_color || esp_lcd_panel_invert_color(internal->panel_handle, true) == ESP_OK);
ok = ok && (config->gamma_curve >= 4 || esp_lcd_panel_io_tx_param(internal->io_handle, LCD_CMD_GAMSET, &GAMMA_CURVE_VALUES[config->gamma_curve], 1) == ESP_OK);
ok = ok && esp_lcd_panel_disp_on_off(internal->panel_handle, true) == ESP_OK; ok = ok && esp_lcd_panel_disp_on_off(internal->panel_handle, true) == ESP_OK;
if (!ok) { if (!ok) {