blob: 7517c5c3d2fb6ce961a64b0d1ecdb50ab2b2ddbf [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001#include "lcd.h"
2#include "st7735.c"
3#include "font.c"
4#include "hal.h"
5
6#define NULL 0
7#define printf obm_printf
8#define mdelay(x) Delay((x) * 1000)
9
10#ifdef CONFIG_SPI_LCD_3WIRE
11#define FB_SIZE (CONFIG_SPI_LCD_XRES * CONFIG_SPI_LCD_YRES * 2 * 2)
12#else
13#define FB_SIZE (CONFIG_SPI_LCD_XRES * CONFIG_SPI_LCD_YRES * 2)
14#endif
15
16static unsigned char *gFramebuffer = NULL;
17
18static inline void LCD_SELECT_DATA_OR_CMD(int a)
19{
20#ifndef CONFIG_SPI_LCD_3WIRE
21 gpio_direction_output(CONFIG_SPI_LCD_RS_PIN, a);
22#endif
23}
24
25void LCD_SEND_DATA(void)
26{
27 LCD_SELECT_DATA_OR_CMD(1);
28}
29
30void LCD_SEND_CMD(void)
31{
32 LCD_SELECT_DATA_OR_CMD(0);
33}
34
35void lcd_power(int on)
36{
37#ifdef CONFIG_SPI_LCD_POWER_PIN
38 gpio_direction_output(CONFIG_SPI_LCD_POWER_PIN, on);
39#endif
40}
41
42void lcd_reset(void)
43{
44 gpio_direction_output(CONFIG_SPI_LCD_RST_PIN, 1);
45 mdelay(50);
46 gpio_direction_output(CONFIG_SPI_LCD_RST_PIN, 0);
47 mdelay(50);
48 gpio_direction_output(CONFIG_SPI_LCD_RST_PIN, 1);
49 mdelay(150);
50}
51
52static void lcd_set_backlight(int on)
53{
54 gpio_direction_output(CONFIG_SPI_LCD_BL_PIN, on);
55}
56
57static void lcd_spi_write(unsigned int data)
58{
59 Assert_CS();
60 SPI_FireUp();
61 SPI_WriteData(data);
62 SPI_WaitSSPComplete();
63 SPI_DisableSSP();
64 Deassert_CS();
65}
66
67static int lcd_write_cmd(unsigned char cmd)
68{
69 int ret = 0;
70 unsigned short bits, _data;
71#ifdef CONFIG_SPI_LCD_3WIRE
72 bits = 9;
73 _data = cmd;
74#else
75 bits = 8;
76 _data = cmd;
77 LCD_SEND_CMD();
78#endif
79 SPI_ConfigDSS(bits);
80 lcd_spi_write(_data);
81
82 return ret;
83}
84
85static int lcd_write_data(unsigned char data)
86{
87 int ret = 0;
88 unsigned short bits, _data;
89#ifdef CONFIG_SPI_LCD_3WIRE
90 bits = 9;
91 _data = 0x100 | data;
92#else
93 bits = 8;
94 _data = data;
95 LCD_SEND_DATA();
96#endif
97 SPI_ConfigDSS(bits);
98 lcd_spi_write(_data);
99 return ret;
100}
101
102static int lcd_write_data16(unsigned short data)
103{
104 int ret = 0;
105 unsigned int bits, _data;
106#ifdef CONFIG_SPI_LCD_3WIRE
107 unsigned char h, l;
108 bits = 18;
109 h = (data >> 8) & 0xff;
110 l = data & 0xff;
111 _data = ((0x100 | h) << 9) | (0x100 | l);
112#else
113 bits = 16;
114 _data = data;
115 LCD_SEND_DATA();
116#endif
117 SPI_ConfigDSS(bits);
118 lcd_spi_write(_data);
119 return ret;
120}
121
122static int lcd_set_window(unsigned char xs, unsigned char ys, unsigned char xe, unsigned char ye)
123{
124 lcd_write_cmd(0x2a); // column addr set
125 lcd_write_data(0x00);
126 lcd_write_data(xs + 2);
127 lcd_write_data(0x00);
128 lcd_write_data(xe + 2);
129 lcd_write_cmd(0x2b); // row addr set
130 lcd_write_data(0x00);
131 lcd_write_data(ys + 3);
132 lcd_write_data(0x00);
133 lcd_write_data(ye + 3);
134 return 0;
135}
136
137static int lcd_write_memory(unsigned char *buf, int cnt)
138{
139 int i;
140 lcd_write_cmd(0x2c); // memory write command
141
142 for (i = 0; i < cnt; i++)
143 lcd_write_data(buf[i]);
144
145 return 0;
146}
147
148static int lcd_fill(unsigned short color)
149{
150 unsigned char x, y, low, high;
151 unsigned short *buf = (unsigned short *)gFramebuffer;
152 memset(buf, 0, FB_SIZE);
153
154 lcd_set_window(0, 0, CONFIG_SPI_LCD_XRES - 1, CONFIG_SPI_LCD_YRES - 1);
155 for (x=0; x < CONFIG_SPI_LCD_XRES; x++)
156 for (y=0; y < CONFIG_SPI_LCD_YRES; y++) {
157 low = color & 0xff;
158 high = (color & 0xff00) >> 8;
159#ifdef CONFIG_SPI_LCD_3WIRE
160 *(buf++) = low;
161 *(buf++) = high;
162#else
163 *(buf++) = (low << 8) | high;
164#endif
165 }
166
167 return lcd_write_memory(gFramebuffer, FB_SIZE);
168}
169
170static int lcd_draw_logo(
171 unsigned char p_x, unsigned char line,
172 unsigned char W, unsigned char H,
173 unsigned char *buf, unsigned short txt_color, unsigned short bg_color)
174{
175 int i, j, k;
176 unsigned char c;
177 int index, size;
178 unsigned short *buff = (unsigned short *)gFramebuffer;
179
180 lcd_set_window(line, p_x, (line + H - 1), (p_x + W - 1));
181
182 index = 0;
183 for(i = 0; i < W; i++) {
184 for(k = (H / 8 -1); k >= 0; k--) {
185 c = *buf++;
186 for(j = (8 - 1); j >= 0; j--) {
187 if((1 << (7 - j)) & c)
188 *(buff++) = txt_color;
189 else
190 *(buff++) = bg_color;
191 index++;
192 }
193 }
194 }
195
196 size = index;
197 return lcd_write_memory(gFramebuffer, size * 2);
198}
199
200static void panel_init(void *sequence)
201{
202 struct lcd_cmd *array = (struct lcd_cmd *)sequence;
203 if (!array) {
204 printf("Warning: null init sequence.\n");
205 return;
206 }
207
208 while (array->type != CMD_TYPE_END) {
209 switch (array->type) {
210 case CMD_TYPE_START:
211 break;
212 case CMD_TYPE_CMD:
213 lcd_write_cmd(array->data);
214 break;
215 case CMD_TYPE_DATA:
216 lcd_write_data(array->data);
217 break;
218 case CMD_TYPE_DELAY:
219 mdelay(array->data);
220 break;
221 }
222 array++;
223 }
224
225 printf("Panel: init done.\r\n");
226}
227
228int spi_lcd_init(void)
229{
230 int ret;
231
232 gFramebuffer = malloc(FB_SIZE);
233 lcd_reset();
234
235 panel_init(st7735_init_sequence);
236
237 lcd_fill(0); // 0: Black, 0xF800: Red, 0x7E0: Green, 0x1F: Blue
238 lcd_set_backlight(1);
239
240 return 0;
241}
242
243void lcd_display_char(unsigned char x, unsigned char y, const char c)
244{
245 int i, j, len;
246 unsigned short pos;
247 unsigned char *font;
248
249 pos = c - ' ';
250
251 /* font length */
252 len = (LCD_Currentfonts->width * LCD_Currentfonts->height) / 8;
253
254 font = (unsigned char *)&LCD_Currentfonts->table[pos * len];
255
256 lcd_set_window (x, y, x + LCD_Currentfonts->width - 1, y + LCD_Currentfonts->height - 1);
257 lcd_write_cmd(0x2c);
258
259 for (i = 0; i < len; i++) {
260 for (j = 0; j < 8; j++) {
261 if (font[i] & (0x80 >> j))
262 lcd_write_data16(0xffff);
263 else
264 lcd_write_data16(0);
265 }
266 }
267}
268
269void lcd_display_string(unsigned short x, unsigned short y, char *str)
270{
271 unsigned short x0, y0;
272 x0 = x;
273 y0 = y;
274
275 while (*str) {
276 if (x > CONFIG_SPI_LCD_XRES) {
277 x = x0;
278 y += LCD_Currentfonts->height;
279 }
280
281 if (y > CONFIG_SPI_LCD_YRES) {
282 x = x0;
283 y = y0;
284 }
285
286 lcd_display_char(x, y, *str);
287 str++;
288 x += LCD_Currentfonts->width;
289 }
290}