display: Add support for an ST7789V based LCD

This adds a driver for st7789v lcd controller, and TL019FQV01 lcd.
The bulk of the driver is based on the existing ili9340 driver.

Signed-off-by: Marc Reilly <marc@cpdesign.com.au>
This commit is contained in:
Marc Reilly 2019-07-04 11:15:33 +01:00 committed by Maureen Helm
commit b0203ac95b
7 changed files with 720 additions and 0 deletions

View file

@ -8,6 +8,7 @@ zephyr_sources_ifdef(CONFIG_SDL_DISPLAY display_sdl.c)
zephyr_sources_ifdef(CONFIG_DUMMY_DISPLAY display_dummy.c)
zephyr_sources_ifdef(CONFIG_FRAMEBUF_DISPLAY display_framebuf.c)
zephyr_sources_ifdef(CONFIG_ILI9340 display_ili9340.c)
zephyr_sources_ifdef(CONFIG_ST7789V display_st7789v.c)
zephyr_sources_ifdef(CONFIG_MICROBIT_DISPLAY
mb_display.c
@ -20,3 +21,7 @@ zephyr_sources_ifdef(CONFIG_ILI9340_LCD_ADAFRUIT_1480
zephyr_sources_ifdef(CONFIG_ILI9340_LCD_SEEED_TFTV2
display_ili9340_seeed_tftv2.c
)
zephyr_sources_ifdef(CONFIG_ST7789V_LCD_TL019FQV01
display_st7789v_tl019fqv01.c
)

View file

@ -24,6 +24,7 @@ source "drivers/display/Kconfig.ili9340"
source "drivers/display/Kconfig.sdl"
source "drivers/display/Kconfig.ssd1306"
source "drivers/display/Kconfig.ssd16xx"
source "drivers/display/Kconfig.st7789v"
source "drivers/display/Kconfig.dummy"
config FRAMEBUF_DISPLAY

View file

@ -0,0 +1,68 @@
# Kconfig - ST7789V display driver configuration options
#
# Copyright (c) 2019 Marc Reilly <marc@cpdesign.com.au>
#
# SPDX-License-Identifier: Apache-2.0
#
menuconfig ST7789V
bool "ST7789V display driver"
depends on SPI
help
Enable driver for ST7789V display driver.
if ST7789V
choice
prompt "LCD"
help
Specify the type of LCD connected to the ST7789V display controller.
config ST7789V_LCD_TL019FQV01
bool "TDO TL019FQV01"
endchoice
choice
prompt "Color pixel format"
default ST7789V_RGB565
help
Specify the color pixel format for the ST7789V display controller.
config ST7789V_RGB888
bool "RGB888"
config ST7789V_RGB565
bool "RGB565"
endchoice
if ST7789V_RGB565
config ST7789V_SWAP_PIXEL_LCD_ENDIANNESS
bool "Swap pixel endianness at LCD"
help
Pixel data bytes are swapped when being blitted to the LCD.
Note that this isn't just a swap of RGB <--> BGR, (if the endianness is
swapped then the 3 lowest bits of G are sent first/last).
You may want to enable this if you are using lvgl and your colors
don't look right.
config ST7789V_REVERSE_LCD_RGB_ORDER
bool "Reverse draw order of controller ram to LCD"
help
This reverses the order that the controller draws RGB to the LCD.
config ST7789V_REVERSE_X
bool "Reverse X axis"
help
Address pixels from right to left.
config ST7789V_REVERSE_Y
bool "Reverse Y axis"
help
Address pixels from bottom to top.
endif #ST7789V_RGB565
endif #ST7789V

View file

@ -0,0 +1,368 @@
/*
* Copyright (c) 2017 Jan Van Winkel <jan.van_winkel@dxplore.eu>
* Copyright (c) 2019 Nordic Semiconductor ASA
* Copyright (c) 2019 Marc Reilly
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "display_st7789v.h"
#include <device.h>
#include <drivers/spi.h>
#include <drivers/gpio.h>
#include <sys/byteorder.h>
#include <drivers/display.h>
#define LOG_LEVEL CONFIG_DISPLAY_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(display_st7789v);
#define ST7789V_CS_PIN DT_INST_0_SITRONIX_ST7789V_CS_GPIOS_PIN
#define ST7789V_CMD_DATA_PIN DT_INST_0_SITRONIX_ST7789V_CMD_DATA_GPIOS_PIN
#define ST7789V_RESET_PIN DT_INST_0_SITRONIX_ST7789V_RESET_GPIOS_PIN
struct st7789v_data {
struct device *spi_dev;
struct spi_config spi_config;
#ifdef DT_INST_0_SITRONIX_ST7789V_CS_GPIOS_CONTROLLER
struct spi_cs_control cs_ctrl;
#endif
#ifdef DT_INST_0_SITRONIX_ST7789V_RESET_GPIOS_CONTROLLER
struct device *reset_gpio;
#endif
struct device *cmd_data_gpio;
u16_t height;
u16_t width;
u16_t x_offset;
u16_t y_offset;
};
#ifdef CONFIG_ST7789V_RGB565
#define ST7789V_PIXEL_SIZE 2u
#else
#define ST7789V_PIXEL_SIZE 3u
#endif
static int st7789v_blanking_off(const struct device *dev);
static int st7789v_blanking_on(const struct device *dev);
void st7789v_set_lcd_margins(struct st7789v_data *data,
u16_t x_offset, u16_t y_offset)
{
data->x_offset = x_offset;
data->y_offset = y_offset;
}
static void st7789v_set_cmd(struct st7789v_data *data, int is_cmd)
{
gpio_pin_write(data->cmd_data_gpio, ST7789V_CMD_DATA_PIN, !is_cmd);
}
void st7789v_transmit(struct st7789v_data *data, u8_t cmd,
u8_t *tx_data, size_t tx_count)
{
struct spi_buf tx_buf = { .buf = &cmd, .len = 1 };
struct spi_buf_set tx_bufs = { .buffers = &tx_buf, .count = 1 };
st7789v_set_cmd(data, true);
spi_write(data->spi_dev, &data->spi_config, &tx_bufs);
if (tx_data != NULL) {
tx_buf.buf = tx_data;
tx_buf.len = tx_count;
st7789v_set_cmd(data, false);
spi_write(data->spi_dev, &data->spi_config, &tx_bufs);
}
}
static void st7789v_exit_sleep(struct st7789v_data *data)
{
st7789v_transmit(data, ST7789V_CMD_SLEEP_OUT, NULL, 0);
k_sleep(120);
}
static void st7789v_reset_display(struct st7789v_data *data)
{
LOG_DBG("Resetting display");
#ifdef DT_INST_0_SITRONIX_ST7789V_RESET_GPIOS_CONTROLLER
gpio_pin_write(data->reset_gpio, ST7789V_RESET_PIN, 1);
k_sleep(1);
gpio_pin_write(data->reset_gpio, ST7789V_RESET_PIN, 0);
k_sleep(6);
gpio_pin_write(data->reset_gpio, ST7789V_RESET_PIN, 1);
k_sleep(20);
#else
st7789v_transmit(p_st7789v, ST7789V_CMD_SW_RESET, NULL, 0);
k_sleep(5);
#endif
}
int st7789v_init(struct device *dev)
{
struct st7789v_data *data = (struct st7789v_data *)dev->driver_data;
data->spi_dev = device_get_binding(DT_INST_0_SITRONIX_ST7789V_BUS_NAME);
if (data->spi_dev == NULL) {
LOG_ERR("Could not get SPI device for LCD");
return -EPERM;
}
data->spi_config.frequency = DT_INST_0_SITRONIX_ST7789V_SPI_MAX_FREQUENCY;
data->spi_config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8);
data->spi_config.slave = DT_INST_0_SITRONIX_ST7789V_BASE_ADDRESS;
#ifdef DT_INST_0_SITRONIX_ST7789V_CS_GPIOS_CONTROLLER
data->cs_ctrl.gpio_dev =
device_get_binding(DT_INST_0_SITRONIX_ST7789V_CS_GPIOS_CONTROLLER);
data->cs_ctrl.gpio_pin = DT_INST_0_SITRONIX_ST7789V_CS_GPIOS_PIN;
data->cs_ctrl.delay = 0U;
data->spi_config.cs = &(data->cs_ctrl);
#else
data->spi_config.cs = NULL;
#endif
#ifdef DT_INST_0_SITRONIX_ST7789V_RESET_GPIOS_CONTROLLER
data->reset_gpio =
device_get_binding(DT_INST_0_SITRONIX_ST7789V_RESET_GPIOS_CONTROLLER);
if (data->reset_gpio == NULL) {
LOG_ERR("Could not get GPIO port for display reset");
return -EPERM;
}
if (gpio_pin_configure(data->reset_gpio, ST7789V_RESET_PIN, GPIO_DIR_OUT)) {
LOG_ERR("Couldn't configure reset pin");
return -EIO;
}
#endif
data->cmd_data_gpio =
device_get_binding(DT_INST_0_SITRONIX_ST7789V_CMD_DATA_GPIOS_CONTROLLER);
if (data->cmd_data_gpio == NULL) {
LOG_ERR("Could not get GPIO port for cmd/DATA port");
return -EPERM;
}
if (gpio_pin_configure(data->cmd_data_gpio, ST7789V_CMD_DATA_PIN,
GPIO_DIR_OUT)) {
LOG_ERR("Couldn't configure cmd/DATA pin");
return -EIO;
}
data->width = 240;
data->height = 320;
data->x_offset = 0;
data->y_offset = 0;
#ifdef DT_INST_0_SITRONIX_ST7789V_WIDTH
data->width = DT_INST_0_SITRONIX_ST7789V_WIDTH;
#endif
#ifdef DT_INST_0_SITRONIX_ST7789V_HEIGHT
data->height = DT_INST_0_SITRONIX_ST7789V_HEIGHT;
#endif
st7789v_reset_display(data);
st7789v_blanking_on(dev);
st7789v_lcd_init(data);
st7789v_exit_sleep(data);
return 0;
}
int st7789v_cmd_read8(struct st7789v_data *data, int cmd, u8_t *pRet)
{
u8_t sendbuff[4];
sendbuff[0] = cmd;
const struct spi_buf tx_buf[2] = {
{ .buf = sendbuff, .len = 1 },
{ .buf = 0, .len = 1 },
};
const struct spi_buf rx_buf[2] = {
{ .buf = 0, .len = 1 },
{ .buf = pRet, .len = 1 }
};
struct spi_buf_set tx_bufs = { .buffers = tx_buf, .count = 2 };
struct spi_buf_set rx_bufs = { .buffers = rx_buf, .count = 2 };
st7789v_set_cmd(data, 1);
int ret = spi_transceive(data->spi_dev, &data->spi_config, &tx_bufs,
&rx_bufs);
st7789v_set_cmd(data, 0);
return ret;
}
static int st7789v_blanking_on(const struct device *dev)
{
struct st7789v_data *driver = (struct st7789v_data *)dev->driver_data;
st7789v_transmit(driver, ST7789V_CMD_DISP_OFF, NULL, 0);
return 0;
}
static int st7789v_blanking_off(const struct device *dev)
{
struct st7789v_data *driver = (struct st7789v_data *)dev->driver_data;
st7789v_transmit(driver, ST7789V_CMD_DISP_ON, NULL, 0);
return 0;
}
static int st7789v_read(const struct device *dev,
const u16_t x,
const u16_t y,
const struct display_buffer_descriptor *desc,
void *buf)
{
return -ENOTSUP;
}
static void st7789v_set_mem_area(struct st7789v_data *data, const u16_t x,
const u16_t y, const u16_t w, const u16_t h)
{
u16_t spi_data[2];
u16_t ram_x = x + data->x_offset;
u16_t ram_y = y + data->y_offset;
spi_data[0] = sys_cpu_to_be16(ram_x);
spi_data[1] = sys_cpu_to_be16(ram_x + w - 1);
st7789v_transmit(data, ST7789V_CMD_CASET, (u8_t *)&spi_data[0], 4);
spi_data[0] = sys_cpu_to_be16(ram_y);
spi_data[1] = sys_cpu_to_be16(ram_y + h - 1);
st7789v_transmit(data, ST7789V_CMD_RASET, (u8_t *)&spi_data[0], 4);
}
static int st7789v_write(const struct device *dev,
const u16_t x,
const u16_t y,
const struct display_buffer_descriptor *desc,
const void *buf)
{
struct st7789v_data *data = (struct st7789v_data *)dev->driver_data;
const u8_t *write_data_start = (u8_t *) buf;
struct spi_buf tx_buf;
struct spi_buf_set tx_bufs;
u16_t write_cnt;
u16_t nbr_of_writes;
u16_t write_h;
__ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width");
__ASSERT((desc->pitch * ST7789V_PIXEL_SIZE * desc->height) <= desc->buf_size,
"Input buffer to small");
LOG_DBG("Writing %dx%d (w,h) @ %dx%d (x,y)",
desc->width, desc->height, x, y);
st7789v_set_mem_area(data, x, y, desc->width, desc->height);
if (desc->pitch > desc->width) {
write_h = 1U;
nbr_of_writes = desc->height;
} else {
write_h = desc->height;
nbr_of_writes = 1U;
}
st7789v_transmit(data, ST7789V_CMD_RAMWR,
(void *) write_data_start,
desc->width * ST7789V_PIXEL_SIZE * write_h);
tx_bufs.buffers = &tx_buf;
tx_bufs.count = 1;
write_data_start += (desc->pitch * ST7789V_PIXEL_SIZE);
for (write_cnt = 1U; write_cnt < nbr_of_writes; ++write_cnt) {
tx_buf.buf = (void *)write_data_start;
tx_buf.len = desc->width * ST7789V_PIXEL_SIZE * write_h;
spi_write(data->spi_dev, &data->spi_config, &tx_bufs);
write_data_start += (desc->pitch * ST7789V_PIXEL_SIZE);
}
return 0;
}
void *st7789v_get_framebuffer(const struct device *dev)
{
return NULL;
}
int st7789v_set_brightness(const struct device *dev,
const u8_t brightness)
{
return -ENOTSUP;
}
int st7789v_set_contrast(const struct device *dev,
const u8_t contrast)
{
return -ENOTSUP;
}
void st7789v_get_capabilities(const struct device *dev,
struct display_capabilities *capabilities)
{
struct st7789v_data *data = (struct st7789v_data *)dev->driver_data;
memset(capabilities, 0, sizeof(struct display_capabilities));
capabilities->x_resolution = data->width;
capabilities->y_resolution = data->height;
#ifdef CONFIG_ST7789V_RGB565
capabilities->supported_pixel_formats = PIXEL_FORMAT_RGB_565;
capabilities->current_pixel_format = PIXEL_FORMAT_RGB_565;
#else
capabilities->supported_pixel_formats = PIXEL_FORMAT_RGB_888;
capabilities->current_pixel_format = PIXEL_FORMAT_RGB_888;
#endif
capabilities->current_orientation = DISPLAY_ORIENTATION_NORMAL;
}
int st7789v_set_pixel_format(const struct device *dev,
const enum display_pixel_format pixel_format)
{
#ifdef CONFIG_ST7789V_RGB565
if (pixel_format == PIXEL_FORMAT_RGB_565) {
#else
if (pixel_format == PIXEL_FORMAT_RGB_888) {
#endif
return 0;
}
LOG_ERR("Pixel format change not implemented");
return -ENOTSUP;
}
int st7789v_set_orientation(const struct device *dev,
const enum display_orientation orientation)
{
if (orientation == DISPLAY_ORIENTATION_NORMAL) {
return 0;
}
LOG_ERR("Changing display orientation not implemented");
return -ENOTSUP;
}
static const struct display_driver_api st7789v_api = {
.blanking_on = st7789v_blanking_on,
.blanking_off = st7789v_blanking_off,
.write = st7789v_write,
.read = st7789v_read,
.get_framebuffer = st7789v_get_framebuffer,
.set_brightness = st7789v_set_brightness,
.set_contrast = st7789v_set_contrast,
.get_capabilities = st7789v_get_capabilities,
.set_pixel_format = st7789v_set_pixel_format,
.set_orientation = st7789v_set_orientation,
};
static struct st7789v_data st7789v_data;
DEVICE_AND_API_INIT(st7789v, DT_INST_0_SITRONIX_ST7789V_LABEL, &st7789v_init,
&st7789v_data, NULL, APPLICATION,
CONFIG_APPLICATION_INIT_PRIORITY, &st7789v_api);

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2019 Marc Reilly
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ST7789V_DISPLAY_DRIVER_H__
#define ST7789V_DISPLAY_DRIVER_H__
#include <zephyr.h>
#define ST7789V_CMD_SW_RESET 0x01
#define ST7789V_CMD_SLEEP_IN 0x10
#define ST7789V_CMD_SLEEP_OUT 0x11
#define ST7789V_CMD_INV_OFF 0x20
#define ST7789V_CMD_INV_ON 0x21
#define ST7789V_CMD_GAMSET 0x26
#define ST7789V_CMD_DISP_OFF 0x28
#define ST7789V_CMD_DISP_ON 0x29
#define ST7789V_CMD_CASET 0x2a
#define ST7789V_CMD_RASET 0x2b
#define ST7789V_CMD_RAMWR 0x2c
#define ST7789V_CMD_MADCTL 0x36
#define ST7789V_MADCTL_MY_TOP_TO_BOTTOM 0x00
#define ST7789V_MADCTL_MY_BOTTOM_TO_TOP 0x80
#define ST7789V_MADCTL_MX_LEFT_TO_RIGHT 0x00
#define ST7789V_MADCTL_MX_RIGHT_TO_LEFT 0x40
#define ST7789V_MADCTL_MV_REVERSE_MODE 0x20
#define ST7789V_MADCTL_MV_NORMAL_MODE 0x00
#define ST7789V_MADCTL_ML 0x10
#define ST7789V_MADCTL_RBG 0x00
#define ST7789V_MADCTL_BGR 0x08
#define ST7789V_MADCTL_MH_LEFT_TO_RIGHT 0x00
#define ST7789V_MADCTL_MH_RIGHT_TO_LEFT 0x04
#define ST7789V_CMD_COLMOD 0x3a
#define ST7789V_COLMOD_RGB_65K (0x5 << 4)
#define ST7789V_COLMOD_RGB_262K (0x6 << 4)
#define ST7789V_COLMOD_FMT_12bit (3)
#define ST7789V_COLMOD_FMT_16bit (5)
#define ST7789V_COLMOD_FMT_18bit (6)
#define ST7789V_CMD_RAMCTRL 0xb0
#define ST7789V_CMD_RGBCTRL 0xb1
#define ST7789V_CMD_PORCTRL 0xb2
#define ST7789V_CMD_CMD2EN 0xdf
#define ST7789V_CMD_DGMEN 0xba
#define ST7789V_CMD_GCTRL 0xb7
#define ST7789V_CMD_VCOMS 0xbb
#define ST7789V_CMD_LCMCTRL 0xc0
#define ST7789V_LCMCTRL_XMY 0x40
#define ST7789V_LCMCTRL_XBGR 0x20
#define ST7789V_LCMCTRL_XINV 0x10
#define ST7789V_LCMCTRL_XMX 0x08
#define ST7789V_LCMCTRL_XMH 0x04
#define ST7789V_LCMCTRL_XMV 0x02
#define ST7789V_CMD_VDVVRHEN 0xc2
#define ST7789V_CMD_VRH 0xc3
#define ST7789V_CMD_VDS 0xc4
#define ST7789V_CMD_FRCTRL2 0xc6
#define ST7789V_CMD_PWCTRL1 0xd0
#define ST7789V_CMD_PVGAMCTRL 0xe0
#define ST7789V_CMD_NVGAMCTRL 0xe1
struct st7789v_data;
void st7789v_set_lcd_margins(struct st7789v_data *data,
u16_t x_offset, u16_t y_offset);
void st7789v_lcd_init(struct st7789v_data *data);
void st7789v_transmit(struct st7789v_data *data, u8_t cmd,
u8_t *tx_data, size_t tx_count);
#endif

View file

@ -0,0 +1,153 @@
/*
* Copyright (c) 2019 Marc Reilly
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "display_st7789v.h"
#include <zephyr.h>
#include <stddef.h>
void st7789v_lcd_init(struct st7789v_data *p_st7789v)
{
/* the LCD itself is smaller than the area of the ram on
* the controller. In its 'natural' orientation the LCD is
* 170 columns and 320 rows which is centered in the controller
* RAM area (so the LCD actually starts at column 35).
* We switch the rows/column addressing around so that the
* display is 320x170, and so the effective LCD is offset
* by 35 "rows".
*/
st7789v_set_lcd_margins(p_st7789v, 0, 35);
u8_t cmd;
u8_t data[14];
cmd = ST7789V_CMD_PORCTRL;
data[0] = 0x0c;
data[1] = 0x0c;
data[2] = 0x00;
data[3] = 0x33;
data[4] = 0x33;
st7789v_transmit(p_st7789v, cmd, data, 5);
cmd = ST7789V_CMD_CMD2EN;
data[0] = 0x5a;
data[1] = 0x69;
data[2] = 0x02;
data[3] = 0x01;
st7789v_transmit(p_st7789v, cmd, data, 4);
cmd = ST7789V_CMD_DGMEN;
data[0] = 0x00;
st7789v_transmit(p_st7789v, cmd, data, 1);
cmd = ST7789V_CMD_GCTRL;
data[0] = 0x35;
st7789v_transmit(p_st7789v, cmd, data, 1);
cmd = ST7789V_CMD_VCOMS;
data[0] = 0x2b;
st7789v_transmit(p_st7789v, cmd, data, 1);
#if CONFIG_ST7789V_REVERSE_LCD_RGB_ORDER
cmd = ST7789V_CMD_LCMCTRL;
data[0] = ST7789V_LCMCTRL_XBGR;
st7789v_transmit(p_st7789v, cmd, data, 1);
#endif
cmd = ST7789V_CMD_VDVVRHEN;
data[0] = 0x01;
st7789v_transmit(p_st7789v, cmd, data, 1);
cmd = ST7789V_CMD_VRH;
data[0] = 0x0f;
st7789v_transmit(p_st7789v, cmd, data, 1);
cmd = ST7789V_CMD_VDS;
data[0] = 0x20;
st7789v_transmit(p_st7789v, cmd, data, 1);
cmd = ST7789V_CMD_FRCTRL2;
data[0] = 0x0f;
st7789v_transmit(p_st7789v, cmd, data, 1);
cmd = ST7789V_CMD_PWCTRL1;
data[0] = 0x52;
data[1] = (0x2 << 6) | (0x2 << 4) | 0x01;
st7789v_transmit(p_st7789v, cmd, data, 2);
cmd = ST7789V_CMD_MADCTL;
data[0] = ST7789V_MADCTL_MV_REVERSE_MODE;
#ifdef CONFIG_ST7789V_REVERSE_X
data[0] |= ST7789V_MADCTL_MX_RIGHT_TO_LEFT;
#endif
#ifdef CONFIG_ST7789V_REVERSE_Y
data[0] |= ST7789V_MADCTL_MY_BOTTOM_TO_TOP;
#endif
st7789v_transmit(p_st7789v, cmd, data, 1);
cmd = ST7789V_CMD_COLMOD;
#ifdef CONFIG_ST7789V_RGB565
data[0] = ST7789V_COLMOD_RGB_65K
| ST7789V_COLMOD_FMT_16bit;
#else
data[0] = ST7789V_COLMOD_RGB_262K
| ST7789V_COLMOD_FMT_18bit;
#endif
st7789v_transmit(p_st7789v, cmd, data, 1);
cmd = ST7789V_CMD_INV_ON;
st7789v_transmit(p_st7789v, cmd, NULL, 0);
cmd = ST7789V_CMD_GAMSET;
data[0] = 0x01U;
st7789v_transmit(p_st7789v, cmd, data, 1);
cmd = ST7789V_CMD_PVGAMCTRL;
data[0] = 0xD0 | 0x00; /* v63 | V0 */
data[1] = 0x00; /* v1 */
data[2] = 0x02; /* v2 */
data[3] = 0x07; /* v4 */
data[4] = 0x0B; /* V6 */
data[5] = (0x01 << 4) | 0x0a; /* J0 | V13 */
data[6] = 0x31; /* V2 */
data[7] = (0x5 << 4) | 0x4; /* V36 | V27 */
data[8] = 0x40; /* V43 */
data[9] = (0x02 << 4) | 0x09; /* J1 | V50 */
data[10] = 0x12; /* V57 */
data[11] = 0x12; /* V59 */
data[12] = 0x12; /* V61 */
data[13] = 0x17; /* V62 */
st7789v_transmit(p_st7789v, cmd, data, 14);
cmd = ST7789V_CMD_NVGAMCTRL;
data[0] = (0xd << 4) | 0x00; /* V63 | V0 */
data[1] = 0x00; /* v1 */
data[2] = 0x02; /* v2 */
data[3] = 0x07; /* v4 */
data[4] = 0x05; /* V6 */
data[5] = (0x01 << 4) | 0x05; /* J0 | V13 */
data[6] = 0x2D; /* V20 */
data[7] = (0x4 << 4) | 0x4; /* V36 | V27 */
data[8] = 0x44; /* V43 */
data[9] = (0x01 << 4) | 0x0c; /* J1 | V50 */
data[10] = 0x18; /* V57 */
data[11] = 0x16; /* V59 */
data[12] = 0x1c; /* V61 */
data[13] = 0x1d; /* V62 */
st7789v_transmit(p_st7789v, cmd, data, 14);
cmd = ST7789V_CMD_RAMCTRL;
data[0] = 0x00;
data[1] = (0x3 << 6) | (0x3u << 4);
#if CONFIG_ST7789V_SWAP_PIXEL_LCD_ENDIANNESS
data[1] |= 0x08;
#endif
st7789v_transmit(p_st7789v, cmd, data, 2);
cmd = ST7789V_CMD_RGBCTRL;
data[0] = 0x80 | (0x2 << 5) | 0xd;
data[1] = 0x08;
data[2] = 0x14;
st7789v_transmit(p_st7789v, cmd, data, 3);
}

View file

@ -0,0 +1,45 @@
#
# Copyright (c) 2019, Marc Reilly <marc@cpdesign.com.au>
#
# SPDX-License-Identifier: Apache-2.0
#
title: ST7789V 320x240 Display Controller
description: >
This is a representation of the ST7789V 320x240 Display Controller
inherits:
!include spi-device.yaml
properties:
compatible:
constraint: "sitronix,st7789v"
reset-gpios:
type: compound
category: required
cmd-data-gpios:
type: compound
category: required
height:
type: int
category: required
description: Height in pixels of the panel driven by the controller
width:
type: int
category: required
description: Width in pixels of the panel driven by the controller
x-offset:
type: int
category: optional
description: The column offset in pixels of the LCD to the controller memory
y-offset:
type: int
category: optional
description: The row offset in pixels of the LCD to the controller memory