diff --git a/drivers/ili9341/ili9341.c b/drivers/ili9341/ili9341.c index 36212e2be2..11f8ef9892 100644 --- a/drivers/ili9341/ili9341.c +++ b/drivers/ili9341/ili9341.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2018 Koen Zandberg + * 2023 Gunar Schorcht * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -14,6 +15,7 @@ * @brief Device driver implementation for the ili9341 display controller * * @author Koen Zandberg + * @author Gunar Schorcht * * @} */ @@ -22,8 +24,8 @@ #include #include "byteorder.h" #include "periph/spi.h" -#include "ztimer.h" #include "kernel_defines.h" +#include "ztimer.h" #include "ili9341.h" #include "ili9341_internal.h" @@ -33,18 +35,6 @@ #define ENABLE_DEBUG 0 #include "debug.h" -static void _write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data, - size_t len) -{ - gpio_clear(dev->params->dcx_pin); - spi_transfer_byte(dev->params->spi, dev->params->cs_pin, len ? true : false, cmd); - gpio_set(dev->params->dcx_pin); - if (len) { - spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false, data, - NULL, len); - } -} - /* datasheet page 178, table converted to equation. * gvdd in 1mv increments: 4850 = 4.85V */ static uint8_t _ili9341_calc_pwrctl1(uint16_t gvdd) @@ -66,72 +56,57 @@ static uint8_t _ili9341_calc_vml(int16_t vcoml) static int _init(lcd_t *dev, const lcd_params_t *params) { assert(params->lines >= 16 && params->lines <= 320 && !(params->lines & 0x7)); - dev->params = params; - uint8_t command_params[4] = { 0 }; - gpio_init(dev->params->dcx_pin, GPIO_OUT); - int res = spi_init_cs(dev->params->spi, dev->params->cs_pin); - if (res != SPI_OK) { - DEBUG("[ili9341] init: error initializing the CS pin [%i]\n", res); - return -1; - } - if (gpio_is_valid(dev->params->rst_pin)) { - gpio_init(dev->params->rst_pin, GPIO_OUT); - gpio_clear(dev->params->rst_pin); - ztimer_sleep(ZTIMER_MSEC, 120); - gpio_set(dev->params->rst_pin); - } - ztimer_sleep(ZTIMER_MSEC, 120); + uint8_t command_params[4] = { 0 }; /* Acquire once at release at the end */ - spi_acquire(dev->params->spi, dev->params->cs_pin, dev->params->spi_mode, - dev->params->spi_clk); + lcd_ll_acquire(dev); /* Soft Reset */ - _write_cmd(dev, LCD_CMD_SWRESET, NULL, 0); + lcd_ll_write_cmd(dev, LCD_CMD_SWRESET, NULL, 0); ztimer_sleep(ZTIMER_MSEC, 120); /* Display off */ - _write_cmd(dev, LCD_CMD_DISPOFF, NULL, 0); + lcd_ll_write_cmd(dev, LCD_CMD_DISPOFF, NULL, 0); /* PWRCTL1/2 */ command_params[0] = _ili9341_calc_pwrctl1(CONFIG_ILI9341_GVDD); - _write_cmd(dev, LCD_CMD_PWCTRL1, command_params, 1); + lcd_ll_write_cmd(dev, LCD_CMD_PWCTRL1, command_params, 1); command_params[0] = 0x10; /* PWRCTL 0 0 0 */ - _write_cmd(dev, LCD_CMD_PWCTRL2, command_params, 1); + lcd_ll_write_cmd(dev, LCD_CMD_PWCTRL2, command_params, 1); /* VCOMCTL */ command_params[0] = _ili9341_calc_vmh(CONFIG_ILI9341_VCOMH); command_params[1] = _ili9341_calc_vml(CONFIG_ILI9341_VCOML); - _write_cmd(dev, LCD_CMD_VMCTRL1, command_params, 2); + lcd_ll_write_cmd(dev, LCD_CMD_VMCTRL1, command_params, 2); command_params[0] = 0x86; - _write_cmd(dev, LCD_CMD_VMCTRL2, command_params, 1); + lcd_ll_write_cmd(dev, LCD_CMD_VMCTRL2, command_params, 1); /* Memory access CTL */ command_params[0] = dev->params->rotation; command_params[0] |= dev->params->rgb ? 0 : LCD_MADCTL_BGR; - _write_cmd(dev, LCD_CMD_MADCTL, command_params, 1); + lcd_ll_write_cmd(dev, LCD_CMD_MADCTL, command_params, 1); /* Frame control */ command_params[0] = 0x00; command_params[1] = 0x18; - _write_cmd(dev, LCD_CMD_FRAMECTL1, command_params, 2); + lcd_ll_write_cmd(dev, LCD_CMD_FRAMECTL1, command_params, 2); /* Display function control */ command_params[0] = 0x08; command_params[1] = 0x82; /* number of lines, see datasheet p. 166 (DISCTRL::NL) */ command_params[2] = (params->lines >> 3) - 1; - _write_cmd(dev, LCD_CMD_DFUNC, command_params, 3); + lcd_ll_write_cmd(dev, LCD_CMD_DFUNC, command_params, 3); /* Pixel format */ command_params[0] = 0x55; /* 16 bit mode */ - _write_cmd(dev, LCD_CMD_PIXSET, command_params, 1); + lcd_ll_write_cmd(dev, LCD_CMD_PIXSET, command_params, 1); command_params[0] = 0x01; - _write_cmd(dev, LCD_CMD_GAMSET, command_params, 1); + lcd_ll_write_cmd(dev, LCD_CMD_GAMSET, command_params, 1); /* Gamma correction */ { @@ -139,52 +114,34 @@ static int _init(lcd_t *dev, const lcd_params_t *params) 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00 }; - _write_cmd(dev, LCD_CMD_PGAMCTRL, gamma_pos, - sizeof(gamma_pos)); + lcd_ll_write_cmd(dev, LCD_CMD_PGAMCTRL, gamma_pos, + sizeof(gamma_pos)); } { static const uint8_t gamma_neg[] = { 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F }; - _write_cmd(dev, LCD_CMD_NGAMCTRL, gamma_neg, - sizeof(gamma_neg)); + lcd_ll_write_cmd(dev, LCD_CMD_NGAMCTRL, gamma_neg, + sizeof(gamma_neg)); } if (dev->params->inverted) { - _write_cmd(dev, LCD_CMD_DINVON, NULL, 0); + lcd_ll_write_cmd(dev, LCD_CMD_DINVON, NULL, 0); } /* Sleep out (turn off sleep mode) */ - _write_cmd(dev, LCD_CMD_SLPOUT, NULL, 0); + lcd_ll_write_cmd(dev, LCD_CMD_SLPOUT, NULL, 0); /* Display on */ - _write_cmd(dev, LCD_CMD_DISPON, NULL, 0); - spi_release(dev->params->spi); + lcd_ll_write_cmd(dev, LCD_CMD_DISPON, NULL, 0); + + /* Finally release the device */ + lcd_ll_release(dev); + return 0; } -static void _set_area(const lcd_t *dev, uint16_t x1, uint16_t x2, - uint16_t y1, uint16_t y2) -{ - be_uint16_t params[2]; - - x1 += dev->params->offset_x; - x2 += dev->params->offset_x; - y1 += dev->params->offset_y; - y2 += dev->params->offset_y; - - params[0] = byteorder_htons(x1); - params[1] = byteorder_htons(x2); - - _write_cmd(dev, LCD_CMD_CASET, (uint8_t *)params, - sizeof(params)); - params[0] = byteorder_htons(y1); - params[1] = byteorder_htons(y2); - _write_cmd(dev, LCD_CMD_PASET, (uint8_t *)params, - sizeof(params)); -} - const lcd_driver_t lcd_ili9341_driver = { .init = _init, - .set_area = _set_area, + .set_area = NULL, /* default implementation is used */ }; diff --git a/drivers/include/lcd.h b/drivers/include/lcd.h index 8ab2dbb2ce..a29163342f 100644 --- a/drivers/include/lcd.h +++ b/drivers/include/lcd.h @@ -126,6 +126,11 @@ struct lcd_driver { /** * @brief Set area LCD work area * + * This function pointer can be NULL if the controller specific driver + * does not require anything special. In this case the default + * implementation is used which sets the column addresses and the row + * addresses of the area including the coordinates of the opposite corner. + * * @param[in] dev Pointer to the selected driver * @param[in] x1 x coordinate of the first corner * @param[in] x2 x coordinate of the opposite corner @@ -137,6 +142,52 @@ struct lcd_driver { uint16_t y2); }; +/** + * @brief Low Level to acquire the device + * + * @param[out] dev device descriptor + */ +void lcd_ll_acquire(const lcd_t *dev); + +/** + * @brief Low Level function to release the device + * + * @param[out] dev device descriptor + */ +void lcd_ll_release(const lcd_t *dev); + +/** + * @brief Low level function to write a command + * + * @pre The device must have already been acquired with @ref lcd_ll_acquire + * before this function can be called. + * + * @param[in] dev device descriptor + * @param[in] cmd command code + * @param[in] data command data to the device + * @param[in] len length of the command data + */ +void lcd_ll_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data, + size_t len); + +/** + * @brief Low level function for read command command + * + * @note Very often the SPI MISO signal of the serial interface or the RDX + * signal of the MCU 8080 parallel interface are not connected to the + * display. In this case the read command does not provide valid data. + * + * @pre The device must have already been acquired with @ref lcd_ll_acquire + * before this function can be called. + * @pre len > 0 + * + * @param[in] dev device descriptor + * @param[in] cmd command + * @param[out] data data from the device + * @param[in] len length of the returned data + */ +void lcd_ll_read_cmd(const lcd_t *dev, uint8_t cmd, uint8_t *data, size_t len); + /** * @brief Setup an lcd display device * diff --git a/drivers/include/st7735.h b/drivers/include/st7735.h index ccc0e10efa..b9c0c42f62 100644 --- a/drivers/include/st7735.h +++ b/drivers/include/st7735.h @@ -83,7 +83,7 @@ extern "C" { #endif /** - * @name ILI9341 display rotation modes + * @name ST7735 display rotation modes * @{ */ #define ST7735_ROTATION_VERT 0 /**< Vertical mode */ diff --git a/drivers/lcd/lcd.c b/drivers/lcd/lcd.c index bb6b0cfd74..8abe505189 100644 --- a/drivers/lcd/lcd.c +++ b/drivers/lcd/lcd.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2018 Koen Zandberg * 2021 Francisco Molina + * 2023 Gunar Schorcht * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -16,6 +17,7 @@ * * @author Koen Zandberg * @author Francisco Molina + * @author Gunar Schorcht * * @} */ @@ -25,6 +27,7 @@ #include "byteorder.h" #include "periph/spi.h" #include "kernel_defines.h" +#include "ztimer.h" #include "lcd.h" #include "lcd_internal.h" @@ -32,38 +35,155 @@ #define ENABLE_DEBUG 0 #include "debug.h" -static void _lcd_spi_acquire(const lcd_t *dev) +static inline void _lcd_write_byte(const lcd_t *dev, bool cont, uint8_t data) { - spi_acquire(dev->params->spi, dev->params->cs_pin, dev->params->spi_mode, - dev->params->spi_clk); + if (dev->params->spi != SPI_UNDEF) { + /* SPI serial interface is used */ + spi_transfer_byte(dev->params->spi, dev->params->cs_pin, cont, data); + } + else { + assert(false); + } +} + +static inline void _lcd_write_bytes(const lcd_t *dev, bool cont, + const void *data, size_t len) +{ + if (dev->params->spi != SPI_UNDEF) { + /* SPI serial interface is used */ + spi_transfer_bytes(dev->params->spi, + dev->params->cs_pin, cont, data, NULL, len); + } + else { + assert(false); + } +} + +static inline void _lcd_read_bytes(const lcd_t *dev, bool cont, + void *data, size_t len) +{ + if (dev->params->spi != SPI_UNDEF) { + /* SPI serial interface is used */ + /* Dummy read */ + spi_transfer_byte(dev->params->spi, + dev->params->cs_pin, true, 0x00); + spi_transfer_bytes(dev->params->spi, + dev->params->cs_pin, cont, NULL, data, len); + } + else { + assert(false); + } } static void _lcd_cmd_start(const lcd_t *dev, uint8_t cmd, bool cont) { gpio_clear(dev->params->dcx_pin); - spi_transfer_byte(dev->params->spi, dev->params->cs_pin, cont, cmd); + _lcd_write_byte(dev, cont, cmd); gpio_set(dev->params->dcx_pin); } -static void _write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data, - size_t len) +static void _lcd_set_area_default(const lcd_t *dev, uint16_t x1, uint16_t x2, + uint16_t y1, uint16_t y2) { - _lcd_cmd_start(dev, cmd, len ? true : false); - if (len) { - spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false, data, - NULL, len); - } + be_uint16_t params[2]; + + x1 += dev->params->offset_x; + x2 += dev->params->offset_x; + y1 += dev->params->offset_y; + y2 += dev->params->offset_y; + + /* Function is called by a high level function of the LCD driver where + * the device is already acquired. So we don't must acquire it here. + * Therefore the low level write command function is called. */ + + params[0] = byteorder_htons(x1); + params[1] = byteorder_htons(x2); + lcd_ll_write_cmd(dev, LCD_CMD_CASET, (uint8_t *)params, + sizeof(params)); + params[0] = byteorder_htons(y1); + params[1] = byteorder_htons(y2); + lcd_ll_write_cmd(dev, LCD_CMD_PASET, (uint8_t *)params, + sizeof(params)); } static void _lcd_set_area(const lcd_t *dev, uint16_t x1, uint16_t x2, - uint16_t y1, uint16_t y2) + uint16_t y1, uint16_t y2) { - assert(dev->driver->set_area); - dev->driver->set_area(dev, x1, x2, y1, y2); + if (dev->driver->set_area) { + dev->driver->set_area(dev, x1, x2, y1, y2); + } + else { + _lcd_set_area_default(dev, x1, x2, y1, y2); + } +} + +void lcd_ll_acquire(const lcd_t *dev) +{ + if (dev->params->spi != SPI_UNDEF) { + /* SPI serial interface is used */ + spi_acquire(dev->params->spi, dev->params->cs_pin, + dev->params->spi_mode, dev->params->spi_clk); + } + else { + assert(false); + } +} + +void lcd_ll_release(const lcd_t *dev) +{ + if (dev->params->spi != SPI_UNDEF) { + /* SPI serial interface is used */ + spi_release(dev->params->spi); + } + else { + assert(false); + } +} + +void lcd_ll_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data, + size_t len) +{ + _lcd_cmd_start(dev, cmd, len ? true : false); + if (len) { + _lcd_write_bytes(dev, false, data, len); + } +} + +void lcd_ll_read_cmd(const lcd_t *dev, uint8_t cmd, uint8_t *data, size_t len) +{ + assert(len); + _lcd_cmd_start(dev, cmd, len ? true : false); + _lcd_read_bytes(dev, false, data, len); } int lcd_init(lcd_t *dev, const lcd_params_t *params) { + dev->params = params; + + assert(gpio_is_valid(dev->params->dcx_pin)); + gpio_init(dev->params->dcx_pin, GPIO_OUT); + + if (dev->params->spi != SPI_UNDEF) { + /* SPI serial interface is used */ + int res = spi_init_cs(dev->params->spi, dev->params->cs_pin); + + if (res != SPI_OK) { + DEBUG("[st7735] init: error initializing the CS pin [%i]\n", res); + return -1; + } + } + else { + assert(false); + } + + if (gpio_is_valid(dev->params->rst_pin)) { + gpio_init(dev->params->rst_pin, GPIO_OUT); + gpio_clear(dev->params->rst_pin); + ztimer_sleep(ZTIMER_MSEC, 120); + gpio_set(dev->params->rst_pin); + } + ztimer_sleep(ZTIMER_MSEC, 120); + if (dev->driver->init) { return dev->driver->init(dev, params); } @@ -73,28 +193,22 @@ int lcd_init(lcd_t *dev, const lcd_params_t *params) } void lcd_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data, - size_t len) + size_t len) { - _lcd_spi_acquire(dev); - _write_cmd(dev, cmd, data, len); - spi_release(dev->params->spi); + lcd_ll_acquire(dev); + lcd_ll_write_cmd(dev, cmd, data, len); + lcd_ll_release(dev); } void lcd_read_cmd(const lcd_t *dev, uint8_t cmd, uint8_t *data, size_t len) { - assert(len); - _lcd_spi_acquire(dev); - _lcd_cmd_start(dev, cmd, true); - /* Dummy transfer */ - spi_transfer_byte(dev->params->spi, dev->params->cs_pin, true, 0x00); - spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false, NULL, - data, len); - spi_release(dev->params->spi); + lcd_ll_acquire(dev); + lcd_ll_read_cmd(dev, cmd, data, len); + lcd_ll_release(dev); } - void lcd_fill(const lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1, - uint16_t y2, uint16_t color) + uint16_t y2, uint16_t color) { /* Send fill area to the display */ @@ -106,7 +220,7 @@ void lcd_fill(const lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1, x1, x2, y1, y2, (unsigned long)num_pix); /* Send fill area to the display */ - _lcd_spi_acquire(dev); + lcd_ll_acquire(dev); _lcd_set_area(dev, x1, x2, y1, y2); /* Memory access command */ @@ -117,16 +231,14 @@ void lcd_fill(const lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1, } for (int i = 0; i < (num_pix - 1); i++) { - spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, true, - (uint8_t *)&color, NULL, sizeof(color)); + _lcd_write_bytes(dev, true, (uint8_t *)&color, sizeof(color)); } - spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false, - (uint8_t *)&color, NULL, sizeof(color)); - spi_release(dev->params->spi); + _lcd_write_bytes(dev, false, (uint8_t *)&color, sizeof(color)); + lcd_ll_release(dev); } void lcd_pixmap(const lcd_t *dev, uint16_t x1, uint16_t x2, - uint16_t y1, uint16_t y2, const uint16_t *color) + uint16_t y1, uint16_t y2, const uint16_t *color) { size_t num_pix = (x2 - x1 + 1) * (y2 - y1 + 1); @@ -134,7 +246,7 @@ void lcd_pixmap(const lcd_t *dev, uint16_t x1, uint16_t x2, "y1: %" PRIu16 ", y2: %" PRIu16 ". Num pixels: %lu\n", x1, x2, y1, y2, (unsigned long)num_pix); - _lcd_spi_acquire(dev); + lcd_ll_acquire(dev); /* Send fill area to the display */ _lcd_set_area(dev, x1, x2, y1, y2); @@ -145,19 +257,16 @@ void lcd_pixmap(const lcd_t *dev, uint16_t x1, uint16_t x2, if (IS_ACTIVE(CONFIG_LCD_LE_MODE)) { for (size_t i = 0; i < num_pix - 1; i++) { uint16_t ncolor = htons(*(color + i)); - spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, true, - &ncolor, NULL, sizeof(uint16_t)); + _lcd_write_bytes(dev, true, &ncolor, sizeof(uint16_t)); } uint16_t ncolor = htons(*(color + num_pix - 1)); - spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false, - &ncolor, NULL, sizeof(uint16_t)); + _lcd_write_bytes(dev, false, &ncolor, sizeof(uint16_t)); } else { - spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false, - (const uint8_t *)color, NULL, num_pix * 2); + _lcd_write_bytes(dev, false, (const uint8_t *)color, num_pix * 2); } - spi_release(dev->params->spi); + lcd_ll_release(dev); } void lcd_invert_on(const lcd_t *dev) diff --git a/drivers/st7735/Kconfig b/drivers/st7735/Kconfig index 1c873ac3f0..c015fa6398 100644 --- a/drivers/st7735/Kconfig +++ b/drivers/st7735/Kconfig @@ -16,12 +16,6 @@ config MODULE_ST7735 select MODULE_ZTIMER select MODULE_ZTIMER_MSEC -config HAVE_ST7735 - bool - select MODULE_ST7735 if MODULE_DISP_DEV - help - Indicates that an ST7735 display is present. - config MODULE_ST7789 bool depends on HAVE_ST7789 @@ -29,6 +23,12 @@ config MODULE_ST7789 help ST7789 display driver +config HAVE_ST7735 + bool + select MODULE_ST7735 if MODULE_DISP_DEV + help + Indicates that an ST7735 display is present. + config HAVE_ST7789 bool select MODULE_ST7735 if MODULE_DISP_DEV diff --git a/drivers/st7735/st7735.c b/drivers/st7735/st7735.c index 2c7deef504..63ab9fb84b 100644 --- a/drivers/st7735/st7735.c +++ b/drivers/st7735/st7735.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2018 Koen Zandberg * 2021 Francisco Molina + * 2023 Gunar Schorcht * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -16,16 +17,21 @@ * * @author Koen Zandberg * @author Francisco Molina + * @author Gunar Schorcht * * @} */ #include #include + #include "byteorder.h" -#include "periph/spi.h" -#include "ztimer.h" #include "kernel_defines.h" +#include "ztimer.h" + +#if IS_USED(MODULE_LCD_SPI) +#include "periph/spi.h" +#endif #include "st7735.h" #include "st7735_internal.h" @@ -35,18 +41,6 @@ #define ENABLE_DEBUG 0 #include "debug.h" -static void _write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data, - size_t len) -{ - gpio_clear(dev->params->dcx_pin); - spi_transfer_byte(dev->params->spi, dev->params->cs_pin, len ? true : false, cmd); - gpio_set(dev->params->dcx_pin); - if (len) { - spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false, data, - NULL, len); - } -} - /* datasheet page 178, table converted to equation. * gvdd in 1mv increments: 4850 = 4.85V */ static uint8_t _st7735_calc_pwrctl1(uint16_t gvdd) @@ -72,92 +66,75 @@ static int _init(lcd_t *dev, const lcd_params_t *params) else { assert(params->lines <= 162); } - dev->params = params; + uint8_t command_params[4] = { 0 }; - gpio_init(dev->params->dcx_pin, GPIO_OUT); - int res = spi_init_cs(dev->params->spi, dev->params->cs_pin); - - if (res != SPI_OK) { - DEBUG("[st7735] init: error initializing the CS pin [%i]\n", res); - return -1; - } - - if (gpio_is_valid(dev->params->rst_pin)) { - gpio_init(dev->params->rst_pin, GPIO_OUT); - gpio_clear(dev->params->rst_pin); - ztimer_sleep(ZTIMER_MSEC, 120); - gpio_set(dev->params->rst_pin); - } - ztimer_sleep(ZTIMER_MSEC, 120); - - /* Acquire once at release at the end */ - spi_acquire(dev->params->spi, dev->params->cs_pin, dev->params->spi_mode, - dev->params->spi_clk); + /* Acquire once and release at the end */ + lcd_ll_acquire(dev); /* Soft Reset */ - _write_cmd(dev, LCD_CMD_SWRESET, NULL, 0); + lcd_ll_write_cmd(dev, LCD_CMD_SWRESET, NULL, 0); ztimer_sleep(ZTIMER_MSEC, 120); /* Display off */ - _write_cmd(dev, LCD_CMD_DISPOFF, NULL, 0); + lcd_ll_write_cmd(dev, LCD_CMD_DISPOFF, NULL, 0); /* PWRCTL1 */ command_params[0] = _st7735_calc_pwrctl1(CONFIG_ST7735_GVDD); - _write_cmd(dev, LCD_CMD_PWCTRL1, command_params, 1); + lcd_ll_write_cmd(dev, LCD_CMD_PWCTRL1, command_params, 1); /* PWCTR2 VGH = 14.7V, VGL = -7.35V */ command_params[0] = 0x01; command_params[1] = 0x05; - _write_cmd(dev, LCD_CMD_PWCTRL2, command_params, 2); + lcd_ll_write_cmd(dev, LCD_CMD_PWCTRL2, command_params, 2); /* PWCTR3 Opamp current small, Boost frequency */ command_params[0] = 0x02; command_params[1] = 0x01; command_params[2] = 0x02; - _write_cmd(dev, LCD_CMD_PWCTRL3, command_params, 3); + lcd_ll_write_cmd(dev, LCD_CMD_PWCTRL3, command_params, 3); /* PWCTR6 */ command_params[0] = 0x02; command_params[1] = 0x11; command_params[2] = 0x15; - _write_cmd(dev, LCD_CMD_PWCTRL6, command_params, 3); + lcd_ll_write_cmd(dev, LCD_CMD_PWCTRL6, command_params, 3); /* No display Inversion , Line inversion */ command_params[0] = 0x07; - _write_cmd(dev, LCD_CMD_INVCTR, command_params, 1); + lcd_ll_write_cmd(dev, LCD_CMD_INVCTR, command_params, 1); /* VCOMCTL */ command_params[0] = _st7735_calc_vmh(CONFIG_ST7735_VCOMH); command_params[1] = _st7735_calc_vml(CONFIG_ST7735_VCOML); - _write_cmd(dev, LCD_CMD_VMCTRL1, command_params, 2); + lcd_ll_write_cmd(dev, LCD_CMD_VMCTRL1, command_params, 2); command_params[0] = 0x86; - _write_cmd(dev, LCD_CMD_VMCTRL2, command_params, 1); + lcd_ll_write_cmd(dev, LCD_CMD_VMCTRL2, command_params, 1); /* Memory access CTL */ command_params[0] = dev->params->rotation; command_params[0] |= dev->params->rgb ? 0 : LCD_MADCTL_BGR; - _write_cmd(dev, LCD_CMD_MADCTL, command_params, 1); + lcd_ll_write_cmd(dev, LCD_CMD_MADCTL, command_params, 1); /* Frame control */ command_params[0] = 0x00; command_params[1] = 0x18; - _write_cmd(dev, LCD_CMD_FRAMECTL1, command_params, 2); + lcd_ll_write_cmd(dev, LCD_CMD_FRAMECTL1, command_params, 2); /* Display function control */ command_params[0] = 0x08; command_params[1] = 0x82; /* number of lines, see datasheet p. 166 (DISCTRL::NL) */ command_params[2] = (params->lines >> 3) - 1; - _write_cmd(dev, LCD_CMD_DFUNC, command_params, 3); + lcd_ll_write_cmd(dev, LCD_CMD_DFUNC, command_params, 3); /* Pixel format */ command_params[0] = 0x55; /* 16 bit mode */ - _write_cmd(dev, LCD_CMD_PIXSET, command_params, 1); + lcd_ll_write_cmd(dev, LCD_CMD_PIXSET, command_params, 1); command_params[0] = 0x01; - _write_cmd(dev, LCD_CMD_GAMSET, command_params, 1); + lcd_ll_write_cmd(dev, LCD_CMD_GAMSET, command_params, 1); /* Gamma correction */ { @@ -165,57 +142,38 @@ static int _init(lcd_t *dev, const lcd_params_t *params) 0x02, 0x1c, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10 }; - _write_cmd(dev, LCD_CMD_PGAMCTRL, gamma_pos, - sizeof(gamma_pos)); + lcd_ll_write_cmd(dev, LCD_CMD_PGAMCTRL, gamma_pos, + sizeof(gamma_pos)); } { static const uint8_t gamma_neg[] = { 0x03, 0x1d, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10 }; - _write_cmd(dev, LCD_CMD_NGAMCTRL, gamma_neg, - sizeof(gamma_neg)); + lcd_ll_write_cmd(dev, LCD_CMD_NGAMCTRL, gamma_neg, + sizeof(gamma_neg)); } if (dev->params->inverted) { - _write_cmd(dev, LCD_CMD_DINVON, NULL, 0); + lcd_ll_write_cmd(dev, LCD_CMD_DINVON, NULL, 0); } /* Sleep out (turn off sleep mode) */ - _write_cmd(dev, LCD_CMD_SLPOUT, NULL, 0); + lcd_ll_write_cmd(dev, LCD_CMD_SLPOUT, NULL, 0); /* Normal display mode on */ - _write_cmd(dev, LCD_CMD_NORON, NULL, 0); + lcd_ll_write_cmd(dev, LCD_CMD_NORON, NULL, 0); ztimer_sleep(ZTIMER_MSEC, 1); /* Display on */ - _write_cmd(dev, LCD_CMD_DISPON, NULL, 0); - spi_release(dev->params->spi); + lcd_ll_write_cmd(dev, LCD_CMD_DISPON, NULL, 0); + + /* Finally release the device */ + lcd_ll_release(dev); return 0; } -static void _set_area(const lcd_t *dev, uint16_t x1, uint16_t x2, - uint16_t y1, uint16_t y2) -{ - be_uint16_t params[2]; - - x1 += dev->params->offset_x; - x2 += dev->params->offset_x; - y1 += dev->params->offset_y; - y2 += dev->params->offset_y; - - params[0] = byteorder_htons(x1); - params[1] = byteorder_htons(x2); - - _write_cmd(dev, LCD_CMD_CASET, (uint8_t *)params, - sizeof(params)); - params[0] = byteorder_htons(y1); - params[1] = byteorder_htons(y2); - _write_cmd(dev, LCD_CMD_PASET, (uint8_t *)params, - sizeof(params)); -} - const lcd_driver_t lcd_st7735_driver = { .init = _init, - .set_area = _set_area, + .set_area = NULL, /* default implementation is used */ };