提交 ca363253 编写于 作者: A Annie_wang

update docs

Signed-off-by: NAnnie_wang <annie.wangli@huawei.com>
上级 c30d987d
# LCD # LCD
## Overview ## Overview
### Function
The Liquid Crystal Display (LCD) driver performs operations such as powering on the LCD and initializing the internal registers of the driver integrated circuits (ICs). The Liquid Crystal Display (LCD) driver performs operations such as powering on the LCD and initializing the internal registers of the driver integrated circuits (ICs).
The display driver model developed based on the Hardware Driver Foundation [(HDF)](../driver/driver-hdf-overview.md) provides a basic framework for LCD driver development, improves driver development efficiency, and facilitates porting of the driver across OSs and chip platforms. The figure below shows the HDF-based display driver model. The display driver model based on the [Hardware Driver Foundation (HDF)](../driver/driver-hdf-overview.md) provides the following functions:
- Provides a basic framework for LCD driver development to improve development efficiency.
- Facilitates driver porting across OSs and chip platforms.
The following figure shows the HDF-based display driver model.
**Figure 1** HDF-based display driver model **Figure 1** HDF-based display driver model
![image](figures/architecture-of-the-display-driver-model.png "Display Driver Model") ![image](figures/architecture-of-the-display-driver-model.png "Display Driver Model")
The display driver model consists of the display common driver layer, SoC adapter layer, and LCD panel driver layer. The HDF-based display driver model shields the differences between kernel forms through platform and OSAL APIs so that the LCD driver can be easily ported across OSs and chip platforms. The display driver model connects to the display common Hardware Abstraction Layer (HAL), supports the implementation of the Hardware Device Interface (HDI), and provides various driver capability interfaces for graphics services through the Display-HDI.
The display driver model consists of the display common driver layer, SoC adapter layer, and LCD panel driver layer. The HDF-based display driver model shields the differences between kernel forms through platform and OSAL APIs so the LCD driver can be easily ported between different OSs and chip platforms. The display driver model connects to the display common Hardware Abstraction Layer (HAL), supports the implementation of the Hardware Device Interface (HDI), and provides various driver capability interfaces for graphics services through the Display-HDI.
- Display common driver layer: connects to the display common HAL through the IOService data channel provided by the HDF to receive and process various upper-layer calls in a centralized manner. - Display common driver layer: connects to the display common HAL through the IOService data channel provided by the HDF to receive and process various upper-layer calls in a centralized manner.
...@@ -23,8 +29,7 @@ The display driver model consists of the display common driver layer, SoC adapte ...@@ -23,8 +29,7 @@ The display driver model consists of the display common driver layer, SoC adapte
The display driver model leverages the capabilities and APIs provided by the platform to simplify the display driver development and improve the efficiency. The display driver model leverages the capabilities and APIs provided by the platform to simplify the display driver development and improve the efficiency.
### Basic Concepts
## Available APIs
The LCD interfaces include the Mobile Industry Processor Interface (MIPI) Display Serial Interface (DSI), Transistor-Transistor Logic (TTL) interface, and Low Voltage Differential Signaling (LVDS) interface. The MIPI DSI and TTL interfaces are commonly used. Here is a brief introduction to them. The LCD interfaces include the Mobile Industry Processor Interface (MIPI) Display Serial Interface (DSI), Transistor-Transistor Logic (TTL) interface, and Low Voltage Differential Signaling (LVDS) interface. The MIPI DSI and TTL interfaces are commonly used. Here is a brief introduction to them.
...@@ -42,14 +47,31 @@ The LCD interfaces include the Mobile Industry Processor Interface (MIPI) Displa ...@@ -42,14 +47,31 @@ The LCD interfaces include the Mobile Industry Processor Interface (MIPI) Displa
![](figures/ttl-interface.png "ttl-interface") ![](figures/ttl-interface.png "ttl-interface")
TTL level signals are generated by TTL devices, which are a major type of digital integrated circuits. TTL devices are manufactured using the bipolar process and feature high speed, low power consumption, and diversified types. TTL level signals are generated by TTL devices, which are a major type of digital integrated circuits. TTL devices are manufactured using the bipolar process and feature high speed, low power consumption, and diversified types.
The TTL interface is used to transmit data in parallel mode under control signals. It transmits data signals, clock signals, and control signals (such as line synchronization signals, frame synchronization signals, and data validity signals). For the LCD with the TTL, additional peripheral interfaces, such as the Serial Peripheral Interface (SPI) and Inter-Integrated Circuit (I2C), are required for the read and write of the internal registers. The TTL interface is used to transmit data in parallel mode under control signals. It transmits data signals, clock signals, and control signals (such as line synchronization signals, frame synchronization signals, and data validity signals). For the LCD with the TTL, additional peripheral interfaces, such as the Serial Peripheral Interface (SPI) and Inter-Integrated Circuit (I2C), are required for the read and write of the internal registers.
### Constraints
In addition to the IC model, you must consider the LCD peripheral circuit design, LCD interface unit of the baseband chip, backlight IC control, and upper-layer software programs. All these factors affect the development of the LCD driver.
## Development Guidelines
### When to Use
## How to Develop Before applying your device with OpenHarmony system, you need to perform LCD driver adaption. The HDF-based display driver model provides a unified driver model for LCD adaptation regardless of the OS (LiteOS or Linux OS) and chip platform (Hi35xx, Hi38xx, or V3S).
The HDF-based display driver model provides a unified driver model for LCDs regardless of the OS (LiteOS or Linux OS) and chip platform (Hi35xx, Hi38xx, or V3S). The development procedure is as follows: ### Available APIs
Table 1 APIs required for LCD driver adaptation
| API | Description |
| :------------------------------------------------------ | ------------------- |
| display :: host | Sets device information. |
| static int32_t LcdResetOn(void) | Sets the status of the reset pin.|
| int32_t SampleEntryInit(struct HdfDeviceObject *object) | Initializes the entry function of the device driver. |
### How to Develop
1. Add the device configuration related to the LCD driver. 1. Add the device configuration related to the LCD driver.
...@@ -58,23 +80,26 @@ The HDF-based display driver model provides a unified driver model for LCDs rega ...@@ -58,23 +80,26 @@ The HDF-based display driver model provides a unified driver model for LCDs rega
3. Add the LCD panel driver and register the panel driver functions in the driver entry function **Init**. The functions provide capabilities for: 3. Add the LCD panel driver and register the panel driver functions in the driver entry function **Init**. The functions provide capabilities for:
- Powering on/off the LCD device - Powering on/off the LCD device
Based on the LCD hardware connection, use the GPIO APIs provided by the platform to perform operations on the LCD pins, such as the reset pin and IOVCC pin. For details about the power-on sequence, see the SPEC provided by the LCD supplier. Based on the LCD hardware connection, use the GPIO APIs provided by the platform to perform operations on the LCD pins, such as the reset pin and IOVCC pin. For details about the power-on sequence, see the SPEC provided by the LCD supplier.
- Sending the initialization sequence - Sending the initialization sequence
Based on the LCD hardware interfaces, use the I2C, SPI, and MIPI interfaces provided by the platform to download the LCD initialization sequence. For details, see the SPEC provided by the LCD supplier.
4. Implement other HDF APIs as required, for example, **Release()**. Based on the LCD hardware interfaces, use the I2C, SPI, and MIPI interfaces provided by the platform to download the LCD initialization sequence. For details, see the SPEC provided by the LCD supplier.
5. Use the HDF to create other device nodes for implementing service logic or debugging as required. 4. (Optional) Implement other HDF APIs, such as **Release()**, as required.
5. (Optional) Create other device nodes for implementing service logic or debugging based on the HDF as required.
## Development Example ### Example
Add the device configuration. The following uses the Hi35xx series chips as an example to describe how to perform LCD driver adaptation.
1. Add device information in the **vendor/bearpi/bearpi_hm_micro/hdf_config/device_info/device_info.hcs** file.
``` ```c++
/* Configuration of the devices related to the display driver */ /* Configuration of the devices related to the display driver */
display :: host { display :: host {
hostName = "display_host"; hostName = "display_host";
/* Configuration of the HDF display driver */ /* Configuration of the HDF display driver */
device_hdf_disp :: device { device_hdf_disp :: device {
...@@ -109,15 +134,15 @@ display :: host { ...@@ -109,15 +134,15 @@ display :: host {
moduleName = "LCD_SampleXX"; moduleName = "LCD_SampleXX";
} }
} }
} }
``` ```
Adapt the driver to the chip at the SoC adapter layer. The following example shows how to adapt the MIPI device to the Hi35xx series chips at the SoC adapter layer:
2. Configure the chip platform driver information in the **drivers/hdf_core/framework/model/display/driver/adapter_soc/hi35xx_disp.c file**.
``` ```c++
static int32_t MipiDsiInit(struct PanelInfo *info) /* Configuration of the display driver to adapt to the MIPI and chip platform */
{ static int32_t MipiDsiInit(struct PanelInfo *info)
{
int32_t ret; int32_t ret;
struct DevHandle *mipiHandle = NULL; struct DevHandle *mipiHandle = NULL;
struct MipiCfg cfg; struct MipiCfg cfg;
...@@ -152,34 +177,37 @@ static int32_t MipiDsiInit(struct PanelInfo *info) ...@@ -152,34 +177,37 @@ static int32_t MipiDsiInit(struct PanelInfo *info)
HDF_LOGI("%s:pixelClk = %d, phyDataRate = %d\n", __func__, HDF_LOGI("%s:pixelClk = %d, phyDataRate = %d\n", __func__,
cfg.pixelClk, cfg.phyDataRate); cfg.pixelClk, cfg.phyDataRate);
return ret; return ret;
} }
``` ```
Develop an LCD driver. The sample code is as follows: 3. Add a device in **drivers/hdf_core/framework/model/display/driver/panel/mipi_icn9700.c**.
- Define driver-related interface information.
```
#define RESET_GPIO 5 ```c++
#define MIPI_DSI0 0 #define RESET_GPIO 5
#define BLK_PWM1 1 #define MIPI_DSI0 0
#define PWM_MAX_PERIOD 100000 #define BLK_PWM1 1
/* Set the backlight. */ #define PWM_MAX_PERIOD 100000
#define MIN_LEVEL 0 /* Set the backlight. */
#define MAX_LEVEL 255 #define MIN_LEVEL 0
#define DEFAULT_LEVEL 100 #define MAX_LEVEL 255
#define DEFAULT_LEVEL 100
#define WIDTH 480 #define WIDTH 480
#define HEIGHT 960 #define HEIGHT 960
#define HORIZONTAL_BACK_PORCH 20 #define HORIZONTAL_BACK_PORCH 20
#define HORIZONTAL_FRONT_PORCH 20 #define HORIZONTAL_FRONT_PORCH 20
#define HORIZONTAL_SYNC_WIDTH 10 #define HORIZONTAL_SYNC_WIDTH 10
#define VERTICAL_BACK_PORCH 14 #define VERTICAL_BACK_PORCH 14
#define VERTICAL_FRONT_PORCH 16 #define VERTICAL_FRONT_PORCH 16
#define VERTICAL_SYNC_WIDTH 2 #define VERTICAL_SYNC_WIDTH 2
#define FRAME_RATE 60 #define FRAME_RATE 60
```
/* PanelInfo structure */
struct PanelInfo { - Define the **PanelInfo** structure.
```c++
struct PanelInfo {
uint32_t width; uint32_t width;
uint32_t height; uint32_t height;
uint32_t hbp; uint32_t hbp;
...@@ -194,64 +222,46 @@ struct PanelInfo { ...@@ -194,64 +222,46 @@ struct PanelInfo {
struct MipiDsiDesc mipi; struct MipiDsiDesc mipi;
struct BlkDesc blk; struct BlkDesc blk;
struct PwmCfg pwm; struct PwmCfg pwm;
}; };
```
/* Initialization sequence of the LCD panel */
static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A }; - Initialize the LCD.
static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 };
static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B }; ```c++
static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A }; static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A };
static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C }; static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 };
static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C }; static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B };
static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 }; static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A };
static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 }; static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C };
static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 }; static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C };
static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 }; static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 };
static uint8_t g_payLoad10[] = { 0xb7, 0x41 }; static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 };
static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 }; static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 };
static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 }; static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 };
static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 }; static uint8_t g_payLoad10[] = { 0xb7, 0x41 };
static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF }; static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 };
static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 }; static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 };
static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 }; static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 };
static uint8_t g_payLoad17[] = { 0xc7, 0x04 }; static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF };
static uint8_t g_payLoad18[] = { static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 };
static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 };
static uint8_t g_payLoad17[] = { 0xc7, 0x04 };
static uint8_t g_payLoad18[] = {
0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40, 0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40,
0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52,
0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06 0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06
}; };
static uint8_t g_payLoad19[] = { 0x11 }; static uint8_t g_payLoad19[] = { 0x11 };
static uint8_t g_payLoad20[] = { 0x29 }; static uint8_t g_payLoad20[] = { 0x29 };
static DevHandle g_mipiHandle = NULL;
struct DsiCmdDesc g_OnCmd[] = { static DevHandle g_pwmHandle = NULL;
{ 0x29, 0, sizeof(g_payLoad0), g_payLoad0 }, ```
{ 0x29, 0, sizeof(g_payLoad1), g_payLoad1 },
{ 0x29, 0, sizeof(g_payLoad2), g_payLoad2 }, - Set the status of the reset pin.
{ 0x29, 0, sizeof(g_payLoad3), g_payLoad3 },
{ 0x29, 0, sizeof(g_payLoad4), g_payLoad4 }, ```c++
{ 0x29, 0, sizeof(g_payLoad5), g_payLoad5 }, static int32_t LcdResetOn(void)
{ 0x29, 0, sizeof(g_payLoad6), g_payLoad6 }, {
{ 0x29, 0, sizeof(g_payLoad7), g_payLoad7 },
{ 0x29, 0, sizeof(g_payLoad8), g_payLoad8 },
{ 0x29, 0, sizeof(g_payLoad9), g_payLoad9 },
{ 0x23, 0, sizeof(g_payLoad10), g_payLoad10 },
{ 0x29, 0, sizeof(g_payLoad11), g_payLoad11 },
{ 0x29, 0, sizeof(g_payLoad12), g_payLoad12 },
{ 0x29, 0, sizeof(g_payLoad13), g_payLoad13 },
{ 0x29, 0, sizeof(g_payLoad14), g_payLoad14 },
{ 0x29, 0, sizeof(g_payLoad15), g_payLoad15 },
{ 0x29, 0, sizeof(g_payLoad16), g_payLoad16 },
{ 0x23, 0, sizeof(g_payLoad17), g_payLoad17 },
{ 0x29, 1, sizeof(g_payLoad18), g_payLoad18 },
{ 0x05, 120, sizeof(g_payLoad19), g_payLoad19 },
{ 0x05, 120, sizeof(g_payLoad20), g_payLoad20 },
};
static DevHandle g_mipiHandle = NULL;
static DevHandle g_pwmHandle = NULL;
/* Set the status of the reset pin. */
static int32_t LcdResetOn(void)
{
int32_t ret; int32_t ret;
ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT); ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT);
if (ret != HDF_SUCCESS) { if (ret != HDF_SUCCESS) {
...@@ -266,79 +276,14 @@ static int32_t LcdResetOn(void) ...@@ -266,79 +276,14 @@ static int32_t LcdResetOn(void)
/* Set the delay to 20 ms. */ /* Set the delay to 20 ms. */
OsalMSleep(20); OsalMSleep(20);
return HDF_SUCCESS; return HDF_SUCCESS;
}
static int32_t SampleInit(void)
{
/* Open the MIPI DSI device handle. */
g_mipiHandle = MipiDsiOpen(MIPI_DSI0);
if (g_mipiHandle == NULL) {
HDF_LOGE("%s: MipiDsiOpen failure", __func__);
return HDF_FAILURE;
} }
return HDF_SUCCESS; ```
}
static int32_t SampleOn(void) - Initialize the entry function of the device driver.
{
int32_t ret; ```c++
/* Power on the LCD. */ int32_t SampleEntryInit(struct HdfDeviceObject *object)
ret = LcdResetOn(); {
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: LcdResetOn failure", __func__);
return HDF_FAILURE;
}
if (g_mipiHandle == NULL) {
HDF_LOGE("%s: g_mipiHandle is null", __func__);
return HDF_FAILURE;
}
/* Send the initialization sequence via MIPI. */
int32_t count = sizeof(g_OnCmd) / sizeof(g_OnCmd[0]);
int32_t i;
for (i = 0; i < count; i++) {
ret = MipiDsiTx(g_mipiHandle, &(g_OnCmd[i]));
if (ret != HDF_SUCCESS) {
HDF_LOGE("MipiDsiTx failure");
return HDF_FAILURE;
}
}
/* Set MIPI to the high speed (HS) mode. */
MipiDsiSetHsMode(g_mipiHandle);
return HDF_SUCCESS;
}
/* PanelInfo structure variables */
static struct PanelInfo g_panelInfo = {
.width = WIDTH, /* width */
.height = HEIGHT, /* height */
.hbp = HORIZONTAL_BACK_PORCH, /* horizontal back porch */
.hfp = HORIZONTAL_FRONT_PORCH, /* horizontal front porch */
.hsw = HORIZONTAL_SYNC_WIDTH, /* horizontal sync width */
.vbp = VERTICAL_BACK_PORCH, /* vertical back porch */
.vfp = VERTICAL_FRONT_PORCH, /* vertical front porch */
.vsw = VERTICAL_SYNC_WIDTH, /* vertical sync width */
.frameRate = FRAME_RATE, /* frame rate */
.intfType = MIPI_DSI, /* panel interface type */
.intfSync = OUTPUT_USER, /* output timing type */
/* MIPI configuration */
.mipi = { DSI_2_LANES, DSI_VIDEO_MODE, VIDEO_BURST_MODE, FORMAT_RGB_24_BIT },
/* backlight config info */
.blk = { BLK_PWM, MIN_LEVEL, MAX_LEVEL, DEFAULT_LEVEL },
.pwm = { BLK_PWM1, PWM_MAX_PERIOD },
};
/* Basic APIs that need to be adapted for the chip driver */
static struct PanelData g_panelData = {
.info = &g_panelInfo,
.init = SampleInit,
.on = SampleOn,
.off = SampleOff,
.setBacklight = SampleSetBacklight,
};
/* Entry function of the chip driver */
int32_t SampleEntryInit(struct HdfDeviceObject *object)
{
HDF_LOGI("%s: enter", __func__); HDF_LOGI("%s: enter", __func__);
if (object == NULL) { if (object == NULL) {
HDF_LOGE("%s: param is null!", __func__); HDF_LOGE("%s: param is null!", __func__);
...@@ -350,13 +295,13 @@ int32_t SampleEntryInit(struct HdfDeviceObject *object) ...@@ -350,13 +295,13 @@ int32_t SampleEntryInit(struct HdfDeviceObject *object)
return HDF_FAILURE; return HDF_FAILURE;
} }
return HDF_SUCCESS; return HDF_SUCCESS;
} }
struct HdfDriverEntry g_sampleDevEntry = { struct HdfDriverEntry g_sampleDevEntry = {
.moduleVersion = 1, .moduleVersion = 1,
.moduleName = "LCD_SAMPLE", .moduleName = "LCD_SAMPLE",
.Init = SampleEntryInit, .Init = SampleEntryInit,
}; };
HDF_INIT(g_sampleDevEntry); HDF_INIT(g_sampleDevEntry);
``` ```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册