feat(driver): add ST7735, ST7789, ST7796, ILI9341 display drivers (#5020)
Co-authored-by: Zoltan Janosy <zjanosy@fishman.com> Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
212
docs/integration/driver/display/gen_mipi.rst
Normal file
212
docs/integration/driver/display/gen_mipi.rst
Normal file
@@ -0,0 +1,212 @@
|
||||
=================================================
|
||||
Generic MIPI DCS compatible LCD Controller driver
|
||||
=================================================
|
||||
|
||||
Overview
|
||||
-------------
|
||||
|
||||
From the `Wikipedia <https://en.wikipedia.org/wiki/MIPI_Alliance>`__:
|
||||
|
||||
`MIPI Allience <https://www.mipi.org/>`__ is a global business alliance that develops technical specifications
|
||||
for the mobile ecosystem, particularly smart phones but including mobile-influenced industries. MIPI was founded in 2003 by Arm, Intel, Nokia, Samsung,
|
||||
STMicroelectronics and Texas Instruments.
|
||||
|
||||
MIPI Allience published a series of specifications related to display devices, including DBI (Display Bus Interface), DSI (Display Serial Interface) and DCS
|
||||
Display Command Set). Usually when one talks about a MIPI-compatible display, one thinks of a device with a DSI serial interface. However, the DBI specification
|
||||
includes a number of other, legacy interfaces, like SPI and a 8080-compatible parallel interface, which are often used to interface LCD displays to microcontrollers.
|
||||
Furthermore, the DCS specification contains a standard command set, which is supported by a large number of legacy TFT LCD controllers, including the popular Sitronix
|
||||
(ST7735, ST7789, ST7796) and Ilitek (ILI9341) SOCs.
|
||||
|
||||
The DCS command set provides a common interface to configure display orientation, color resolution, various power modes, and provide generic video memory access. On top
|
||||
of that standard command set each LCD controller chip has a number of vendor-specific commands to configure voltage generator levels, timings, or gamma curves.
|
||||
|
||||
It is important to understand that this generic MIPI LCD driver is not a hardware driver for displays with DSI interface. Instead, it implements the MIPI DCS command
|
||||
set, and provides a common framework for chip-specific display controllers.
|
||||
|
||||
.. tip::
|
||||
Although this is a generic driver, it can be used to support compatible chips which do not have a specific driver.
|
||||
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
There are no prerequisites.
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the generic MIPI LCD driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_GENERIC_MIPI 1
|
||||
|
||||
.. note::
|
||||
:c:macro:`LV_USE_GENERIC_MIPI` is automatically enabled when a compatible driver is enabled.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
You need to implement two platform-dependent functions:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
/* Send large array of pixel data to the LCD. If necessary, this function has to do the byte-swapping. This function can do the transfer in the background. */
|
||||
int32_t my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
The only difference between the :cpp:func:`my_lcd_send_cmd()` and :cpp:func:`my_lcd_send_color()` functions is that :cpp:func:`my_lcd_send_cmd()` is used to send short commands and it is expected
|
||||
complete the transaction when it returns (in other words, it should be blocking), while :cpp:func:`my_lcd_send_color()` is only used to send pixel data, and it is recommended to use
|
||||
DMA to transmit data in the background. More sophisticated methods can be also implemented, like queing transfers and scheduling them in the background.
|
||||
|
||||
Please note that while display flushing is handled by the driver, it is the user's responsibility to call :cpp:func:`lv_display_flush_ready()`
|
||||
when the color transfer completes. In case of a DMA transfer this is usually done in a transfer ready callback.
|
||||
|
||||
.. note::
|
||||
While it is acceptable to use a blocking implementation for the pixel transfer as well, performance will suffer.
|
||||
|
||||
.. tip::
|
||||
Care must be taken to avoid sending a command while there is an active transfer going on in the background. It is the user's responsibility to implement this either
|
||||
by polling the hardware, polling a global variable (which is reset at the end of the transfer), or by using a semaphore or other locking mechanism.
|
||||
|
||||
Please also note that the driver does not handle the draw buffer allocation, because this may be platform-dependent, too. Thus you need to allocate the buffers and assign them
|
||||
to the display object as usual by calling :cpp:func:`lv_display_set_draw_buffers()`.
|
||||
|
||||
The driver can be used to create multiple displays. In such a configuration the callbacks must be able to distinguish between the displays. Usually one would
|
||||
implement a separate set of callbacks for each display. Also note that the user must take care of arbitrating the bus when multiple devices are connected to it.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. note::
|
||||
You can find the actual implementation of the callbacks on an STM32F746 using STM32CubeIDE and the ST HAL libraries
|
||||
`here <https://github.com/lvgl/lvgl/doc/integration/drivers/display/lcd_stm32_hal.rst>`__.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "src/dev/display/st7789/lv_st7789.h"
|
||||
|
||||
#define LCD_H_RES 240
|
||||
#define LCD_V_RES 320
|
||||
#define LCD_BUF_LINES 60
|
||||
|
||||
lv_display_t *my_disp;
|
||||
|
||||
...
|
||||
|
||||
|
||||
/* Initialize LCD I/O bus, reset LCD */
|
||||
static int32_t my_lcd_io_init(void)
|
||||
{
|
||||
...
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/* Send command to the LCD controller */
|
||||
static void my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
/* Send pixel data to the LCD controller */
|
||||
static void my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
...
|
||||
|
||||
/* Initialize LVGL */
|
||||
lv_init();
|
||||
|
||||
/* Initialize LCD bus I/O */
|
||||
if (my_lcd_io_init() != 0)
|
||||
return;
|
||||
|
||||
/* Create the LVGL display object and the LCD display driver */
|
||||
my_disp = lv_lcd_generic_mipi_create(LCD_H_RES, LCD_V_RES, LV_LCD_FLAG_NONE, my_lcd_send_cmd, my_lcd_send_color);
|
||||
|
||||
/* Set display orientation to landscape */
|
||||
lv_display_set_rotation(my_disp, LV_DISPLAY_ROTATION_90);
|
||||
|
||||
/* Configure draw buffers, etc. */
|
||||
lv_color_t * buf1 = NULL;
|
||||
lv_color_t * buf2 = NULL;
|
||||
|
||||
uint32_t buf_size = LCD_H_RES * LCD_BUF_LINES * lv_color_format_get_size(lv_disp_get_color_format(my_disp));
|
||||
|
||||
buf1 = lv_malloc(buf_size);
|
||||
if(buf1 == NULL) {
|
||||
LV_LOG_ERROR("display draw buffer malloc failed");
|
||||
return;
|
||||
}
|
||||
/* Allocate secondary buffer if needed */
|
||||
...
|
||||
|
||||
lv_display_set_buffers(my_disp, buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
|
||||
ui_init(my_disp);
|
||||
|
||||
while(true) {
|
||||
...
|
||||
|
||||
/* Periodically call the lv_timer handler */
|
||||
lv_timer_handler();
|
||||
}
|
||||
}
|
||||
|
||||
Advanced topics
|
||||
---------------
|
||||
|
||||
Create flags
|
||||
^^^^^^^^^^^^
|
||||
|
||||
The third argument of the :cpp:func:`lv_lcd_generic_mipi_create()` function is a flag array. This can be used to configure the orientation and RGB ordering of the panel if the
|
||||
default settings do not work for you. In particular, the generic MIPI driver accepts the following flags:
|
||||
|
||||
.. code:: c
|
||||
|
||||
LV_LCD_FLAG_NONE
|
||||
LV_LCD_FLAG_MIRROR_X
|
||||
LV_LCD_FLAG_MIRROR_Y
|
||||
LV_LCD_FLAG_BGR
|
||||
|
||||
You can pass multiple flags by ORing them together, e.g., :c:macro:`LV_LCD_FLAG_MIRROR_X | LV_LCD_FLAG_BGR`.
|
||||
|
||||
Custom command lists
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
While the chip-specific drivers do their best to initialize the LCD controller correctly, it is possible, that different TFT panels need different configurations.
|
||||
In particular a correct gamma setup is crucial for good color reproduction. Unfortunately, finding a good set of parameters is not easy. Usually the manufacturer
|
||||
of the panel provides some example code with recommended register settings.
|
||||
|
||||
You can use the ``my_lcd_send_cmd()`` function to send an arbitrary command to the LCD controller. However, to make it easier to send a large number of parameters
|
||||
the generic MIPI driver supports sending a custom command list to the controller. The commands must be put into a 'uint8_t' array:
|
||||
|
||||
.. code:: c
|
||||
|
||||
static const uint8_t init_cmd_list[] = {
|
||||
<command 1>, <number of parameters>, <parameter 1>, ... <parameter N>,
|
||||
<command 2>, <number of parameters>, <parameter 1>, ... <parameter N>,
|
||||
...
|
||||
LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF /* terminate list: this is required! */
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
lv_lcd_generic_mipi_send_cmd_list(my_disp, init_cmd_list);
|
||||
|
||||
You can add a delay between the commands by using the pseudo-command ``LV_LCD_CMD_DELAY_MS``, which must be followed by the delay given in 10ms units.
|
||||
To terminate the command list you must use a delay with a value of ``LV_LCD_CMD_EOF``, as shown above.
|
||||
|
||||
See an actual example of sending a command list `here <https://github.com/lvgl/lvgl/src/dev/display/st7789/lv_st7789.c>`__.
|
||||
@@ -1,5 +1,68 @@
|
||||
=======
|
||||
ILI9341
|
||||
=======
|
||||
=============================
|
||||
ILI9341 LCD Controller driver
|
||||
=============================
|
||||
|
||||
TODO
|
||||
Overview
|
||||
-------------
|
||||
|
||||
The `ILI9341 <https://www.buydisplay.com/download/ic/ILI9341.pdf>`__ is a 262,144-color single-chip SOC driver for a-TFT liquid crystal display with resolution of 240RGBx320
|
||||
dots, comprising a 720-channel source driver, a 320-channel gate driver, 172,800 bytes GRAM for graphic
|
||||
display data of 240RGBx320 dots, and power supply circuit.
|
||||
ILI9341 supports parallel 8-/9-/16-/18-bit data bus MCU interface, 6-/16-/18-bit data bus RGB interface and
|
||||
3-/4-line serial peripheral interface (SPI).
|
||||
|
||||
The ILI9341 LCD controller `driver <https://github.com/lvgl/lvgl/src/dev/display/ili9341>`__ is a platform-agnostic driver, based on the `generic MIPI driver <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
It implements display initialization, supports display rotation and implements the display flush callback. The user needs to implement only two platform-specific functions to send
|
||||
a command or pixel data to the controller via SPI or parallel bus. Typically these are implemented by calling the appropriate SDK library functions on the given platform.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
There are no prerequisites.
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the ILI9341 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_ILI9341 1
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
You need to implement two platform-dependent functions:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
/* Send large array of pixel data to the LCD. If necessary, this function has to do the byte-swapping. This function can do the transfer in the background. */
|
||||
int32_t my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
To create an ILI9341-based display use the function
|
||||
|
||||
.. code:: c
|
||||
|
||||
/**
|
||||
* Create an LCD display with ILI9341 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_ili9341_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_ili9341_send_cmd_cb_t send_cmd_cb, lv_ili9341_send_color_cb_t send_color_cb);
|
||||
|
||||
|
||||
For additional details and a working example see the `generic MIPI driver documentation <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
|
||||
@@ -6,3 +6,6 @@ Display
|
||||
:maxdepth: 2
|
||||
|
||||
ili9341
|
||||
st7735
|
||||
st7789
|
||||
st7796
|
||||
|
||||
109
docs/integration/driver/display/lcd_stm32_hal.rst
Normal file
109
docs/integration/driver/display/lcd_stm32_hal.rst
Normal file
@@ -0,0 +1,109 @@
|
||||
==================================================================================================
|
||||
LCD driver SPI bus I/O implementation example for STM32 devices using the STM32Cube HAL SPI driver
|
||||
==================================================================================================
|
||||
|
||||
This is an example implementation of an SPI bus driver using STM32CubeIDE and the ST HAL libraries, tested on a Nucleo-F746ZG board. This code example only implements
|
||||
the LCD driver specific parts, so you still have to configure the hardware using STM32CubeMX or STM32CubeIDE. It is not meant as the best possible implementation,
|
||||
but since it uses DMA for the pixel transfer, it has a good performance.
|
||||
|
||||
To use this code without change you need to name the appropriate GPIO pins as follows:
|
||||
|
||||
.. code:: c
|
||||
|
||||
LCD_RESET /* Reset */
|
||||
LCD_CS /* Chip Select */
|
||||
LCD_DCX /* Data/Command Select */
|
||||
|
||||
The example code uses the SPI1 port. The SPI controller of the STM32F746 is capable of 16-bit transfers, and it can swap the 16-bit pixel data bytes on the fly, so
|
||||
there is no need to do this in software. This improves the performance considerably.
|
||||
|
||||
This code implements a rather simple locking mechanism using a global variable :cpp:var:`my_disp_bus_busy` to prevent accessing the controller while there is a DMA transfer
|
||||
going on in the background. In a more sophisticated implementation this could be replaced with a semaphore or a transaction queue.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include "lvgl.h"
|
||||
|
||||
...
|
||||
|
||||
lv_display_t *my_disp;
|
||||
volatile int my_disp_bus_busy = 0;
|
||||
|
||||
...
|
||||
|
||||
/* DMA transfer ready callback */
|
||||
static void my_lcd_color_transfer_ready_cb(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
/* CS high */
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
my_disp_bus_busy = 0;
|
||||
lv_display_flush_ready(my_disp);
|
||||
}
|
||||
|
||||
/* Initialize LCD I/O bus, reset LCD */
|
||||
static int32_t my_lcd_io_init(void)
|
||||
{
|
||||
/* Register SPI Tx Complete Callback */
|
||||
HAL_SPI_RegisterCallback(&hspi1, HAL_SPI_TX_COMPLETE_CB_ID, stm32_lcd_color_transfer_ready_cb);
|
||||
|
||||
/* reset LCD */
|
||||
HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_RESET);
|
||||
HAL_Delay(100);
|
||||
HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_SET);
|
||||
HAL_Delay(100);
|
||||
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||
static void my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
LV_UNUSED(disp);
|
||||
/* Set the SPI in 8-bit mode */
|
||||
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
HAL_SPI_Init(&hspi1);
|
||||
/* DCX low (command) */
|
||||
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_RESET);
|
||||
/* CS low */
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
|
||||
/* send command */
|
||||
if (HAL_SPI_Transmit(&hspi1, cmd, cmd_size, BUS_SPI1_POLL_TIMEOUT) == HAL_OK) {
|
||||
/* DCX high (data) */
|
||||
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
|
||||
/* for short data blocks we use polling transfer */
|
||||
HAL_SPI_Transmit(&hspi1, (uint8_t *)param, (uint16_t)param_size, BUS_SPI1_POLL_TIMEOUT);
|
||||
/* CS high */
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
}
|
||||
|
||||
/* Send large array of pixel data to the LCD. If necessary, this function has to do the byte-swapping. This function can do the transfer in the background. */
|
||||
static void my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
LV_UNUSED(disp);
|
||||
while (my_disp_bus_busy); /* wait until previous transfer is finished */
|
||||
/* Set the SPI in 8-bit mode */
|
||||
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
HAL_SPI_Init(&hspi1);
|
||||
/* DCX low (command) */
|
||||
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_RESET);
|
||||
/* CS low */
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
|
||||
/* send command */
|
||||
if (HAL_SPI_Transmit(&hspi1, cmd, cmd_size, BUS_SPI1_POLL_TIMEOUT) == HAL_OK) {
|
||||
/* DCX high (data) */
|
||||
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
|
||||
/* for color data use DMA transfer */
|
||||
/* Set the SPI in 16-bit mode to match endianess */
|
||||
hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
|
||||
HAL_SPI_Init(&hspi1);
|
||||
my_disp_bus_busy = 1;
|
||||
HAL_SPI_Transmit_DMA(&hspi1, param, (uint16_t)param_size / 2);
|
||||
|
||||
/* NOTE: CS will be reset in the transfer ready callback */
|
||||
}
|
||||
}
|
||||
70
docs/integration/driver/display/st7735.rst
Normal file
70
docs/integration/driver/display/st7735.rst
Normal file
@@ -0,0 +1,70 @@
|
||||
=============================
|
||||
ST7735 LCD Controller driver
|
||||
=============================
|
||||
|
||||
Overview
|
||||
-------------
|
||||
|
||||
The `ST7735S <https://www.buydisplay.com/download/ic/ST7735S.pdf>`__ is a single-chip controller/driver for 262K-color, graphic type TFT-LCD. It consists of 396
|
||||
source line and 162 gate line driving circuits. This chip is capable of connecting directly to an external
|
||||
microprocessor, and accepts Serial Peripheral Interface (SPI), 8-bit/9-bit/16-bit/18-bit parallel interface.
|
||||
Display data can be stored in the on-chip display data RAM of 132 x 162 x 18 bits. It can perform display data
|
||||
RAM read/write operation with no external operation clock to minimize power consumption. In addition,
|
||||
because of the integrated power supply circuits necessary to drive liquid crystal, it is possible to make a
|
||||
display system with fewer components.
|
||||
|
||||
The ST7735 LCD controller `driver <https://github.com/lvgl/lvgl/src/dev/display/st7735>`__ is a platform-agnostic driver, based on the `generic MIPI driver <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
It implements display initialization, supports display rotation and implements the display flush callback. The user needs to implement only two platform-specific functions to send
|
||||
a command or pixel data to the controller via SPI or parallel bus. Typically these are implemented by calling the appropriate SDK library functions on the given platform.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
There are no prerequisites.
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the ST7735 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_ST7735 1
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
You need to implement two platform-dependent functions:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
/* Send large array of pixel data to the LCD. If necessary, this function has to do the byte-swapping. This function can do the transfer in the background. */
|
||||
int32_t my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
To create an ST7735-based display use the function
|
||||
|
||||
.. code:: c
|
||||
|
||||
/**
|
||||
* Create an LCD display with ST7735 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_st7735_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7735_send_cmd_cb_t send_cmd_cb, lv_st7735_send_color_cb_t send_color_cb);
|
||||
|
||||
|
||||
For additional details and a working example see the `generic MIPI driver documentation <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
69
docs/integration/driver/display/st7789.rst
Normal file
69
docs/integration/driver/display/st7789.rst
Normal file
@@ -0,0 +1,69 @@
|
||||
=============================
|
||||
ST7789 LCD Controller driver
|
||||
=============================
|
||||
|
||||
Overview
|
||||
-------------
|
||||
|
||||
The `ST7789 <https://www.buydisplay.com/download/ic/ST7789.pdf>`__ is a single-chip controller/driver for 262K-color, graphic type TFT-LCD. It consists of 720
|
||||
source line and 320 gate line driving circuits. This chip is capable of connecting directly to an external
|
||||
microprocessor, and accepts, 8-bits/9-bits/16-bits/18-bits parallel interface. Display data can be stored in the
|
||||
on-chip display data RAM of 240x320x18 bits. It can perform display data RAM read/write operation with no
|
||||
external operation clock to minimize power consumption. In addition, because of the integrated power supply
|
||||
circuit necessary to drive liquid crystal; it is possible to make a display system with the fewest components.
|
||||
|
||||
The ST7789 LCD controller `driver <https://github.com/lvgl/lvgl/src/dev/display/st7789>`__ is a platform-agnostic driver, based on the `generic MIPI driver <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
It implements display initialization, supports display rotation and implements the display flush callback. The user needs to implement only two platform-specific functions to send
|
||||
a command or pixel data to the controller via SPI or parallel bus. Typically these are implemented by calling the appropriate SDK library functions on the given platform.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
There are no prerequisites.
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the ST7789 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_ST7789 1
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
You need to implement two platform-dependent functions:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
/* Send large array of pixel data to the LCD. If necessary, this function has to do the byte-swapping. This function can do the transfer in the background. */
|
||||
int32_t my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
To create an ST7789-based display use the function
|
||||
|
||||
.. code:: c
|
||||
|
||||
/**
|
||||
* Create an LCD display with ST7789 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_st7789_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7789_send_cmd_cb_t send_cmd_cb, lv_st7789_send_color_cb_t send_color_cb);
|
||||
|
||||
|
||||
For additional details and a working example see the `generic MIPI driver documentation <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
70
docs/integration/driver/display/st7796.rst
Normal file
70
docs/integration/driver/display/st7796.rst
Normal file
@@ -0,0 +1,70 @@
|
||||
=============================
|
||||
ST7796 LCD Controller driver
|
||||
=============================
|
||||
|
||||
Overview
|
||||
-------------
|
||||
|
||||
The `ST7796S <https://www.buydisplay.com/download/ic/ST7796S.pdf>`__ is a single-chip controller/driver for 262K-color, graphic type TFT-LCD. It consists of 960
|
||||
source lines and 480 gate lines driving circuits. The ST7796S is capable of connecting directly to an external
|
||||
microprocessor, and accepts 8-bit/9-bit/16-bit/18-bit parallel interface, SPI, and the ST7796S also provides
|
||||
MIPI interface. Display data can be stored in the on-chip display data RAM of 320x480x18 bits. It can perform
|
||||
display data RAM read-/write-operation with no external clock to minimize power consumption. In addition,
|
||||
because of the integrated power supply circuit necessary to drive liquid crystal; it is possible to make a display
|
||||
system with fewest components.
|
||||
|
||||
The ST7796 LCD controller `driver <https://github.com/lvgl/lvgl/src/dev/display/st7796>`__ is a platform-agnostic driver, based on the `generic MIPI driver <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
It implements display initialization, supports display rotation and implements the display flush callback. The user needs to implement only two platform-specific functions to send
|
||||
a command or pixel data to the controller via SPI or parallel bus. Typically these are implemented by calling the appropriate SDK library functions on the given platform.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
There are no prerequisites.
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the ST7796 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_ST7796 1
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
You need to implement two platform-dependent functions:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
/* Send large array of pixel data to the LCD. If necessary, this function has to do the byte-swapping. This function can do the transfer in the background. */
|
||||
int32_t my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
To create an ST7796-based display use the function
|
||||
|
||||
.. code:: c
|
||||
|
||||
/**
|
||||
* Create an LCD display with ST7796 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_st7796_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7796_send_cmd_cb_t send_cmd_cb, lv_st7796_send_color_cb_t send_color_cb);
|
||||
|
||||
|
||||
For additional details and a working example see the `generic MIPI driver documentation <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
@@ -856,6 +856,15 @@
|
||||
/*Driver for evdev input devices*/
|
||||
#define LV_USE_EVDEV 0
|
||||
|
||||
/*Drivers for LCD devices connected via SPI/parallel port*/
|
||||
#define LV_USE_ST7735 0
|
||||
#define LV_USE_ST7789 0
|
||||
#define LV_USE_ST7796 0
|
||||
#define LV_USE_ILI9341 0
|
||||
|
||||
#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)
|
||||
|
||||
|
||||
/*==================
|
||||
* EXAMPLES
|
||||
*==================*/
|
||||
|
||||
117
src/dev/display/ili9341/lv_ili9341.c
Normal file
117
src/dev/display/ili9341/lv_ili9341.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* @file lv_ili9341.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_ili9341.h"
|
||||
|
||||
#if LV_USE_ILI9341
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define CMD_FRMCTR1 0xB1 /* Frame Rate Control (In Normal Mode/Full Colors) */
|
||||
#define CMD_FRMCTR2 0xB2 /* Frame Rate Control (In Idle Mode/8 colors) */
|
||||
#define CMD_FRMCTR3 0xB3 /* Frame Rate control (In Partial Mode/Full Colors) */
|
||||
#define CMD_INVCTR 0xB4 /* Display Inversion Control */
|
||||
#define CMD_DFUNCTR 0xB6 /* Display Function Control */
|
||||
#define CMD_PWCTR1 0xC0 /* Power Control 1 */
|
||||
#define CMD_PWCTR2 0xC1 /* Power Control 2 */
|
||||
#define CMD_VMCTR1 0xC5 /* VCOM Control 1 */
|
||||
#define CMD_VMCTR2 0xC7 /* VCOM Control 2 */
|
||||
#define CMD_PWCTRA 0xCB /* Power Control A */
|
||||
#define CMD_PWCTRB 0xCF /* Power Control B */
|
||||
#define CMD_GMCTRP1 0xE0 /* Positive Gamma Correction */
|
||||
#define CMD_GMCTRN1 0xE1 /* Negative Gamma Correction */
|
||||
#define CMD_DTCTRA 0xE8 /* Driver timing control A */
|
||||
#define CMD_DTCTRB 0xEA /* Driver timing control B */
|
||||
#define CMD_PONSEQ 0xED /* Power On Sequence */
|
||||
#define CMD_RDINDEX 0xD9 /* ili9341 */
|
||||
#define CMD_IDXRD 0xDD /* ILI9341 only, indexed control register read */
|
||||
#define CMD_ENA3G 0xF2 /* Enable 3 Gamma control */
|
||||
#define CMD_IFCTR 0xF6 /* Interface Control */
|
||||
#define CMD_PRCTR 0xF7 /* Pump ratio control */
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC CONSTANTS
|
||||
**********************/
|
||||
|
||||
/* init commands based on LovyanGFX ILI9341 driver */
|
||||
static const uint8_t init_cmd_list[] = {
|
||||
CMD_PWCTRB, 3, 0x00, 0xC1, 0x30,
|
||||
CMD_PONSEQ, 4, 0x64, 0x03, 0x12, 0x81,
|
||||
CMD_DTCTRA, 3, 0x85, 0x00, 0x78,
|
||||
CMD_PWCTRA, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
||||
CMD_PRCTR, 1, 0x20,
|
||||
CMD_DTCTRB, 2, 0x00, 0x00,
|
||||
CMD_PWCTR1, 1, 0x23,
|
||||
CMD_PWCTR2, 1, 0x10,
|
||||
CMD_VMCTR1, 2, 0x3e, 0x28,
|
||||
CMD_VMCTR2, 1, 0x86,
|
||||
CMD_FRMCTR1, 2, 0x00, 0x13,
|
||||
CMD_DFUNCTR, 2, 0x0A, 0xA2,
|
||||
CMD_IFCTR, 3, 0x09, 0x30, 0x00,
|
||||
CMD_ENA3G, 1, 0x00,
|
||||
LV_LCD_CMD_SET_GAMMA_CURVE, 1, 0x01,
|
||||
CMD_GMCTRP1, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
|
||||
CMD_GMCTRN1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
|
||||
LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_ili9341_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_ili9341_send_cmd_cb_t send_cmd_cb, lv_ili9341_send_color_cb_t send_color_cb)
|
||||
{
|
||||
lv_display_t * disp = lv_lcd_generic_mipi_create(hor_res, ver_res, flags, send_cmd_cb, send_color_cb);
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list);
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lv_ili9341_set_gap(lv_display_t * disp, uint16_t x, uint16_t y)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gap(disp, x, y);
|
||||
}
|
||||
|
||||
void lv_ili9341_set_invert(lv_display_t * disp, bool invert)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_invert(disp, invert);
|
||||
}
|
||||
|
||||
void lv_ili9341_set_gamma_curve(lv_display_t * disp, uint8_t gamma)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gamma_curve(disp, gamma);
|
||||
}
|
||||
|
||||
void lv_ili9341_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list)
|
||||
{
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, cmd_list);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ILI9341*/
|
||||
93
src/dev/display/ili9341/lv_ili9341.h
Normal file
93
src/dev/display/ili9341/lv_ili9341.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* lv_ili9341.h
|
||||
*
|
||||
* This driver is just a wrapper around the generic MIPI compatible LCD controller driver
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ILI9341_H
|
||||
#define LV_ILI9341_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../lcd/lv_lcd_generic_mipi.h"
|
||||
|
||||
#if LV_USE_ILI9341
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef lv_lcd_send_cmd_cb_t lv_ili9341_send_cmd_cb_t;
|
||||
typedef lv_lcd_send_color_cb_t lv_ili9341_send_color_cb_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an LCD display with ILI9341 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_ili9341_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_ili9341_send_cmd_cb_t send_cmd_cb, lv_ili9341_send_color_cb_t send_color_cb);
|
||||
|
||||
/**
|
||||
* Set gap, i.e., the offset of the (0,0) pixel in the VRAM
|
||||
* @param disp display object
|
||||
* @param x x offset
|
||||
* @param y y offset
|
||||
*/
|
||||
void lv_ili9341_set_gap(lv_display_t * disp, uint16_t x, uint16_t y);
|
||||
|
||||
/**
|
||||
* Set color inversion
|
||||
* @param disp display object
|
||||
* @param invert false: normal, true: invert
|
||||
*/
|
||||
void lv_ili9341_set_invert(lv_display_t * disp, bool invert);
|
||||
|
||||
/**
|
||||
* Set gamma curve
|
||||
* @param disp display object
|
||||
* @param gamma gamma curve
|
||||
*/
|
||||
void lv_ili9341_set_gamma_curve(lv_display_t * disp, uint8_t gamma);
|
||||
|
||||
/**
|
||||
* Send list of commands.
|
||||
* @param disp display object
|
||||
* @param cmd_list controller and panel-specific commands
|
||||
*/
|
||||
void lv_ili9341_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list);
|
||||
|
||||
/**********************
|
||||
* OTHERS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_ILI9341*/
|
||||
|
||||
#endif /* LV_ILI9341_H */
|
||||
340
src/dev/display/lcd/lv_lcd_generic_mipi.c
Normal file
340
src/dev/display/lcd/lv_lcd_generic_mipi.c
Normal file
@@ -0,0 +1,340 @@
|
||||
/**
|
||||
* @file lv_lcd_generic_mipi.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_lcd_generic_mipi.h"
|
||||
|
||||
#if LV_USE_GENERIC_MIPI
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void send_cmd(lv_lcd_generic_mipi_driver_t * drv, uint8_t cmd, uint8_t * param, size_t param_size);
|
||||
static void send_color(lv_lcd_generic_mipi_driver_t * drv, uint8_t cmd, uint8_t * param, size_t param_size);
|
||||
static void init(lv_lcd_generic_mipi_driver_t * drv, lv_lcd_flag_t flags);
|
||||
static void set_mirror(lv_lcd_generic_mipi_driver_t * drv, bool mirror_x, bool mirror_y);
|
||||
static void set_swap_xy(lv_lcd_generic_mipi_driver_t * drv, bool swap);
|
||||
static void set_rotation(lv_lcd_generic_mipi_driver_t * drv, lv_display_rotation_t rot);
|
||||
static void res_chg_event_cb(lv_event_t * e);
|
||||
static lv_lcd_generic_mipi_driver_t * get_driver(lv_display_t * disp);
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_lcd_generic_mipi_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_lcd_send_cmd_cb_t send_cmd_cb, lv_lcd_send_color_cb_t send_color_cb)
|
||||
{
|
||||
lv_display_t * disp = lv_display_create(hor_res, ver_res);
|
||||
if(disp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_lcd_generic_mipi_driver_t * drv = (lv_lcd_generic_mipi_driver_t *)lv_malloc(sizeof(lv_lcd_generic_mipi_driver_t));
|
||||
if(drv == NULL) {
|
||||
lv_display_delete(disp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* init driver struct */
|
||||
drv->disp = disp;
|
||||
drv->send_cmd = send_cmd_cb;
|
||||
drv->send_color = send_color_cb;
|
||||
lv_display_set_driver_data(disp, (void *)drv);
|
||||
|
||||
/* init controller */
|
||||
init(drv, flags);
|
||||
|
||||
/* register resolution change callback (NOTE: this handles screen rotation as well) */
|
||||
lv_display_add_event_cb(disp, res_chg_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL);
|
||||
|
||||
/* register flush callback */
|
||||
lv_display_set_flush_cb(disp, flush_cb);
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lv_lcd_generic_mipi_set_gap(lv_display_t * disp, uint16_t x, uint16_t y)
|
||||
{
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
drv->x_gap = x;
|
||||
drv->y_gap = y;
|
||||
}
|
||||
|
||||
void lv_lcd_generic_mipi_set_invert(lv_display_t * disp, bool invert)
|
||||
{
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
send_cmd(drv, invert ? LV_LCD_CMD_ENTER_INVERT_MODE : LV_LCD_CMD_EXIT_INVERT_MODE, NULL, 0);
|
||||
}
|
||||
|
||||
void lv_lcd_generic_mipi_set_address_mode(lv_display_t * disp, bool mirror_x, bool mirror_y, bool swap_xy, bool bgr)
|
||||
{
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
uint8_t mad = drv->madctl_reg & ~(LV_LCD_MASK_RGB_ORDER);
|
||||
if(bgr) {
|
||||
mad |= LV_LCD_BIT_RGB_ORDER__BGR;
|
||||
}
|
||||
drv->madctl_reg = mad;
|
||||
drv->mirror_x = mirror_x;
|
||||
drv->mirror_y = mirror_y;
|
||||
drv->swap_xy = swap_xy;
|
||||
set_rotation(drv, lv_display_get_rotation(disp)); /* update screen */
|
||||
}
|
||||
|
||||
void lv_lcd_generic_mipi_set_gamma_curve(lv_display_t * disp, uint8_t gamma)
|
||||
{
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
send_cmd(drv, LV_LCD_CMD_SET_GAMMA_CURVE, (uint8_t[]) {
|
||||
gamma,
|
||||
}, 1);
|
||||
}
|
||||
|
||||
void lv_lcd_generic_mipi_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list)
|
||||
{
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
while(1) {
|
||||
uint8_t cmd = *cmd_list++;
|
||||
uint8_t num = *cmd_list++;
|
||||
if(cmd == LV_LCD_CMD_DELAY_MS) {
|
||||
if(num == LV_LCD_CMD_EOF) /* end of list */
|
||||
break;
|
||||
else { /* delay in 10 ms units*/
|
||||
lv_delay_ms((uint32_t)(num) * 10);
|
||||
}
|
||||
}
|
||||
else {
|
||||
drv->send_cmd(drv->disp, &cmd, 1, cmd_list, num);
|
||||
cmd_list += num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Helper function to call the user-supplied 'send_cmd' function
|
||||
* @param drv LCD driver object
|
||||
* @param cmd command byte
|
||||
* @param param parameter buffer
|
||||
* @param param_size number of bytes of the parameters
|
||||
*/
|
||||
static void send_cmd(lv_lcd_generic_mipi_driver_t * drv, uint8_t cmd, uint8_t * param, size_t param_size)
|
||||
{
|
||||
uint8_t cmdbuf = cmd; /* MIPI uses 8 bit commands */
|
||||
drv->send_cmd(drv->disp, &cmdbuf, 1, param, param_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to call the user-supplied 'send_color' function
|
||||
* @param drv LCD driver object
|
||||
* @param cmd command byte
|
||||
* @param param parameter buffer
|
||||
* @param param_size number of bytes of the parameters
|
||||
*/
|
||||
static void send_color(lv_lcd_generic_mipi_driver_t * drv, uint8_t cmd, uint8_t * param, size_t param_size)
|
||||
{
|
||||
uint8_t cmdbuf = cmd; /* MIPI uses 8 bit commands */
|
||||
drv->send_color(drv->disp, &cmdbuf, 1, param, param_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize LCD driver after a hard reset
|
||||
* @param drv LCD driver object
|
||||
*/
|
||||
static void init(lv_lcd_generic_mipi_driver_t * drv, lv_lcd_flag_t flags)
|
||||
{
|
||||
drv->x_gap = 0;
|
||||
drv->y_gap = 0;
|
||||
|
||||
/* init color mode and RGB order */
|
||||
drv->madctl_reg = flags & LV_LCD_FLAG_BGR ? LV_LCD_BIT_RGB_ORDER__BGR : LV_LCD_BIT_RGB_ORDER__RGB;
|
||||
drv->colmod_reg = flags & LV_LCD_FLAG_RGB666 ? LV_LCD_PIXEL_FORMAT_RGB666 : LV_LCD_PIXEL_FORMAT_RGB565;
|
||||
|
||||
/* init orientation */
|
||||
drv->mirror_x = flags & LV_LCD_FLAG_MIRROR_X;
|
||||
drv->mirror_y = flags & LV_LCD_FLAG_MIRROR_Y;
|
||||
drv->swap_xy = false;
|
||||
/* update madctl_reg */
|
||||
set_swap_xy(drv, drv->swap_xy);
|
||||
set_mirror(drv, drv->mirror_x, drv->mirror_y);
|
||||
|
||||
/* enter sleep mode first */
|
||||
send_cmd(drv, LV_LCD_CMD_ENTER_SLEEP_MODE, NULL, 0);
|
||||
lv_delay_ms(10);
|
||||
|
||||
/* perform software reset */
|
||||
send_cmd(drv, LV_LCD_CMD_SOFT_RESET, NULL, 0);
|
||||
lv_delay_ms(200);
|
||||
|
||||
/* LCD goes into sleep mode and display will be turned off after power on reset, exit sleep mode first */
|
||||
send_cmd(drv, LV_LCD_CMD_EXIT_SLEEP_MODE, NULL, 0);
|
||||
lv_delay_ms(300);
|
||||
|
||||
send_cmd(drv, LV_LCD_CMD_ENTER_NORMAL_MODE, NULL, 0);
|
||||
|
||||
send_cmd(drv, LV_LCD_CMD_SET_ADDRESS_MODE, (uint8_t[]) {
|
||||
drv->madctl_reg,
|
||||
}, 1);
|
||||
send_cmd(drv, LV_LCD_CMD_SET_PIXEL_FORMAT, (uint8_t[]) {
|
||||
drv->colmod_reg,
|
||||
}, 1);
|
||||
send_cmd(drv, LV_LCD_CMD_SET_DISPLAY_ON, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set readout directions (used for rotating the display)
|
||||
* @param drv LCD driver object
|
||||
* @param mirror_x false: normal, true: mirrored
|
||||
* @param mirror_y false: normal, true: mirrored
|
||||
*/
|
||||
static void set_mirror(lv_lcd_generic_mipi_driver_t * drv, bool mirror_x, bool mirror_y)
|
||||
{
|
||||
uint8_t mad = drv->madctl_reg & ~(LV_LCD_MASK_COLUMN_ADDRESS_ORDER | LV_LCD_MASK_PAGE_ADDRESS_ORDER);
|
||||
if(mirror_x) {
|
||||
mad |= LV_LCD_BIT_COLUMN_ADDRESS_ORDER__RTOL;
|
||||
}
|
||||
if(mirror_y) {
|
||||
mad |= LV_LCD_BIT_PAGE_ADDRESS_ORDER__BTOT;
|
||||
}
|
||||
drv->madctl_reg = mad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap horizontal and vertical readout (used for rotating the display)
|
||||
* @param drv LCD driver object
|
||||
* @param swap false: normal, true: swapped
|
||||
*/
|
||||
static void set_swap_xy(lv_lcd_generic_mipi_driver_t * drv, bool swap)
|
||||
{
|
||||
uint8_t mad = drv->madctl_reg & ~(LV_LCD_MASK_PAGE_COLUMN_ORDER);
|
||||
if(swap) {
|
||||
mad |= LV_LCD_BIT_PAGE_COLUMN_ORDER__REVERSE;
|
||||
}
|
||||
drv->madctl_reg = mad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush display buffer to the LCD
|
||||
* @param disp display object
|
||||
* @param hor_res horizontal resolution
|
||||
* @param area area stored in the buffer
|
||||
* @param px_map buffer containing pixel data
|
||||
* @note transfers pixel data to the LCD controller using the callbacks 'send_cmd' and 'send_color', which were
|
||||
* passed to the 'lv_st7789_create()' function
|
||||
*/
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
|
||||
{
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
|
||||
int32_t x_start = area->x1;
|
||||
int32_t x_end = area->x2 + 1;
|
||||
int32_t y_start = area->y1;
|
||||
int32_t y_end = area->y2 + 1;
|
||||
|
||||
LV_ASSERT((x_start < x_end) && (y_start < y_end) && "start position must be smaller than end position");
|
||||
|
||||
x_start += drv->x_gap;
|
||||
x_end += drv->x_gap;
|
||||
y_start += drv->y_gap;
|
||||
y_end += drv->y_gap;
|
||||
|
||||
/* define an area of frame memory where MCU can access */
|
||||
send_cmd(drv, LV_LCD_CMD_SET_COLUMN_ADDRESS, (uint8_t[]) {
|
||||
(x_start >> 8) & 0xFF,
|
||||
x_start & 0xFF,
|
||||
((x_end - 1) >> 8) & 0xFF,
|
||||
(x_end - 1) & 0xFF,
|
||||
}, 4);
|
||||
send_cmd(drv, LV_LCD_CMD_SET_PAGE_ADDRESS, (uint8_t[]) {
|
||||
(y_start >> 8) & 0xFF,
|
||||
y_start & 0xFF,
|
||||
((y_end - 1) >> 8) & 0xFF,
|
||||
(y_end - 1) & 0xFF,
|
||||
}, 4);
|
||||
/* transfer frame buffer */
|
||||
size_t len = (x_end - x_start) * (y_end - y_start) * lv_color_format_get_size(lv_display_get_color_format(disp));
|
||||
send_color(drv, LV_LCD_CMD_WRITE_MEMORY_START, px_map, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rotation taking into account the current mirror and swap settings
|
||||
* @param drv LCD driver object
|
||||
* @param rot rotation
|
||||
*/
|
||||
static void set_rotation(lv_lcd_generic_mipi_driver_t * drv, lv_display_rotation_t rot)
|
||||
{
|
||||
switch(rot) {
|
||||
case LV_DISPLAY_ROTATION_0:
|
||||
set_swap_xy(drv, drv->swap_xy);
|
||||
set_mirror(drv, drv->mirror_x, drv->mirror_y);
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_90:
|
||||
set_swap_xy(drv, !drv->swap_xy);
|
||||
set_mirror(drv, !drv->mirror_x, drv->mirror_y);
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_180:
|
||||
set_swap_xy(drv, drv->swap_xy);
|
||||
set_mirror(drv, !drv->mirror_x, !drv->mirror_y);
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_270:
|
||||
set_swap_xy(drv, !drv->swap_xy);
|
||||
set_mirror(drv, drv->mirror_x, !drv->mirror_y);
|
||||
break;
|
||||
}
|
||||
send_cmd(drv, LV_LCD_CMD_SET_ADDRESS_MODE, (uint8_t[]) {
|
||||
drv->madctl_reg
|
||||
}, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_RESOLUTION_CHANGED event (handles both resolution and rotation change)
|
||||
* @param e LV_EVENT_RESOLUTION_CHANGED event
|
||||
*/
|
||||
static void res_chg_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_display_t * disp = lv_event_get_target(e);
|
||||
lv_lcd_generic_mipi_driver_t * drv = get_driver(disp);
|
||||
|
||||
uint16_t hor_res = lv_display_get_horizontal_resolution(disp);
|
||||
uint16_t ver_res = lv_display_get_vertical_resolution(disp);
|
||||
lv_display_rotation_t rot = lv_display_get_rotation(disp);
|
||||
|
||||
/* TODO: implement resolution change */
|
||||
LV_UNUSED(hor_res);
|
||||
LV_UNUSED(ver_res);
|
||||
|
||||
/* handle rotation */
|
||||
set_rotation(drv, rot);
|
||||
}
|
||||
|
||||
static lv_lcd_generic_mipi_driver_t * get_driver(lv_display_t * disp)
|
||||
{
|
||||
return (lv_lcd_generic_mipi_driver_t *)lv_display_get_driver_data(disp);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GENERIC_MIPI*/
|
||||
241
src/dev/display/lcd/lv_lcd_generic_mipi.h
Normal file
241
src/dev/display/lcd/lv_lcd_generic_mipi.h
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* lv_lcd_generic_mipi.h
|
||||
*
|
||||
* Generic driver for controllers adhering to the MIPI DBI/DCS specification
|
||||
*
|
||||
* Works with:
|
||||
*
|
||||
* ST7735
|
||||
* ST7789
|
||||
* ST7796
|
||||
* ILI9341
|
||||
* ILI9488 (NOTE: in SPI mode ILI9488 only supports RGB666 mode, which is currently not supported)
|
||||
*
|
||||
* any probably many more
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_LCD_GENERIC_MIPI_H
|
||||
#define LV_LCD_GENERIC_MIPI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../display/lv_display.h"
|
||||
|
||||
#if LV_USE_GENERIC_MIPI
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/* MIPI DCS (Display Command Set) v1.02.00 User Command Set */
|
||||
#define LV_LCD_CMD_NOP 0x00 /* No Operation */
|
||||
#define LV_LCD_CMD_SOFT_RESET 0x01 /* Software Reset */
|
||||
#define LV_LCD_CMD_GET_POWER_MODE 0x0A /* Get the current power mode */
|
||||
#define LV_LCD_CMD_GET_ADDRESS_MODE 0x0B /* Get the data order for transfers from the Host to the display module and from the frame memory to the display device */
|
||||
#define LV_LCD_CMD_GET_PIXEL_FORMAT 0x0C /* Get the current pixel format */
|
||||
#define LV_LCD_CMD_GET_DISPLAY_MODE 0x0D /* Get the current display mode from the peripheral */
|
||||
#define LV_LCD_CMD_GET_SIGNAL_MODE 0x0E /* Get display module signaling mode */
|
||||
#define LV_LCD_CMD_GET_DIAGNOSTIC_RESULT 0x0F /* Get Peripheral Self-Diagnostic Result */
|
||||
#define LV_LCD_CMD_ENTER_SLEEP_MODE 0x10 /* Power for the display panel is off */
|
||||
#define LV_LCD_CMD_EXIT_SLEEP_MODE 0x11 /* Power for the display panel is on */
|
||||
#define LV_LCD_CMD_ENTER_PARTIAL_MODE 0x12 /* Part of the display area is used for image display */
|
||||
#define LV_LCD_CMD_ENTER_NORMAL_MODE 0x13 /* The whole display area is used for image display */
|
||||
#define LV_LCD_CMD_EXIT_INVERT_MODE 0x20 /* Displayed image colors are not inverted */
|
||||
#define LV_LCD_CMD_ENTER_INVERT_MODE 0x21 /* Displayed image colors are inverted */
|
||||
#define LV_LCD_CMD_SET_GAMMA_CURVE 0x26 /* Selects the gamma curve used by the display device */
|
||||
#define LV_LCD_CMD_SET_DISPLAY_OFF 0x28 /* Blanks the display device */
|
||||
#define LV_LCD_CMD_SET_DISPLAY_ON 0x29 /* Show the image on the display device */
|
||||
#define LV_LCD_CMD_SET_COLUMN_ADDRESS 0x2A /* Set the column extent */
|
||||
#define LV_LCD_CMD_SET_PAGE_ADDRESS 0x2B /* Set the page extent */
|
||||
#define LV_LCD_CMD_WRITE_MEMORY_START 0x2C /* Transfer image data from the Host Processor to the peripheral starting at the location provided by set_column_address and set_page_address */
|
||||
#define LV_LCD_CMD_READ_MEMORY_START 0x2E /* Transfer image data from the peripheral to the Host Processor interface starting at the location provided by set_column_address and set_page_address */
|
||||
#define LV_LCD_CMD_SET_PARTIAL_ROWS 0x30 /* Defines the number of rows in the partial display area on the display device */
|
||||
#define LV_LCD_CMD_SET_PARTIAL_COLUMNS 0x31 /* Defines the number of columns in the partial display area on the display device */
|
||||
#define LV_LCD_CMD_SET_SCROLL_AREA 0x33 /* Defines the vertical scrolling and fixed area on display device */
|
||||
#define LV_LCD_CMD_SET_TEAR_OFF 0x34 /* Synchronization information is not sent from the display module to the host processor */
|
||||
#define LV_LCD_CMD_SET_TEAR_ON 0x35 /* Synchronization information is sent from the display module to the host processor at the start of VFP */
|
||||
#define LV_LCD_CMD_SET_ADDRESS_MODE 0x36 /* Set the data order for transfers from the Host to the display module and from the frame memory to the display device */
|
||||
#define LV_LCD_CMD_SET_SCROLL_START 0x37 /* Defines the vertical scrolling starting point */
|
||||
#define LV_LCD_CMD_EXIT_IDLE_MODE 0x38 /* Full color depth is used on the display panel */
|
||||
#define LV_LCD_CMD_ENTER_IDLE_MODE 0x39 /* Reduced color depth is used on the display panel */
|
||||
#define LV_LCD_CMD_SET_PIXEL_FORMAT 0x3A /* Defines how many bits per pixel are used in the interface */
|
||||
#define LV_LCD_CMD_WRITE_MEMORY_CONTINUE 0x3C /* Transfer image information from the Host Processor interface to the peripheral from the last written location */
|
||||
#define LV_LCD_CMD_READ_MEMORY_CONTINUE 0x3E /* Read image data from the peripheral continuing after the last read_memory_continue or read_memory_start */
|
||||
#define LV_LCD_CMD_SET_TEAR_SCANLINE 0x44 /* Synchronization information is sent from the display module to the host processor when the display device refresh reaches the provided scanline */
|
||||
#define LV_LCD_CMD_GET_SCANLINE 0x45 /* Get the current scanline */
|
||||
#define LV_LCD_CMD_READ_DDB_CONTINUE 0xA8 /* Continue reading the DDB from the last read location */
|
||||
#define LV_LCD_CMD_READ_DDB_START 0xA1 /* Read the DDB from the provided location */
|
||||
|
||||
/* address mode flag masks */
|
||||
#define LV_LCD_MASK_FLIP_VERTICAL (1 << 0) /* This bit flips the image shown on the display device top to bottom. No change is made to the frame memory */
|
||||
#define LV_LCD_MASK_FLIP_HORIZONTAL (1 << 1) /* This bit flips the image shown on the display device left to right. No change is made to the frame memory */
|
||||
#define LV_LCD_MASK_DATA_LATCH_DATA_ORDER (1 << 2) /* Display Data Latch Order */
|
||||
#define LV_LCD_MASK_RGB_ORDER (1 << 3) /* RGB/BGR Order */
|
||||
#define LV_LCD_MASK_LINE_ADDRESS_ORDER (1 << 4) /* Line Address Order */
|
||||
#define LV_LCD_MASK_PAGE_COLUMN_ORDER (1 << 5) /* Page/Column Order */
|
||||
#define LV_LCD_MASK_COLUMN_ADDRESS_ORDER (1 << 6) /* Column Address Order */
|
||||
#define LV_LCD_MASK_PAGE_ADDRESS_ORDER (1 << 7) /* Page Address Order */
|
||||
|
||||
#define LV_LCD_BIT_FLIP_VERTICAL__NOT_FLIPPED 0
|
||||
#define LV_LCD_BIT_FLIP_VERTICAL__FLIPPED LV_LCD_MASK_FLIP_VERTICAL /* This bit flips the image shown on the display device top to bottom. No change is made to the frame memory */
|
||||
#define LV_LCD_BIT_FLIP_HORIZONTAL__NOT_FLIPPED 0
|
||||
#define LV_LCD_BIT_FLIP_HORIZONTAL__FLIPPED LV_LCD_MASK_FLIP_HORIZONTAL /* This bit flips the image shown on the display device left to right. No change is made to the frame memory */
|
||||
#define LV_LCD_BIT_DATA_LATCH_DATA_ORDER__LTOR 0 /* Display Data Latch Order: LCD Refresh Left to Right */
|
||||
#define LV_LCD_BIT_DATA_LATCH_DATA_ORDER__RTOL LV_LCD_MASK_DATA_LATCH_DATA_ORDER /* Display Data Latch Order: LCD Refresh Right to Left */
|
||||
#define LV_LCD_BIT_RGB_ORDER__RGB 0 /* RGB/BGR Order: RGB */
|
||||
#define LV_LCD_BIT_RGB_ORDER__BGR LV_LCD_MASK_RGB_ORDER /* RGB/BGR Order: BGR */
|
||||
#define LV_LCD_BIT_LINE_ADDRESS_ORDER__TTOB 0 /* Line Address Order: LCD Refresh Top to Bottom */
|
||||
#define LV_LCD_BIT_LINE_ADDRESS_ORDER__BTOT LV_LCD_MASK_LINE_ADDRESS_ORDER /* Line Address Order: LCD Refresh Botton to Top */
|
||||
#define LV_LCD_BIT_PAGE_COLUMN_ORDER__NORMAL 0 /* Page/Column Order: Normal Mode */
|
||||
#define LV_LCD_BIT_PAGE_COLUMN_ORDER__REVERSE LV_LCD_MASK_PAGE_COLUMN_ORDER /* Page/Column Order: Reverse Mode */
|
||||
#define LV_LCD_BIT_COLUMN_ADDRESS_ORDER__LTOR 0 /* Column Address Order: Left to Right */
|
||||
#define LV_LCD_BIT_COLUMN_ADDRESS_ORDER__RTOL LV_LCD_MASK_COLUMN_ADDRESS_ORDER /* Column Address Order: Right to Left */
|
||||
#define LV_LCD_BIT_PAGE_ADDRESS_ORDER__TTOB 0 /* Page Address Order: Top to Bottom */
|
||||
#define LV_LCD_BIT_PAGE_ADDRESS_ORDER__BTOT LV_LCD_MASK_PAGE_ADDRESS_ORDER /* Page Address Order: Bottom to Top */
|
||||
|
||||
/* predefined gamma curves */
|
||||
#define LV_LCD_GAMMA_2_2 0x01 /* 2.2 */
|
||||
#define LV_LCD_GAMMA_1_8 0x02 /* 1.8 */
|
||||
#define LV_LCD_GAMMA_2_5 0x04 /* 2.5 */
|
||||
#define LV_LCD_GAMMA_1_0 0x08 /* 1.0 */
|
||||
|
||||
/* common pixel formats */
|
||||
#define LV_LCD_PIXEL_FORMAT_RGB565 0x55 /* bus: 16 bits, pixel: 16 bits */
|
||||
#define LV_LCD_PIXEL_FORMAT_RGB666 0x66 /* bus: 18 bits, pixel: 18 bits */
|
||||
|
||||
/* flags for lv_lcd_xxx_create() */
|
||||
#define LV_LCD_FLAG_NONE 0x00000000UL
|
||||
#define LV_LCD_FLAG_MIRROR_X 0x00000001UL
|
||||
#define LV_LCD_FLAG_MIRROR_Y 0x00000002UL
|
||||
#define LV_LCD_FLAG_BGR 0x00000008UL
|
||||
#define LV_LCD_FLAG_RGB666 0x00000010UL
|
||||
|
||||
/* command list */
|
||||
#define LV_LCD_CMD_DELAY_MS 0xff
|
||||
#define LV_LCD_CMD_EOF 0xff
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Configuration flags for lv_lcd_xxx_create()
|
||||
*
|
||||
*/
|
||||
typedef uint32_t lv_lcd_flag_t;
|
||||
|
||||
/**
|
||||
* Prototype of a platform-dependent callback to transfer commands and data to the LCD controller.
|
||||
* @param disp display object
|
||||
* @param cmd command buffer (can handle 16 bit commands as well)
|
||||
* @param cmd_size number of bytes of the command
|
||||
* @param param parameter buffer
|
||||
* @param param_size number of bytes of the parameters
|
||||
*/
|
||||
typedef void (*lv_lcd_send_cmd_cb_t)(lv_display_t * disp, const uint8_t * cmd, size_t cmd_size, const uint8_t * param,
|
||||
size_t param_size);
|
||||
|
||||
/**
|
||||
* Prototype of a platform-dependent callback to transfer pixel data to the LCD controller.
|
||||
* @param disp display object
|
||||
* @param cmd command buffer (can handle 16 bit commands as well)
|
||||
* @param cmd_size number of bytes of the command
|
||||
* @param param parameter buffer
|
||||
* @param param_size number of bytes of the parameters
|
||||
*/
|
||||
typedef void (*lv_lcd_send_color_cb_t)(lv_display_t * disp, const uint8_t * cmd, size_t cmd_size, uint8_t * param,
|
||||
size_t param_size);
|
||||
|
||||
/**
|
||||
* Generic MIPI compatible LCD driver
|
||||
*/
|
||||
typedef struct {
|
||||
lv_display_t * disp; /* the associated LVGL display object */
|
||||
lv_lcd_send_cmd_cb_t send_cmd; /* platform-specific implementation to send a command to the LCD controller */
|
||||
lv_lcd_send_color_cb_t send_color; /* platform-specific implementation to send pixel data to the LCD controller */
|
||||
uint16_t x_gap; /* x offset of the (0,0) pixel in VRAM */
|
||||
uint16_t y_gap; /* y offset of the (0,0) pixel in VRAM */
|
||||
uint8_t madctl_reg; /* current value of MADCTL register */
|
||||
uint8_t colmod_reg; /* current value of COLMOD register */
|
||||
bool mirror_x;
|
||||
bool mirror_y;
|
||||
bool swap_xy;
|
||||
} lv_lcd_generic_mipi_driver_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a MIPI DCS compatible LCD display
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_lcd_generic_mipi_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_lcd_send_cmd_cb_t send_cmd_cb, lv_lcd_send_color_cb_t send_color_cb);
|
||||
|
||||
/**
|
||||
* Set gap, i.e., the offset of the (0,0) pixel in the VRAM
|
||||
* @param disp display object
|
||||
* @param x x offset
|
||||
* @param y y offset
|
||||
*/
|
||||
void lv_lcd_generic_mipi_set_gap(lv_display_t * disp, uint16_t x, uint16_t y);
|
||||
|
||||
/**
|
||||
* Set color inversion
|
||||
* @param disp display object
|
||||
* @param invert false: normal, true: invert
|
||||
*/
|
||||
void lv_lcd_generic_mipi_set_invert(lv_display_t * disp, bool invert);
|
||||
|
||||
/**
|
||||
* Set address mode
|
||||
* @param disp display object
|
||||
* @param mirror_x horizontal mirror (false: normal, true: mirrored)
|
||||
* @param mirror_y vertical mirror (false: normal, true: mirrored)
|
||||
* @param swap_xy swap axes (false: normal, true: swap)
|
||||
* @param bgr RGB/BGR order (false: RGB, true: BGR)
|
||||
*/
|
||||
void lv_lcd_generic_mipi_set_address_mode(lv_display_t * disp, bool mirror_x, bool mirror_y, bool swap_xy, bool bgr);
|
||||
|
||||
/**
|
||||
* Set gamma curve
|
||||
* @param disp display object
|
||||
* @param gamma gamma curve
|
||||
*/
|
||||
void lv_lcd_generic_mipi_set_gamma_curve(lv_display_t * disp, uint8_t gamma);
|
||||
|
||||
/**
|
||||
* Send list of commands.
|
||||
* @param disp display object
|
||||
* @param cmd_list controller and panel-specific commands
|
||||
*/
|
||||
void lv_lcd_generic_mipi_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list);
|
||||
|
||||
/**********************
|
||||
* OTHERS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_GENERIC_MIPI*/
|
||||
|
||||
#endif /* LV_LCD_GENERIC_MIPI_H */
|
||||
113
src/dev/display/st7735/lv_st7735.c
Normal file
113
src/dev/display/st7735/lv_st7735.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* @file lv_st7735.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_st7735.h"
|
||||
|
||||
#if LV_USE_ST7735
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define CMD_GAMSET 0x26
|
||||
|
||||
#define CMD_FRMCTR1 0xB1
|
||||
#define CMD_FRMCTR2 0xB2
|
||||
#define CMD_FRMCTR3 0xB3
|
||||
#define CMD_INVCTR 0xB4
|
||||
#define CMD_DISSET5 0xB6
|
||||
|
||||
#define CMD_PWCTR1 0xC0
|
||||
#define CMD_PWCTR2 0xC1
|
||||
#define CMD_PWCTR3 0xC2
|
||||
#define CMD_PWCTR4 0xC3
|
||||
#define CMD_PWCTR5 0xC4
|
||||
#define CMD_VMCTR1 0xC5
|
||||
#define CMD_VMOFCTR 0xC7
|
||||
|
||||
#define CMD_NVFCTR1 0xD9
|
||||
|
||||
#define CMD_GMCTRP1 0xE0
|
||||
#define CMD_GMCTRN1 0xE1
|
||||
|
||||
#define CMD_PWCTR6 0xFC
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC CONSTANTS
|
||||
**********************/
|
||||
|
||||
/* init commands for buydisplay.com ER-TFTM018-3 */
|
||||
static const uint8_t init_cmd_list[] = {
|
||||
0xB1, 3, 0x05, 0x3C, 0x3C,
|
||||
0xB2, 3, 0x05, 0x3C, 0x3C,
|
||||
0xB3, 6, 0x05, 0x3C, 0x3C, 0x05, 0x3C, 0x3C,
|
||||
0xB4, 1, 0x03,
|
||||
0xC0, 3, 0x28, 0x08, 0x04,
|
||||
0xC1, 1, 0XC0,
|
||||
0xC2, 2, 0x0D, 0x00,
|
||||
0xC3, 2, 0x8D, 0x2A,
|
||||
0xC4, 2, 0x8D, 0xEE,
|
||||
0xC5, 1, 0x10,
|
||||
0xE0, 16, 0x04, 0x22, 0x07, 0x0A, 0x2E, 0x30, 0x25, 0x2A, 0x28, 0x26, 0x2E, 0x3A, 0x00, 0x01, 0x03, 0x13,
|
||||
0xE1, 16, 0x04, 0x16, 0x06, 0x0D, 0x2D, 0x26, 0x23, 0x27, 0x27, 0x25, 0x2D, 0x3B, 0x00, 0x01, 0x04, 0x13,
|
||||
LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_st7735_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7735_send_cmd_cb_t send_cmd_cb, lv_st7735_send_color_cb_t send_color_cb)
|
||||
{
|
||||
lv_display_t * disp = lv_lcd_generic_mipi_create(hor_res, ver_res, flags, send_cmd_cb, send_color_cb);
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list);
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lv_st7735_set_gap(lv_display_t * disp, uint16_t x, uint16_t y)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gap(disp, x, y);
|
||||
}
|
||||
|
||||
void lv_st7735_set_invert(lv_display_t * disp, bool invert)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_invert(disp, invert);
|
||||
}
|
||||
|
||||
void lv_st7735_set_gamma_curve(lv_display_t * disp, uint8_t gamma)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gamma_curve(disp, gamma);
|
||||
}
|
||||
|
||||
void lv_st7735_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list)
|
||||
{
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, cmd_list);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ST7735*/
|
||||
93
src/dev/display/st7735/lv_st7735.h
Normal file
93
src/dev/display/st7735/lv_st7735.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* lv_st7735.h
|
||||
*
|
||||
* This driver is just a wrapper around the generic MIPI compatible LCD controller driver
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ST7735_H
|
||||
#define LV_ST7735_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../lcd/lv_lcd_generic_mipi.h"
|
||||
|
||||
#if LV_USE_ST7735
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef lv_lcd_send_cmd_cb_t lv_st7735_send_cmd_cb_t;
|
||||
typedef lv_lcd_send_color_cb_t lv_st7735_send_color_cb_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an LCD display with ST7735 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_st7735_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7735_send_cmd_cb_t send_cmd_cb, lv_st7735_send_color_cb_t send_color_cb);
|
||||
|
||||
/**
|
||||
* Set gap, i.e., the offset of the (0,0) pixel in the VRAM
|
||||
* @param disp display object
|
||||
* @param x x offset
|
||||
* @param y y offset
|
||||
*/
|
||||
void lv_st7735_set_gap(lv_display_t * disp, uint16_t x, uint16_t y);
|
||||
|
||||
/**
|
||||
* Set color inversion
|
||||
* @param disp display object
|
||||
* @param invert false: normal, true: invert
|
||||
*/
|
||||
void lv_st7735_set_invert(lv_display_t * disp, bool invert);
|
||||
|
||||
/**
|
||||
* Set gamma curve
|
||||
* @param disp display object
|
||||
* @param gamma gamma curve
|
||||
*/
|
||||
void lv_st7735_set_gamma_curve(lv_display_t * disp, uint8_t gamma);
|
||||
|
||||
/**
|
||||
* Send list of commands.
|
||||
* @param disp display object
|
||||
* @param cmd_list controller and panel-specific commands
|
||||
*/
|
||||
void lv_st7735_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list);
|
||||
|
||||
/**********************
|
||||
* OTHERS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ST7735*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /* LV_ST7735_H */
|
||||
116
src/dev/display/st7789/lv_st7789.c
Normal file
116
src/dev/display/st7789/lv_st7789.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @file lv_st7789.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_st7789.h"
|
||||
|
||||
#if LV_USE_ST7789
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define CMD_FRMCTR1 0xB1
|
||||
#define CMD_FRMCTR2 0xB2
|
||||
#define CMD_FRMCTR3 0xB3
|
||||
#define CMD_INVCTR 0xB4
|
||||
#define CMD_DFUNCTR 0xB6
|
||||
#define CMD_ETMOD 0xB7
|
||||
#define CMD_PWCTR1 0xC0
|
||||
#define CMD_PWCTR2 0xC1
|
||||
#define CMD_PWCTR3 0xC2
|
||||
#define CMD_PWCTR4 0xC3
|
||||
#define CMD_PWCTR5 0xC4
|
||||
#define CMD_VMCTR 0xC5
|
||||
#define CMD_GMCTRP1 0xE0
|
||||
#define CMD_GMCTRN1 0xE1
|
||||
#define CMD_DOCA 0xE8
|
||||
#define CMD_CSCON 0xF0
|
||||
|
||||
#define CMD_RAMCTRL 0xB0
|
||||
#define CMD_PORCTRL 0xB2 /* Porch control */
|
||||
#define CMD_GCTRL 0xB7 /* Gate control */
|
||||
#define CMD_VCOMS 0xBB /* VCOMS setting */
|
||||
#define CMD_LCMCTRL 0xC0 /* LCM control */
|
||||
#define CMD_VDVVRHEN 0xC2 /* VDV and VRH command enable */
|
||||
#define CMD_VRHS 0xC3 /* VRH set */
|
||||
#define CMD_VDVSET 0xC4 /* VDV setting */
|
||||
#define CMD_FRCTR2 0xC6 /* FR Control 2 */
|
||||
#define CMD_PWCTRL1 0xD0 /* Power control 1 */
|
||||
#define CMD_PVGAMCTRL 0xE0 /* Positive Gamma Correction */
|
||||
#define CMD_NVGAMCTRL 0xE1 /* Negative Gamma Correction */
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC CONSTANTS
|
||||
**********************/
|
||||
|
||||
/* init commands based on LovyanGFX ST7789 driver */
|
||||
static const uint8_t init_cmd_list[] = {
|
||||
CMD_GCTRL, 1, 0x44, /* GCTRL -- panel dependent */
|
||||
CMD_VCOMS, 1, 0x24, /* VCOMS -- panel dependent */
|
||||
CMD_VRHS, 1, 0x13, /* VRHS - panel dependent */
|
||||
CMD_PWCTRL1, 2, 0xa4, 0xa1,
|
||||
CMD_RAMCTRL, 2, 0x00, 0xC0, /* controls mapping of RGB565 to RGB666 */
|
||||
CMD_PVGAMCTRL, 14, 0xd0, 0x00, 0x02, 0x07, 0x0a, 0x28, 0x32, 0x44, 0x42, 0x06, 0x0e, 0x12, 0x14, 0x17,
|
||||
CMD_NVGAMCTRL, 14, 0xd0, 0x00, 0x02, 0x07, 0x0a, 0x28, 0x31, 0x54, 0x47, 0x0e, 0x1c, 0x17, 0x1b, 0x1e,
|
||||
LV_LCD_CMD_SET_GAMMA_CURVE, 1, 0x01,
|
||||
LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_st7789_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7789_send_cmd_cb_t send_cmd_cb, lv_st7789_send_color_cb_t send_color_cb)
|
||||
{
|
||||
lv_display_t * disp = lv_lcd_generic_mipi_create(hor_res, ver_res, flags, send_cmd_cb, send_color_cb);
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list);
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lv_st7789_set_gap(lv_display_t * disp, uint16_t x, uint16_t y)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gap(disp, x, y);
|
||||
}
|
||||
|
||||
void lv_st7789_set_invert(lv_display_t * disp, bool invert)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_invert(disp, invert);
|
||||
}
|
||||
|
||||
void lv_st7789_set_gamma_curve(lv_display_t * disp, uint8_t gamma)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gamma_curve(disp, gamma);
|
||||
}
|
||||
|
||||
void lv_st7789_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list)
|
||||
{
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, cmd_list);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ST7789*/
|
||||
93
src/dev/display/st7789/lv_st7789.h
Normal file
93
src/dev/display/st7789/lv_st7789.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* lv_st7789.h
|
||||
*
|
||||
* This driver is just a wrapper around the generic MIPI compatible LCD controller driver
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ST7789_H
|
||||
#define LV_ST7789_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../lcd/lv_lcd_generic_mipi.h"
|
||||
|
||||
#if LV_USE_ST7789
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef lv_lcd_send_cmd_cb_t lv_st7789_send_cmd_cb_t;
|
||||
typedef lv_lcd_send_color_cb_t lv_st7789_send_color_cb_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an LCD display with ST7789 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_st7789_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7789_send_cmd_cb_t send_cmd_cb, lv_st7789_send_color_cb_t send_color_cb);
|
||||
|
||||
/**
|
||||
* Set gap, i.e., the offset of the (0,0) pixel in the VRAM
|
||||
* @param disp display object
|
||||
* @param x x offset
|
||||
* @param y y offset
|
||||
*/
|
||||
void lv_st7789_set_gap(lv_display_t * disp, uint16_t x, uint16_t y);
|
||||
|
||||
/**
|
||||
* Set color inversion
|
||||
* @param disp display object
|
||||
* @param invert false: normal, true: invert
|
||||
*/
|
||||
void lv_st7789_set_invert(lv_display_t * disp, bool invert);
|
||||
|
||||
/**
|
||||
* Set gamma curve
|
||||
* @param disp display object
|
||||
* @param gamma gamma curve
|
||||
*/
|
||||
void lv_st7789_set_gamma_curve(lv_display_t * disp, uint8_t gamma);
|
||||
|
||||
/**
|
||||
* Send list of commands.
|
||||
* @param disp display object
|
||||
* @param cmd_list controller and panel-specific commands
|
||||
*/
|
||||
void lv_st7789_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list);
|
||||
|
||||
/**********************
|
||||
* OTHERS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_ST7789*/
|
||||
|
||||
#endif //LV_ST7789_H
|
||||
122
src/dev/display/st7796/lv_st7796.c
Normal file
122
src/dev/display/st7796/lv_st7796.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* @file lv_st7796.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_st7796.h"
|
||||
|
||||
#if LV_USE_ST7796
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define CMD_FRMCTR1 0xB1
|
||||
#define CMD_FRMCTR2 0xB2
|
||||
#define CMD_FRMCTR3 0xB3
|
||||
#define CMD_INVCTR 0xB4
|
||||
#define CMD_DFUNCTR 0xB6
|
||||
#define CMD_ETMOD 0xB7
|
||||
#define CMD_PWCTR1 0xC0
|
||||
#define CMD_PWCTR2 0xC1
|
||||
#define CMD_PWCTR3 0xC2
|
||||
#define CMD_PWCTR4 0xC3
|
||||
#define CMD_PWCTR5 0xC4
|
||||
#define CMD_VMCTR 0xC5
|
||||
#define CMD_GMCTRP1 0xE0
|
||||
#define CMD_GMCTRN1 0xE1
|
||||
#define CMD_DOCA 0xE8
|
||||
#define CMD_CSCON 0xF0
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC CONSTANTS
|
||||
**********************/
|
||||
|
||||
/* init commands based on LovyanGFX */
|
||||
static const uint8_t init_cmd_list[] = {
|
||||
CMD_CSCON, 1, 0xC3, /* Enable extension command 2 partI */
|
||||
CMD_CSCON, 1, 0x96, /* Enable extension command 2 partII */
|
||||
CMD_INVCTR, 1, 0x01, /* 1-dot inversion */
|
||||
CMD_DFUNCTR, 3, 0x80, /* Display Function Control: Bypass */
|
||||
0x22, /* Source Output Scan from S1 to S960, Gate Output scan from G1 to G480, scan cycle = 2 */
|
||||
0x3B, /* LCD Drive Line = 8 * (59 + 1) */
|
||||
CMD_DOCA, 8, 0x40, 0x8A, 0x00, 0x00,
|
||||
0x29, /* Source equalizing period time = 22.5 us */
|
||||
0x19, /* Timing for "Gate start" = 25 (Tclk) */
|
||||
0xA5, /* Timing for "Gate End" = 37 (Tclk), Gate driver EQ function ON */
|
||||
0x33,
|
||||
CMD_PWCTR2, 1, 0x06, /* Power control2: VAP(GVDD) = 3.85 + (vcom + vcom offset), VAN(GVCL) = -3.85 + (vcom + vcom offset) */
|
||||
CMD_PWCTR3, 1, 0xA7, /* Power control 3: Source driving current level = low, Gamma driving current level = High */
|
||||
CMD_VMCTR, 1, 0x18, /* VCOM Control: VCOM = 0.9 */
|
||||
LV_LCD_CMD_DELAY_MS, 12, /* delay 120 ms */
|
||||
CMD_GMCTRP1, 14, /* Gamma */
|
||||
0xF0, 0x09, 0x0B, 0x06, 0x04, 0x15, 0x2F,
|
||||
0x54, 0x42, 0x3C, 0x17, 0x14, 0x18, 0x1B,
|
||||
CMD_GMCTRN1, 14,
|
||||
0xE0, 0x09, 0x0B, 0x06, 0x04, 0x03, 0x2B,
|
||||
0x43, 0x42, 0x3B, 0x16, 0x14, 0x17, 0x1B,
|
||||
LV_LCD_CMD_DELAY_MS, 12, /* delay 120 ms */
|
||||
CMD_CSCON, 1, 0x3C, /* Disable extension command 2 partI */
|
||||
CMD_CSCON, 1, 0x69, /* Disable extension command 2 partII */
|
||||
LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_st7796_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7796_send_cmd_cb_t send_cmd_cb, lv_st7796_send_color_cb_t send_color_cb)
|
||||
{
|
||||
lv_display_t * disp = lv_lcd_generic_mipi_create(hor_res, ver_res, flags, send_cmd_cb, send_color_cb);
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list);
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lv_st7796_set_gap(lv_display_t * disp, uint16_t x, uint16_t y)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gap(disp, x, y);
|
||||
}
|
||||
|
||||
void lv_st7796_set_invert(lv_display_t * disp, bool invert)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_invert(disp, invert);
|
||||
}
|
||||
|
||||
void lv_st7796_set_gamma_curve(lv_display_t * disp, uint8_t gamma)
|
||||
{
|
||||
/* NOTE: the generic method is not supported on ST7796, TODO: implement gamma tables */
|
||||
LV_UNUSED(disp);
|
||||
LV_UNUSED(gamma);
|
||||
}
|
||||
|
||||
void lv_st7796_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list)
|
||||
{
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, cmd_list);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ST7796*/
|
||||
|
||||
93
src/dev/display/st7796/lv_st7796.h
Normal file
93
src/dev/display/st7796/lv_st7796.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* lv_st7796.h
|
||||
*
|
||||
* This driver is just a wrapper around the generic MIPI compatible LCD controller driver
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ST7796_H
|
||||
#define LV_ST7796_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../lcd/lv_lcd_generic_mipi.h"
|
||||
|
||||
#if LV_USE_ST7796
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef lv_lcd_send_cmd_cb_t lv_st7796_send_cmd_cb_t;
|
||||
typedef lv_lcd_send_color_cb_t lv_st7796_send_color_cb_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an LCD display with ST7796 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_st7796_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7796_send_cmd_cb_t send_cmd_cb, lv_st7796_send_color_cb_t send_color_cb);
|
||||
|
||||
/**
|
||||
* Set gap, i.e., the offset of the (0,0) pixel in the VRAM
|
||||
* @param disp display object
|
||||
* @param x x offset
|
||||
* @param y y offset
|
||||
*/
|
||||
void lv_st7796_set_gap(lv_display_t * disp, uint16_t x, uint16_t y);
|
||||
|
||||
/**
|
||||
* Set color inversion
|
||||
* @param disp display object
|
||||
* @param invert false: normal, true: invert
|
||||
*/
|
||||
void lv_st7796_set_invert(lv_display_t * disp, bool invert);
|
||||
|
||||
/**
|
||||
* Set gamma curve
|
||||
* @param disp display object
|
||||
* @param gamma gamma curve
|
||||
*/
|
||||
void lv_st7796_set_gamma_curve(lv_display_t * disp, uint8_t gamma);
|
||||
|
||||
/**
|
||||
* Send list of commands.
|
||||
* @param disp display object
|
||||
* @param cmd_list controller and panel-specific commands
|
||||
*/
|
||||
void lv_st7796_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list);
|
||||
|
||||
/**********************
|
||||
* OTHERS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_ST7796*/
|
||||
|
||||
#endif /* LV_ST7796_H */
|
||||
@@ -2826,6 +2826,45 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Drivers for LCD devices connected via SPI/parallel port*/
|
||||
#ifndef LV_USE_ST7735
|
||||
#ifdef CONFIG_LV_USE_ST7735
|
||||
#define LV_USE_ST7735 CONFIG_LV_USE_ST7735
|
||||
#else
|
||||
#define LV_USE_ST7735 0
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_USE_ST7789
|
||||
#ifdef CONFIG_LV_USE_ST7789
|
||||
#define LV_USE_ST7789 CONFIG_LV_USE_ST7789
|
||||
#else
|
||||
#define LV_USE_ST7789 0
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_USE_ST7796
|
||||
#ifdef CONFIG_LV_USE_ST7796
|
||||
#define LV_USE_ST7796 CONFIG_LV_USE_ST7796
|
||||
#else
|
||||
#define LV_USE_ST7796 0
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_USE_ILI9341
|
||||
#ifdef CONFIG_LV_USE_ILI9341
|
||||
#define LV_USE_ILI9341 CONFIG_LV_USE_ILI9341
|
||||
#else
|
||||
#define LV_USE_ILI9341 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LV_USE_GENERIC_MIPI
|
||||
#ifdef CONFIG_LV_USE_GENERIC_MIPI
|
||||
#define LV_USE_GENERIC_MIPI CONFIG_LV_USE_GENERIC_MIPI
|
||||
#else
|
||||
#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*==================
|
||||
* EXAMPLES
|
||||
*==================*/
|
||||
|
||||
@@ -99,6 +99,11 @@
|
||||
|
||||
#define LV_CACHE_DEF_SIZE (10 * 1024 * 1024)
|
||||
|
||||
#define LV_USE_ILI9341 1
|
||||
#define LV_USE_ST7735 1
|
||||
#define LV_USE_ST7789 1
|
||||
#define LV_USE_ST7796 1
|
||||
|
||||
#define LV_USE_FREETYPE 1
|
||||
#define LV_FREETYPE_CACHE_SIZE 768
|
||||
#define LV_FREETYPE_USE_LVGL_PORT 0
|
||||
|
||||
Reference in New Issue
Block a user