• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "gpio_if.h"
10 #include "hdf_device_desc.h"
11 #include "hdf_log.h"
12 #include "osal_mem.h"
13 #include "osal_time.h"
14 #include "spi_if.h"
15 #include "ssp_st7789.h"
16 
17 #define WIDTH         240
18 #define HEIGHT        320
19 #define FRAME_RATE    50
20 
21 static struct LcdCmd g_onCmd[] = {
22     { LCD_CMD,  0x11, 120 },
23     { LCD_CMD,  0x36, 0 },
24     { LCD_DATA, 0x00, 0 },
25     { LCD_CMD,  0xb2, 0 },
26     { LCD_DATA, 0x00, 0 },
27     { LCD_DATA, 0x00, 0 },
28     { LCD_DATA, 0x00, 0 },
29     { LCD_DATA, 0x33, 0 },
30     { LCD_DATA, 0x33, 0 },
31     { LCD_CMD,  0xb7, 0 },
32     { LCD_DATA, 0x35, 0 },
33     { LCD_CMD,  0xb8, 0 },
34     { LCD_DATA, 0x2f, 0 },
35     { LCD_DATA, 0x2b, 0 },
36     { LCD_DATA, 0x2f, 0 },
37     { LCD_CMD,  0xbb, 0 },
38     { LCD_DATA, 0x24, 0 },
39     { LCD_CMD,  0xc0, 0 },
40     { LCD_DATA, 0x2c, 0 },
41     { LCD_CMD,  0xc3, 0 },
42     { LCD_DATA, 0x20, 0 },
43     { LCD_CMD,  0xc4, 0 },
44     { LCD_DATA, 0x03, 0 },
45     { LCD_CMD,  0xc6, 0 },
46     { LCD_DATA, 0x11, 0 },
47     { LCD_CMD,  0xd0, 0 },
48     { LCD_DATA, 0xa4, 0 },
49     { LCD_DATA, 0xa1, 0 },
50     { LCD_CMD,  0xe8, 0 },
51     { LCD_DATA, 0x03, 0 },
52     { LCD_CMD,  0xe9, 0 },
53     { LCD_DATA, 0x0d, 0 },
54     { LCD_DATA, 0x12, 0 },
55     { LCD_DATA, 0x00, 0 },
56     { LCD_CMD,  0x21, 0 },
57     { LCD_CMD,  0xb0, 0 },
58     { LCD_DATA, 0x11, 0 },
59     { LCD_DATA, 0x04, 0 },
60     { LCD_DATA, 0x00, 0 },
61     { LCD_CMD,  0xb1, 0 },
62     { LCD_DATA, 0xc0, 0 },
63     { LCD_DATA, 0x02, 0 },
64     { LCD_DATA, 0x14, 0 },
65     { LCD_CMD,  0x3a, 0 },
66     { LCD_DATA, 0x66, 0 },
67     { LCD_CMD,  0x11, 0 },
68     { LCD_CMD,  0x29, 0 },
69     { LCD_CMD,  0x2c, 0 },
70 };
71 
72 static struct LcdCmd g_offCmd[] = {
73     { LCD_CMD,  0x28, 20 },
74     { LCD_CMD,  0x10, 120 },
75 };
76 
77 static DevHandle g_spiHdl = NULL;
78 
SpiWrite9Bits(DevHandle spiHandle,uint8_t cmd,uint8_t data)79 static int32_t SpiWrite9Bits(DevHandle spiHandle, uint8_t cmd, uint8_t data)
80 {
81     int32_t ret;
82     uint16_t wbuff[1] = {0};
83 
84     wbuff[0] = ((cmd << BITS_PER_BYTE) | data);
85     ret = SpiWrite(spiHandle, (uint8_t *)wbuff, SPI_MSG_SIZE);
86     if (ret != HDF_SUCCESS) {
87         HDF_LOGE("SpiWrite failed, ret:%d", ret);
88         return HDF_FAILURE;
89     }
90     return HDF_SUCCESS;
91 }
92 
GetSpiHandle(void)93 static DevHandle GetSpiHandle(void)
94 {
95     int32_t ret;
96     DevHandle spiHandle = NULL;
97     struct SpiDevInfo spiDevinfo;
98     struct SpiCfg cfg;
99 
100     spiDevinfo.busNum = 1;
101     spiDevinfo.csNum = 0;
102     spiHandle = SpiOpen(&spiDevinfo);
103     if (spiHandle == NULL) {
104         HDF_LOGE("SpiOpen failed");
105         return NULL;
106     }
107     cfg.mode = SPI_CLK_PHASE | SPI_CLK_POLARITY;
108     cfg.bitsPerWord = BITS_PER_WORD;
109     cfg.maxSpeedHz = SPI_MAX_SPEED;
110     ret = SpiSetCfg(spiHandle, &cfg);
111     if (ret != HDF_SUCCESS) {
112         HDF_LOGE("SpiSetCfg failed, ret:%d", ret);
113         SpiClose(spiHandle);
114         return NULL;
115     }
116     HDF_LOGI("Spi init success!");
117     return spiHandle;
118 }
119 
LcdResetOn(void)120 static int32_t LcdResetOn(void)
121 {
122     int32_t ret;
123 
124     ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT);
125     if (ret != HDF_SUCCESS) {
126         HDF_LOGE("set lcd reset dir failed, ret:%d", ret);
127         return HDF_FAILURE;
128     }
129     ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH);
130     if (ret != HDF_SUCCESS) {
131         HDF_LOGE("set lcd reset hi failed, ret:%d", ret);
132         return HDF_FAILURE;
133     }
134     ret = GpioWrite(RESET_GPIO, GPIO_VAL_LOW);
135     if (ret != HDF_SUCCESS) {
136         HDF_LOGE("set lcd reset how failed, ret:%d", ret);
137         return HDF_FAILURE;
138     }
139     /* delay 10ms */
140     OsalMSleep(10);
141     ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH);
142     if (ret != HDF_SUCCESS) {
143         HDF_LOGE("set lcd reset hi after delay failed, ret:%d", ret);
144         return HDF_FAILURE;
145     }
146     /* delay 120ms */
147     OsalMSleep(120);
148     return HDF_SUCCESS;
149 }
150 
LcdResetOff(void)151 static int32_t LcdResetOff(void)
152 {
153     int32_t ret;
154 
155     ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT);
156     if (ret != HDF_SUCCESS) {
157         HDF_LOGE("GpioSetDir failed, ret:%d", ret);
158         return HDF_FAILURE;
159     }
160     ret = GpioWrite(RESET_GPIO, GPIO_VAL_LOW);
161     if (ret != HDF_SUCCESS) {
162         HDF_LOGE("GpioWrite failed, ret:%d", ret);
163         return HDF_FAILURE;
164     }
165     /* delay 20ms */
166     OsalMSleep(20);
167     return HDF_SUCCESS;
168 }
169 
St7789Init(void)170 static int32_t St7789Init(void)
171 {
172     g_spiHdl = GetSpiHandle();
173     if (g_spiHdl == NULL) {
174         HDF_LOGE("GetSpiHandle failed");
175         return HDF_FAILURE;
176     }
177     return HDF_SUCCESS;
178 }
179 
St7789On(void)180 static int32_t St7789On(void)
181 {
182     int32_t ret;
183     int i;
184 
185     /* lcd reset power on */
186     ret = LcdResetOn();
187     if (ret != HDF_SUCCESS) {
188         HDF_LOGE("%s: LcdResetOn failed", __func__);
189         return HDF_FAILURE;
190     }
191     if (g_spiHdl == NULL) {
192         HDF_LOGE("%s: g_spiHdl is null", __func__);
193         return HDF_FAILURE;
194     }
195     int32_t count = sizeof(g_onCmd) / sizeof(g_onCmd[0]);
196     for (i = 0; i < count; i++) {
197         ret = SpiWrite9Bits(g_spiHdl, g_onCmd[i].cmd, g_onCmd[i].data);
198         if (ret != HDF_SUCCESS) {
199             HDF_LOGE("SpiWrite failed");
200             return HDF_FAILURE;
201         }
202         if (g_onCmd[i].delay > 0) {
203             OsalMSleep(g_onCmd[i].delay);
204         }
205     }
206     return HDF_SUCCESS;
207 }
208 
St7789Off(void)209 static int32_t St7789Off(void)
210 {
211     int32_t ret;
212     int i;
213 
214     if (g_spiHdl == NULL) {
215         HDF_LOGE("%s: g_spiHdl is null", __func__);
216         return HDF_FAILURE;
217     }
218     /* send mipi init code */
219     int32_t count = sizeof(g_offCmd) / sizeof(g_offCmd[0]);
220 
221     for (i = 0; i < count; i++) {
222         ret = SpiWrite9Bits(g_spiHdl, g_offCmd[i].cmd, g_offCmd[i].data);
223         if (ret != HDF_SUCCESS) {
224             HDF_LOGE("SpiWrite9Bits failed");
225             return HDF_FAILURE;
226         }
227         if (g_offCmd[i].delay > 0) {
228             OsalMSleep(g_offCmd[i].delay);
229         }
230     }
231     /* lcd reset power off */
232     ret = LcdResetOff();
233     if (ret != HDF_SUCCESS) {
234         HDF_LOGE("%s: LcdResetOff failed", __func__);
235         return HDF_FAILURE;
236     }
237     return HDF_SUCCESS;
238 }
239 
St7789SetBacklight(uint32_t level)240 static int32_t St7789SetBacklight(uint32_t level)
241 {
242     (void)level;
243     return HDF_SUCCESS;
244 }
245 
246 static struct PanelInfo g_panelInfo = {
247     .width = WIDTH,                   /* width */
248     .height = HEIGHT,                 /* height */
249     .frameRate = FRAME_RATE,          /* frame rate */
250     .intfType = LCD_6BIT,             /* panel interface type */
251     .intfSync = 42,    /* Hi3559AV100: For ili9341 at 50 Hz (6bit) */
252 };
253 
254 static struct PanelData g_panelData = {
255     .info = &g_panelInfo,
256     .init = St7789Init,
257     .on = St7789On,
258     .off = St7789Off,
259     .setBacklight = St7789SetBacklight,
260 };
261 
SspSt7789EntryInit(struct HdfDeviceObject * object)262 static int32_t SspSt7789EntryInit(struct HdfDeviceObject *object)
263 {
264     if (object == NULL) {
265         HDF_LOGE("%s: param is null", __func__);
266         return HDF_FAILURE;
267     }
268     if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) {
269         HDF_LOGE("%s: PanelDataRegister failed", __func__);
270         return HDF_FAILURE;
271     }
272     HDF_LOGI("%s: exit succ", __func__);
273     return HDF_SUCCESS;
274 }
275 
276 struct HdfDriverEntry g_st7789DevEntry = {
277     .moduleVersion = 1,
278     .moduleName = "LCD_ST7789",
279     .Init = SspSt7789EntryInit,
280 };
281 
282 HDF_INIT(g_st7789DevEntry);
283