1 /**************************************************************************//**
2  * @file     LCDLIB.c
3  * @version  V3.00
4  * @brief    RHE6616TP01(8-COM, 40-SEG, 1/4 Bias) LCD library source file
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  * @copyright (C) 2019-2020 Nuvoton Technology Corp. All rights reserved.
8  *****************************************************************************/
9 
10 #include <rtthread.h>
11 #include <rtdevice.h>
12 
13 #include "drv_slcd.h"
14 #include "slcd_rhe6616tp01.h"
15 
16 #define DBG_SECTION_NAME "slcd_demo"
17 #define DBG_LEVEL DBG_LOG
18 #include <rtdbg.h>
19 
20 static rt_device_t g_psDev = RT_NULL;
21 
22 /**************************************************************************//**
23  *
24  * Defines each text's segment (alphabet+numeric) in terms of COM and SEG numbers,
25  * Using this way that text segment can be consisted of each bit in the
26  * following bit pattern:
27  * @illustration
28  *              A
29  *         -----------
30  *         |\   |   /|
31  *         F G  H  I B
32  *         |  \ | /  |
33  *         --J-- --K--
34  *         |   /| \  |
35  *         E  L M  N C
36  *         | /  |   \|
37  *         -----------
38  *              D
39  *
40  *              0
41  *         -----------
42  *         |\   |   /|
43  *        5| 6  7  8 |1
44  *         |  \ | /  |
45  *         --9-- -10--
46  *         |   /| \  |
47  *        4| 11 12 13|2
48  *         | /  |   \|
49  *         -----------
50  *              3
51  *
52  *****************************************************************************/
53 static const char acMainDigitRawData[ZONE_MAIN_DIG_CNT][ZONE_MAIN_SEG_NUM][2] =
54 {
55     {
56         // digit 1, {com, seg}
57         // A     // B     // C     // D
58         {0,  1}, {0,  0}, {3,  0}, {3,  1},
59         // E     // F     // G     // H
60         {2,  3}, {0,  3}, {0,  2}, {1,  1},
61         // I     // J     // K     // L
62         {1,  0}, {1,  2}, {2,  0}, {3,  2},
63         // M     // N
64         {2,  2}, {2,  1},
65     },
66     {
67         // digit 2, {com, seg}
68         // A     // B     // C     // D
69         {0, 18}, {0, 19}, {3, 19}, {3, 18},
70         // E     // F     // G     // H
71         {2, 16}, {0, 16}, {0, 17}, {1, 18},
72         // I     // J     // K     // L
73         {1, 19}, {1, 17}, {2, 19}, {3, 17},
74         // M     // N
75         {2, 17}, {2, 18},
76     },
77     {
78         // digit 3, {com, seg}
79         // A     // B     // C     // D
80         {0, 22}, {0, 23}, {3, 23}, {3, 22},
81         // E     // F     // G     // H
82         {2, 20}, {0, 20}, {0, 21}, {1, 22},
83         // I     // J     // K     // L
84         {1, 23}, {1, 21}, {2, 23}, {3, 21},
85         // M     // N
86         {2, 21}, {2, 22},
87     },
88     {
89         // digit 4, {com, seg}
90         // A     // B     // C     // D
91         {0, 26}, {0, 27}, {3, 27}, {3, 26},
92         // E     // F     // G     // H
93         {2, 24}, {0, 24}, {0, 25}, {1, 26},
94         // I     // J     // K     // L
95         {1, 27}, {1, 25}, {2, 27}, {3, 25},
96         // M     // N
97         {2, 25}, {2, 26},
98     },
99     {
100         // digit 5, {com, seg}
101         // A     // B     // C     // D
102         {0, 30}, {0, 31}, {3, 31}, {3, 30},
103         // E     // F     // G     // H
104         {2, 28}, {0, 28}, {0, 29}, {1, 30},
105         // I     // J     // K     // L
106         {1, 31}, {1, 29}, {2, 31}, {3, 29},
107         // M     // N
108         {2, 29}, {2, 30},
109     },
110     {
111         // digit 6, {com, seg}
112         // A     // B     // C     // D
113         {0, 34}, {0, 35}, {3, 35}, {3, 34},
114         // E     // F     // G     // H
115         {2, 32}, {0, 32}, {0, 33}, {1, 34},
116         // I     // J     // K     // L
117         {1, 35}, {1, 33}, {2, 35}, {3, 33},
118         // M     // N
119         {2, 33}, {2, 34},
120     },
121     {
122         // digit 7, {com, seg}
123         // A     // B     // C     // D
124         {0, 38}, {0, 39}, {3, 39}, {3, 38},
125         // E     // F     // G     // H
126         {2, 36}, {0, 36}, {0, 37}, {1, 38},
127         // I     // J     // K     // L
128         {1, 39}, {1, 37}, {2, 39}, {3, 37},
129         // M     // N
130         {2, 37}, {2, 38},
131     },
132 };
133 
134 
135 /**************************************************************************//**
136  *
137  * Defines each text's segment (numeric) in terms of COM and BIT numbers,
138  * Using this way that text segment can be consisted of each bit in the
139  * following bit pattern:
140  * @illustration
141  *
142  *         ---A---
143  *         |     |
144  *         F     B
145  *         |     |
146  *         ---G---
147  *         |     |
148  *         E     C
149  *         |     |
150  *         ---D---
151  *
152  *         ---0---
153  *         |     |
154  *         5     1
155  *         |     |
156  *         ---6---
157  *         |     |
158  *         4     2
159  *         |     |
160  *         ---3---
161  *
162  *****************************************************************************/
163 static const char acPPMDigitRawData[ZONE_PPM_DIG_CNT][ZONE_PPM_SEG_NUM][2] =
164 {
165     {
166         // digit 1, {com, seg}
167         // A     // B     // C     // D
168         {4, 16}, {5, 17}, {7, 17}, {7, 16},
169         // E     // F     // G
170         {6, 16}, {5, 16}, {6, 17},
171     },
172     {
173         // digit 2, {com, seg}
174         // A     // B     // C     // D
175         {4, 18}, {5, 19}, {7, 19}, {7, 18},
176         // E     // F     // G
177         {6, 18}, {5, 18}, {6, 19},
178     },
179     {
180         // digit 3, {com, seg}
181         // A     // B     // C     // D
182         {4, 20}, {5, 21}, {7, 21}, {7, 20},
183         // E     // F     // G
184         {6, 20}, {5, 20}, {6, 21},
185     },
186 };
187 
188 static const char acTEMPDigitRawData[ZONE_TEMP_DIG_CNT][ZONE_TEMP_SEG_NUM][2] =
189 {
190     {
191         // digit 1, {com, seg}
192         // A     // B     // C     // D
193         {4, 22}, {5, 23}, {7, 23}, {7, 22},
194         // E     // F     // G
195         {6, 22}, {5, 22}, {6, 23},
196     },
197     {
198         // digit 2, {com, seg}
199         // A     // B     // C     // D
200         {4, 24}, {5, 25}, {7, 25}, {7, 24},
201         // E     // F     // G
202         {6, 24}, {5, 24}, {6, 25},
203     },
204     {
205         // digit 3, {com, seg}
206         // A     // B     // C     // D
207         {4, 26}, {5, 27}, {7, 27}, {7, 26},
208         // E     // F     // G
209         {6, 26}, {5, 26}, {6, 27},
210     },
211 };
212 
213 static const char acVERDigitRawData[ZONE_VER_DIG_CNT][ZONE_VER_SEG_NUM][2] =
214 {
215     {
216         // digit 1, {com, seg}
217         // A     // B     // C     // D
218         {4, 28}, {5, 29}, {7, 29}, {7, 28},
219         // E     // F     // G
220         {6, 28}, {5, 28}, {6, 29},
221     },
222     {
223         // digit 2, {com, seg}
224         // A     // B     // C     // D
225         {4, 30}, {5, 31}, {7, 31}, {7, 30},
226         // E     // F     // G
227         {6, 30}, {5, 30}, {6, 31},
228     },
229     {
230         // digit 3, {com, seg}
231         // A     // B     // C     // D
232         {4, 32}, {5, 33}, {7, 33}, {7, 32},
233         // E     // F     // G
234         {6, 32}, {5, 32}, {6, 33},
235     },
236     {
237         // digit 4, {com, seg}
238         // A     // B     // C     // D
239         {4, 34}, {5, 35}, {7, 35}, {7, 34},
240         // E     // F     // G
241         {6, 34}, {5, 34}, {6, 35},
242     },
243     {
244         // digit 5, {com, seg}
245         // A     // B     // C     // D
246         {4, 36}, {5, 37}, {7, 37}, {7, 36},
247         // E     // F     // G
248         {6, 36}, {5, 36}, {6, 37},
249     },
250     {
251         // digit 6, {com, seg}
252         // A     // B     // C     // D
253         {4, 38}, {5, 39}, {7, 39}, {7, 38},
254         // E     // F     // G
255         {6, 38}, {5, 38}, {6, 39},
256     },
257 };
258 
259 static const char acTimeDigitRawData[ZONE_TIME_DIG_CNT][ZONE_TIME_SEG_NUM][2] =
260 {
261     {
262         // digit 1, {com, seg}
263         // A     // B     // C     // D
264         {7,  2}, {6,  3}, {4,  3}, {4,  2},
265         // E     // F     // G
266         {5,  2}, {6,  2}, {5, 3},
267     },
268     {
269         // digit 2, {com, seg}
270         // A     // B     // C     // D
271         {7,  4}, {6,  5}, {4,  5}, {4,  4},
272         // E     // F     // G
273         {5,  4}, {6,  4}, {5, 5},
274     },
275     {
276         // digit 3, {com, seg}
277         // A     // B     // C     // D
278         {7,  6}, {6,  7}, {4,  7}, {4,  6},
279         // E     // F     // G
280         {5,  6}, {6,  6}, {5, 7},
281     },
282     {
283         // digit 4, {com, seg}
284         // A     // B     // C     // D
285         {7,  8}, {6,  9}, {4,  9}, {4,  8},
286         // E     // F     // G
287         {5,  8}, {6,  8}, {5, 9},
288     },
289 };
290 
291 static const char acNuMicroDigitRawData[ZONE_NUMICRO_DIG_CNT][ZONE_NUMICRO_SEG_NUM][2] =
292 {
293     {
294         // digit 1, {com, seg}
295         // A     // B     // C     // D
296         {3,  4}, {2,  5}, {0,  5}, {0,  4},
297         // E     // F     // G
298         {1,  4}, {2,  4}, {1,  5},
299     },
300     {
301         // digit 2, {com, seg}
302         // A     // B     // C     // D
303         {3,  6}, {2,  7}, {0,  7}, {0,  6},
304         // E     // F     // G
305         {1,  6}, {2,  6}, {1,  7},
306     },
307     {
308         // digit 3, {com, seg}
309         // A     // B     // C     // D
310         {3,  8}, {2,  9}, {0,  9}, {0,  8},
311         // E     // F     // G
312         {1,  8}, {2,  8}, {1,  9},
313     },
314 };
315 
316 /**************************************************************************//**
317  *
318  * Defines segments for the alphabet - ASCII table 0x20 to 0x7A
319  * Bit pattern below defined for alphabet (text segments)
320  *
321  *****************************************************************************/
322 static const uint16_t auMainDigitMap[] =
323 {
324     0x0000, /* space */
325     0x1100, /* ! */
326     0x0280, /* " */
327     0x0000, /* # */
328     0x0000, /* $ */
329     0x0000, /* % */
330     0x0000, /* & */
331     0x0000, /* ? */
332     0x0039, /* ( */
333     0x000f, /* ) */
334     0x3fc0, /* * */
335     0x1540, /* + */
336     0x0000, /* , */
337     0x0440, /* - */
338     0x8000, /* . */
339     0x2200, /* / */
340 
341     0x003F, /* 0 */
342     0x0006, /* 1 */
343     0x061B, /* 2 */
344     0x060F, /* 3 */
345     0x0626, /* 4 */
346     0x062D, /* 5 */
347     0x063D, /* 6 */
348     0x0007, /* 7 */
349     0x063F, /* 8 */
350     0x062F, /* 9 */
351 
352     0x0000, /* : */
353     0x0000, /* ; */
354     0x2100, /* < */
355     0x0000, /* = */
356     0x0840, /* > */
357     0x1403, /* ? */
358     0x3FFF, /* @ */
359 
360     0x0637, /* A */
361     0x2339, /* B */
362     0x0039, /* C */
363     0x2139, /* D */
364     0x0639, /* E */
365     0x0631, /* F */
366     0x043D, /* G */
367     0x0636, /* H */
368     0x1080, /* I */
369     0x000E, /* J */
370     0x2330, /* K */
371     0x0038, /* L */
372     0x0176, /* M */
373     0x2076, /* N */
374     0x003F, /* O */
375     0x0633, /* P */
376     0x203F, /* Q */
377     0x2331, /* R */
378     0x062D, /* S */
379     0x1081, /* T */
380     0x003E, /* U */
381     0x0930, /* V */
382     0x2836, /* W */
383     0x2940, /* X */
384     0x1140, /* Y */
385     0x0909, /* Z */
386 
387     0x0039, /* [ */
388     0x0900, /* backslash */
389     0x000F, /* ] */
390     0x2800, /* ^ */
391     0x0008, /* _ */
392     0x0040, /* ` */
393 
394     0x1218, /* a */
395     0x063C, /* b */
396     0x0618, /* c */
397     0x061E, /* d */
398     0x0A18, /* e */
399     0x0231, /* f */
400     0x048F, /* g */
401     0x1230, /* h */
402     0x1000, /* i */
403     0x000E, /* j */
404     0x2330, /* k */
405     0x0038, /* l */
406     0x1614, /* m */
407     0x1404, /* n */
408     0x061C, /* o */
409     0x0331, /* p */
410     0x0447, /* q */
411     0x1400, /* r */
412     0x2408, /* s */
413     0x0238, /* t */
414     0x1018, /* u */
415     0x0810, /* v */
416     0x2814, /* w */
417     0x2940, /* x */
418     0x0446, /* y */
419     0x0A08, /* z */
420 
421     0x0000,
422 };
423 
424 /**************************************************************************//**
425  * Defines segments for the numeric display
426  *****************************************************************************/
427 static const uint16_t auPPMDigitMap[] =
428 {
429     0x3F, /* 0 */
430     0x06, /* 1 */
431     0x5B, /* 2 */
432     0x4F, /* 3 */
433     0x66, /* 4 */
434     0x6D, /* 5 */
435     0x7D, /* 6 */
436     0x07, /* 7 */
437     0x7F, /* 8 */
438     0x6F, /* 9 */
439 };
440 
441 static const uint16_t auTEMPDigitMap[] =
442 {
443     0x3F, /* 0 */
444     0x06, /* 1 */
445     0x5B, /* 2 */
446     0x4F, /* 3 */
447     0x66, /* 4 */
448     0x6D, /* 5 */
449     0x7D, /* 6 */
450     0x07, /* 7 */
451     0x7F, /* 8 */
452     0x6F, /* 9 */
453 };
454 
455 static const uint16_t auVERDigitMap[] =
456 {
457     0x3F, /* 0 */
458     0x06, /* 1 */
459     0x5B, /* 2 */
460     0x4F, /* 3 */
461     0x66, /* 4 */
462     0x6D, /* 5 */
463     0x7D, /* 6 */
464     0x07, /* 7 */
465     0x7F, /* 8 */
466     0x6F, /* 9 */
467 };
468 
469 static const uint16_t auTimeDigitMap[] =
470 {
471     0x3F, /* 0 */
472     0x06, /* 1 */
473     0x5B, /* 2 */
474     0x4F, /* 3 */
475     0x66, /* 4 */
476     0x6D, /* 5 */
477     0x7D, /* 6 */
478     0x07, /* 7 */
479     0x7F, /* 8 */
480     0x6F, /* 9 */
481 };
482 
483 static const uint16_t auNuMicroDigitMap[] =
484 {
485     0x3F, /* 0 */
486     0x06, /* 1 */
487     0x5B, /* 2 */
488     0x4F, /* 3 */
489     0x66, /* 4 */
490     0x6D, /* 5 */
491     0x7D, /* 6 */
492     0x07, /* 7 */
493     0x7F, /* 8 */
494     0x6F, /* 9 */
495 };
496 
497 /* Zone information */
498 static const LCD_ZONE_INFO_T g_LCDZoneInfo[] =
499 {
500     {ZONE_MAIN_DIG_CNT,     ZONE_MAIN_SEG_NUM},
501     {ZONE_PPM_DIG_CNT,      ZONE_PPM_SEG_NUM},
502     {ZONE_TEMP_DIG_CNT,     ZONE_TEMP_SEG_NUM},
503     {ZONE_VER_DIG_CNT,      ZONE_VER_SEG_NUM},
504     {ZONE_TIME_DIG_CNT,     ZONE_TIME_SEG_NUM},
505     {ZONE_NUMICRO_DIG_CNT,  ZONE_NUMICRO_SEG_NUM},
506 };
507 
508 /* Raw data table for each zone */
509 static const char *g_GetLCDComSeg[] =
510 {
511     (const char *)(acMainDigitRawData),
512     (const char *)(acPPMDigitRawData),
513     (const char *)(acTEMPDigitRawData),
514     (const char *)(acVERDigitRawData),
515     (const char *)(acTimeDigitRawData),
516     (const char *)(acNuMicroDigitRawData),
517 };
518 
519 /* Display mapping table for each zone */
520 static const uint16_t *g_LCDDispTable[] =
521 {
522     (const uint16_t *)(auMainDigitMap),
523     (const uint16_t *)(auPPMDigitMap),
524     (const uint16_t *)(auTEMPDigitMap),
525     (const uint16_t *)(auVERDigitMap),
526     (const uint16_t *)(auTimeDigitMap),
527     (const uint16_t *)(auNuMicroDigitMap),
528 };
529 
530 
SLCD_SetPixel(uint32_t u32Com,uint32_t u32Seg,uint32_t u32OnFlag)531 void SLCD_SetPixel(uint32_t u32Com, uint32_t u32Seg, uint32_t u32OnFlag)
532 {
533     if (g_psDev)
534     {
535         struct nu_slcd_pixel sNuSLCDPxl;
536 
537         sNuSLCDPxl.m_u32Com = u32Com;
538         sNuSLCDPxl.m_u32Seg = u32Seg;
539         sNuSLCDPxl.m_u32OnFlag = u32OnFlag;
540         rt_device_write(g_psDev, 0, (void *)&sNuSLCDPxl, sizeof(struct nu_slcd_pixel));
541     }
542 }
543 
544 /**
545  *  @brief Display text on LCD
546  *
547  *  @param[in]  u32Zone     the assigned number of display area
548  *  @param[in]  InputStr    Text string to show on display
549  *
550  *  @return None
551  */
LCDLIB_Printf(uint32_t u32Zone,char * InputStr)552 void LCDLIB_Printf(uint32_t u32Zone, char *InputStr)
553 {
554     uint32_t    i, index, ch, len;
555     uint16_t    DispData;
556     uint32_t    com, seg;
557 
558     len = rt_strlen(InputStr);
559 
560     /* Fill out all characters on display */
561     for (index = 0; index < g_LCDZoneInfo[u32Zone].u32DigitCnt; index++)
562     {
563         if (index < len)
564         {
565             ch = *InputStr;
566         }
567         else
568         {
569             /* Padding with SPACE */
570             ch = 0x20;
571         }
572 
573         /* For Main Zone */
574         if (u32Zone == ZONE_MAIN_DIGIT)
575         {
576             /* The Main Digit Table is an ASCII table beginning with "SPACE" (hex is 0x20) */
577             ch = ch - 0x20;
578             DispData = *(g_LCDDispTable[u32Zone] + ch);
579         }
580         /* For Other Zones (Support '0' ~ '9' only) */
581         else if ((ch >= '0') && (ch <= '9'))
582         {
583             ch = ch - '0';
584             DispData = *(g_LCDDispTable[u32Zone] + ch);
585         }
586         /* Out of definition. Will show "SPACE" */
587         else
588         {
589             DispData = 0;
590         }
591 
592         for (i = 0; i < g_LCDZoneInfo[u32Zone].u32MaxSegNum; i++)
593         {
594             com = *(g_GetLCDComSeg[u32Zone]
595                     + (index * g_LCDZoneInfo[u32Zone].u32MaxSegNum * 2)
596                     + (i * 2) + 0);
597             seg = *(g_GetLCDComSeg[u32Zone]
598                     + (index * g_LCDZoneInfo[u32Zone].u32MaxSegNum * 2)
599                     + (i * 2) + 1);
600 
601             /* Turn off display */
602             SLCD_SetPixel(com, seg, 0);
603 
604             if (DispData & (1 << i))
605             {
606                 /* Turn on display */
607                 SLCD_SetPixel(com, seg, 1);
608             }
609         }
610 
611         InputStr++;
612     }
613 }
614 
615 /**
616  *  @brief Display number on LCD
617  *
618  *  @param[in]  u32Zone     the assigned number of display area
619  *  @param[in]  InputNum    number to show on display
620  *
621  *  @return None
622  */
LCDLIB_PrintNumber(uint32_t u32Zone,uint32_t InputNum)623 void LCDLIB_PrintNumber(uint32_t u32Zone, uint32_t InputNum)
624 {
625     uint32_t    i, index, val, div;
626     uint16_t    DispData;
627     uint32_t    com, seg;
628 
629     /* Extract useful digits */
630     div = 1;
631 
632     /* Fill out all characters on display */
633     index = g_LCDZoneInfo[u32Zone].u32DigitCnt;
634     while (index != 0)
635     {
636         index--;
637 
638         val = (InputNum / div) % 10;
639         if (u32Zone == ZONE_MAIN_DIGIT)
640             val += 16; /* The Main Digit Table is an ASCII table beginning with "SPACE" */
641 
642         DispData = *(g_LCDDispTable[u32Zone] + val);
643 
644         for (i = 0; i < g_LCDZoneInfo[u32Zone].u32MaxSegNum; i++)
645         {
646             com = *(g_GetLCDComSeg[u32Zone]
647                     + (index * g_LCDZoneInfo[u32Zone].u32MaxSegNum * 2)
648                     + (i * 2) + 0);
649             seg = *(g_GetLCDComSeg[u32Zone]
650                     + (index * g_LCDZoneInfo[u32Zone].u32MaxSegNum * 2)
651                     + (i * 2) + 1);
652 
653             /* Turn off display */
654             SLCD_SetPixel(com, seg, 0);
655 
656             if (DispData & (1 << i))
657             {
658                 /* Turn on display */
659                 SLCD_SetPixel(com, seg, 1);
660             }
661         }
662 
663         div = div * 10;
664     }
665 }
666 
667 /**
668  *  @brief Display character on LCD
669  *
670  *  @param[in]  u32Zone     the assigned number of display area
671  *  @param[in]  u32Index    the requested display position in zone
672  *  @param[in]  u8Ch        Character to show on display
673  *
674  *  @return None
675  */
LCDLIB_PutChar(uint32_t u32Zone,uint32_t u32Index,uint8_t u8Ch)676 void LCDLIB_PutChar(uint32_t u32Zone, uint32_t u32Index, uint8_t u8Ch)
677 {
678     uint32_t    i;
679     uint16_t    DispData;
680     uint32_t    com, seg;
681 
682     if (u32Index <= g_LCDZoneInfo[u32Zone].u32DigitCnt)
683     {
684         /* For Main Zone */
685         if (u32Zone == ZONE_MAIN_DIGIT)
686         {
687             /* The Main Digit Table is an ASCII table beginning with "SPACE" (hex is 0x20) */
688             u8Ch = u8Ch - 0x20;
689             DispData = *(g_LCDDispTable[u32Zone] + u8Ch);
690         }
691         /* For Other Zones (Support '0' ~ '9' only) */
692         else if ((u8Ch >= '0') && (u8Ch <= '9'))
693         {
694             u8Ch = u8Ch - '0';
695             DispData = *(g_LCDDispTable[u32Zone] + u8Ch);
696         }
697         /* Out of definition. Will show "SPACE" */
698         else
699         {
700             DispData = 0;
701         }
702 
703         for (i = 0; i < g_LCDZoneInfo[u32Zone].u32MaxSegNum; i++)
704         {
705             com = *(g_GetLCDComSeg[u32Zone]
706                     + (u32Index * g_LCDZoneInfo[u32Zone].u32MaxSegNum * 2)
707                     + (i * 2) + 0);
708 
709             seg = *(g_GetLCDComSeg[u32Zone]
710                     + (u32Index * g_LCDZoneInfo[u32Zone].u32MaxSegNum * 2)
711                     + (i * 2) + 1);
712 
713             /* Turn off display */
714             SLCD_SetPixel(com, seg, 0);
715 
716             if (DispData & (1 << i))
717             {
718                 /* Turn on display */
719                 SLCD_SetPixel(com, seg, 1);
720             }
721         }
722     }
723 }
724 
725 /**
726  *  @brief Display symbol on LCD
727  *
728  *  @param[in]  u32Symbol   the combination of com, seg position
729  *  @param[in]  u32OnOff    1: display symbol
730  *                          0: not display symbol
731  *
732  *  @return     None
733  */
LCDLIB_SetSymbol(uint32_t u32Symbol,uint32_t u32OnOff)734 void LCDLIB_SetSymbol(uint32_t u32Symbol, uint32_t u32OnOff)
735 {
736     uint32_t com, seg;
737 
738     com = (u32Symbol & 0xF);
739     seg = ((u32Symbol & 0xFF0) >> 4);
740 
741     if (u32OnOff)
742         SLCD_SetPixel(com, seg, 1); /* Turn on display */
743     else
744         SLCD_SetPixel(com, seg, 0); /* Turn off display */
745 
746 }
747 
748 static S_LCD_CFG_T g_LCDCfg_RHE6616TP01 =
749 {
750     __LXT,                      /*!< LCD clock source frequency */
751     LCD_COM_DUTY_1_8,           /*!< COM duty */
752     LCD_BIAS_LV_1_4,            /*!< Bias level */
753     64,                         /*!< Operation frame rate */
754     LCD_WAVEFORM_TYPE_A_NORMAL, /*!< Waveform type */
755     LCD_DISABLE_ALL_INT,        /*!< Interrupt source */
756     LCD_LOW_DRIVING_AND_BUF_ON, /*!< Driving mode */
757     LCD_VOLTAGE_SOURCE_CP,      /*!< Voltage source */
758 };
759 
nu_slcd_panel_init(void)760 static int nu_slcd_panel_init(void)
761 {
762     uint32_t u32CPVol;
763     rt_err_t ret = RT_EOK;
764 
765     g_psDev = rt_device_find("slcd");
766     if (g_psDev == RT_NULL)
767     {
768         LOG_E("can't find slcd failed!\n");
769         goto fail_nu_slcd_panel_init;
770     }
771 
772     /* Give owned SLCD configuration before openning. */
773     ret = rt_device_control(g_psDev, NU_SLCD_CMD_SET_LCD_CFG, (void *)&g_LCDCfg_RHE6616TP01);
774     if (ret != RT_EOK)
775     {
776         LOG_E("configure SLCD failed!\n");
777         goto fail_nu_slcd_panel_init;
778     }
779 
780     /* Open SLCD. */
781     ret = rt_device_open(g_psDev, RT_DEVICE_FLAG_WRONLY);
782     if (ret != RT_EOK)
783     {
784         LOG_E("open dev failed!\n");
785         goto fail_nu_slcd_panel_init;
786     }
787 
788     /* Note: This panel need inject 4.8v, but m2354 charge pump max voltage is 3.6v. */
789     u32CPVol = LCD_CP_VOLTAGE_LV_5;
790     ret = rt_device_control(g_psDev, NU_SLCD_CMD_SET_CP_VOLTAGE, (void *)&u32CPVol);
791     if (ret != RT_EOK)
792     {
793         LOG_E("faile to control cp voltage!\n");
794         goto fail_nu_slcd_panel_init;
795     }
796 
797     return (int)ret;
798 
799 fail_nu_slcd_panel_init:
800 
801     if (g_psDev)
802     {
803         rt_device_close(g_psDev);
804         g_psDev = RT_NULL;
805     }
806     return (int)ret;
807 }
808 INIT_COMPONENT_EXPORT(nu_slcd_panel_init);
809 
810 /*** (C) COPYRIGHT 2019-2020 Nuvoton Technology Corp. ***/
811