diff options
| author | Fernando Birra <fpb@fct.unl.pt> | 2024-06-04 23:41:26 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-05 08:41:26 +1000 |
| commit | a82b0628b399c35bcdf70f14cabfa0bb27f86af8 (patch) | |
| tree | 49c0378a5cd7ca6bb9ad0c601ef8aaa4c5db190c | |
| parent | 75d11e04215edc43eeef71756a23d7f46e66c459 (diff) | |
GC9xxx LCD family drivers (GC9107 and GC9A01) (#23091)
Co-authored-by: Nick Brassel <nick@tzarc.org>
Co-authored-by: jack <0x6A73@pm.me>
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: フィルターペーパー <76888457+filterpaper@users.noreply.github.com>
Co-authored-by: rookiebwoy <81021475+rookiebwoy@users.noreply.github.com>
Fixup boardsource/equals (#23106)
Fix make clean test:os_detection (#23112)
Fix make clean test:os_detection (#23112)"
Fixup boardsource/equals (#23106)"
| -rw-r--r-- | drivers/painter/gc9a01/qp_gc9a01_opcodes.h | 77 | ||||
| -rw-r--r-- | drivers/painter/gc9xxx/qp_gc9107.c | 114 | ||||
| -rw-r--r-- | drivers/painter/gc9xxx/qp_gc9107.h | 37 | ||||
| -rw-r--r-- | drivers/painter/gc9xxx/qp_gc9107_opcodes.h | 135 | ||||
| -rw-r--r-- | drivers/painter/gc9xxx/qp_gc9a01.c (renamed from drivers/painter/gc9a01/qp_gc9a01.c) | 78 | ||||
| -rw-r--r-- | drivers/painter/gc9xxx/qp_gc9a01.h (renamed from drivers/painter/gc9a01/qp_gc9a01.h) | 0 | ||||
| -rw-r--r-- | drivers/painter/gc9xxx/qp_gc9a01_opcodes.h | 104 | ||||
| -rw-r--r-- | drivers/painter/gc9xxx/qp_gc9xxx_opcodes.h | 55 | ||||
| -rw-r--r-- | quantum/painter/qp.h | 6 | ||||
| -rw-r--r-- | quantum/painter/qp_internal.c | 1 | ||||
| -rw-r--r-- | quantum/painter/rules.mk | 16 |
11 files changed, 490 insertions, 133 deletions
diff --git a/drivers/painter/gc9a01/qp_gc9a01_opcodes.h b/drivers/painter/gc9a01/qp_gc9a01_opcodes.h deleted file mode 100644 index 828e42752b..0000000000 --- a/drivers/painter/gc9a01/qp_gc9a01_opcodes.h +++ /dev/null | |||
| @@ -1,77 +0,0 @@ | |||
| 1 | // Copyright 2021 Paul Cotter (@gr1mr3aver) | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 6 | // Quantum Painter GC9A01 command opcodes | ||
| 7 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 8 | |||
| 9 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 10 | // Level 1 command opcodes | ||
| 11 | |||
| 12 | #define GC9A01_GET_ID_INFO 0x04 // Get ID information | ||
| 13 | #define GC9A01_GET_STATUS 0x09 // Get status | ||
| 14 | #define GC9A01_CMD_SLEEP_ON 0x10 // Enter sleep mode | ||
| 15 | #define GC9A01_CMD_SLEEP_OFF 0x11 // Exit sleep mode | ||
| 16 | #define GC9A01_CMD_PARTIAL_ON 0x12 // Enter partial mode | ||
| 17 | #define GC9A01_CMD_PARTIAL_OFF 0x13 // Exit partial mode | ||
| 18 | #define GC9A01_CMD_INVERT_ON 0x20 // Enter inverted mode | ||
| 19 | #define GC9A01_CMD_INVERT_OFF 0x21 // Exit inverted mode | ||
| 20 | #define GC9A01_CMD_DISPLAY_OFF 0x28 // Disable display | ||
| 21 | #define GC9A01_CMD_DISPLAY_ON 0x29 // Enable display | ||
| 22 | #define GC9A01_SET_COL_ADDR 0x2A // Set column address | ||
| 23 | #define GC9A01_SET_PAGE_ADDR 0x2B // Set page address | ||
| 24 | #define GC9A01_SET_MEM 0x2C // Set memory | ||
| 25 | #define GC9A01_SET_PARTIAL_AREA 0x30 // Set partial area | ||
| 26 | #define GC9A01_SET_VSCROLL 0x33 // Set vertical scroll def | ||
| 27 | #define GC9A01_CMD_TEARING_ON 0x34 // Tearing line enabled | ||
| 28 | #define GC9A01_CMD_TEARING_OFF 0x35 // Tearing line disabled | ||
| 29 | #define GC9A01_SET_MEM_ACS_CTL 0x36 // Set mem access ctl | ||
| 30 | #define GC9A01_SET_VSCROLL_ADDR 0x37 // Set vscroll start addr | ||
| 31 | #define GC9A01_CMD_IDLE_OFF 0x38 // Exit idle mode | ||
| 32 | #define GC9A01_CMD_IDLE_ON 0x39 // Enter idle mode | ||
| 33 | #define GC9A01_SET_PIX_FMT 0x3A // Set pixel format | ||
| 34 | #define GC9A01_SET_MEM_CONT 0x3C // Set memory continue | ||
| 35 | #define GC9A01_SET_TEAR_SCANLINE 0x44 // Set tearing scanline | ||
| 36 | #define GC9A01_GET_TEAR_SCANLINE 0x45 // Get tearing scanline | ||
| 37 | #define GC9A01_SET_BRIGHTNESS 0x51 // Set brightness | ||
| 38 | #define GC9A01_SET_DISPLAY_CTL 0x53 // Set display ctl | ||
| 39 | #define GC9A01_GET_ID1 0xDA // Get ID1 | ||
| 40 | #define GC9A01_GET_ID2 0xDB // Get ID2 | ||
| 41 | #define GC9A01_GET_ID3 0xDC // Get ID3 | ||
| 42 | |||
| 43 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 44 | // Level 2 command opcodes | ||
| 45 | |||
| 46 | #define GC9A01_SET_RGB_IF_SIG_CTL 0xB0 // RGB IF signal ctl | ||
| 47 | #define GC9A01_SET_BLANKING_PORCH_CTL 0xB5 // Set blanking porch ctl | ||
| 48 | #define GC9A01_SET_FUNCTION_CTL 0xB6 // Set function ctl | ||
| 49 | #define GC9A01_SET_TEARING_EFFECT 0xBA // Set backlight ctl 3 | ||
| 50 | #define GC9A01_SET_IF_CTL 0xF6 // Set interface control | ||
| 51 | |||
| 52 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 53 | // Level 3 command opcodes | ||
| 54 | |||
| 55 | #define GC9A01_SET_FRAME_RATE 0xE8 // Set frame rate | ||
| 56 | #define GC9A01_SET_SPI_2DATA 0xE9 // Set frame rate | ||
| 57 | #define GC9A01_SET_POWER_CTL_1 0xC1 // Set power ctl 1 | ||
| 58 | #define GC9A01_SET_POWER_CTL_2 0xC3 // Set power ctl 2 | ||
| 59 | #define GC9A01_SET_POWER_CTL_3 0xC4 // Set power ctl 3 | ||
| 60 | #define GC9A01_SET_POWER_CTL_4 0xC9 // Set power ctl 4 | ||
| 61 | #define GC9A01_SET_POWER_CTL_7 0xA7 // Set power ctl 7 | ||
| 62 | #define GC9A01_SET_INTER_REG_ENABLE1 0xFE // Enable Inter Register 1 | ||
| 63 | #define GC9A01_SET_INTER_REG_ENABLE2 0xEF // Enable Inter Register 2 | ||
| 64 | #define GC9A01_SET_GAMMA1 0xF0 // | ||
| 65 | #define GC9A01_SET_GAMMA2 0xF1 | ||
| 66 | #define GC9A01_SET_GAMMA3 0xF2 | ||
| 67 | #define GC9A01_SET_GAMMA4 0xF3 | ||
| 68 | |||
| 69 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 70 | // MADCTL Flags | ||
| 71 | #define GC9A01_MADCTL_MY 0b10000000 | ||
| 72 | #define GC9A01_MADCTL_MX 0b01000000 | ||
| 73 | #define GC9A01_MADCTL_MV 0b00100000 | ||
| 74 | #define GC9A01_MADCTL_ML 0b00010000 | ||
| 75 | #define GC9A01_MADCTL_RGB 0b00000000 | ||
| 76 | #define GC9A01_MADCTL_BGR 0b00001000 | ||
| 77 | #define GC9A01_MADCTL_MH 0b00000100 | ||
diff --git a/drivers/painter/gc9xxx/qp_gc9107.c b/drivers/painter/gc9xxx/qp_gc9107.c new file mode 100644 index 0000000000..108344da4f --- /dev/null +++ b/drivers/painter/gc9xxx/qp_gc9107.c | |||
| @@ -0,0 +1,114 @@ | |||
| 1 | // Copyright 2024 Fernando Birra | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | #include "qp_internal.h" | ||
| 4 | #include "qp_comms.h" | ||
| 5 | #include "qp_gc9107.h" | ||
| 6 | #include "qp_gc9xxx_opcodes.h" | ||
| 7 | #include "qp_gc9107_opcodes.h" | ||
| 8 | #include "qp_tft_panel.h" | ||
| 9 | |||
| 10 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 11 | // Driver storage | ||
| 12 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 13 | |||
| 14 | tft_panel_dc_reset_painter_device_t gc9107_drivers[GC9107_NUM_DEVICES] = {0}; | ||
| 15 | |||
| 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 17 | // Initialization | ||
| 18 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 19 | __attribute__((weak)) bool qp_gc9107_init(painter_device_t device, painter_rotation_t rotation) { | ||
| 20 | // A lot of these "unknown" opcodes are sourced from other OSS projects and are seemingly required for this display to function. | ||
| 21 | // clang-format off | ||
| 22 | const uint8_t gc9107_init_sequence[] = { | ||
| 23 | GC9XXX_SET_INTER_REG_ENABLE1, 5, 0, | ||
| 24 | GC9XXX_SET_INTER_REG_ENABLE2, 5, 0, | ||
| 25 | GC9107_SET_FUNCTION_CTL6, 0, 1, GC9107_ALLOW_SET_COMPLEMENT_RGB | 0x08 | GC9107_ALLOW_SET_FRAMERATE, | ||
| 26 | GC9107_SET_COMPLEMENT_RGB, 0, 1, GC9107_COMPLEMENT_WITH_LSB, | ||
| 27 | 0xAB, 0, 1, 0x0E, | ||
| 28 | GC9107_SET_FRAME_RATE, 0, 1, 0x19, | ||
| 29 | GC9XXX_SET_PIXEL_FORMAT, 0, 1, GC9107_PIXEL_FORMAT_16_BPP_IFPF, | ||
| 30 | GC9XXX_CMD_SLEEP_OFF, 120, 0, | ||
| 31 | GC9XXX_CMD_DISPLAY_ON, 20, 0 | ||
| 32 | }; | ||
| 33 | |||
| 34 | // clang-format on | ||
| 35 | qp_comms_bulk_command_sequence(device, gc9107_init_sequence, sizeof(gc9107_init_sequence)); | ||
| 36 | |||
| 37 | // Configure the rotation (i.e. the ordering and direction of memory writes in GRAM) | ||
| 38 | const uint8_t madctl[] = { | ||
| 39 | [QP_ROTATION_0] = GC9XXX_MADCTL_BGR, | ||
| 40 | [QP_ROTATION_90] = GC9XXX_MADCTL_BGR | GC9XXX_MADCTL_MX | GC9XXX_MADCTL_MV, | ||
| 41 | [QP_ROTATION_180] = GC9XXX_MADCTL_BGR | GC9XXX_MADCTL_MX | GC9XXX_MADCTL_MY, | ||
| 42 | [QP_ROTATION_270] = GC9XXX_MADCTL_BGR | GC9XXX_MADCTL_MV | GC9XXX_MADCTL_MY, | ||
| 43 | }; | ||
| 44 | qp_comms_command_databyte(device, GC9XXX_SET_MEM_ACS_CTL, madctl[rotation]); | ||
| 45 | |||
| 46 | return true; | ||
| 47 | } | ||
| 48 | |||
| 49 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 50 | // Driver vtable | ||
| 51 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 52 | |||
| 53 | const tft_panel_dc_reset_painter_driver_vtable_t gc9107_driver_vtable = { | ||
| 54 | .base = | ||
| 55 | { | ||
| 56 | .init = qp_gc9107_init, | ||
| 57 | .power = qp_tft_panel_power, | ||
| 58 | .clear = qp_tft_panel_clear, | ||
| 59 | .flush = qp_tft_panel_flush, | ||
| 60 | .pixdata = qp_tft_panel_pixdata, | ||
| 61 | .viewport = qp_tft_panel_viewport, | ||
| 62 | .palette_convert = qp_tft_panel_palette_convert_rgb565_swapped, | ||
| 63 | .append_pixels = qp_tft_panel_append_pixels_rgb565, | ||
| 64 | .append_pixdata = qp_tft_panel_append_pixdata, | ||
| 65 | }, | ||
| 66 | .num_window_bytes = 2, | ||
| 67 | .swap_window_coords = false, | ||
| 68 | .opcodes = | ||
| 69 | { | ||
| 70 | .display_on = GC9XXX_CMD_DISPLAY_ON, | ||
| 71 | .display_off = GC9XXX_CMD_DISPLAY_OFF, | ||
| 72 | .set_column_address = GC9XXX_SET_COL_ADDR, | ||
| 73 | .set_row_address = GC9XXX_SET_ROW_ADDR, | ||
| 74 | .enable_writes = GC9XXX_SET_MEM, | ||
| 75 | }, | ||
| 76 | }; | ||
| 77 | |||
| 78 | #ifdef QUANTUM_PAINTER_GC9107_SPI_ENABLE | ||
| 79 | // Factory function for creating a handle to the GC9107 device | ||
| 80 | painter_device_t qp_gc9107_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode) { | ||
| 81 | for (uint32_t i = 0; i < GC9107_NUM_DEVICES; ++i) { | ||
| 82 | tft_panel_dc_reset_painter_device_t *driver = &gc9107_drivers[i]; | ||
| 83 | if (!driver->base.driver_vtable) { | ||
| 84 | driver->base.driver_vtable = (const painter_driver_vtable_t *)&gc9107_driver_vtable; | ||
| 85 | driver->base.comms_vtable = (const painter_comms_vtable_t *)&spi_comms_with_dc_vtable; | ||
| 86 | driver->base.native_bits_per_pixel = 16; // RGB565 | ||
| 87 | driver->base.panel_width = panel_width; | ||
| 88 | driver->base.panel_height = panel_height; | ||
| 89 | driver->base.rotation = QP_ROTATION_0; | ||
| 90 | driver->base.offset_x = 2; | ||
| 91 | driver->base.offset_y = 1; | ||
| 92 | |||
| 93 | // SPI and other pin configuration | ||
| 94 | driver->base.comms_config = &driver->spi_dc_reset_config; | ||
| 95 | driver->spi_dc_reset_config.spi_config.chip_select_pin = chip_select_pin; | ||
| 96 | driver->spi_dc_reset_config.spi_config.divisor = spi_divisor; | ||
| 97 | driver->spi_dc_reset_config.spi_config.lsb_first = false; | ||
| 98 | driver->spi_dc_reset_config.spi_config.mode = spi_mode; | ||
| 99 | driver->spi_dc_reset_config.dc_pin = dc_pin; | ||
| 100 | driver->spi_dc_reset_config.reset_pin = reset_pin; | ||
| 101 | driver->spi_dc_reset_config.command_params_uses_command_pin = false; | ||
| 102 | |||
| 103 | if (!qp_internal_register_device((painter_device_t)driver)) { | ||
| 104 | memset(driver, 0, sizeof(tft_panel_dc_reset_painter_device_t)); | ||
| 105 | return NULL; | ||
| 106 | } | ||
| 107 | |||
| 108 | return (painter_device_t)driver; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | return NULL; | ||
| 112 | } | ||
| 113 | |||
| 114 | #endif // QUANTUM_PAINTER_GC9107_SPI_ENABLE | ||
diff --git a/drivers/painter/gc9xxx/qp_gc9107.h b/drivers/painter/gc9xxx/qp_gc9107.h new file mode 100644 index 0000000000..b0b08f7665 --- /dev/null +++ b/drivers/painter/gc9xxx/qp_gc9107.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | // Copyright 2024 Fernando Birra (@gr1mr3aver) | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include "gpio.h" | ||
| 6 | #include "qp_internal.h" | ||
| 7 | |||
| 8 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 9 | // Quantum Painter GC9107 configurables (add to your keyboard's config.h) | ||
| 10 | |||
| 11 | #ifndef GC9107_NUM_DEVICES | ||
| 12 | /** | ||
| 13 | * @def This controls the maximum number of GC9107 devices that Quantum Painter can communicate with at any one time. | ||
| 14 | * Increasing this number allows for multiple displays to be used. | ||
| 15 | */ | ||
| 16 | # define GC9107_NUM_DEVICES 1 | ||
| 17 | #endif | ||
| 18 | |||
| 19 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 20 | // Quantum Painter GC9107 device factories | ||
| 21 | |||
| 22 | #ifdef QUANTUM_PAINTER_GC9107_SPI_ENABLE | ||
| 23 | /** | ||
| 24 | * Factory method for an GC9107 SPI LCD device. | ||
| 25 | * | ||
| 26 | * @param panel_width[in] the width of the display panel | ||
| 27 | * @param panel_height[in] the height of the display panel | ||
| 28 | * @param chip_select_pin[in] the GPIO pin used for SPI chip select | ||
| 29 | * @param dc_pin[in] the GPIO pin used for D/C control | ||
| 30 | * @param reset_pin[in] the GPIO pin used for RST | ||
| 31 | * @param spi_divisor[in] the SPI divisor to use when communicating with the display | ||
| 32 | * @param spi_mode[in] the SPI mode to use when communicating with the display | ||
| 33 | * @return the device handle used with all drawing routines in Quantum Painter | ||
| 34 | */ | ||
| 35 | painter_device_t qp_gc9107_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode); | ||
| 36 | |||
| 37 | #endif // QUANTUM_PAINTER_GC9107_SPI_ENABLE | ||
diff --git a/drivers/painter/gc9xxx/qp_gc9107_opcodes.h b/drivers/painter/gc9xxx/qp_gc9107_opcodes.h new file mode 100644 index 0000000000..e9b308eb49 --- /dev/null +++ b/drivers/painter/gc9xxx/qp_gc9107_opcodes.h | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | // Copyright 2024 Fernando Birra | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 6 | // Quantum Painter GC9107 command opcodes | ||
| 7 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 8 | |||
| 9 | #define GC9107_GET_POWER_MODE 0x0A // Get power mode | ||
| 10 | #define GC9107_GET_MADCTL 0x0B // Get MADCTL | ||
| 11 | #define GC9107_GET_PIXEL_FMT 0x0C // Get pixel format | ||
| 12 | #define GC9107_GET_IMAGE_FMT 0x0D // Get image format | ||
| 13 | #define GC9107_GET_SIGNAL_MODE 0x0E // Get signal mode | ||
| 14 | #define GC9107_GET_DIAG_RESULT 0x0F // Get self-diagnostic results | ||
| 15 | |||
| 16 | #define GC9107_SET_FRAME_RATE 0xA8 // Set frame rate | ||
| 17 | #define GC9107_SET_COMPLEMENT_RGB 0xAC // Set complement Principle RGB | ||
| 18 | #define GC9107_SET_BLANK_PORCH 0xAD // Set blank porch control, 0;front_porch[6:0],0;back_porch[6:0] | ||
| 19 | #define GC9107_SET_FUNCTION_CTL1 0xB1 // Set access to AVDD_VCL_CLK and VGH_VGL_CLK commands | ||
| 20 | #define GC9107_SET_FUNCTION_CTL2 0xB2 // Set access to VGH, VGH control commands | ||
| 21 | #define GC9107_SET_FUNCTION_CTL3 0xB3 // Set access to Gamma control commands | ||
| 22 | #define GC9107_SET_DISPLAY_INVERSION 0xB4 // Set Display Inversion control | ||
| 23 | #define GC9107_SET_FUNCTION_CTL6 0xB6 // Set access to commands SET_FRAME_RATE, SET_COMPLEMENT_RGB and SET_BLANK_PORCH | ||
| 24 | #define GC9107_SET_CUSTOM_ID_INFO 0xD3 // Set customized display id information | ||
| 25 | #define GC9107_AVDD_VCL_CLK 0xE3 // AVDD_CLK | ||
| 26 | #define GC9107_SET_VGH 0xE8 // Set VGH | ||
| 27 | #define GC9107_SET_VGL 0xE9 // Set VGL | ||
| 28 | #define GC9107_SET_VGH_VGL_CLK 0xEA // Set VGH and VGL clock divisors | ||
| 29 | |||
| 30 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 31 | // GC9107 Parameter constants | ||
| 32 | |||
| 33 | // Parameter values for | ||
| 34 | // GC9107_SET_PIXEL_FORMAT | ||
| 35 | #define GC9107_PIXEL_FORMAT_12_BPP_IFPF (0b001 << 0) // 12 bits per pixel | ||
| 36 | #define GC9107_PIXEL_FORMAT_16_BPP_IFPF (0b101 << 0) // 16 bits per pixel | ||
| 37 | #define GC9107_PIXEL_FORMAT_18_BPP_IFPB (0b110 << 0) // 18 bits per pixel | ||
| 38 | |||
| 39 | // Parameter values for | ||
| 40 | // GC9107_SET_COMPLEMENT_RGB | ||
| 41 | #define GC9107_COMPLEMENT_WITH_0 0x00 // R0 <- B0 <- 0, except if data is FFh | ||
| 42 | #define GC9107_COMPLEMENT_WITH_1 0x40 // R0 <- B0 <- 1, except if data is 00h | ||
| 43 | #define GC9107_COMPLEMENT_WITH_MSB 0x80 // R0 <- R5, B0 <- B5 | ||
| 44 | #define GC9107_COMPLEMENT_WITH_LSB 0xC0 // R0 <- B0 <- G0 | ||
| 45 | // Parameter masks for | ||
| 46 | // GC9107_SET_FUNCTION_CTL1 | ||
| 47 | #define GC9107_ALLOW_AVDD_VCL_CLK 0b00001000 // Allow AVDD_VCL_CLK command | ||
| 48 | // Parameter masks for | ||
| 49 | // GC9107_SET_FUNCTION_CTL2 | ||
| 50 | #define GC9107_ALLOW_SET_VGH 0b00000001 // Allow GC9107_SET_VGH | ||
| 51 | #define GC9107_ALLOW_SET_VGL 0b00000010 // Allow GC9107_SET_VGL | ||
| 52 | #define GC9107_ALLOW_SET_VGH_VGL_CLK 0b00000100 // Allow GC9107_SET_VGH_VGL_CLK | ||
| 53 | // Parameter masks for | ||
| 54 | // GC9107_SET_FUNCTION_CTL3 | ||
| 55 | #define GC9107_ALLOW_SET_GAMMA1 0b00000001 // Allow GC9107_SET_GAMMA1 | ||
| 56 | #define GC9107_ALLOW_SET_GAMMA2 0b00000010 // Allow GC9107_SET_GAMMA2 | ||
| 57 | // Parameter mask for | ||
| 58 | // GC9107_SET_FUNCTION_CTL6 | ||
| 59 | #define GC9107_ALLOW_SET_FRAMERATE 0b000000001 // Allow GC9107_SET_FRAME_RATE | ||
| 60 | #define GC9107_ALLOW_SET_COMPLEMENT_RGB 0b000010000 // Allow GC9107_SET_COMPLEMENT_RGB | ||
| 61 | #define GC9107_ALLOW_SET_BLANK_PORCH 0b000100000 // Allow GFC9107_SET_BLANK_PORCH | ||
| 62 | // Parameter values for | ||
| 63 | // AVDD_CLK_AD part (Most significant nibble) | ||
| 64 | #define GC9107_AVDD_CLK_AD_2T 0x00 | ||
| 65 | #define GC9107_AVDD_CLK_AD_3T 0x10 | ||
| 66 | #define GC9107_AVDD_CLK_AD_4T 0x20 | ||
| 67 | #define GC9107_AVDD_CLK_AD_5T 0x30 | ||
| 68 | #define GC9107_AVDD_CLK_AD_6T 0x40 | ||
| 69 | #define GC9107_AVDD_CLK_AD_7T 0x50 | ||
| 70 | #define GC9107_AVDD_CLK_AD_8T 0x60 | ||
| 71 | #define GC9107_AVDD_CLK_AD_9T 0x70 | ||
| 72 | // Parameter values for | ||
| 73 | // VCL_CLK_AD part (Least significant nibble) | ||
| 74 | #define GC9107_VCL_CLK_AD_2T 0x00 | ||
| 75 | #define GC9107_VCL_CLK_AD_3T 0x01 | ||
| 76 | #define GC9107_VCL_CLK_AD_4T 0x02 | ||
| 77 | #define GC9107_VCL_CLK_AD_5T 0x03 | ||
| 78 | #define GC9107_VCL_CLK_AD_6T 0x04 | ||
| 79 | #define GC9107_VCL_CLK_AD_7T 0x05 | ||
| 80 | #define GC9107_VCL_CLK_AD_8T 0x06 | ||
| 81 | #define GC9107_VCL_CLK_AD_9T 0x07 | ||
| 82 | // Parameter values for | ||
| 83 | // GC9107_SET_VGH | ||
| 84 | #define GC9107_VGH_P100 0x20 // +10 V | ||
| 85 | #define GC9107_VGH_P110 0x21 // +11 V | ||
| 86 | #define GC9107_VGH_P120 0x22 // +12 V | ||
| 87 | #define GC9107_VGH_P130 0x23 // +13 V | ||
| 88 | #define GC9107_VGH_P140 0x24 // +14 V | ||
| 89 | #define GC9107_VGH_P150 0x25 // +15 V | ||
| 90 | // Parameter values for | ||
| 91 | // GC9107_SET_VGL | ||
| 92 | #define VGL_N_075 0x40 // -7.5 V | ||
| 93 | #define VGL_N_085 0x41 // -8.5 V | ||
| 94 | #define VGL_N_095 0x42 // -9.5 V | ||
| 95 | #define VGL_N_100 0x43 // -10.0 V | ||
| 96 | #define VGL_N_105 0x44 // -10.5 V | ||
| 97 | #define VGL_N_110 0x45 // -11.0 V | ||
| 98 | #define VGL_N_120 0x46 // -12.0 V | ||
| 99 | #define VGL_N_130 0x47 // -13.0 V | ||
| 100 | // Parameter masks for | ||
| 101 | // GC9107_SET_VGH_VGL_CLK (VGH Divisor) | ||
| 102 | #define GC9107_VGH_CLK_DIV_2 0x00 // Clock divisor = 2 -> 6.0 Mhz | ||
| 103 | #define GC9107_VGH_CLK_DIV_3 0x10 // Clock divisor = 3 -> 4.0 Mhz | ||
| 104 | #define GC9107_VGH_CLK_DIV_4 0x20 // Clock divisor = 4 -> 3.0 Mhz | ||
| 105 | #define GC9107_VGH_CLK_DIV_5 0x30 // Clock divisor = 5 -> 2.4 Mhz | ||
| 106 | #define GC9107_VGH_CLK_DIV_6 0x40 // Clock divisor = 6 -> 2.0 Mhz | ||
| 107 | #define GC9107_VGH_CLK_DIV_7 0x50 // Clock divisor = 7 -> 1.7 Mhz | ||
| 108 | #define GC9107_VGH_CLK_DIV_8 0x60 // Clock divisor = 8 -> 1.5 Mhz | ||
| 109 | #define GC9107_VGH_CLK_DIV_9 0x70 // Clock divisor = 9 -> 1.3 Mhz | ||
| 110 | #define GC9107_VGH_CLK_DIV_10 0x80 // Clock divisor = 10 -> 1.2 Mhz | ||
| 111 | #define GC9107_VGH_CLK_DIV_12 0x90 // Clock divisor = 12 -> 1.0 Mhz | ||
| 112 | #define GC9107_VGH_CLK_DIV_15 0xA0 // Clock divisor = 15 -> 0.8 Mhz | ||
| 113 | #define GC9107_VGH_CLK_DIV_20 0xB0 // Clock divisor = 20 -> 0.6 Mhz | ||
| 114 | #define GC9107_VGH_CLK_DIV_24 0xC0 // Clock divisor = 24 -> 0.5 Mhz | ||
| 115 | #define GC9107_VGH_CLK_DIV_30 0xD0 // Clock divisor = 30 -> 0.4 Mhz | ||
| 116 | #define GC9107_VGH_CLK_DIV_40 0xE0 // Clock divisor = 40 -> 0.3 Mhz | ||
| 117 | #define GC9107_VGH_CLK_DIV_60 0xE0 // Clock divisor = 40 -> 0.2 Mhz | ||
| 118 | // Parameter masks for | ||
| 119 | // GC9107_SET_VGH_VGL_CLK (VGL Divisor) | ||
| 120 | #define GC9107_VGL_CLK_DIV_2 0x00 // Clock divisor = 2 -> 6.0 Mhz | ||
| 121 | #define GC9107_VGL_CLK_DIV_3 0x01 // Clock divisor = 3 -> 4.0 Mhz | ||
| 122 | #define GC9107_VGL_CLK_DIV_4 0x02 // Clock divisor = 4 -> 3.0 Mhz | ||
| 123 | #define GC9107_VGL_CLK_DIV_5 0x03 // Clock divisor = 5 -> 2.4 Mhz | ||
| 124 | #define GC9107_VGL_CLK_DIV_6 0x04 // Clock divisor = 6 -> 2.0 Mhz | ||
| 125 | #define GC9107_VGL_CLK_DIV_7 0x05 // Clock divisor = 7 -> 1.7 Mhz | ||
| 126 | #define GC9107_VGL_CLK_DIV_8 0x06 // Clock divisor = 8 -> 1.5 Mhz | ||
| 127 | #define GC9107_VGL_CLK_DIV_9 0x07 // Clock divisor = 9 -> 1.3 Mhz | ||
| 128 | #define GC9107_VGL_CLK_DIV_10 0x08 // Clock divisor = 10 -> 1.2 Mhz | ||
| 129 | #define GC9107_VGL_CLK_DIV_12 0x09 // Clock divisor = 12 -> 1.0 Mhz | ||
| 130 | #define GC9107_VGL_CLK_DIV_15 0x0A // Clock divisor = 15 -> 0.8 Mhz | ||
| 131 | #define GC9107_VGL_CLK_DIV_20 0x0B // Clock divisor = 20 -> 0.6 Mhz | ||
| 132 | #define GC9107_VGL_CLK_DIV_24 0x0C // Clock divisor = 24 -> 0.5 Mhz | ||
| 133 | #define GC9107_VGL_CLK_DIV_30 0x0D // Clock divisor = 30 -> 0.4 Mhz | ||
| 134 | #define GC9107_VGL_CLK_DIV_40 0x0E // Clock divisor = 40 -> 0.3 Mhz | ||
| 135 | #define GC9107_VGL_CLK_DIV_60 0x0E // Clock divisor = 40 -> 0.2 Mhz | ||
diff --git a/drivers/painter/gc9a01/qp_gc9a01.c b/drivers/painter/gc9xxx/qp_gc9a01.c index fe6fa7a9d0..f037a4cc87 100644 --- a/drivers/painter/gc9a01/qp_gc9a01.c +++ b/drivers/painter/gc9xxx/qp_gc9a01.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "qp_internal.h" | 5 | #include "qp_internal.h" |
| 6 | #include "qp_comms.h" | 6 | #include "qp_comms.h" |
| 7 | #include "qp_gc9a01.h" | 7 | #include "qp_gc9a01.h" |
| 8 | #include "qp_gc9xxx_opcodes.h" | ||
| 8 | #include "qp_gc9a01_opcodes.h" | 9 | #include "qp_gc9a01_opcodes.h" |
| 9 | #include "qp_tft_panel.h" | 10 | #include "qp_tft_panel.h" |
| 10 | 11 | ||
| @@ -20,71 +21,40 @@ tft_panel_dc_reset_painter_device_t gc9a01_drivers[GC9A01_NUM_DEVICES] = {0}; | |||
| 20 | __attribute__((weak)) bool qp_gc9a01_init(painter_device_t device, painter_rotation_t rotation) { | 21 | __attribute__((weak)) bool qp_gc9a01_init(painter_device_t device, painter_rotation_t rotation) { |
| 21 | // A lot of these "unknown" opcodes are sourced from other OSS projects and are seemingly required for this display to function. | 22 | // A lot of these "unknown" opcodes are sourced from other OSS projects and are seemingly required for this display to function. |
| 22 | // clang-format off | 23 | // clang-format off |
| 24 | |||
| 23 | const uint8_t gc9a01_init_sequence[] = { | 25 | const uint8_t gc9a01_init_sequence[] = { |
| 24 | // Command, Delay, N, Data[N] | 26 | // Command, Delay, N, Data[N] |
| 25 | GC9A01_SET_INTER_REG_ENABLE2, 0, 0, | 27 | GC9XXX_SET_INTER_REG_ENABLE1, 0, 0, |
| 26 | 0xEB, 0, 1, 0x14, | 28 | GC9XXX_SET_INTER_REG_ENABLE2, 0, 0, |
| 27 | GC9A01_SET_INTER_REG_ENABLE1, 0, 0, | ||
| 28 | GC9A01_SET_INTER_REG_ENABLE2, 0, 0, | ||
| 29 | 0xEB, 0, 1, 0x14, | ||
| 30 | 0x84, 0, 1, 0x40, | 29 | 0x84, 0, 1, 0x40, |
| 31 | 0x85, 0, 1, 0xFF, | 30 | GC9A01_SET_FUNCTION_CTL, 0, 3, 0x00, GC9A01_SOURCE_OUTPUT_SCAN_DIRECTION_S360_TO_S1 | GC9A01_GATE_OUTPUT_SCAN_DIRECTION_G1_TO_G32, GC9A01_LCD_DRIVE_LINE_240, // Only works if the previous command is present (undocumented) |
| 32 | 0x86, 0, 1, 0xFF, | 31 | GC9A01_SET_POWER_CTL_2, 0, 1, 0x20, |
| 33 | 0x87, 0, 1, 0xFF, | 32 | GC9A01_SET_POWER_CTL_3, 0, 1, 0x20, |
| 34 | 0x88, 0, 1, 0x0A, | ||
| 35 | 0x89, 0, 1, 0x21, | ||
| 36 | 0x8a, 0, 1, 0x00, | ||
| 37 | 0x8b, 0, 1, 0x80, | ||
| 38 | 0x8c, 0, 1, 0x01, | ||
| 39 | 0x8d, 0, 1, 0x01, | ||
| 40 | 0x8e, 0, 1, 0xFF, | ||
| 41 | 0x8f, 0, 1, 0xFF, | ||
| 42 | GC9A01_SET_FUNCTION_CTL, 0, 2, 0x00, 0x20, | ||
| 43 | GC9A01_SET_PIX_FMT, 0, 1, 0x55, | ||
| 44 | 0x90, 0, 4, 0x08, 0x08, 0x08, 0x08, | ||
| 45 | 0xBD, 0, 1, 0x06, | ||
| 46 | 0xBC, 0, 1, 0x00, | ||
| 47 | 0xFF, 0, 3, 0x60, 0x01, 0x04, | ||
| 48 | GC9A01_SET_POWER_CTL_2, 0, 1, 0x13, | ||
| 49 | GC9A01_SET_POWER_CTL_3, 0, 1, 0x13, | ||
| 50 | GC9A01_SET_POWER_CTL_4, 0, 1, 0x22, | 33 | GC9A01_SET_POWER_CTL_4, 0, 1, 0x22, |
| 51 | 0xBE, 0, 1, 0x11, | 34 | GC9XXX_SET_GAMMA1, 0, 6, 0x45, 0x09, 0x08, 0x08, 0x26, 0x2A, |
| 52 | 0xE1, 0, 2, 0x10, 0x0E, | 35 | GC9XXX_SET_GAMMA2, 0, 6, 0x43, 0x70, 0x72, 0x36, 0x37, 0x6F, |
| 53 | 0xDF, 0, 3, 0x21, 0x0C, 0x02, | ||
| 54 | GC9A01_SET_GAMMA1, 0, 6, 0x45, 0x09, 0x08, 0x08, 0x26, 0x2A, | ||
| 55 | GC9A01_SET_GAMMA2, 0, 6, 0x43, 0x70, 0x72, 0x36, 0x37, 0x6F, | ||
| 56 | GC9A01_SET_GAMMA3, 0, 6, 0x45, 0x09, 0x08, 0x08, 0x26, 0x2A, | 36 | GC9A01_SET_GAMMA3, 0, 6, 0x45, 0x09, 0x08, 0x08, 0x26, 0x2A, |
| 57 | GC9A01_SET_GAMMA4, 0, 6, 0x43, 0x70, 0x72, 0x36, 0x37, 0x6F, | 37 | GC9A01_SET_GAMMA4, 0, 6, 0x43, 0x70, 0x72, 0x36, 0x37, 0x6F, |
| 58 | 0xED, 0, 2, 0x1B, 0x0B, | ||
| 59 | 0xAE, 0, 1, 0x77, | ||
| 60 | 0xCD, 0, 1, 0x63, | ||
| 61 | 0x70, 0, 9, 0x07, 0x07, 0x04, 0x0E, 0x0F, 0x09, 0x07, 0x08, 0x03, | ||
| 62 | GC9A01_SET_FRAME_RATE, 0, 1, 0x34, | ||
| 63 | 0x62, 0, 12, 0x18, 0x0D, 0x71, 0xED, 0x70, 0x70, 0x18, 0x0F, 0x71, 0xEF, 0x70, 0x70, | ||
| 64 | 0x63, 0, 12, 0x18, 0x11, 0x71, 0xF1, 0x70, 0x70, 0x18, 0x13, 0x71, 0xF3, 0x70, 0x70, | ||
| 65 | 0x64, 0, 7, 0x28, 0x29, 0xF1, 0x01, 0xF1, 0x00, 0x07, | ||
| 66 | 0x66, 0, 10, 0x3C, 0x00, 0xCD, 0x67, 0x45, 0x45, 0x10, 0x00, 0x00, 0x00, | 38 | 0x66, 0, 10, 0x3C, 0x00, 0xCD, 0x67, 0x45, 0x45, 0x10, 0x00, 0x00, 0x00, |
| 67 | 0x67, 0, 10, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x54, 0x10, 0x32, 0x98, | 39 | 0x67, 0, 10, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x54, 0x10, 0x32, 0x98, |
| 68 | 0x74, 0, 7, 0x10, 0x85, 0x80, 0x00, 0x00, 0x4E, 0x00, | 40 | GC9XXX_CMD_TEARING_ON, 0, 0, |
| 69 | 0x98, 0, 2, 0x3E, 0x07, | 41 | GC9XXX_SET_PIXEL_FORMAT, 0, 1, GC9A01_PIXEL_FORMAT_16_BPP_DBI, |
| 70 | GC9A01_CMD_TEARING_OFF, 0, 0, | 42 | GC9XXX_CMD_INVERT_ON, 0, 0, |
| 71 | GC9A01_CMD_INVERT_OFF, 0, 0, | 43 | GC9XXX_CMD_SLEEP_OFF, 120, 0, |
| 72 | GC9A01_CMD_SLEEP_OFF, 120, 0, | 44 | GC9XXX_CMD_DISPLAY_ON, 20, 0 |
| 73 | GC9A01_CMD_DISPLAY_ON, 20, 0 | ||
| 74 | }; | 45 | }; |
| 75 | // clang-format on | 46 | // clang-format on |
| 76 | 47 | ||
| 77 | // clang-format on | ||
| 78 | qp_comms_bulk_command_sequence(device, gc9a01_init_sequence, sizeof(gc9a01_init_sequence)); | 48 | qp_comms_bulk_command_sequence(device, gc9a01_init_sequence, sizeof(gc9a01_init_sequence)); |
| 79 | 49 | ||
| 80 | // Configure the rotation (i.e. the ordering and direction of memory writes in GRAM) | 50 | // Configure the rotation (i.e. the ordering and direction of memory writes in GRAM) |
| 81 | const uint8_t madctl[] = { | 51 | const uint8_t madctl[] = { |
| 82 | [QP_ROTATION_0] = GC9A01_MADCTL_BGR, | 52 | [QP_ROTATION_0] = GC9XXX_MADCTL_BGR, |
| 83 | [QP_ROTATION_90] = GC9A01_MADCTL_BGR | GC9A01_MADCTL_MX | GC9A01_MADCTL_MV, | 53 | [QP_ROTATION_90] = GC9XXX_MADCTL_BGR | GC9XXX_MADCTL_MX | GC9XXX_MADCTL_MV, |
| 84 | [QP_ROTATION_180] = GC9A01_MADCTL_BGR | GC9A01_MADCTL_MX | GC9A01_MADCTL_MY, | 54 | [QP_ROTATION_180] = GC9XXX_MADCTL_BGR | GC9XXX_MADCTL_MX | GC9XXX_MADCTL_MY, |
| 85 | [QP_ROTATION_270] = GC9A01_MADCTL_BGR | GC9A01_MADCTL_MV | GC9A01_MADCTL_MY, | 55 | [QP_ROTATION_270] = GC9XXX_MADCTL_BGR | GC9XXX_MADCTL_MV | GC9XXX_MADCTL_MY, |
| 86 | }; | 56 | }; |
| 87 | qp_comms_command_databyte(device, GC9A01_SET_MEM_ACS_CTL, madctl[rotation]); | 57 | qp_comms_command_databyte(device, GC9XXX_SET_MEM_ACS_CTL, madctl[rotation]); |
| 88 | 58 | ||
| 89 | return true; | 59 | return true; |
| 90 | } | 60 | } |
| @@ -110,11 +80,11 @@ const tft_panel_dc_reset_painter_driver_vtable_t gc9a01_driver_vtable = { | |||
| 110 | .swap_window_coords = false, | 80 | .swap_window_coords = false, |
| 111 | .opcodes = | 81 | .opcodes = |
| 112 | { | 82 | { |
| 113 | .display_on = GC9A01_CMD_DISPLAY_ON, | 83 | .display_on = GC9XXX_CMD_DISPLAY_ON, |
| 114 | .display_off = GC9A01_CMD_DISPLAY_OFF, | 84 | .display_off = GC9XXX_CMD_DISPLAY_OFF, |
| 115 | .set_column_address = GC9A01_SET_COL_ADDR, | 85 | .set_column_address = GC9XXX_SET_COL_ADDR, |
| 116 | .set_row_address = GC9A01_SET_PAGE_ADDR, | 86 | .set_row_address = GC9XXX_SET_ROW_ADDR, |
| 117 | .enable_writes = GC9A01_SET_MEM, | 87 | .enable_writes = GC9XXX_SET_MEM, |
| 118 | }, | 88 | }, |
| 119 | }; | 89 | }; |
| 120 | 90 | ||
diff --git a/drivers/painter/gc9a01/qp_gc9a01.h b/drivers/painter/gc9xxx/qp_gc9a01.h index 31a3804b50..31a3804b50 100644 --- a/drivers/painter/gc9a01/qp_gc9a01.h +++ b/drivers/painter/gc9xxx/qp_gc9a01.h | |||
diff --git a/drivers/painter/gc9xxx/qp_gc9a01_opcodes.h b/drivers/painter/gc9xxx/qp_gc9a01_opcodes.h new file mode 100644 index 0000000000..5853902e68 --- /dev/null +++ b/drivers/painter/gc9xxx/qp_gc9a01_opcodes.h | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | // Copyright 2021 Paul Cotter (@gr1mr3aver) | ||
| 2 | // Copyright 2024 Fernando Birra | ||
| 3 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 4 | #pragma once | ||
| 5 | |||
| 6 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 7 | // Quantum Painter GC9A01 command opcodes | ||
| 8 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 9 | |||
| 10 | #define GC9A01_SET_MEM_CONT 0x3C // Set memory continue | ||
| 11 | #define GC9A01_SET_BRIGHTNESS 0x51 // Set brightness | ||
| 12 | #define GC9A01_SET_DISPLAY_CTL 0x53 // Set display ctl | ||
| 13 | |||
| 14 | #define GC9A01_SET_RGB_IF_SIG_CTL 0xB0 // RGB IF signal ctl | ||
| 15 | #define GC9A01_SET_BLANKING_PORCH_CTL 0xB5 // Set blanking porch ctl | ||
| 16 | #define GC9A01_SET_FUNCTION_CTL 0xB6 // Set function ctl | ||
| 17 | #define GC9A01_SET_TEARING_EFFECT 0xBA // Set tering effect control | ||
| 18 | #define GC9A01_SET_POWER_CTL_7 0xA7 // Set power ctl 7 | ||
| 19 | #define GC9A01_SET_POWER_CTL_1 0xC1 // Set power ctl 1 | ||
| 20 | #define GC9A01_SET_POWER_CTL_2 0xC3 // Set power ctl 2 | ||
| 21 | #define GC9A01_SET_POWER_CTL_3 0xC4 // Set power ctl 3 | ||
| 22 | #define GC9A01_SET_POWER_CTL_4 0xC9 // Set power ctl 4 | ||
| 23 | #define GC9A01_SET_FRAME_RATE 0xE8 // Set frame rate | ||
| 24 | #define GC9A01_SET_SPI_2DATA 0xE9 // Set frame rate | ||
| 25 | #define GC9A01_SET_GAMMA3 0xF2 // Set gamma 3 | ||
| 26 | #define GC9A01_SET_GAMMA4 0xF3 // Set gamma 4 | ||
| 27 | #define GC9A01_SET_IF_CTL 0xF6 // Set interface control | ||
| 28 | |||
| 29 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 30 | // GC9A01 MADCTL Flags | ||
| 31 | #define GC9A01_MADCTL_MH 0b00000100 | ||
| 32 | |||
| 33 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 34 | // GC9A01 Parameter constants | ||
| 35 | |||
| 36 | // Parameter values for | ||
| 37 | // GC9A01_SET_PIXEL_FORMAT | ||
| 38 | #define GC9A01_PIXEL_FORMAT_12_BPP_DBI (0b011 << 0) // 12 bits/pixel MCU interface format | ||
| 39 | #define GC9A01_PIXEL_FORMAT_16_BPP_DBI (0b101 << 0) // 16 bits/pixel MCU interface format | ||
| 40 | #define GC9A01_PIXEL_FORMAT_18_BPP_DBI (0b110 << 0) // 18 bits/pixel MCU interface format | ||
| 41 | #define GC9A01_PIXEL_FORMAT_16_BPP_DPI (0b101 << 4) // 16 bits/pixel RGB interface format | ||
| 42 | #define GC9A01_PIXEL_FORMAT_18_BPP_DPI (0b110 << 4) // 18 bits/pixel RGB interface format | ||
| 43 | |||
| 44 | // Parameter values for | ||
| 45 | // GC9A01_SET_FUNCTION_CTL (2nd parameter) | ||
| 46 | #define GC9A01_SOURCE_OUTPUT_SCAN_DIRECTION_S1_TO_S360 0b00000000 | ||
| 47 | #define GC9A01_SOURCE_OUTPUT_SCAN_DIRECTION_S360_TO_S1 0b00100000 | ||
| 48 | #define GC9A01_GATE_OUTPUT_SCAN_DIRECTION_G1_TO_G32 0b00000000 | ||
| 49 | #define GC9A01_GATE_OUTPUT_SCAN_DIRECTION_G32_TO_G1 0b01000000 | ||
| 50 | #define GC9A01_SCAN_MODE_INTER 0x10 | ||
| 51 | |||
| 52 | // Parameter values for | ||
| 53 | // GC9A01_SET_FUNCTION_CTL (3rd parameter) | ||
| 54 | #define GC9A01_LCD_DRIVE_LINE_16 0x01 | ||
| 55 | #define GC9A01_LCD_DRIVE_LINE_24 0x02 | ||
| 56 | #define GC9A01_LCD_DRIVE_LINE_32 0x03 | ||
| 57 | #define GC9A01_LCD_DRIVE_LINE_40 0x04 | ||
| 58 | #define GC9A01_LCD_DRIVE_LINE_48 0x05 | ||
| 59 | #define GC9A01_LCD_DRIVE_LINE_56 0x06 | ||
| 60 | #define GC9A01_LCD_DRIVE_LINE_64 0x07 | ||
| 61 | #define GC9A01_LCD_DRIVE_LINE_72 0x08 | ||
| 62 | #define GC9A01_LCD_DRIVE_LINE_80 0x09 | ||
| 63 | #define GC9A01_LCD_DRIVE_LINE_88 0x0A | ||
| 64 | #define GC9A01_LCD_DRIVE_LINE_96 0x0B | ||
| 65 | #define GC9A01_LCD_DRIVE_LINE_104 0x0C | ||
| 66 | #define GC9A01_LCD_DRIVE_LINE_112 0x0D | ||
| 67 | #define GC9A01_LCD_DRIVE_LINE_120 0x0E | ||
| 68 | #define GC9A01_LCD_DRIVE_LINE_128 0x0F | ||
| 69 | #define GC9A01_LCD_DRIVE_LINE_136 0x10 | ||
| 70 | #define GC9A01_LCD_DRIVE_LINE_144 0x11 | ||
| 71 | #define GC9A01_LCD_DRIVE_LINE_152 0x12 | ||
| 72 | #define GC9A01_LCD_DRIVE_LINE_160 0x13 | ||
| 73 | #define GC9A01_LCD_DRIVE_LINE_168 0x14 | ||
| 74 | #define GC9A01_LCD_DRIVE_LINE_176 0x15 | ||
| 75 | #define GC9A01_LCD_DRIVE_LINE_184 0x16 | ||
| 76 | #define GC9A01_LCD_DRIVE_LINE_192 0x17 | ||
| 77 | #define GC9A01_LCD_DRIVE_LINE_200 0x18 | ||
| 78 | #define GC9A01_LCD_DRIVE_LINE_208 0x19 | ||
| 79 | #define GC9A01_LCD_DRIVE_LINE_216 0x1A | ||
| 80 | #define GC9A01_LCD_DRIVE_LINE_224 0x1B | ||
| 81 | #define GC9A01_LCD_DRIVE_LINE_232 0x1C | ||
| 82 | #define GC9A01_LCD_DRIVE_LINE_240 0x1D | ||
| 83 | |||
| 84 | // Parameter values for | ||
| 85 | // GC9A01_SET_DISPLAY_CTL | ||
| 86 | #define GC9A01_BRIGHTNESS_CONTROL_ON 0b00100000 | ||
| 87 | #define GC9A01_DIMMING_ON 0b00001000 | ||
| 88 | #define GC9A01_BACKLIGHT_ON 0b00000100 | ||
| 89 | #define GC9A01_BRIGHTNESS_CONTROL_OFF 0b00000000 | ||
| 90 | #define GC9A01_DIMMING_OFF 0b00000000 | ||
| 91 | #define GC9A01_BACKLIGHT_OFF 0b00000000 | ||
| 92 | |||
| 93 | // Parameter values for | ||
| 94 | // GC9A01_SET_IF_CTL | ||
| 95 | #define GC9A01_DISPLAY_MODE_INTERNAL_CLOCK 0b00000000 | ||
| 96 | #define GC9A01_DISPLAY_MODE_RGB_INTERFACE 0b00000100 | ||
| 97 | #define GC9A01_DISPLAY_MODE_VSYNC_INTERFACE 0b00001000 | ||
| 98 | #define GC9A01_DSISPLAY_MODE_DISABLED 0b00001100 | ||
| 99 | |||
| 100 | #define GC0A01_GRAM_INTERFACE_VSYNC 0b00000000 | ||
| 101 | #define GC9A01_GRAM_INTERFACE_RGB 0b00000010 | ||
| 102 | |||
| 103 | #define GC9A01_RGB_INTERFACE_MODE_1_TRANSFER 0b00000000 | ||
| 104 | #define GC9A01_RGB_INTERFACE_MODE_3_TRANSFER 0b00000001 \ No newline at end of file | ||
diff --git a/drivers/painter/gc9xxx/qp_gc9xxx_opcodes.h b/drivers/painter/gc9xxx/qp_gc9xxx_opcodes.h new file mode 100644 index 0000000000..7e0fbf9110 --- /dev/null +++ b/drivers/painter/gc9xxx/qp_gc9xxx_opcodes.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | // Copyright 2021 Paul Cotter (@gr1mr3aver) | ||
| 2 | // Copyright 2024 Fernando Birra | ||
| 3 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 4 | #pragma once | ||
| 5 | |||
| 6 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 7 | // Quantum Painter GC9xxx command opcodes | ||
| 8 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 9 | |||
| 10 | #define GC9XXX_GET_ID_INFO 0x04 // Get ID information | ||
| 11 | #define GC9XXX_GET_STATUS 0x09 // Get status | ||
| 12 | |||
| 13 | #define GC9XXX_CMD_SLEEP_ON 0x10 // Enter sleep mode | ||
| 14 | #define GC9XXX_CMD_SLEEP_OFF 0x11 // Exit sleep mode | ||
| 15 | #define GC9XXX_CMD_PARTIAL_ON 0x12 // Enter partial mode | ||
| 16 | #define GC9XXX_CMD_PARTIAL_OFF 0x13 // Exit partial mode | ||
| 17 | |||
| 18 | #define GC9XXX_CMD_INVERT_OFF 0x20 // Exit inverted mode | ||
| 19 | #define GC9XXX_CMD_INVERT_ON 0x21 // Enter inverted mode | ||
| 20 | #define GC9XXX_CMD_DISPLAY_OFF 0x28 // Disable display | ||
| 21 | #define GC9XXX_CMD_DISPLAY_ON 0x29 // Enable display | ||
| 22 | #define GC9XXX_SET_COL_ADDR 0x2A // Set column address (MSB(StartCol),LSB(StartCol),MSB(EndCol),LSB(EndCol) | ||
| 23 | #define GC9XXX_SET_ROW_ADDR 0x2B // Set row address (MSB(StartRow),LSB(StartRow),MSB(EndRow),LSB(EndRow) | ||
| 24 | #define GC9XXX_SET_MEM 0x2C // Set (write) memory | ||
| 25 | |||
| 26 | #define GC9XXX_SET_PARTIAL_AREA 0x30 // Set partial area (MSB(StartRow),LSB(StartRow),MSB(EndRow),LSB(EndRow) | ||
| 27 | #define GC9XXX_SET_VSCROLL 0x33 // Set vertical scroll MSB(TFA),LSB(TFA),MSB(VSA),LSB(VSA)+ GC9107 extra param: MSB(BFA),LSB(BFA) | ||
| 28 | #define GC9XXX_CMD_TEARING_OFF 0x34 // Tearing effect line OFF | ||
| 29 | #define GC9XXX_CMD_TEARING_ON 0x35 // Tearing effect line ON | ||
| 30 | #define GC9XXX_SET_MEM_ACS_CTL 0x36 // Set mem access ctl | ||
| 31 | #define GC9XXX_SET_VSCROLL_ADDR 0x37 // Set vscroll start addr | ||
| 32 | #define GC9XXX_CMD_IDLE_OFF 0x38 // Exit idle mode | ||
| 33 | #define GC9XXX_CMD_IDLE_ON 0x39 // Enter idle mode | ||
| 34 | #define GC9XXX_SET_PIXEL_FORMAT 0x3A // Set pixel format | ||
| 35 | #define GC9XXX_SET_TEAR_SCANLINE 0x44 // Set tearing scanline (Scanline = LS bit of Param 1 (GC9A01) + Param 2(GC9XXX)) | ||
| 36 | #define GC9XXX_GET_TEAR_SCANLINE 0x45 // Get tearing scanline (Scanline = LS bit of Param 1 (GC9A01) + Param 2(GC9XXX)) | ||
| 37 | #define GC9XXX_GET_ID1 0xDA // Get ID1 | ||
| 38 | #define GC9XXX_GET_ID2 0xDB // Get ID2 | ||
| 39 | #define GC9XXX_GET_ID3 0xDC // Get ID3 | ||
| 40 | #define GC9XXX_SET_INTER_REG_ENABLE1 0xFE // Enable Inter Register 1 | ||
| 41 | #define GC9XXX_SET_INTER_REG_ENABLE2 0xEF // Enable Inter Register 2 | ||
| 42 | #define GC9XXX_SET_GAMMA1 0xF0 // Set gamma 1 | ||
| 43 | #define GC9XXX_SET_GAMMA2 0xF1 // Set gamma 2 | ||
| 44 | |||
| 45 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 46 | // MADCTL Flags | ||
| 47 | #define GC9XXX_MADCTL_MY 0b10000000 // Mirror Y (row address order) | ||
| 48 | #define GC9XXX_MADCTL_MX 0b01000000 // Mirror X (column address order) | ||
| 49 | #define GC9XXX_MADCTL_MV 0b00100000 // Vertical Refresh Order (bottom to top) | ||
| 50 | #define GC9XXX_MADCTL_ML 0b00010000 | ||
| 51 | #define GC9XXX_MADCTL_BGR 0b00001000 | ||
| 52 | #define GC9XXX_MADCTL_RGB 0b00000000 | ||
| 53 | |||
| 54 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 55 | // GC9XXX Parameter constants | ||
diff --git a/quantum/painter/qp.h b/quantum/painter/qp.h index 02acbf589a..820c418f43 100644 --- a/quantum/painter/qp.h +++ b/quantum/painter/qp.h | |||
| @@ -539,6 +539,12 @@ int16_t qp_drawtext_recolor(painter_device_t device, uint16_t x, uint16_t y, pai | |||
| 539 | # define GC9A01_NUM_DEVICES 0 | 539 | # define GC9A01_NUM_DEVICES 0 |
| 540 | #endif // QUANTUM_PAINTER_GC9A01_ENABLE | 540 | #endif // QUANTUM_PAINTER_GC9A01_ENABLE |
| 541 | 541 | ||
| 542 | #ifdef QUANTUM_PAINTER_GC9107_ENABLE | ||
| 543 | # include "qp_gc9107.h" | ||
| 544 | #else // QUANTUM_PAINTER_GC9107_ENABLE | ||
| 545 | # define GC9107_NUM_DEVICES 0 | ||
| 546 | #endif // QUANTUM_PAINTER_GC9107_ENABLE | ||
| 547 | |||
| 542 | #ifdef QUANTUM_PAINTER_SSD1351_ENABLE | 548 | #ifdef QUANTUM_PAINTER_SSD1351_ENABLE |
| 543 | # include "qp_ssd1351.h" | 549 | # include "qp_ssd1351.h" |
| 544 | #else // QUANTUM_PAINTER_SSD1351_ENABLE | 550 | #else // QUANTUM_PAINTER_SSD1351_ENABLE |
diff --git a/quantum/painter/qp_internal.c b/quantum/painter/qp_internal.c index 1f0f981796..7d4a6430af 100644 --- a/quantum/painter/qp_internal.c +++ b/quantum/painter/qp_internal.c | |||
| @@ -16,6 +16,7 @@ enum { | |||
| 16 | + (ST7789_NUM_DEVICES) // ST7789 | 16 | + (ST7789_NUM_DEVICES) // ST7789 |
| 17 | + (ST7735_NUM_DEVICES) // ST7735 | 17 | + (ST7735_NUM_DEVICES) // ST7735 |
| 18 | + (GC9A01_NUM_DEVICES) // GC9A01 | 18 | + (GC9A01_NUM_DEVICES) // GC9A01 |
| 19 | + (GC9107_NUM_DEVICES) // GC9107 | ||
| 19 | + (SSD1351_NUM_DEVICES) // SSD1351 | 20 | + (SSD1351_NUM_DEVICES) // SSD1351 |
| 20 | + (SH1106_NUM_DEVICES) // SH1106 | 21 | + (SH1106_NUM_DEVICES) // SH1106 |
| 21 | }; | 22 | }; |
diff --git a/quantum/painter/rules.mk b/quantum/painter/rules.mk index d991a6d742..7b2ab702ee 100644 --- a/quantum/painter/rules.mk +++ b/quantum/painter/rules.mk | |||
| @@ -14,6 +14,7 @@ VALID_QUANTUM_PAINTER_DRIVERS := \ | |||
| 14 | st7735_spi \ | 14 | st7735_spi \ |
| 15 | st7789_spi \ | 15 | st7789_spi \ |
| 16 | gc9a01_spi \ | 16 | gc9a01_spi \ |
| 17 | gc9107_spi \ | ||
| 17 | ssd1351_spi \ | 18 | ssd1351_spi \ |
| 18 | sh1106_i2c \ | 19 | sh1106_i2c \ |
| 19 | sh1106_spi | 20 | sh1106_spi |
| @@ -131,10 +132,21 @@ define handle_quantum_painter_driver | |||
| 131 | OPT_DEFS += -DQUANTUM_PAINTER_GC9A01_ENABLE -DQUANTUM_PAINTER_GC9A01_SPI_ENABLE | 132 | OPT_DEFS += -DQUANTUM_PAINTER_GC9A01_ENABLE -DQUANTUM_PAINTER_GC9A01_SPI_ENABLE |
| 132 | COMMON_VPATH += \ | 133 | COMMON_VPATH += \ |
| 133 | $(DRIVER_PATH)/painter/tft_panel \ | 134 | $(DRIVER_PATH)/painter/tft_panel \ |
| 134 | $(DRIVER_PATH)/painter/gc9a01 | 135 | $(DRIVER_PATH)/painter/gc9xxx |
| 135 | SRC += \ | 136 | SRC += \ |
| 136 | $(DRIVER_PATH)/painter/tft_panel/qp_tft_panel.c \ | 137 | $(DRIVER_PATH)/painter/tft_panel/qp_tft_panel.c \ |
| 137 | $(DRIVER_PATH)/painter/gc9a01/qp_gc9a01.c | 138 | $(DRIVER_PATH)/painter/gc9xxx/qp_gc9a01.c |
| 139 | |||
| 140 | else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),gc9107_spi) | ||
| 141 | QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes | ||
| 142 | QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET := yes | ||
| 143 | OPT_DEFS += -DQUANTUM_PAINTER_GC9107_ENABLE -DQUANTUM_PAINTER_GC9107_SPI_ENABLE | ||
| 144 | COMMON_VPATH += \ | ||
| 145 | $(DRIVER_PATH)/painter/tft_panel \ | ||
| 146 | $(DRIVER_PATH)/painter/gc9xxx | ||
| 147 | SRC += \ | ||
| 148 | $(DRIVER_PATH)/painter/tft_panel/qp_tft_panel.c \ | ||
| 149 | $(DRIVER_PATH)/painter/gc9xxx/qp_gc9107.c | ||
| 138 | 150 | ||
| 139 | else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),ssd1351_spi) | 151 | else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),ssd1351_spi) |
| 140 | QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes | 152 | QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes |
