1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-01-05 RiceChen the first version
9 */
10
11 #include <rtdevice.h>
12 #include "drv_spi.h"
13 #include "drv_lcd.h"
14 #include "drv_lcd_font.h"
15 #include "drv_gpio.h"
16
17 #define DBG_SECTION_NAME "LCD"
18 #define DBG_COLOR
19 #define DBG_LEVEL DBG_LOG
20 #include <rtdbg.h>
21
22 #define LCD_PWR_PIN GET_PIN(B, 15)
23 #define LCD_DC_PIN GET_PIN(C, 6)
24 #define LCD_RES_PIN GET_PIN(C, 7)
25 #define LCD_CLEAR_SEND_NUMBER 5760
26
27 rt_uint16_t BACK_COLOR = WHITE, FORE_COLOR = BLACK;
28
29 static struct rt_spi_device *spi_dev_lcd;
30
rt_hw_lcd_config(void)31 static int rt_hw_lcd_config(void)
32 {
33 spi_dev_lcd = (struct rt_spi_device *)rt_device_find("lcd");
34
35 /* config spi */
36 {
37 struct rt_spi_configuration cfg;
38 cfg.data_width = 8;
39 cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_3 | RT_SPI_MSB;
40 cfg.max_hz = 42 * 1000 * 1000; /* 42M, SPI max 42MHz, lcd 4-wire spi */
41
42 rt_spi_configure(spi_dev_lcd, &cfg);
43 }
44
45 return RT_EOK;
46 }
47
lcd_write_cmd(const rt_uint8_t cmd)48 static rt_err_t lcd_write_cmd(const rt_uint8_t cmd)
49 {
50 rt_size_t len;
51
52 rt_pin_write(LCD_DC_PIN, PIN_LOW);
53
54 len = rt_spi_send(spi_dev_lcd, &cmd, 1);
55
56 if (len != 1)
57 {
58 LOG_I("lcd_write_cmd error. %d", len);
59 return -RT_ERROR;
60 }
61 else
62 {
63 return RT_EOK;
64 }
65 }
66
lcd_write_data(const rt_uint8_t data)67 static rt_err_t lcd_write_data(const rt_uint8_t data)
68 {
69 rt_size_t len;
70
71 rt_pin_write(LCD_DC_PIN, PIN_HIGH);
72
73 len = rt_spi_send(spi_dev_lcd, &data, 1);
74
75 if (len != 1)
76 {
77 LOG_I("lcd_write_data error. %d", len);
78 return -RT_ERROR;
79 }
80 else
81 {
82 return RT_EOK;
83 }
84 }
85
lcd_write_half_word(const rt_uint16_t da)86 static rt_err_t lcd_write_half_word(const rt_uint16_t da)
87 {
88 rt_size_t len;
89 char data[2] = {0};
90
91 data[0] = da >> 8;
92 data[1] = da;
93
94 rt_pin_write(LCD_DC_PIN, PIN_HIGH);
95 len = rt_spi_send(spi_dev_lcd, data, 2);
96 if (len != 2)
97 {
98 LOG_I("lcd_write_half_word error. %d", len);
99 return -RT_ERROR;
100 }
101 else
102 {
103 return RT_EOK;
104 }
105 }
106
lcd_gpio_init(void)107 static void lcd_gpio_init(void)
108 {
109 rt_hw_lcd_config();
110
111 rt_pin_mode(LCD_DC_PIN, PIN_MODE_OUTPUT);
112 rt_pin_mode(LCD_RES_PIN, PIN_MODE_OUTPUT);
113
114 rt_pin_mode(LCD_PWR_PIN, PIN_MODE_OUTPUT);
115 rt_pin_write(LCD_PWR_PIN, PIN_LOW);
116
117 rt_pin_write(LCD_RES_PIN, PIN_LOW);
118 //wait at least 100ms for reset
119 rt_thread_delay(RT_TICK_PER_SECOND / 10);
120 rt_pin_write(LCD_RES_PIN, PIN_HIGH);
121 }
122
rt_hw_lcd_init(void)123 static int rt_hw_lcd_init(void)
124 {
125 rt_hw_spi_device_attach("spi2", "lcd", GET_PIN(C, 3));
126 lcd_gpio_init();
127 /* Memory Data Access Control */
128 lcd_write_cmd(0x36);
129 lcd_write_data(0x00);
130 /* RGB 5-6-5-bit */
131 lcd_write_cmd(0x3A);
132 lcd_write_data(0x65);
133 /* Porch Setting */
134 lcd_write_cmd(0xB2);
135 lcd_write_data(0x0C);
136 lcd_write_data(0x0C);
137 lcd_write_data(0x00);
138 lcd_write_data(0x33);
139 lcd_write_data(0x33);
140 /* Gate Control */
141 lcd_write_cmd(0xB7);
142 lcd_write_data(0x72);
143 /* VCOM Setting */
144 lcd_write_cmd(0xBB);
145 lcd_write_data(0x3D);
146 /* LCM Control */
147 lcd_write_cmd(0xC0);
148 lcd_write_data(0x2C);
149 /* VDV and VRH Command Enable */
150 lcd_write_cmd(0xC2);
151 lcd_write_data(0x01);
152 /* VRH Set */
153 lcd_write_cmd(0xC3);
154 lcd_write_data(0x19);
155 /* VDV Set */
156 lcd_write_cmd(0xC4);
157 lcd_write_data(0x20);
158 /* Frame Rate Control in Normal Mode */
159 lcd_write_cmd(0xC6);
160 lcd_write_data(0x0F);
161 /* Power Control 1 */
162 lcd_write_cmd(0xD0);
163 lcd_write_data(0xA4);
164 lcd_write_data(0xA1);
165 /* Positive Voltage Gamma Control */
166 lcd_write_cmd(0xE0);
167 lcd_write_data(0xD0);
168 lcd_write_data(0x04);
169 lcd_write_data(0x0D);
170 lcd_write_data(0x11);
171 lcd_write_data(0x13);
172 lcd_write_data(0x2B);
173 lcd_write_data(0x3F);
174 lcd_write_data(0x54);
175 lcd_write_data(0x4C);
176 lcd_write_data(0x18);
177 lcd_write_data(0x0D);
178 lcd_write_data(0x0B);
179 lcd_write_data(0x1F);
180 lcd_write_data(0x23);
181 /* Negative Voltage Gamma Control */
182 lcd_write_cmd(0xE1);
183 lcd_write_data(0xD0);
184 lcd_write_data(0x04);
185 lcd_write_data(0x0C);
186 lcd_write_data(0x11);
187 lcd_write_data(0x13);
188 lcd_write_data(0x2C);
189 lcd_write_data(0x3F);
190 lcd_write_data(0x44);
191 lcd_write_data(0x51);
192 lcd_write_data(0x2F);
193 lcd_write_data(0x1F);
194 lcd_write_data(0x1F);
195 lcd_write_data(0x20);
196 lcd_write_data(0x23);
197 /* Display Inversion On */
198 lcd_write_cmd(0x21);
199 /* Sleep Out */
200 lcd_write_cmd(0x11);
201 /* wait for power stability */
202 rt_thread_mdelay(100);
203
204 lcd_clear(WHITE);
205 lcd_show_string(0, 0, 32, "RT-Thread");
206
207 /* display on */
208 rt_pin_write(LCD_PWR_PIN, PIN_HIGH);
209 lcd_write_cmd(0x29);
210
211 return RT_EOK;
212 }
213 INIT_DEVICE_EXPORT(rt_hw_lcd_init);
214
215 /**
216 * Set background color and foreground color
217 *
218 * @param back background color
219 * @param fore fore color
220 *
221 * @return void
222 */
lcd_set_color(rt_uint16_t back,rt_uint16_t fore)223 void lcd_set_color(rt_uint16_t back, rt_uint16_t fore)
224 {
225 BACK_COLOR = back;
226 FORE_COLOR = fore;
227 }
228
lcd_display_on(void)229 void lcd_display_on(void)
230 {
231 rt_pin_write(LCD_PWR_PIN, PIN_HIGH);
232 }
233
lcd_display_off(void)234 void lcd_display_off(void)
235 {
236 rt_pin_write(LCD_PWR_PIN, PIN_LOW);
237 }
238
239 /* lcd enter the minimum power consumption mode and backlight off. */
lcd_enter_sleep(void)240 void lcd_enter_sleep(void)
241 {
242 rt_pin_write(LCD_PWR_PIN, PIN_LOW);
243 rt_thread_mdelay(5);
244 lcd_write_cmd(0x10);
245 }
246 /* lcd turn off sleep mode and backlight on. */
lcd_exit_sleep(void)247 void lcd_exit_sleep(void)
248 {
249 rt_pin_write(LCD_PWR_PIN, PIN_HIGH);
250 rt_thread_mdelay(5);
251 lcd_write_cmd(0x11);
252 rt_thread_mdelay(120);
253 }
254
255 /**
256 * Set drawing area
257 *
258 * @param x1 start of x position
259 * @param y1 start of y position
260 * @param x2 end of x position
261 * @param y2 end of y position
262 *
263 * @return void
264 */
lcd_address_set(rt_uint16_t x1,rt_uint16_t y1,rt_uint16_t x2,rt_uint16_t y2)265 void lcd_address_set(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2)
266 {
267 lcd_write_cmd(0x2a);
268 lcd_write_data(x1 >> 8);
269 lcd_write_data(x1);
270 lcd_write_data(x2 >> 8);
271 lcd_write_data(x2);
272
273 lcd_write_cmd(0x2b);
274 lcd_write_data(y1 >> 8);
275 lcd_write_data(y1);
276 lcd_write_data(y2 >> 8);
277 lcd_write_data(y2);
278
279 lcd_write_cmd(0x2C);
280 }
281
282 /**
283 * clear the lcd.
284 *
285 * @param color Fill color
286 *
287 * @return void
288 */
lcd_clear(rt_uint16_t color)289 void lcd_clear(rt_uint16_t color)
290 {
291 rt_uint16_t i, j;
292 rt_uint8_t data[2] = {0};
293 rt_uint8_t *buf = RT_NULL;
294
295 data[0] = color >> 8;
296 data[1] = color;
297 lcd_address_set(0, 0, LCD_W - 1, LCD_H - 1);
298
299 /* 5760 = 240*240/20 */
300 buf = rt_malloc(LCD_CLEAR_SEND_NUMBER);
301 if (buf)
302 {
303 /* 2880 = 5760/2 color is 16 bit */
304 for (j = 0; j < LCD_CLEAR_SEND_NUMBER / 2; j++)
305 {
306 buf[j * 2] = data[0];
307 buf[j * 2 + 1] = data[1];
308 }
309
310 rt_pin_write(LCD_DC_PIN, PIN_HIGH);
311 for (i = 0; i < 20; i++)
312 {
313 rt_spi_send(spi_dev_lcd, buf, LCD_CLEAR_SEND_NUMBER);
314 }
315 rt_free(buf);
316 }
317 else
318 {
319 rt_pin_write(LCD_DC_PIN, PIN_HIGH);
320 for (i = 0; i < LCD_W; i++)
321 {
322 for (j = 0; j < LCD_H; j++)
323 {
324 rt_spi_send(spi_dev_lcd, data, 2);
325 }
326 }
327 }
328 }
329
330 /**
331 * display a point on the lcd.
332 *
333 * @param x x position
334 * @param y y position
335 *
336 * @return void
337 */
lcd_draw_point(rt_uint16_t x,rt_uint16_t y)338 void lcd_draw_point(rt_uint16_t x, rt_uint16_t y)
339 {
340 lcd_address_set(x, y, x, y);
341 lcd_write_half_word(FORE_COLOR);
342 }
343
344 /**
345 * display a point on the lcd using the given colour.
346 *
347 * @param x x position
348 * @param y y position
349 * @param color color of point
350 *
351 * @return void
352 */
lcd_draw_point_color(rt_uint16_t x,rt_uint16_t y,rt_uint16_t color)353 void lcd_draw_point_color(rt_uint16_t x, rt_uint16_t y, rt_uint16_t color)
354 {
355 lcd_address_set(x, y, x, y);
356 lcd_write_half_word(color);
357 }
358
359 /**
360 * full color on the lcd.
361 *
362 * @param x_start start of x position
363 * @param y_start start of y position
364 * @param x_end end of x position
365 * @param y_end end of y position
366 * @param color Fill color
367 *
368 * @return void
369 */
lcd_fill(rt_uint16_t x_start,rt_uint16_t y_start,rt_uint16_t x_end,rt_uint16_t y_end,rt_uint16_t color)370 void lcd_fill(rt_uint16_t x_start, rt_uint16_t y_start, rt_uint16_t x_end, rt_uint16_t y_end, rt_uint16_t color)
371 {
372 rt_uint16_t i = 0, j = 0;
373 rt_uint32_t size = 0, size_remain = 0;
374 rt_uint8_t *fill_buf = RT_NULL;
375
376 size = (x_end - x_start) * (y_end - y_start) * 2;
377
378 if (size > LCD_CLEAR_SEND_NUMBER)
379 {
380 /* the number of remaining to be filled */
381 size_remain = size - LCD_CLEAR_SEND_NUMBER;
382 size = LCD_CLEAR_SEND_NUMBER;
383 }
384
385 lcd_address_set(x_start, y_start, x_end, y_end);
386
387 fill_buf = (rt_uint8_t *)rt_malloc(size);
388 if (fill_buf)
389 {
390 /* fast fill */
391 while (1)
392 {
393 for (i = 0; i < size / 2; i++)
394 {
395 fill_buf[2 * i] = color >> 8;
396 fill_buf[2 * i + 1] = color;
397 }
398 rt_pin_write(LCD_DC_PIN, PIN_HIGH);
399 rt_spi_send(spi_dev_lcd, fill_buf, size);
400
401 /* Fill completed */
402 if (size_remain == 0)
403 break;
404
405 /* calculate the number of fill next time */
406 if (size_remain > LCD_CLEAR_SEND_NUMBER)
407 {
408 size_remain = size_remain - LCD_CLEAR_SEND_NUMBER;
409 }
410 else
411 {
412 size = size_remain;
413 size_remain = 0;
414 }
415 }
416 rt_free(fill_buf);
417 }
418 else
419 {
420 for (i = y_start; i <= y_end; i++)
421 {
422 for (j = x_start; j <= x_end; j++)lcd_write_half_word(color);
423 }
424 }
425 }
426
427 /**
428 * display a line on the lcd.
429 *
430 * @param x1 x1 position
431 * @param y1 y1 position
432 * @param x2 x2 position
433 * @param y2 y2 position
434 *
435 * @return void
436 */
lcd_draw_line(rt_uint16_t x1,rt_uint16_t y1,rt_uint16_t x2,rt_uint16_t y2)437 void lcd_draw_line(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2)
438 {
439 rt_uint16_t t;
440 rt_uint32_t i = 0;
441 int xerr = 0, yerr = 0, delta_x, delta_y, distance;
442 int incx, incy, row, col;
443
444 if (y1 == y2)
445 {
446 /* fast draw transverse line */
447 lcd_address_set(x1, y1, x2, y2);
448
449 rt_uint8_t line_buf[480] = {0};
450
451 for (i = 0; i < x2 - x1; i++)
452 {
453 line_buf[2 * i] = FORE_COLOR >> 8;
454 line_buf[2 * i + 1] = FORE_COLOR;
455 }
456
457 rt_pin_write(LCD_DC_PIN, PIN_HIGH);
458 rt_spi_send(spi_dev_lcd, line_buf, (x2 - x1) * 2);
459
460 return ;
461 }
462
463 delta_x = x2 - x1;
464 delta_y = y2 - y1;
465 row = x1;
466 col = y1;
467 if (delta_x > 0)incx = 1;
468 else if (delta_x == 0)incx = 0;
469 else
470 {
471 incx = -1;
472 delta_x = -delta_x;
473 }
474 if (delta_y > 0)incy = 1;
475 else if (delta_y == 0)incy = 0;
476 else
477 {
478 incy = -1;
479 delta_y = -delta_y;
480 }
481 if (delta_x > delta_y)distance = delta_x;
482 else distance = delta_y;
483 for (t = 0; t <= distance + 1; t++)
484 {
485 lcd_draw_point(row, col);
486 xerr += delta_x ;
487 yerr += delta_y ;
488 if (xerr > distance)
489 {
490 xerr -= distance;
491 row += incx;
492 }
493 if (yerr > distance)
494 {
495 yerr -= distance;
496 col += incy;
497 }
498 }
499 }
500
501 /**
502 * display a rectangle on the lcd.
503 *
504 * @param x1 x1 position
505 * @param y1 y1 position
506 * @param x2 x2 position
507 * @param y2 y2 position
508 *
509 * @return void
510 */
lcd_draw_rectangle(rt_uint16_t x1,rt_uint16_t y1,rt_uint16_t x2,rt_uint16_t y2)511 void lcd_draw_rectangle(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2)
512 {
513 lcd_draw_line(x1, y1, x2, y1);
514 lcd_draw_line(x1, y1, x1, y2);
515 lcd_draw_line(x1, y2, x2, y2);
516 lcd_draw_line(x2, y1, x2, y2);
517 }
518
519 /**
520 * display a circle on the lcd.
521 *
522 * @param x x position of Center
523 * @param y y position of Center
524 * @param r radius
525 *
526 * @return void
527 */
lcd_draw_circle(rt_uint16_t x0,rt_uint16_t y0,rt_uint8_t r)528 void lcd_draw_circle(rt_uint16_t x0, rt_uint16_t y0, rt_uint8_t r)
529 {
530 int a, b;
531 int di;
532 a = 0;
533 b = r;
534 di = 3 - (r << 1);
535 while (a <= b)
536 {
537 lcd_draw_point(x0 - b, y0 - a);
538 lcd_draw_point(x0 + b, y0 - a);
539 lcd_draw_point(x0 - a, y0 + b);
540 lcd_draw_point(x0 - b, y0 - a);
541 lcd_draw_point(x0 - a, y0 - b);
542 lcd_draw_point(x0 + b, y0 + a);
543 lcd_draw_point(x0 + a, y0 - b);
544 lcd_draw_point(x0 + a, y0 + b);
545 lcd_draw_point(x0 - b, y0 + a);
546 a++;
547 //Bresenham
548 if (di < 0)di += 4 * a + 6;
549 else
550 {
551 di += 10 + 4 * (a - b);
552 b--;
553 }
554 lcd_draw_point(x0 + a, y0 + b);
555 }
556 }
557
lcd_show_char(rt_uint16_t x,rt_uint16_t y,rt_uint8_t data,rt_uint32_t size)558 static void lcd_show_char(rt_uint16_t x, rt_uint16_t y, rt_uint8_t data, rt_uint32_t size)
559 {
560 rt_uint8_t temp;
561 rt_uint8_t num = 0;;
562 rt_uint8_t pos, t;
563 rt_uint16_t colortemp = FORE_COLOR;
564 rt_uint8_t *font_buf = RT_NULL;
565
566 if (x > LCD_W - size / 2 || y > LCD_H - size)return;
567
568 data = data - ' ';
569 #ifdef ASC2_1608
570 if (size == 16)
571 {
572 lcd_address_set(x, y, x + size / 2 - 1, y + size - 1);//(x,y,x+8-1,y+16-1)
573
574 font_buf = (rt_uint8_t *)rt_malloc(size * size);
575 if (!font_buf)
576 {
577 /* fast show char */
578 for (pos = 0; pos < size * (size / 2) / 8; pos++)
579 {
580 temp = asc2_1608[(rt_uint16_t)data * size * (size / 2) / 8 + pos];
581 for (t = 0; t < 8; t++)
582 {
583 if (temp & 0x80)colortemp = FORE_COLOR;
584 else colortemp = BACK_COLOR;
585 lcd_write_half_word(colortemp);
586 temp <<= 1;
587 }
588 }
589 }
590 else
591 {
592 for (pos = 0; pos < size * (size / 2) / 8; pos++)
593 {
594 temp = asc2_1608[(rt_uint16_t)data * size * (size / 2) / 8 + pos];
595 for (t = 0; t < 8; t++)
596 {
597 if (temp & 0x80)colortemp = FORE_COLOR;
598 else colortemp = BACK_COLOR;
599 font_buf[2 * (8 * pos + t)] = colortemp >> 8;
600 font_buf[2 * (8 * pos + t) + 1] = colortemp;
601 temp <<= 1;
602 }
603 }
604 rt_pin_write(LCD_DC_PIN, PIN_HIGH);
605 rt_spi_send(spi_dev_lcd, font_buf, size * size);
606 rt_free(font_buf);
607 }
608 }
609 else
610 #endif
611
612 #ifdef ASC2_2412
613 if (size == 24)
614 {
615 lcd_address_set(x, y, x + size / 2 - 1, y + size - 1);
616
617 font_buf = (rt_uint8_t *)rt_malloc(size * size);
618 if (!font_buf)
619 {
620 /* fast show char */
621 for (pos = 0; pos < (size * 16) / 8; pos++)
622 {
623 temp = asc2_2412[(rt_uint16_t)data * (size * 16) / 8 + pos];
624 if (pos % 2 == 0)
625 {
626 num = 8;
627 }
628 else
629 {
630 num = 4;
631 }
632
633 for (t = 0; t < num; t++)
634 {
635 if (temp & 0x80)colortemp = FORE_COLOR;
636 else colortemp = BACK_COLOR;
637 lcd_write_half_word(colortemp);
638 temp <<= 1;
639 }
640 }
641 }
642 else
643 {
644 for (pos = 0; pos < (size * 16) / 8; pos++)
645 {
646 temp = asc2_2412[(rt_uint16_t)data * (size * 16) / 8 + pos];
647 if (pos % 2 == 0)
648 {
649 num = 8;
650 }
651 else
652 {
653 num = 4;
654 }
655
656 for (t = 0; t < num; t++)
657 {
658 if (temp & 0x80)colortemp = FORE_COLOR;
659 else colortemp = BACK_COLOR;
660 if (num == 8)
661 {
662 font_buf[2 * (12 * (pos / 2) + t)] = colortemp >> 8;
663 font_buf[2 * (12 * (pos / 2) + t) + 1] = colortemp;
664 }
665 else
666 {
667 font_buf[2 * (8 + 12 * (pos / 2) + t)] = colortemp >> 8;
668 font_buf[2 * (8 + 12 * (pos / 2) + t) + 1] = colortemp;
669 }
670 temp <<= 1;
671 }
672 }
673 rt_pin_write(LCD_DC_PIN, PIN_HIGH);
674 rt_spi_send(spi_dev_lcd, font_buf, size * size);
675 rt_free(font_buf);
676 }
677 }
678 else
679 #endif
680
681 #ifdef ASC2_3216
682 if (size == 32)
683 {
684 lcd_address_set(x, y, x + size / 2 - 1, y + size - 1);
685
686 font_buf = (rt_uint8_t *)rt_malloc(size * size);
687 if (!font_buf)
688 {
689 /* fast show char */
690 for (pos = 0; pos < size * (size / 2) / 8; pos++)
691 {
692 temp = asc2_3216[(rt_uint16_t)data * size * (size / 2) / 8 + pos];
693 for (t = 0; t < 8; t++)
694 {
695 if (temp & 0x80)colortemp = FORE_COLOR;
696 else colortemp = BACK_COLOR;
697 lcd_write_half_word(colortemp);
698 temp <<= 1;
699 }
700 }
701 }
702 else
703 {
704 for (pos = 0; pos < size * (size / 2) / 8; pos++)
705 {
706 temp = asc2_3216[(rt_uint16_t)data * size * (size / 2) / 8 + pos];
707 for (t = 0; t < 8; t++)
708 {
709 if (temp & 0x80)colortemp = FORE_COLOR;
710 else colortemp = BACK_COLOR;
711 font_buf[2 * (8 * pos + t)] = colortemp >> 8;
712 font_buf[2 * (8 * pos + t) + 1] = colortemp;
713 temp <<= 1;
714 }
715 }
716 rt_pin_write(LCD_DC_PIN, PIN_HIGH);
717 rt_spi_send(spi_dev_lcd, font_buf, size * size);
718 rt_free(font_buf);
719 }
720 }
721 else
722 #endif
723 {
724 LOG_E("There is no any define ASC2_1208 && ASC2_2412 && ASC2_2416 && ASC2_3216 !");
725 }
726 }
727
728 /**
729 * display the number on the lcd.
730 *
731 * @param x x position
732 * @param y y position
733 * @param num number
734 * @param len length of number
735 * @param size size of font
736 *
737 * @return void
738 */
lcd_show_num(rt_uint16_t x,rt_uint16_t y,rt_uint32_t num,rt_uint8_t len,rt_uint32_t size)739 void lcd_show_num(rt_uint16_t x, rt_uint16_t y, rt_uint32_t num, rt_uint8_t len, rt_uint32_t size)
740 {
741 lcd_show_string(x, y, size, "%d", num);
742 }
743
744 /**
745 * display the string on the lcd.
746 *
747 * @param x x position
748 * @param y y position
749 * @param size size of font
750 * @param p the string to be display
751 *
752 * @return 0: display success
753 * -1: size of font is not support
754 */
lcd_show_string(rt_uint16_t x,rt_uint16_t y,rt_uint32_t size,const char * fmt,...)755 rt_err_t lcd_show_string(rt_uint16_t x, rt_uint16_t y, rt_uint32_t size, const char *fmt, ...)
756 {
757 #define LCD_STRING_BUF_LEN 128
758
759 va_list args;
760 rt_uint8_t buf[LCD_STRING_BUF_LEN] = {0};
761 rt_uint8_t *p = RT_NULL;
762
763 if (size != 16 && size != 24 && size != 32)
764 {
765 LOG_E("font size(%d) is not support!", size);
766 return -RT_ERROR;
767 }
768
769 va_start(args, fmt);
770 rt_vsnprintf((char *)buf, 100, (const char *)fmt, args);
771 va_end(args);
772
773 p = buf;
774 while (*p != '\0')
775 {
776 if (x > LCD_W - size / 2)
777 {
778 x = 0;
779 y += size;
780 }
781 if (y > LCD_H - size)
782 {
783 y = x = 0;
784 lcd_clear(RED);
785 }
786 lcd_show_char(x, y, *p, size);
787 x += size / 2;
788 p++;
789 }
790
791 return RT_EOK;
792 }
793
794 /**
795 * display the image on the lcd.
796 *
797 * @param x x position
798 * @param y y position
799 * @param length length of image
800 * @param wide wide of image
801 * @param p image
802 *
803 * @return 0: display success
804 * -1: the image is too large
805 */
lcd_show_image(rt_uint16_t x,rt_uint16_t y,rt_uint16_t length,rt_uint16_t wide,const rt_uint8_t * p)806 rt_err_t lcd_show_image(rt_uint16_t x, rt_uint16_t y, rt_uint16_t length, rt_uint16_t wide, const rt_uint8_t *p)
807 {
808 RT_ASSERT(p);
809
810 if (x + length > LCD_W || y + wide > LCD_H)
811 {
812 return -RT_ERROR;
813 }
814
815 lcd_address_set(x, y, x + length - 1, y + wide - 1);
816
817 rt_pin_write(LCD_DC_PIN, PIN_HIGH);
818 rt_spi_send(spi_dev_lcd, p, length * wide * 2);
819
820 return RT_EOK;
821 }
822