1# LCD
2
3## Overview
4
5### Function
6
7The Liquid Crystal Display (LCD) driver performs operations such as powering on the LCD and initializing the internal registers of the driver integrated circuits (ICs).
8
9The display driver model based on the [Hardware Driver Foundation (HDF)](driver-overview-foundation.md) provides the following functions:
10
11- Provides a basic framework for LCD driver development to improve development efficiency.
12
13- Facilitates driver porting across OSs and chip platforms.
14
15The following figure shows the HDF-based display driver model.
16
17**Figure 1** HDF-based display driver model
18
19![image](figures/architecture-of-the-display-driver-model.png "Display Driver Model")
20
21The 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.
22
23- 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.
24
25- SoC adapter layer: decouples the display driver from the SoC driver, configures parameters related to the chip platform, and passes the calls from the platform driver layer to the LCD driver layer.
26
27- LCD panel driver layer: provides LCD-related APIs for sending the initialization sequence, powering on/off, and setting the backlight.
28
29The display driver model leverages the capabilities and APIs provided by the platform to simplify the display driver development and improve the efficiency.
30
31### Basic Concepts
32
33The 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.
34
35- MIPI DSI
36
37    **Figure 2** MIPI DSI
38
39    ![](figures/mipi-dsi.png "MIPI DSI")
40
41    The DSI is defined by the MIPI Alliance for the displays used in mobile devices. The MIPI DSI is used to transmit image data, in compliance with the MIPI protocol. Generally, control information is sent to the peer IC in the form of MIPI packets over the MIPI DSI, without the need of additional peripheral interfaces.
42
43- TTL interface
44
45    **Figure 3** TTL interface
46
47    ![](figures/ttl-interface.png "ttl-interface")
48
49    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.
50
51    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.
52
53### Constraints
54
55In 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.
56
57## Development Guidelines
58
59### When to Use
60
61Before 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).
62
63### Available APIs
64
65To adjust the parameters of the LCD, establish a display channel with the display, and implement the display effect, use **display::host** to register the **PanelInfo** struct and interface information and add device description.
66
67Table 1 APIs required for LCD driver adaptation
68
69| API                                                 | Description               |
70| :------------------------------------------------------ | ------------------- |
71| static int32_t MipiDsiInit(struct PanelInfo *info)      | Initializes the corresponding chip platform driver.|
72| static int32_t LcdResetOn(void)                         | Sets the status of the reset pin.|
73| int32_t SampleEntryInit(struct HdfDeviceObject *object) | Initializes the entry function of the device driver.   |
74
75### How to Develop
76
77
781. Add the device configuration related to the LCD driver.
79
802. Adapt the driver to the chip at the SoC adapter layer.
81
823. Add the LCD panel driver and register the panel driver data in the driver entry function **Init**. The driver data interface implements the following features:
83   - Powering on/off the LCD device
84
85      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.
86
87   - Sending the initialization sequence
88
89      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.
90
914. (Optional) Implement other HDF interfaces as required.
92
935. (Optional) Create other device nodes for implementing service logic or debugging based on the HDF as required.
94
95### Example
96
97The following uses the Hi35xx series chips as an example to describe how to perform LCD driver adaptation.
98
991. Add device information in the **vendor/bearpi/bearpi_hm_micro/hdf_config/device_info/device_info.hcs** file.
100
101   ```c++
102   /* Configuration of the devices related to the display driver */
103   display :: host {
104       hostName = "display_host";
105       /* Configuration of the HDF display driver */
106       device_hdf_disp :: device {
107           device0 :: deviceNode {
108               policy = 2;
109               priority = 200;
110               permission = 0660;
111               moduleName = "HDF_DISP";
112               serviceName = "hdf_disp";
113           }
114       }
115       /* Configuration of the driver device at the SoC adapter layer */
116       device_hi35xx_disp :: device {
117           device0 :: deviceNode {
118               policy = 0;
119               priority = 199;
120               moduleName = "HI351XX_DISP";
121           }
122       }
123       /* Configuration of the LCD driver */
124       device_lcd :: device {
125           device0 :: deviceNode {
126               policy = 0;
127               priority = 100;
128               preload = 0;
129               moduleName = "LCD_Sample";
130           }
131           device1 :: deviceNode {
132               policy = 0;
133               priority = 100;
134               preload = 2;
135               moduleName = "LCD_SampleXX";
136           }
137       }
138   }
139   ```
140
1412. Configure the chip platform driver information in **drivers/hdf_core/framework/model/display/driver/adapter_soc/hi35xx_disp.c**.
142
143   ```c++
144   /* Configuration of the display driver to adapt to the MIPI and chip platform */
145   static int32_t MipiDsiInit(struct PanelInfo *info)
146   {
147       int32_t ret;
148       struct DevHandle *mipiHandle = NULL;
149       struct MipiCfg cfg;
150
151       mipiHandle = MipiDsiOpen(0);
152       if (mipiHandle == NULL) {
153           HDF_LOGE("%s: MipiDsiOpen failure", __func__);
154           return HDF_FAILURE;
155       }
156       cfg.lane = info->mipi.lane;
157       cfg.mode = info->mipi.mode;
158       cfg.format = info->mipi.format;
159       cfg.burstMode = info->mipi.burstMode;
160       cfg.timing.xPixels = info->width;
161       cfg.timing.hsaPixels = info->hsw;
162       cfg.timing.hbpPixels = info->hbp;
163       cfg.timing.hlinePixels = info->width + info->hbp + info->hfp + info->hsw;
164       cfg.timing.vsaLines = info->vsw;
165       cfg.timing.vbpLines = info->vbp;
166       cfg.timing.vfpLines = info->vfp;
167       cfg.timing.ylines = info->height;
168       /* 0 : no care */
169       cfg.timing.edpiCmdSize = 0;
170       cfg.pixelClk = CalcPixelClk(info);
171       cfg.phyDataRate = CalcDataRate(info);
172       /* Configure the MIPI device. */
173       ret = MipiDsiSetCfg(mipiHandle, &cfg);
174       if (ret != HDF_SUCCESS) {
175           HDF_LOGE("%s:MipiDsiSetCfg failure", __func__);
176       }
177       MipiDsiClose(mipiHandle);
178       HDF_LOGI("%s:pixelClk = %d, phyDataRate = %d\n", __func__,
179           cfg.pixelClk, cfg.phyDataRate);
180       return ret;
181   }
182   ```
183
1843. Add a device.
185
186   - Define driver-related interfaces (**drivers/hdf_core/framework/model/display/driver/panel/mipi_icn9700.c**).
187
188     ```c++
189     #define RESET_GPIO                5
190     #define MIPI_DSI0                 0
191     #define BLK_PWM1                  1
192     #define PWM_MAX_PERIOD            100000
193     /* Set the backlight. */
194     #define MIN_LEVEL                 0
195     #define MAX_LEVEL                 255
196     #define DEFAULT_LEVEL             100
197     #define WIDTH                     480
198     #define HEIGHT                    960
199     #define HORIZONTAL_BACK_PORCH     20
200     #define HORIZONTAL_FRONT_PORCH    20
201     #define HORIZONTAL_SYNC_WIDTH     10
202     #define VERTICAL_BACK_PORCH       14
203     #define VERTICAL_FRONT_PORCH      16
204     #define VERTICAL_SYNC_WIDTH       2
205     #define FRAME_RATE                60
206     ```
207
208   - Define the **PanelInfo** struct (**drivers/hdf_core/framework/model/display/driver/hdf_disp.h**).
209
210     ```c++
211     struct PanelInfo {
212         uint32_t width;	          // Width
213         uint32_t height;	      // Height
214         uint32_t hbp;		      // Horizontal back porch
215         uint32_t hfp;		      // Horizontal front porch
216         uint32_t hsw; 		      // Horizontal synchronization width
217         uint32_t vbp;		      // Vertical back porch
218         uint32_t vfp;		      // Vertical front porch
219         uint32_t vsw;		      // Vertical synchronization width
220         uint32_t frameRate;             // Frame rate
221         enum LcdIntfType intfType; // LCD interface type
222         enum IntfSync intfSync;    // User timing parameter
223         struct MipiDsiDesc mipi;
224         struct BlkDesc blk;
225         struct PwmCfg pwm;
226     };
227     ```
228
229   - Initialize the LCD (**drivers/hdf_core/framework/model/display/driver/panel/mipi_icn9700.c**).
230
231     ```c++
232     static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A };
233     static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 };
234     static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B };
235     static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A };
236     static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C };
237     static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C };
238     static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 };
239     static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 };
240     static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 };
241     static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 };
242     static uint8_t g_payLoad10[] = { 0xb7, 0x41 };
243     static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 };
244     static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 };
245     static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 };
246     static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF };
247     static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 };
248     static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 };
249     static uint8_t g_payLoad17[] = { 0xc7, 0x04 };
250     static uint8_t g_payLoad18[] = {
251         0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40,
252         0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52,
253         0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06
254     };
255     static uint8_t g_payLoad19[] = { 0x11 };
256     static uint8_t g_payLoad20[] = { 0x29 };
257     static DevHandle g_mipiHandle = NULL;
258     static DevHandle g_pwmHandle = NULL;
259     ```
260
261   - Set the Reset pin status (**/drivers_hdf_core/framework/model/display/driver/panel/mipi_icn9700.c**).
262
263     ```c++
264     static int32_t LcdResetOn(void)
265     {
266         int32_t ret;
267	 /* Set the pin direction. */
268         ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT);
269         if (ret != HDF_SUCCESS) {
270             HDF_LOGE("GpioSetDir failure, ret:%d", ret);
271             return HDF_FAILURE;
272         }
273	 /* Write the GPIO. */
274         ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH);
275         if (ret != HDF_SUCCESS) {
276             HDF_LOGE("GpioWrite failure, ret:%d", ret);
277             return HDF_FAILURE;
278         }
279         /* Set the delay to 20 ms. */
280         OsalMSleep(20);
281         return HDF_SUCCESS;
282     }
283     ```
284
285   - Define the device driver entry function (**/drivers_hdf_core/framework/model/display/driver/panel/mipi_icn9700.c**).
286
287     ```c++
288     /* Initialize the entry function. */
289     int32_t SampleEntryInit(struct HdfDeviceObject *object)
290     {
291         HDF_LOGI("%s: enter", __func__);
292         if (object == NULL) {
293             HDF_LOGE("%s: param is null!", __func__);
294             return HDF_FAILURE;
295         }
296         /* Register the device driver APIs with the platform driver. */
297         if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) {
298             HDF_LOGE("%s: PanelDataRegister error!", __func__);
299             return HDF_FAILURE;
300         }
301         return HDF_SUCCESS;
302     }
303
304     /* Implement the driver. */
305     struct HdfDriverEntry g_sampleDevEntry = {
306         .moduleVersion = 1,
307         .moduleName = "LCD_SAMPLE",
308         .Init = SampleEntryInit,
309     };
310
311     HDF_INIT(g_sampleDevEntry);
312     ```
313