mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-24 16:37:18 +08:00
feat(drivers): NV3007 driver & docs (#9021)
This commit is contained in:
@@ -13,3 +13,4 @@ Display Controller Support
|
||||
st7735
|
||||
st7789
|
||||
st7796
|
||||
nv3007
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
=============================
|
||||
NV3007 LCD Controller driver
|
||||
=============================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The `NV3007 <https://www.buydisplay.com/download/ic/NV3007.pdf>`__ is a single-chip driver for 262,144-color, a-Si TFT liquid crystal display
|
||||
with maximum resolution of 168RGBx428 dots. It contains 252-channel source driver,
|
||||
a 24-channel GIP driver which used for dual-gate control, 161,784-byte GRAM for
|
||||
graphic display data, internal precise power supply circuit which supports full color,
|
||||
8-color display mode and sleep mode
|
||||
NV3007 supports 3-/4-line serial peripheral interface (SPI) , quad serial
|
||||
peripheral interface (QSPI). The display area can be specified in internal GRAM by
|
||||
window address function.
|
||||
|
||||
The NV3007 LCD controller `driver <https://github.com/lvgl/lvgl/tree/master/src/drivers/display/nv3007>`__ is a platform-agnostic driver, based on the `generic MIPI driver <https://github.com/lvgl/lvgl/blob/master/docs/src/details/integration/external_display_controllers/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 NV3007 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define LV_USE_NV3007 1
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
You need to implement two platform-dependent functions:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||
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 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. */
|
||||
void 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 NV3007-based display use the function
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/**
|
||||
* Create an LCD display with NV3007 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_nv3007_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_nv3007_send_cmd_cb_t send_cmd_cb, lv_nv3007_send_color_cb_t send_color_cb);
|
||||
|
||||
|
||||
Arduino Example
|
||||
---------------
|
||||
|
||||
Here is a simple example of using the NV3007 display with Arduino framework and SPI interface:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
/* Platform-specific includes */
|
||||
#include <SPI.h>
|
||||
|
||||
#define LCD_DC 21
|
||||
#define LCD_CS 5
|
||||
#define LCD_RST 4
|
||||
#define LCD_SCK 18
|
||||
#define LCD_MOSI 23
|
||||
#define LCD_MISO -1
|
||||
#define LCD_BL 15
|
||||
#define SPI_CLK 40000000
|
||||
|
||||
#define BUFFER_SIZE 142 * 50
|
||||
uint8_t buf[BUFFER_SIZE];
|
||||
|
||||
/* Define your platform-specific functions to send commands and data */
|
||||
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)
|
||||
{
|
||||
SPI.beginTransaction(SPISettings(SPI_CLK, MSBFIRST, SPI_MODE0));
|
||||
/* Send command */
|
||||
digitalWrite(LCD_DC, LOW); /* command mode */
|
||||
digitalWrite(LCD_CS, LOW); /* CS low */
|
||||
SPI.transferBytes(cmd, NULL, cmd_size);
|
||||
|
||||
/* Send parameters (if any) */
|
||||
if (param != NULL && param_size > 0)
|
||||
{
|
||||
digitalWrite(LCD_DC, HIGH); /* data mode */
|
||||
SPI.transferBytes(param, NULL, param_size);
|
||||
}
|
||||
digitalWrite(LCD_CS, HIGH); /* CS high */
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
SPI.beginTransaction(SPISettings(SPI_CLK, MSBFIRST, SPI_MODE0));
|
||||
digitalWrite(LCD_CS, LOW);
|
||||
|
||||
/* Send the command first */
|
||||
digitalWrite(LCD_DC, LOW);
|
||||
SPI.transferBytes(cmd, NULL, cmd_size);
|
||||
|
||||
/* Then send the pixel data */
|
||||
if (param && param_size > 0)
|
||||
{
|
||||
digitalWrite(LCD_DC, HIGH);
|
||||
SPI.transferBytes(param, NULL, param_size);
|
||||
}
|
||||
|
||||
digitalWrite(LCD_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
|
||||
/* Important: signal LVGL that we're done */
|
||||
lv_display_flush_ready(disp);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
pinMode(LCD_BL, OUTPUT);
|
||||
digitalWrite(LCD_BL, HIGH); /* turn on backlight */
|
||||
|
||||
pinMode(LCD_DC, OUTPUT);
|
||||
pinMode(LCD_CS, OUTPUT);
|
||||
pinMode(LCD_RST, OUTPUT);
|
||||
/* reset sequence */
|
||||
digitalWrite(LCD_RST, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(LCD_RST, LOW);
|
||||
delay(120);
|
||||
digitalWrite(LCD_RST, HIGH);
|
||||
delay(120);
|
||||
|
||||
SPI.begin(LCD_SCK, LCD_MISO, LCD_MOSI, LCD_CS); /* SCK, MISO, MOSI, SS */
|
||||
|
||||
digitalWrite(LCD_CS, HIGH); /* disable device */
|
||||
delay(100); /* wait for device to stabilize */
|
||||
|
||||
lv_init();
|
||||
|
||||
lv_tick_set_cb(my_tick);
|
||||
|
||||
/* Create NV3007 display */
|
||||
lv_display_t *disp = lv_nv3007_create(142, 428, LV_LCD_FLAG_NONE, my_lcd_send_cmd, my_lcd_send_color);
|
||||
lv_nv3007_set_gap(disp, 0, 14);
|
||||
lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);
|
||||
lv_display_set_color_format(disp, LV_COLOR_FORMAT_RGB565_SWAPPED);
|
||||
lv_display_set_buffers(disp, buf, NULL, BUFFER_SIZE, LV_DISP_RENDER_MODE_PARTIAL);
|
||||
|
||||
/* Create a simple label on the display */
|
||||
lv_obj_t *label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(label, "Hello NV3007!");
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
lv_task_handler();
|
||||
delay(5);
|
||||
}
|
||||
|
||||
For additional details and a working example see the `generic MIPI driver documentation <https://github.com/lvgl/lvgl/blob/master/docs/src/details/integration/external_display_controllers/gen_mipi.rst>`__.
|
||||
+2
-1
@@ -1332,8 +1332,9 @@
|
||||
#define LV_USE_ST7796 0
|
||||
#define LV_USE_ILI9341 0
|
||||
#define LV_USE_FT81X 0
|
||||
#define LV_USE_NV3007 0
|
||||
|
||||
#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)
|
||||
#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341 | LV_USE_NV3007)
|
||||
#define LV_USE_GENERIC_MIPI 1
|
||||
#else
|
||||
#define LV_USE_GENERIC_MIPI 0
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/**
|
||||
* @file lv_nv3007.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_nv3007.h"
|
||||
|
||||
#if LV_USE_NV3007
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define NV3007_SLPIN 0x10
|
||||
#define NV3007_SLPOUT 0x11
|
||||
|
||||
#define NV3007_INVOFF 0x20
|
||||
#define NV3007_INVON 0x21
|
||||
#define NV3007_DISPOFF 0x28
|
||||
#define NV3007_DISPON 0x29
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC CONSTANTS
|
||||
**********************/
|
||||
|
||||
/* init commands based on ArduinoGFX NV3007 driver */
|
||||
static const uint8_t init_cmd_list[] = {
|
||||
0x9a, 1, 0x08,
|
||||
0x9b, 1, 0x08,
|
||||
0x9c, 1, 0xb0,
|
||||
0x9d, 1, 0x16,
|
||||
0x9e, 1, 0xc4,
|
||||
0x8f, 2, 0x55, 0x04,
|
||||
0x84, 1, 0x90,
|
||||
0x83, 1, 0x7b,
|
||||
0x85, 1, 0x33,
|
||||
0x60, 1, 0x00,
|
||||
0x70, 1, 0x00,
|
||||
0x61, 1, 0x02,
|
||||
0x71, 1, 0x02,
|
||||
0x62, 1, 0x04,
|
||||
0x72, 1, 0x04,
|
||||
0x6c, 1, 0x29,
|
||||
0x7c, 1, 0x29,
|
||||
0x6d, 1, 0x31,
|
||||
0x7d, 1, 0x31,
|
||||
0x6e, 1, 0x0f,
|
||||
0x7e, 1, 0x0f,
|
||||
0x66, 1, 0x21,
|
||||
0x76, 1, 0x21,
|
||||
0x68, 1, 0x3A,
|
||||
0x78, 1, 0x3A,
|
||||
0x63, 1, 0x07,
|
||||
0x73, 1, 0x07,
|
||||
0x64, 1, 0x05,
|
||||
0x74, 1, 0x05,
|
||||
0x65, 1, 0x02,
|
||||
0x75, 1, 0x02,
|
||||
0x67, 1, 0x23,
|
||||
0x77, 1, 0x23,
|
||||
0x69, 1, 0x08,
|
||||
0x79, 1, 0x08,
|
||||
0x6a, 1, 0x13,
|
||||
0x7a, 1, 0x13,
|
||||
0x6b, 1, 0x13,
|
||||
0x7b, 1, 0x13,
|
||||
0x6f, 1, 0x00,
|
||||
0x7f, 1, 0x00,
|
||||
0x50, 1, 0x00,
|
||||
0x52, 1, 0xd6,
|
||||
0x53, 1, 0x08,
|
||||
0x54, 1, 0x08,
|
||||
0x55, 1, 0x1e,
|
||||
0x56, 1, 0x1c,
|
||||
|
||||
0xa0, 3, 0x2b, 0x24, 0x00,
|
||||
|
||||
0xa1, 1, 0x87,
|
||||
0xa2, 1, 0x86,
|
||||
0xa5, 1, 0x00,
|
||||
0xa6, 1, 0x00,
|
||||
0xa7, 1, 0x00,
|
||||
0xa8, 1, 0x36,
|
||||
0xa9, 1, 0x7e,
|
||||
0xaa, 1, 0x7e,
|
||||
0xB9, 1, 0x85,
|
||||
0xBA, 1, 0x84,
|
||||
0xBB, 1, 0x83,
|
||||
0xBC, 1, 0x82,
|
||||
0xBD, 1, 0x81,
|
||||
0xBE, 1, 0x80,
|
||||
0xBF, 1, 0x01,
|
||||
0xC0, 1, 0x02,
|
||||
0xc1, 1, 0x00,
|
||||
0xc2, 1, 0x00,
|
||||
0xc3, 1, 0x00,
|
||||
0xc4, 1, 0x33,
|
||||
0xc5, 1, 0x7e,
|
||||
0xc6, 1, 0x7e,
|
||||
0xC8, 2, 0x33, 0x33,
|
||||
0xC9, 1, 0x68,
|
||||
0xCA, 1, 0x69,
|
||||
0xCB, 1, 0x6a,
|
||||
0xCC, 1, 0x6b,
|
||||
0xCD, 2, 0x33, 0x33,
|
||||
0xCE, 1, 0x6c,
|
||||
0xCF, 1, 0x6d,
|
||||
0xD0, 1, 0x6e,
|
||||
0xD1, 1, 0x6f,
|
||||
0xAB, 2, 0x03, 0x67,
|
||||
0xAC, 2, 0x03, 0x6b,
|
||||
0xAD, 2, 0x03, 0x68,
|
||||
0xAE, 2, 0x03, 0x6c,
|
||||
0xb3, 1, 0x00,
|
||||
0xb4, 1, 0x00,
|
||||
0xb5, 1, 0x00,
|
||||
0xB6, 1, 0x32,
|
||||
0xB7, 1, 0x7e,
|
||||
0xB8, 1, 0x7e,
|
||||
0xe0, 1, 0x00,
|
||||
0xe1, 2, 0x03, 0x0f,
|
||||
0xe2, 1, 0x04,
|
||||
0xe3, 1, 0x01,
|
||||
0xe4, 1, 0x0e,
|
||||
0xe5, 1, 0x01,
|
||||
0xe6, 1, 0x19,
|
||||
0xe7, 1, 0x10,
|
||||
0xe8, 1, 0x10,
|
||||
0xea, 1, 0x12,
|
||||
0xeb, 1, 0xd0,
|
||||
0xec, 1, 0x04,
|
||||
0xed, 1, 0x07,
|
||||
0xee, 1, 0x07,
|
||||
0xef, 1, 0x09,
|
||||
0xf0, 1, 0xd0,
|
||||
0xf1, 1, 0x0e,
|
||||
0xF9, 1, 0x17,
|
||||
|
||||
0xf2, 4, 0x2c, 0x1b, 0x0b, 0x20,
|
||||
|
||||
0xe9, 1, 0x29,
|
||||
0xec, 1, 0x04,
|
||||
0x35, 1, 0x00,
|
||||
0x44, 2, 0x00, 0x10,
|
||||
0x46, 1, 0x10,
|
||||
|
||||
LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF
|
||||
};
|
||||
|
||||
static const uint8_t init_cmd_list_2[] = {
|
||||
0x3a, 1, 0x05,
|
||||
NV3007_SLPOUT, 0,
|
||||
LV_LCD_CMD_DELAY_MS, 22,
|
||||
NV3007_DISPON, 0,
|
||||
|
||||
LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_nv3007_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_nv3007_send_cmd_cb_t send_cmd_cb, lv_nv3007_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);
|
||||
|
||||
send_cmd_cb(disp, (const uint8_t[]) {
|
||||
0xFF
|
||||
}, 1, (const uint8_t[]) {
|
||||
0xA5
|
||||
}, 1);
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list);
|
||||
send_cmd_cb(disp, (const uint8_t[]) {
|
||||
0xFF
|
||||
}, 1, (const uint8_t[]) {
|
||||
0x00
|
||||
}, 1);
|
||||
lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list_2);
|
||||
return disp;
|
||||
}
|
||||
|
||||
void lv_nv3007_set_gap(lv_display_t * disp, uint16_t x, uint16_t y)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gap(disp, x, y);
|
||||
}
|
||||
|
||||
void lv_nv3007_set_invert(lv_display_t * disp, bool invert)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_invert(disp, invert);
|
||||
}
|
||||
|
||||
void lv_nv3007_set_gamma_curve(lv_display_t * disp, uint8_t gamma)
|
||||
{
|
||||
lv_lcd_generic_mipi_set_gamma_curve(disp, gamma);
|
||||
}
|
||||
|
||||
void lv_nv3007_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_NV3007*/
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* @file lv_nv3007.h
|
||||
*
|
||||
* This driver is just a wrapper around the generic MIPI compatible LCD controller driver
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_NV3007_H
|
||||
#define LV_NV3007_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../lcd/lv_lcd_generic_mipi.h"
|
||||
|
||||
#if LV_USE_NV3007
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef lv_lcd_send_cmd_cb_t lv_nv3007_send_cmd_cb_t;
|
||||
typedef lv_lcd_send_color_cb_t lv_nv3007_send_color_cb_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an LCD display with NV3007 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_nv3007_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_nv3007_send_cmd_cb_t send_cmd_cb, lv_nv3007_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_nv3007_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_nv3007_set_invert(lv_display_t * disp, bool invert);
|
||||
|
||||
/**
|
||||
* Set gamma curve
|
||||
* @param disp display object
|
||||
* @param gamma gamma curve
|
||||
*/
|
||||
void lv_nv3007_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_nv3007_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list);
|
||||
|
||||
/**********************
|
||||
* OTHERS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#endif /*LV_USE_NV3007*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_NV3007_H*/
|
||||
@@ -31,6 +31,7 @@ extern "C" {
|
||||
#include "display/st7735/lv_st7735.h"
|
||||
#include "display/st7789/lv_st7789.h"
|
||||
#include "display/st7796/lv_st7796.h"
|
||||
#include "display/nv3007/lv_nv3007.h"
|
||||
|
||||
#include "display/renesas_glcdc/lv_renesas_glcdc.h"
|
||||
#include "display/st_ltdc/lv_st_ltdc.h"
|
||||
|
||||
@@ -4301,8 +4301,15 @@
|
||||
#define LV_USE_FT81X 0
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_USE_NV3007
|
||||
#ifdef CONFIG_LV_USE_NV3007
|
||||
#define LV_USE_NV3007 CONFIG_LV_USE_NV3007
|
||||
#else
|
||||
#define LV_USE_NV3007 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)
|
||||
#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341 | LV_USE_NV3007)
|
||||
#ifndef LV_USE_GENERIC_MIPI
|
||||
#ifdef LV_KCONFIG_PRESENT
|
||||
#ifdef CONFIG_LV_USE_GENERIC_MIPI
|
||||
|
||||
Reference in New Issue
Block a user