]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M4F_ATSAM4E_Atmel_Studio/src/ASF/sam/components/display/ili93xx/ili93xx.c
Rename SAM4E demo directory to include the 'F' in 'M4F' - minor point for the sake...
[freertos] / FreeRTOS / Demo / CORTEX_M4F_ATSAM4E_Atmel_Studio / src / ASF / sam / components / display / ili93xx / ili93xx.c
1 /**\r
2  * \file\r
3  *\r
4  * \brief API driver for ILI93XX TFT display component.\r
5  *\r
6  * Copyright (c) 2013 Atmel Corporation. All rights reserved.\r
7  *\r
8  * \asf_license_start\r
9  *\r
10  * \page License\r
11  *\r
12  * Redistribution and use in source and binary forms, with or without\r
13  * modification, are permitted provided that the following conditions are met:\r
14  *\r
15  * 1. Redistributions of source code must retain the above copyright notice,\r
16  *    this list of conditions and the following disclaimer.\r
17  *\r
18  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
19  *    this list of conditions and the following disclaimer in the documentation\r
20  *    and/or other materials provided with the distribution.\r
21  *\r
22  * 3. The name of Atmel may not be used to endorse or promote products derived\r
23  *    from this software without specific prior written permission.\r
24  *\r
25  * 4. This software may only be redistributed and used in connection with an\r
26  *    Atmel microcontroller product.\r
27  *\r
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED\r
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR\r
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
38  * POSSIBILITY OF SUCH DAMAGE.\r
39  *\r
40  * \asf_license_stop\r
41  *\r
42  */\r
43 \r
44 /**\r
45  * \defgroup ili93xx_display_group Display - ILI93XX Controller\r
46  *\r
47  * Low-level driver for the ILI93XX LCD controller. This driver provides access\r
48  * to the main features of the ILI93XX controller.\r
49  * Now ILI9325 and ILI9341 are supported.\r
50  *\r
51  * \{\r
52  */\r
53 \r
54 #include <string.h>\r
55 #include <stdio.h>\r
56 #include <assert.h>\r
57 #include <stdlib.h>\r
58 #include "ili93xx.h"\r
59 #include "ili9341_regs.h"\r
60 #include "ili9325_regs.h"\r
61 \r
62 /** Device type*/\r
63 static uint8_t g_uc_device_type = 0;\r
64 \r
65 /** Pixel cache used to speed up communication */\r
66 #define LCD_DATA_CACHE_SIZE ILI93XX_LCD_WIDTH\r
67 \r
68 /** LCD X-axis and Y-axis length */\r
69 static uint32_t g_ul_lcd_x_length = ILI93XX_LCD_WIDTH;\r
70 static uint32_t g_ul_lcd_y_length = ILI93XX_LCD_HEIGHT;\r
71 \r
72 static ili93xx_color_t g_ul_pixel_cache[LCD_DATA_CACHE_SIZE];\r
73 \r
74 static volatile ili93xx_coord_t limit_start_x, limit_start_y;\r
75 static volatile ili93xx_coord_t limit_end_x, limit_end_y;\r
76 \r
77 /** Global variable describing the font size used by the driver */\r
78 const struct ili93xx_font gfont = {10, 14};\r
79 \r
80 /**\r
81  * Character set table for font 10x14\r
82  * Coding format:\r
83  * Char height is 14 bits, which is coded using 2 bytes per column\r
84  * (2 unused bits).\r
85  * Char width is 10 bits.\r
86  */\r
87 const uint8_t p_uc_charset10x14[] = {\r
88         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
89         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
90         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xCC,\r
91         0xFF, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
92         0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00,\r
93         0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,\r
94         0x0C, 0xC0, 0x0C, 0xC0, 0xFF, 0xFC, 0xFF, 0xFC, 0x0C, 0xC0,\r
95         0x0C, 0xC0, 0xFF, 0xFC, 0xFF, 0xFC, 0x0C, 0xC0, 0x0C, 0xC0,\r
96         0x0C, 0x60, 0x1E, 0x70, 0x3F, 0x30, 0x33, 0x30, 0xFF, 0xFC,\r
97         0xFF, 0xFC, 0x33, 0x30, 0x33, 0xF0, 0x39, 0xE0, 0x18, 0xC0,\r
98         0x60, 0x00, 0xF0, 0x0C, 0xF0, 0x3C, 0x60, 0xF0, 0x03, 0xC0,\r
99         0x0F, 0x00, 0x3C, 0x18, 0xF0, 0x3C, 0xC0, 0x3C, 0x00, 0x18,\r
100         0x3C, 0xF0, 0x7F, 0xF8, 0xC3, 0x1C, 0xC7, 0x8C, 0xCF, 0xCC,\r
101         0xDC, 0xEC, 0x78, 0x78, 0x30, 0x30, 0x00, 0xFC, 0x00, 0xCC,\r
102         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0xEC, 0x00,\r
103         0xF8, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
104         0x00, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x3F, 0xF0, 0x78, 0x78,\r
105         0x60, 0x18, 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0x00,\r
106         0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0x60, 0x18,\r
107         0x78, 0x78, 0x3F, 0xF0, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00,\r
108         0x0C, 0x60, 0x0E, 0xE0, 0x07, 0xC0, 0x03, 0x80, 0x3F, 0xF8,\r
109         0x3F, 0xF8, 0x03, 0x80, 0x07, 0xC0, 0x0E, 0xE0, 0x0C, 0x60,\r
110         0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x3F, 0xF0,\r
111         0x3F, 0xF0, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,\r
112         0x00, 0x44, 0x00, 0xEC, 0x00, 0xF8, 0x00, 0x70, 0x00, 0x00,\r
113         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
114         0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,\r
115         0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,\r
116         0x00, 0x18, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x18, 0x00, 0x00,\r
117         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
118         0x00, 0x00, 0x00, 0x0C, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0,\r
119         0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x00, 0xC0, 0x00, 0x00, 0x00,\r
120         0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0xFC, 0xC1, 0xCC, 0xC3, 0x8C,\r
121         0xC7, 0x0C, 0xCE, 0x0C, 0xFC, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,\r
122         0x00, 0x00, 0x00, 0x00, 0x30, 0x0C, 0x70, 0x0C, 0xFF, 0xFC,\r
123         0xFF, 0xFC, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,\r
124         0x30, 0x0C, 0x70, 0x1C, 0xE0, 0x3C, 0xC0, 0x7C, 0xC0, 0xEC,\r
125         0xC1, 0xCC, 0xC3, 0x8C, 0xE7, 0x0C, 0x7E, 0x0C, 0x3C, 0x0C,\r
126         0x30, 0x30, 0x70, 0x38, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,\r
127         0xC3, 0x0C, 0xC3, 0x0C, 0xE3, 0x1C, 0x7F, 0xF8, 0x3C, 0xF0,\r
128         0x03, 0xC0, 0x07, 0xC0, 0x0E, 0xC0, 0x1C, 0xC0, 0x38, 0xC0,\r
129         0x70, 0xC0, 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0xC0, 0x00, 0xC0,\r
130         0xFC, 0x30, 0xFC, 0x38, 0xCC, 0x1C, 0xCC, 0x0C, 0xCC, 0x0C,\r
131         0xCC, 0x0C, 0xCC, 0x0C, 0xCE, 0x1C, 0xC7, 0xF8, 0xC3, 0xF0,\r
132         0x3F, 0xF0, 0x7F, 0xF8, 0xE3, 0x1C, 0xC3, 0x0C, 0xC3, 0x0C,\r
133         0xC3, 0x0C, 0xC3, 0x0C, 0xE3, 0x9C, 0x71, 0xF8, 0x30, 0xF0,\r
134         0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC3, 0xFC,\r
135         0xC7, 0xFC, 0xCE, 0x00, 0xDC, 0x00, 0xF8, 0x00, 0xF0, 0x00,\r
136         0x3C, 0xF0, 0x7F, 0xF8, 0xE7, 0x9C, 0xC3, 0x0C, 0xC3, 0x0C,\r
137         0xC3, 0x0C, 0xC3, 0x0C, 0xE7, 0x9C, 0x7F, 0xF8, 0x3C, 0xF0,\r
138         0x3C, 0x00, 0x7E, 0x00, 0xE7, 0x0C, 0xC3, 0x0C, 0xC3, 0x1C,\r
139         0xC3, 0x38, 0xC3, 0x70, 0xE7, 0xE0, 0x7F, 0xC0, 0x3F, 0x80,\r
140         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x60, 0x3C, 0xF0,\r
141         0x3C, 0xF0, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
142         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x44, 0x3C, 0xEC,\r
143         0x3C, 0xF8, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
144         0x00, 0x00, 0x03, 0x00, 0x07, 0x80, 0x0F, 0xC0, 0x1C, 0xE0,\r
145         0x38, 0x70, 0x70, 0x38, 0xE0, 0x1C, 0xC0, 0x0C, 0x00, 0x00,\r
146         0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,\r
147         0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,\r
148         0x00, 0x00, 0xC0, 0x0C, 0xE0, 0x1C, 0x70, 0x38, 0x38, 0x70,\r
149         0x1C, 0xE0, 0x0F, 0xC0, 0x07, 0x80, 0x03, 0x00, 0x00, 0x00,\r
150         0x30, 0x00, 0x70, 0x00, 0xE0, 0x00, 0xC0, 0x00, 0xC1, 0xEC,\r
151         0xC3, 0xEC, 0xC3, 0x00, 0xE6, 0x00, 0x7E, 0x00, 0x3C, 0x00,\r
152         0x30, 0xF0, 0x71, 0xF8, 0xE3, 0x9C, 0xC3, 0x0C, 0xC3, 0xFC,\r
153         0xC3, 0xFC, 0xC0, 0x0C, 0xE0, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,\r
154         0x3F, 0xFC, 0x7F, 0xFC, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\r
155         0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0xC0, 0x7F, 0xFC, 0x3F, 0xFC,\r
156         0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C,\r
157         0xC3, 0x0C, 0xC3, 0x0C, 0xE7, 0x9C, 0x7F, 0xF8, 0x3C, 0xF0,\r
158         0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,\r
159         0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C, 0x70, 0x38, 0x30, 0x30,\r
160         0xFF, 0xFC, 0xFF, 0xFC, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C,\r
161         0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,\r
162         0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C,\r
163         0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C,\r
164         0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00,\r
165         0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0xC0, 0x00, 0xC0, 0x00,\r
166         0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,\r
167         0xC3, 0x0C, 0xC3, 0x0C, 0xE3, 0x1C, 0x73, 0xF8, 0x33, 0xF0,\r
168         0xFF, 0xFC, 0xFF, 0xFC, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,\r
169         0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xFF, 0xFC, 0xFF, 0xFC,\r
170         0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xFF, 0xFC,\r
171         0xFF, 0xFC, 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0x00,\r
172         0x00, 0x30, 0x00, 0x38, 0xC0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,\r
173         0xC0, 0x1C, 0xFF, 0xF8, 0xFF, 0xF0, 0xC0, 0x00, 0xC0, 0x00,\r
174         0xFF, 0xFC, 0xFF, 0xFC, 0x07, 0x80, 0x07, 0x80, 0x0F, 0xC0,\r
175         0x1C, 0xE0, 0x38, 0x70, 0x70, 0x38, 0xE0, 0x1C, 0xC0, 0x0C,\r
176         0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,\r
177         0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,\r
178         0xFF, 0xFC, 0xFF, 0xFC, 0x70, 0x00, 0x38, 0x00, 0x1F, 0x00,\r
179         0x1F, 0x00, 0x38, 0x00, 0x70, 0x00, 0xFF, 0xFC, 0xFF, 0xFC,\r
180         0xFF, 0xFC, 0xFF, 0xFC, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00,\r
181         0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0xFF, 0xFC, 0xFF, 0xFC,\r
182         0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,\r
183         0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,\r
184         0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00,\r
185         0xC3, 0x00, 0xC3, 0x00, 0xE7, 0x00, 0x7E, 0x00, 0x3C, 0x00,\r
186         0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0xCC,\r
187         0xC0, 0xEC, 0xC0, 0x7C, 0xE0, 0x38, 0x7F, 0xFC, 0x3F, 0xEC,\r
188         0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x00, 0xC3, 0x80, 0xC3, 0x80,\r
189         0xC3, 0xC0, 0xC3, 0xC0, 0xE7, 0x70, 0x7E, 0x3C, 0x3C, 0x1C,\r
190         0x3C, 0x18, 0x7E, 0x1C, 0xE7, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C,\r
191         0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x9C, 0xE1, 0xF8, 0x60, 0xF0,\r
192         0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xFF, 0xFC,\r
193         0xFF, 0xFC, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00,\r
194         0xFF, 0xF0, 0xFF, 0xF8, 0x00, 0x1C, 0x00, 0x0C, 0x00, 0x0C,\r
195         0x00, 0x0C, 0x00, 0x0C, 0x00, 0x1C, 0xFF, 0xF8, 0xFF, 0xF0,\r
196         0xFF, 0xC0, 0xFF, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C,\r
197         0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0xFF, 0xE0, 0xFF, 0xC0,\r
198         0xFF, 0xF0, 0xFF, 0xF8, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0xF8,\r
199         0x00, 0xF8, 0x00, 0x3C, 0x00, 0x1C, 0xFF, 0xF8, 0xFF, 0xF0,\r
200         0xF0, 0x3C, 0xF8, 0x7C, 0x1C, 0xE0, 0x0F, 0xC0, 0x07, 0x80,\r
201         0x07, 0x80, 0x0F, 0xC0, 0x1C, 0xE0, 0xF8, 0x7C, 0xF0, 0x3C,\r
202         0xFC, 0x00, 0xFE, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xFC,\r
203         0x01, 0xFC, 0x03, 0x80, 0x07, 0x00, 0xFE, 0x00, 0xFC, 0x00,\r
204         0xC0, 0x3C, 0xC0, 0x7C, 0xC0, 0xEC, 0xC1, 0xCC, 0xC3, 0x8C,\r
205         0xC7, 0x0C, 0xCE, 0x0C, 0xDC, 0x0C, 0xF8, 0x0C, 0xF0, 0x0C,\r
206         0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFC, 0xC0, 0x0C,\r
207         0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
208         0x30, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x03, 0x00,\r
209         0x03, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x30,\r
210         0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C,\r
211         0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
212         0x0C, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x00,\r
213         0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0C, 0x00,\r
214         0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,\r
215         0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,\r
216         0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00,\r
217         0x38, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
218         0x00, 0x30, 0x06, 0x78, 0x0E, 0xFC, 0x0C, 0xCC, 0x0C, 0xCC,\r
219         0x0C, 0xCC, 0x0C, 0xCC, 0x0E, 0xCC, 0x07, 0xFC, 0x03, 0xF8,\r
220         0xFF, 0xFC, 0xFF, 0xFC, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C,\r
221         0x03, 0x0C, 0x03, 0x0C, 0x03, 0x9C, 0x01, 0xF8, 0x00, 0xF0,\r
222         0x03, 0xF0, 0x07, 0xF8, 0x0E, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C,\r
223         0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0x30,\r
224         0x00, 0xF0, 0x01, 0xF8, 0x03, 0x9C, 0x03, 0x0C, 0x03, 0x0C,\r
225         0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0xFF, 0xFC, 0xFF, 0xFC,\r
226         0x03, 0xF0, 0x07, 0xF8, 0x0E, 0xDC, 0x0C, 0xCC, 0x0C, 0xCC,\r
227         0x0C, 0xCC, 0x0C, 0xCC, 0x0E, 0xDC, 0x07, 0xD8, 0x03, 0x90,\r
228         0x00, 0x00, 0x03, 0x00, 0x3F, 0xFC, 0x7F, 0xFC, 0xE3, 0x00,\r
229         0xE3, 0x00, 0x70, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,\r
230         0x03, 0x18, 0x07, 0x9C, 0x0F, 0xCC, 0x0C, 0xCC, 0x0C, 0xCC,\r
231         0x0C, 0xCC, 0x0C, 0xCC, 0x0C, 0xDC, 0x0F, 0xF8, 0x07, 0xF0,\r
232         0xFF, 0xFC, 0xFF, 0xFC, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,\r
233         0x03, 0x00, 0x03, 0x80, 0x01, 0xFC, 0x00, 0xFC, 0x00, 0x00,\r
234         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFC,\r
235         0x1B, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
236         0x00, 0x00, 0x00, 0x30, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0C,\r
237         0x00, 0x0C, 0x00, 0x1C, 0xCF, 0xF8, 0xCF, 0xF0, 0x00, 0x00,\r
238         0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0xE0, 0x01, 0xE0,\r
239         0x03, 0xF0, 0x07, 0x38, 0x0E, 0x1C, 0x0C, 0x0C, 0x00, 0x00,\r
240         0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xFF, 0xFC,\r
241         0xFF, 0xFC, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,\r
242         0x0F, 0xFC, 0x0F, 0xFC, 0x0E, 0x00, 0x07, 0x00, 0x03, 0xC0,\r
243         0x03, 0xC0, 0x07, 0x00, 0x0E, 0x00, 0x0F, 0xFC, 0x0F, 0xFC,\r
244         0x0F, 0xFC, 0x0F, 0xFC, 0x03, 0x00, 0x07, 0x00, 0x0E, 0x00,\r
245         0x0C, 0x00, 0x0C, 0x00, 0x0E, 0x00, 0x07, 0xFC, 0x03, 0xFC,\r
246         0x03, 0xF0, 0x07, 0xF8, 0x0E, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C,\r
247         0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0xF8, 0x03, 0xF0,\r
248         0x0F, 0xFC, 0x0F, 0xFC, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,\r
249         0x0C, 0xC0, 0x0C, 0xC0, 0x0F, 0xC0, 0x07, 0x80, 0x03, 0x00,\r
250         0x03, 0x00, 0x07, 0x80, 0x0F, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,\r
251         0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0F, 0xFC, 0x0F, 0xFC,\r
252         0x0F, 0xFC, 0x0F, 0xFC, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00,\r
253         0x0C, 0x00, 0x0C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x00,\r
254         0x03, 0x18, 0x07, 0x9C, 0x0F, 0xCC, 0x0C, 0xCC, 0x0C, 0xCC,\r
255         0x0C, 0xCC, 0x0C, 0xCC, 0x0C, 0xFC, 0x0E, 0x78, 0x06, 0x30,\r
256         0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0xFF, 0xF0, 0xFF, 0xF8,\r
257         0x0C, 0x1C, 0x0C, 0x1C, 0x0C, 0x38, 0x0C, 0x30, 0x00, 0x00,\r
258         0x0F, 0xF0, 0x0F, 0xF8, 0x00, 0x1C, 0x00, 0x0C, 0x00, 0x0C,\r
259         0x00, 0x0C, 0x00, 0x0C, 0x00, 0x1C, 0x0F, 0xF8, 0x0F, 0xF0,\r
260         0x0F, 0xC0, 0x0F, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C,\r
261         0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x0F, 0xE0, 0x0F, 0xC0,\r
262         0x0F, 0xF0, 0x0F, 0xF8, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0xF8,\r
263         0x00, 0xF8, 0x00, 0x1C, 0x00, 0x1C, 0x0F, 0xF8, 0x0F, 0xF0,\r
264         0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0xF0, 0x01, 0xE0,\r
265         0x01, 0xE0, 0x03, 0xF0, 0x07, 0x38, 0x0E, 0x1C, 0x0C, 0x0C,\r
266         0x0C, 0x00, 0x0E, 0x00, 0x07, 0x0C, 0x03, 0x9C, 0x01, 0xF8,\r
267         0x01, 0xF0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x0C, 0x00,\r
268         0x0C, 0x0C, 0x0C, 0x1C, 0x0C, 0x3C, 0x0C, 0x7C, 0x0C, 0xEC,\r
269         0x0D, 0xCC, 0x0F, 0x8C, 0x0F, 0x0C, 0x0E, 0x0C, 0x0C, 0x0C,\r
270         0x00, 0x00, 0x03, 0x00, 0x07, 0x80, 0x3F, 0xF0, 0x7C, 0xF8,\r
271         0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00,\r
272         0x03, 0x0C, 0x03, 0x0C, 0x3F, 0xFC, 0x7F, 0xFC, 0xE3, 0x0C,\r
273         0xC3, 0x0C, 0xC0, 0x0C, 0xE0, 0x0C, 0x70, 0x0C, 0x30, 0x0C,\r
274         0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C,\r
275         0x7C, 0xF8, 0x3F, 0xF0, 0x07, 0x80, 0x03, 0x00, 0x00, 0x00,\r
276         0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00,\r
277         0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00,\r
278         0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC,\r
279         0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC\r
280 };\r
281 \r
282 /**\r
283  * \brief Prepare to write GRAM data for ili93xx.\r
284  */\r
285 static void ili93xx_write_ram_prepare(void)\r
286 {\r
287         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
288                 /** Write Data to GRAM (R22h) */\r
289                 LCD_IR(0);\r
290                 LCD_IR(ILI9325_GRAM_DATA_REG);\r
291         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
292                 /** memory write command (R2Ch)*/\r
293                 LCD_IR(ILI9341_CMD_MEMORY_WRITE);\r
294                 LCD_IR(0);\r
295                 LCD_IR(ILI9341_CMD_WRITE_MEMORY_CONTINUE);\r
296         }\r
297 }\r
298 \r
299 /**\r
300  * \brief Write data to LCD GRAM.\r
301  *\r
302  * \param ul_color 24-bits RGB color.\r
303  */\r
304 static void ili93xx_write_ram(ili93xx_color_t ul_color)\r
305 {\r
306         LCD_WD((ul_color >> 16) & 0xFF);\r
307         LCD_WD((ul_color >> 8) & 0xFF);\r
308         LCD_WD(ul_color & 0xFF);\r
309 }\r
310 \r
311 /**\r
312  * \brief Write multiple data in buffer to LCD controller for ili93xx.\r
313  *\r
314  * \param p_ul_buf data buffer.\r
315  * \param ul_size size in pixels.\r
316  */\r
317 static void ili93xx_write_ram_buffer(const ili93xx_color_t *p_ul_buf,\r
318                 uint32_t ul_size)\r
319 {\r
320         uint32_t ul_addr;\r
321         for (ul_addr = 0; ul_addr < (ul_size - ul_size % 8); ul_addr += 8) {\r
322                 ili93xx_write_ram(p_ul_buf[ul_addr]);\r
323                 ili93xx_write_ram(p_ul_buf[ul_addr + 1]);\r
324                 ili93xx_write_ram(p_ul_buf[ul_addr + 2]);\r
325                 ili93xx_write_ram(p_ul_buf[ul_addr + 3]);\r
326                 ili93xx_write_ram(p_ul_buf[ul_addr + 4]);\r
327                 ili93xx_write_ram(p_ul_buf[ul_addr + 5]);\r
328                 ili93xx_write_ram(p_ul_buf[ul_addr + 6]);\r
329                 ili93xx_write_ram(p_ul_buf[ul_addr + 7]);\r
330         }\r
331         for (; ul_addr < ul_size; ul_addr++) {\r
332                 ili93xx_write_ram(p_ul_buf[ul_addr]);\r
333         }\r
334 }\r
335 \r
336 /**\r
337  * \brief Write a word (16bits)to LCD Register.\r
338  *\r
339  * \param uc_reg register address.\r
340  * \param us_data data to be written.\r
341  */\r
342 static void ili93xx_write_register_word(uint8_t uc_reg, uint16_t us_data)\r
343 {\r
344         LCD_IR(0);\r
345         LCD_IR(uc_reg);\r
346         LCD_WD((us_data >> 8) & 0xFF);\r
347         LCD_WD(us_data & 0xFF);\r
348 }\r
349 \r
350 /**\r
351  * \brief Write data to LCD Register for ili93xx.\r
352  *\r
353  * \param uc_reg register address.\r
354  * \param us_data data to be written.\r
355  */\r
356 static void ili93xx_write_register(uint8_t uc_reg, uint8_t *p_data,\r
357                 uint8_t uc_datacnt)\r
358 {\r
359 uint8_t i;\r
360 \r
361         LCD_IR(0);\r
362         LCD_IR(uc_reg);\r
363         for (i = 0; i < uc_datacnt; i++) {\r
364                 LCD_WD(p_data[i]);\r
365         }\r
366 }\r
367 \r
368 /**\r
369  * \brief Prepare to read GRAM data for ili93xx.\r
370  */\r
371 static void ili93xx_read_ram_prepare(void)\r
372 {\r
373         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
374                 LCD_IR(0);\r
375                 /** Write Data to GRAM (R22h) */\r
376                 LCD_IR(ILI9325_GRAM_DATA_REG);\r
377         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
378                 LCD_IR(0);\r
379                 /** Write Data to GRAM (R2Eh) */\r
380                 LCD_IR(ILI9341_CMD_MEMORY_READ);\r
381         }\r
382 }\r
383 \r
384 /**\r
385  * \brief Read data to LCD GRAM for ili93xx.\r
386  *\r
387  * \note For ili9325, because pixel data LCD GRAM is 18-bits, so convertion\r
388  * to RGB 24-bits will cause low color bit lose.\r
389  *\r
390  * \return color 24-bits RGB color.\r
391  */\r
392 static uint32_t ili93xx_read_ram(void)\r
393 {\r
394         uint8_t value[3];\r
395         uint32_t color;\r
396         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
397                 /** dummy read*/\r
398                 value[0] = LCD_RD();\r
399                 value[1] = LCD_RD();\r
400                 /** data upper byte*/\r
401                 value[0] = LCD_RD();\r
402                 /** data lower byte */\r
403                 value[1] = LCD_RD();\r
404 \r
405                 /** Convert RGB565 to RGB888 */\r
406                 /** For BGR format */\r
407                 color = ((value[0] & 0xF8)) | ((value[0] & 0x07) << 13) |\r
408                                 ((value[1] & 0xE0) << 5) |\r
409                                 ((value[1] & 0x1F) << 19);\r
410         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
411                 /** dummy read */\r
412                 value[0] = LCD_RD();\r
413                 /** the highest byte - R byte*/\r
414                 value[0] = LCD_RD();\r
415                 /** the middle byte - G byte*/\r
416                 value[1] = LCD_RD();\r
417                 /** the lowest byte - B byte*/\r
418                 value[2] = LCD_RD();\r
419                 /** combine R, G, B byte to a color value */\r
420                 color = (value[0] << 16) | (value[1] << 8) | value[2];\r
421         }\r
422 \r
423         return color;\r
424 }\r
425 \r
426 /**\r
427  * \brief Read data from LCD Register.\r
428  *\r
429  * \param uc_reg register address.\r
430  * \param p_data the pointer to the read data.\r
431  * \param uc_datacnt the number of the read data\r
432  */\r
433 static void ili93xx_read_register(uint8_t uc_reg, uint8_t *p_data,\r
434                 uint8_t uc_datacnt)\r
435 {\r
436 uint8_t i;\r
437 \r
438         LCD_IR(0);\r
439         LCD_IR(uc_reg);\r
440 \r
441         for (i = 0; i < uc_datacnt; i++) {\r
442                 p_data[i] = LCD_RD();\r
443         }\r
444 }\r
445 \r
446 /**\r
447  * \brief Delay function.\r
448  */\r
449 static void ili93xx_delay(uint32_t ul_ms)\r
450 {\r
451         volatile uint32_t i;\r
452 \r
453         for (i = 0; i < ul_ms; i++) {\r
454                 for (i = 0; i < 100000; i++) {\r
455                 }\r
456         }\r
457 }\r
458 \r
459 /**\r
460  * \brief Check box coordinates.\r
461  *\r
462  * \param p_ul_x1 X coordinate of upper-left corner on LCD.\r
463  * \param p_ul_y1 Y coordinate of upper-left corner on LCD.\r
464  * \param p_ul_x2 X coordinate of lower-right corner on LCD.\r
465  * \param p_ul_y2 Y coordinate of lower-right corner on LCD.\r
466  */\r
467 static void ili93xx_check_box_coordinates(uint32_t *p_ul_x1, uint32_t *p_ul_y1,\r
468                 uint32_t *p_ul_x2, uint32_t *p_ul_y2)\r
469 {\r
470         uint32_t dw;\r
471 \r
472         if (*p_ul_x1 >= g_ul_lcd_x_length) {\r
473                 *p_ul_x1 = g_ul_lcd_x_length - 1;\r
474         }\r
475 \r
476         if (*p_ul_x2 >= g_ul_lcd_x_length) {\r
477                 *p_ul_x2 = g_ul_lcd_x_length - 1;\r
478         }\r
479 \r
480         if (*p_ul_y1 >= g_ul_lcd_y_length) {\r
481                 *p_ul_y1 = g_ul_lcd_y_length - 1;\r
482         }\r
483 \r
484         if (*p_ul_y2 >= g_ul_lcd_y_length) {\r
485                 *p_ul_y2 = g_ul_lcd_y_length - 1;\r
486         }\r
487 \r
488         if (*p_ul_x1 > *p_ul_x2) {\r
489                 dw = *p_ul_x1;\r
490                 *p_ul_x1 = *p_ul_x2;\r
491                 *p_ul_x2 = dw;\r
492         }\r
493 \r
494         if (*p_ul_y1 > *p_ul_y2) {\r
495                 dw = *p_ul_y1;\r
496                 *p_ul_y1 = *p_ul_y2;\r
497                 *p_ul_y2 = dw;\r
498         }\r
499 }\r
500 \r
501 /**\r
502  * \brief Read device ID to idenfity the device\r
503  *        ILI9325 device ID locates in Device Code Read (R00h) register.\r
504  *        ILI9341 device ID locates in Read ID4 (RD3h) register.\r
505  *\r
506  * \return 0 if secceed in identifying device; otherwise fails.\r
507  */\r
508 uint8_t ili93xx_device_type_identify(void)\r
509 {\r
510         uint8_t paratable[6];\r
511         uint16_t chipid;\r
512 \r
513         /** Read ID4 (RD4h) register to get device code for ILI9341*/\r
514         ili93xx_read_register(ILI9341_CMD_READ_ID4, paratable, 4);\r
515         chipid = ((uint16_t)paratable[2] << 8) + paratable[3];\r
516 \r
517         if (chipid == ILI9341_DEVICE_CODE) {\r
518                 g_uc_device_type = DEVICE_TYPE_ILI9341;\r
519                 return 0;\r
520         }\r
521 \r
522         /** Driver Code Read (R00h) for ILI9325*/\r
523         ili93xx_read_register(ILI9325_DEVICE_CODE_REG, paratable, 2);\r
524         chipid = ((uint16_t)paratable[0] << 8) + paratable[1];\r
525         if (chipid == ILI9325_DEVICE_CODE) {\r
526                 g_uc_device_type = DEVICE_TYPE_ILI9325;\r
527                 return 0;\r
528         }\r
529 \r
530         return 1;\r
531 }\r
532 \r
533 /**\r
534  * \brief Initialize the ILI93XX lcd driver.\r
535  *\r
536  * \note Make sure below works have been done before calling ili93xx_init()\r
537  * 1. ILI93xx related Pins have been initialized correctly.\r
538  * 2. SMC has been configured correctly for access ILI93xx (8-bit system\r
539  *    interface for now).\r
540  *\r
541  * \param p_opt pointer to ILI93xx option structure.\r
542  *\r
543  * \return 0 if initialization succeeds, otherwise fails.\r
544  */\r
545 uint32_t ili93xx_init(struct ili93xx_opt_t *p_opt)\r
546 {\r
547         uint8_t paratable[15];\r
548 \r
549         /** Identify the LCD driver device*/\r
550         if (ili93xx_device_type_identify() != 0) {\r
551                 return 1;\r
552         }\r
553 \r
554         g_ul_lcd_x_length = ILI93XX_LCD_WIDTH;\r
555         g_ul_lcd_y_length = ILI93XX_LCD_HEIGHT;\r
556 \r
557         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
558                 /** Turn off LCD */\r
559                 ili93xx_write_register_word(ILI9325_DISP_CTRL1, ILI9325_DISP_CTRL1_GON |\r
560                                 ILI9325_DISP_CTRL1_DTE | ILI9325_DISP_CTRL1_D(0x03));\r
561 \r
562                 /** Start initial sequence */\r
563                 /** Disable sleep and standby mode*/\r
564                 ili93xx_write_register_word(ILI9325_POWER_CTRL1, 0x0000);\r
565                 /** Start internal OSC */\r
566                 ili93xx_write_register_word(ILI9325_START_OSC_CTRL,\r
567                                 ILI9325_START_OSC_CTRL_EN);\r
568                 /** Set SS bit and direction output from S720 to S1 */\r
569                 ili93xx_write_register_word(ILI9325_DRIVER_OUTPUT_CTRL1,\r
570                                 ILI9325_DRIVER_OUTPUT_CTRL1_SS);\r
571                 /** Set 1 line inversion */\r
572                 ili93xx_write_register_word(ILI9325_LCD_DRIVING_CTRL,\r
573                                 ILI9325_LCD_DRIVING_CTRL_BIT10 | ILI9325_LCD_DRIVING_CTRL_EOR\r
574                                 | ILI9325_LCD_DRIVING_CTRL_BC0);\r
575                 /** Disable resizing feature */\r
576                 ili93xx_write_register_word(ILI9325_RESIZE_CTRL, 0x0000);\r
577                 /** Set the back porch and front porch */\r
578                 ili93xx_write_register_word(ILI9325_DISP_CTRL2,\r
579                                 ILI9325_DISP_CTRL2_BP(\r
580                                 0x07) | ILI9325_DISP_CTRL2_FP(0x02));\r
581                 /** Set non-display area refresh cycle ISC[3:0] */\r
582                 ili93xx_write_register_word(ILI9325_DISP_CTRL3, 0x0000);\r
583                 /** Disable FMARK function */\r
584                 ili93xx_write_register_word(ILI9325_DISP_CTRL4, 0x0000);\r
585                 /** 18-bit RGB interface and writing display data by system\r
586                  *interface */\r
587                 ili93xx_write_register_word(ILI9325_RGB_DISP_INTERFACE_CTRL1,\r
588                                 0x0000);\r
589                 /** Set the output position of frame cycle */\r
590                 ili93xx_write_register_word(ILI9325_FRAME_MAKER_POS, 0x0000);\r
591                 /** RGB interface polarity */\r
592                 ili93xx_write_register_word(ILI9325_RGB_DISP_INTERFACE_CTRL2,\r
593                                 0x0000);\r
594 \r
595                 /** Power on sequence */\r
596                 /** Disable sleep and standby mode */\r
597                 ili93xx_write_register_word(ILI9325_POWER_CTRL1, 0x0000);\r
598 \r
599                 /**\r
600                  * Selects the operating frequency of the step-up circuit 1,2\r
601                  * and Sets the ratio factor of Vci.\r
602                  */\r
603                 ili93xx_write_register_word(ILI9325_POWER_CTRL2, 0x0000);\r
604                 /** Set VREG1OUT voltage */\r
605                 ili93xx_write_register_word(ILI9325_POWER_CTRL3, 0x0000);\r
606                 /** Set VCOM amplitude */\r
607                 ili93xx_write_register_word(ILI9325_POWER_CTRL4, 0x0000);\r
608                 ili93xx_delay(200);\r
609 \r
610                 /** Enable power supply and source driver */\r
611 \r
612                 /**\r
613                  * Adjusts the constant current and Sets the factor used\r
614                  * in the step-up circuits.\r
615                  */\r
616                 ili93xx_write_register_word(ILI9325_POWER_CTRL1,\r
617                                 ILI9325_POWER_CTRL1_SAP | ILI9325_POWER_CTRL1_BT(0x02) |\r
618                                 ILI9325_POWER_CTRL1_APE |\r
619                                 ILI9325_POWER_CTRL1_AP(0x01));\r
620 \r
621                 /**\r
622                  * Select the operating frequency of the step-up circuit 1,2 and\r
623                  * Sets the ratio factor of Vci\r
624                  */\r
625                 ili93xx_write_register_word(ILI9325_POWER_CTRL2,\r
626                                 ILI9325_POWER_CTRL2_DC1(0x02) |\r
627                                 ILI9325_POWER_CTRL2_DC0(0x02) | ILI9325_POWER_CTRL2_VC(0x07));\r
628                 ili93xx_delay(50);\r
629                 /** Internal reference voltage= Vci */\r
630                 ili93xx_write_register_word(ILI9325_POWER_CTRL3,\r
631                                 ILI9325_POWER_CTRL3_PON | ILI9325_POWER_CTRL3_VRH(0x0B));\r
632                 ili93xx_delay(50);\r
633                 /** Set VDV[4:0] for VCOM amplitude */\r
634                 ili93xx_write_register_word(ILI9325_POWER_CTRL4,\r
635                                 ILI9325_POWER_CTRL4_VDV(0x11));\r
636                 /** Set VCM[5:0] for VCOMH */\r
637                 ili93xx_write_register_word(ILI9325_POWER_CTRL7,\r
638                                 ILI9325_POWER_CTRL7_VCM(0x19));\r
639                 /** Set Frame Rate */\r
640                 ili93xx_write_register_word(ILI9325_FRAME_RATE_AND_COLOR_CTRL,\r
641                                 ILI9325_FRAME_RATE_AND_COLOR_CTRL_FRS(0x0D));\r
642                 ili93xx_delay(50);\r
643 \r
644                 /** Adjust the Gamma Curve */\r
645                 ili93xx_write_register_word(ILI9325_GAMMA_CTL1, 0x0000);\r
646                 ili93xx_write_register_word(ILI9325_GAMMA_CTL2,\r
647                                 ILI9325_GAMMA_CTL2_KP3(0x02) |\r
648                                 ILI9325_GAMMA_CTL2_KP2(0x04));\r
649                 ili93xx_write_register_word(ILI9325_GAMMA_CTL3,\r
650                                 ILI9325_GAMMA_CTL3_KP5(0x02) |\r
651                                 ILI9325_GAMMA_CTL3_KP4(0x00));\r
652                 ili93xx_write_register_word(ILI9325_GAMMA_CTL4,\r
653                                 ILI9325_GAMMA_CTL4_RP1(0x00) |\r
654                                 ILI9325_GAMMA_CTL4_RP0(0x07));\r
655                 ili93xx_write_register_word(ILI9325_GAMMA_CTL5,\r
656                                 ILI9325_GAMMA_CTL5_VRP1(0x14) |\r
657                                 ILI9325_GAMMA_CTL5_VRP0(0x04));\r
658                 ili93xx_write_register_word(ILI9325_GAMMA_CTL6,\r
659                                 ILI9325_GAMMA_CTL6_KN1(0x07) |\r
660                                 ILI9325_GAMMA_CTL6_KN0(0x05));\r
661                 ili93xx_write_register_word(ILI9325_GAMMA_CTL7,\r
662                                 ILI9325_GAMMA_CTL7_KN3(0x03) |\r
663                                 ILI9325_GAMMA_CTL7_KN2(0x05));\r
664                 ili93xx_write_register_word(ILI9325_GAMMA_CTL8,\r
665                                 ILI9325_GAMMA_CTL8_KN5(0x07) |\r
666                                 ILI9325_GAMMA_CTL8_KN4(0x07));\r
667                 ili93xx_write_register_word(ILI9325_GAMMA_CTL9,\r
668                                 ILI9325_GAMMA_CTL9_RN1(0x07) |\r
669                                 ILI9325_GAMMA_CTL9_RN0(0x01));\r
670                 ili93xx_write_register_word(ILI9325_GAMMA_CTL10,\r
671                                 ILI9325_GAMMA_CTL10_VRN1(0x00) |\r
672                                 ILI9325_GAMMA_CTL10_VRN0(0x0E));\r
673                 /**\r
674                  * Use the high speed write mode (HWM=1)\r
675                  * When TRI = 1, data are transferred to the internal RAM in\r
676                  * 8-bit x 3 transfers mode via the 8-bit interface.\r
677                  * DFM Set the mode of transferring data to the internal RAM\r
678                  * when TRI = 1.\r
679                  * I/D[1:0] = 11 Horizontal : increment Vertical : increment,\r
680                  * AM=0:Horizontal\r
681                  */\r
682                 ili93xx_write_register_word(ILI9325_ENTRY_MODE,\r
683                                 ILI9325_ENTRY_MODE_TRI | ILI9325_ENTRY_MODE_DFM |\r
684                                 ILI9325_ENTRY_MODE_ID(0x01) | ILI9325_ENTRY_MODE_BGR);\r
685                 /**\r
686                  * Sets the number of lines to drive the LCD at an interval of 8\r
687                  * lines. The scan direction is from G320 to G1\r
688                  */\r
689                 ili93xx_write_register_word(ILI9325_DRIVER_OUTPUT_CTRL2,\r
690                                 ILI9325_DRIVER_OUTPUT_CTRL2_GS |\r
691                                 ILI9325_DRIVER_OUTPUT_CTRL2_NL(0x27));\r
692 \r
693                 /** Vertical Scrolling */\r
694                 /** Disable scrolling and enable the grayscale inversion */\r
695                 ili93xx_write_register_word(ILI9325_BASE_IMG_DISP_CTRL,\r
696                                 ILI9325_BASE_IMG_DISP_CTRL_REV);\r
697                 ili93xx_write_register_word(ILI9325_VERTICAL_SCROLL_CTRL,\r
698                                 0x0000);\r
699 \r
700                 /** Disable Partial Display */\r
701                 ili93xx_write_register_word(ILI9325_PARTIAL_IMG1_DISP_POS,\r
702                                 0x0000);\r
703                 ili93xx_write_register_word(\r
704                                 ILI9325_PARTIAL_IMG1_AREA_START_LINE,\r
705                                 0x0000);\r
706                 ili93xx_write_register_word(ILI9325_PARTIAL_IMG1_AREA_END_LINE,\r
707                                 0x0000);\r
708                 ili93xx_write_register_word(ILI9325_PARTIAL_IMG2_DISP_POS,\r
709                                 0x0000);\r
710                 ili93xx_write_register_word(\r
711                                 ILI9325_PARTIAL_IMG2_AREA_START_LINE,\r
712                                 0x0000);\r
713                 ili93xx_write_register_word(ILI9325_PARTIAL_IMG2_AREA_END_LINE,\r
714                                 0x0000);\r
715 \r
716                 /** Panel Control */\r
717                 ili93xx_write_register_word(ILI9325_PANEL_INTERFACE_CTRL1,\r
718                                 ILI9325_PANEL_INTERFACE_CTRL1_RTNI(0x10));\r
719                 ili93xx_write_register_word(ILI9325_PANEL_INTERFACE_CTRL2,\r
720                                 ILI9325_PANEL_INTERFACE_CTRL2_NOWI(0x06));\r
721                 ili93xx_write_register_word(ILI9325_PANEL_INTERFACE_CTRL4,\r
722                                 ILI9325_PANEL_INTERFACE_CTRL4_DIVE(0x01) |\r
723                                 ILI9325_PANEL_INTERFACE_CTRL4_RTNE(0x10));\r
724 \r
725                 ili93xx_set_window(0, 0, p_opt->ul_width, p_opt->ul_height);\r
726                 ili93xx_set_foreground_color(p_opt->foreground_color);\r
727                 ili93xx_set_cursor_position(0, 0);\r
728         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
729                 /** init for ILI9341 **/\r
730                 /** power control A configuration*/\r
731                 paratable[0] = 0x39;\r
732                 paratable[1] = 0x2C;\r
733                 paratable[2] = 0x00;\r
734                 paratable[3] = 0x34;\r
735                 paratable[4] = 0x02;\r
736                 ili93xx_write_register(ILI9341_CMD_POWER_CONTROL_A, paratable, 5);\r
737 \r
738                 /** power control B configuration */\r
739                 paratable[0] = 0;\r
740                 paratable[1] = 0xAA;\r
741                 paratable[2] = 0xB0;\r
742                 ili93xx_write_register(ILI9341_CMD_POWER_CONTROL_B, paratable, 3);\r
743 \r
744                 /** Pump Ratio Control configuration */\r
745                 paratable[0] = 0x30;\r
746                 ili93xx_write_register(ILI9341_CMD_PUMP_RATIO_CONTROL,\r
747                                 paratable, 1);\r
748 \r
749                 /** Power Control 1 configuration*/\r
750                 paratable[0] = 0x25;\r
751                 ili93xx_write_register(ILI9341_CMD_POWER_CONTROL_1, paratable, 1);\r
752 \r
753                 /** Power Control 2 configuration*/\r
754                 paratable[0] = 0x11;\r
755                 ili93xx_write_register(ILI9341_CMD_POWER_CONTROL_2, paratable, 1);\r
756 \r
757                 /** VOM Control 1 configuration*/\r
758                 paratable[0] = 0x5C;\r
759                 paratable[1] = 0x4C;\r
760                 ili93xx_write_register(ILI9341_CMD_VCOM_CONTROL_1, paratable, 2);\r
761 \r
762                 /** VOM control 2 configuration*/\r
763                 paratable[0] = 0x94;\r
764                 ili93xx_write_register(ILI9341_CMD_VCOM_CONTROL_2, paratable, 1);\r
765 \r
766                 /** Driver Timing Control A configuration*/\r
767                 paratable[0] = 0x85;\r
768                 paratable[1] = 0x01;\r
769                 paratable[2] = 0x78;\r
770                 ili93xx_write_register(ILI9341_CMD_DRIVER_TIMING_CTL_A, paratable, 3);\r
771 \r
772                 /** Driver Timing Control B configuration*/\r
773                 paratable[0] = 0x00;\r
774                 paratable[1] = 0x00;\r
775                 ili93xx_write_register(ILI9341_CMD_DRIVER_TIMING_CTL_B, paratable, 2);\r
776 \r
777                 /** Memory Access Control configuration*/\r
778                 paratable[0] = ILI9341_CMD_MEMORY_ACCESS_CONTROL_MX |\r
779                                 ILI9341_CMD_MEMORY_ACCESS_CONTROL_BGR;\r
780                 ili93xx_write_register(ILI9341_CMD_MEMORY_ACCESS_CONTROL,\r
781                                 paratable, 1);\r
782 \r
783                 /** Colmod Pixel Format Set configuation*/\r
784                 paratable[0] = 0x06;\r
785                 ili93xx_write_register(ILI9341_CMD_PIXEL_FORMAT_SET, paratable, 1);\r
786 \r
787                 /** Display Function Control */\r
788                 paratable[0] = 0x02;\r
789                 paratable[1] = 0x82;\r
790                 paratable[2] = 0x27;\r
791                 paratable[3] = 0x00;\r
792                 ili93xx_write_register(ILI9341_CMD_DISPLAY_FUNCTION_CTL,\r
793                                       paratable, 4);\r
794                                 \r
795                 paratable[0] = 0x00;\r
796                 ili93xx_write_register(ILI9341_CMD_ENABLE_3_GAMMA_CONTROL,\r
797                                       paratable,1);\r
798                 \r
799                 paratable[0] = 0x01;\r
800                 ili93xx_write_register(ILI9341_CMD_GAMMA_SET, paratable,1);\r
801                 \r
802                 /** set gamma curve parameters*/\r
803                 paratable[0]=0x0F;\r
804                 paratable[1]=0x31;\r
805                 paratable[2]=0x2B;\r
806                 paratable[3]=0x0C;\r
807                 paratable[4]=0x0E;\r
808                 paratable[5]=0x08;\r
809                 paratable[6]=0x4E;\r
810                 paratable[7]=0xF1;\r
811                 paratable[8]=0x37;\r
812                 paratable[9]=0x07;\r
813                 paratable[10]=0x10;\r
814                 paratable[11]=0x03;\r
815                 paratable[12]=0x0E;\r
816                 paratable[13]=0x09;\r
817                 paratable[14]=0x00;\r
818                 ili93xx_write_register(ILI9341_CMD_POSITIVE_GAMMA_CORRECTION,\r
819                                       paratable, 15);\r
820                 paratable[0]=0x00;\r
821                 paratable[1]=0x0E;\r
822                 paratable[2]=0x14;\r
823                 paratable[3]=0x03;\r
824                 paratable[4]=0x11;\r
825                 paratable[5]=0x07;\r
826                 paratable[6]=0x31;\r
827                 paratable[7]=0xC1;\r
828                 paratable[8]=0x48;\r
829                 paratable[9]=0x08;\r
830                 paratable[10]=0x0F;\r
831                 paratable[11]=0x0C;\r
832                 paratable[12]=0x31;\r
833                 paratable[13]=0x36;\r
834                 paratable[14]=0x0F;\r
835                 ili93xx_write_register(ILI9341_CMD_NEGATIVE_GAMMA_CORRECTION,\r
836                                       paratable, 15);\r
837                 \r
838                 /** set window area*/\r
839                 ili93xx_set_window(0, 0, p_opt->ul_width, p_opt->ul_height);\r
840                 ili93xx_set_foreground_color(p_opt->foreground_color);\r
841                 /** Leave sleep mode*/\r
842                 ili93xx_write_register(ILI9341_CMD_SLEEP_OUT, paratable, 0);\r
843                 ili93xx_delay(10);\r
844                 /** Display on*/\r
845                 ili93xx_write_register(ILI9341_CMD_DISPLAY_ON, paratable, 0);\r
846         } else {\r
847                 /** exit with return value 1 if device type is not supported.*/\r
848                 return 1;\r
849         }\r
850 \r
851         return 0;\r
852 }\r
853 \r
854 /**\r
855  * \brief get the device type.\r
856  */\r
857 uint8_t ili93xx_device_type(void)\r
858 {\r
859         return g_uc_device_type;\r
860 }\r
861 \r
862 /**\r
863  * \brief Turn on the LCD.\r
864  */\r
865 void ili93xx_display_on(void)\r
866 {\r
867         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
868                 ili93xx_write_register_word(ILI9325_DISP_CTRL1,\r
869                                 ILI9325_DISP_CTRL1_BASEE |\r
870                                 ILI9325_DISP_CTRL1_GON |\r
871                                 ILI9325_DISP_CTRL1_DTE |\r
872                                 ILI9325_DISP_CTRL1_D(0x03));\r
873         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
874                 ili93xx_write_register(ILI9341_CMD_DISPLAY_ON, NULL, 0);\r
875         }\r
876 }\r
877 \r
878 /**\r
879  * \brief Turn off the LCD.\r
880  */\r
881 void ili93xx_display_off(void)\r
882 {\r
883         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
884                 ili93xx_write_register_word(ILI9325_DISP_CTRL1, 0x00);\r
885         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
886                 ili93xx_write_register(ILI9341_CMD_DISPLAY_OFF, NULL, 0);\r
887         }\r
888 }\r
889 \r
890 /**\r
891  * \brief Set foreground color.\r
892  *\r
893  * \param ul_color foreground color.\r
894  */\r
895 void ili93xx_set_foreground_color(ili93xx_color_t ul_color)\r
896 {\r
897         uint32_t i;\r
898 \r
899         /** Fill the cache with selected color */\r
900         for (i = 0; i < LCD_DATA_CACHE_SIZE; ++i) {\r
901                 g_ul_pixel_cache[i] = ul_color;\r
902         }\r
903 }\r
904 \r
905 /**\r
906  * \brief Fill the LCD buffer with the specified color.\r
907  *\r
908  * \param ul_color fill color.\r
909  */\r
910 void ili93xx_fill(ili93xx_color_t ul_color)\r
911 {\r
912         uint32_t dw;\r
913         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
914                 ili93xx_set_cursor_position(0, 0);\r
915         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
916                 ili93xx_set_window(0, 0, g_ul_lcd_x_length, g_ul_lcd_y_length);\r
917         }\r
918 \r
919         ili93xx_write_ram_prepare();\r
920 \r
921         for (dw = ILI93XX_LCD_WIDTH * ILI93XX_LCD_HEIGHT; dw > 0; dw--) {\r
922                 ili93xx_write_ram(ul_color);\r
923         }\r
924 }\r
925 \r
926 /**\r
927  * \brief Set display window.\r
928  *\r
929  * \param ul_x Horizontal address start position\r
930  * \param ul_y Vertical address start position\r
931  * \param ul_width The width of the window.\r
932  * \param ul_height The height of the window.\r
933  */\r
934 void ili93xx_set_window(uint32_t ul_x, uint32_t ul_y, uint32_t ul_width,\r
935                 uint32_t ul_height)\r
936 {\r
937         Assert(ul_x <= (g_ul_lcd_x_length - 1));\r
938         Assert(ul_y <= (g_ul_lcd_y_length - 1));\r
939         Assert(ul_width <= (g_ul_lcd_x_length - ul_x));\r
940         Assert(ul_height <= (g_ul_lcd_y_length - ul_y));\r
941         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
942                 /** Set Horizontal Address Start Position */\r
943                 ili93xx_write_register_word(ILI9325_HORIZONTAL_ADDR_START,\r
944                                 (uint16_t)ul_x);\r
945 \r
946                 /** Set Horizontal Address End Position */\r
947                 ili93xx_write_register_word(ILI9325_HORIZONTAL_ADDR_END,\r
948                                 (uint16_t)(ul_x + ul_width - 1));\r
949 \r
950                 /** Set Vertical Address Start Position */\r
951                 ili93xx_write_register_word(ILI9325_VERTICAL_ADDR_START,\r
952                                 (uint16_t)ul_y);\r
953 \r
954                 /** Set Vertical Address End Position */\r
955                 ili93xx_write_register_word(ILI9325_VERTICAL_ADDR_END,\r
956                                 (uint16_t)(ul_y + ul_height - 1));\r
957         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
958                 uint8_t paratable[4];\r
959 \r
960                 /** Set Column Address Position */\r
961                 paratable[0] = (ul_x >> 8) & 0xFF;\r
962                 paratable[1] = ul_x & 0xFF;\r
963                 paratable[2] = ((ul_x + ul_width - 1) >> 8) & 0xFF;\r
964                 paratable[3] = (ul_x + ul_width - 1) & 0xFF;\r
965                 ili93xx_write_register(ILI9341_CMD_COLUMN_ADDRESS_SET,\r
966                                 paratable, 4);\r
967 \r
968                 /** Set Page Address Position */\r
969                 paratable[0] = (ul_y >> 8) & 0xFF;\r
970                 paratable[1] = ul_y & 0xFF;\r
971                 paratable[2] = ((ul_y + ul_height - 1) >> 8) & 0xFF;\r
972                 paratable[3] = (ul_y + ul_height - 1) & 0xFF;\r
973                 ili93xx_write_register(ILI9341_CMD_PAGE_ADDRESS_SET,\r
974                                        paratable, 4);\r
975         }\r
976 }\r
977 \r
978 /**\r
979  * \brief Set cursor of LCD screen.\r
980  *\r
981  * \param us_x X coordinate of upper-left corner on LCD.\r
982  * \param us_y Y coordinate of upper-left corner on LCD.\r
983  */\r
984 void ili93xx_set_cursor_position(uint16_t us_x, uint16_t us_y)\r
985 {\r
986         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
987                 /** GRAM Horizontal/Vertical Address Set (R20h, R21h) */\r
988                 ili93xx_write_register_word(ILI9325_HORIZONTAL_GRAM_ADDR_SET, us_x);\r
989                 ili93xx_write_register_word(ILI9325_VERTICAL_GRAM_ADDR_SET, us_y);\r
990         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
991                 /** There is no corresponding operation for ILI9341. */\r
992         }\r
993 }\r
994 \r
995 /**\r
996  * \brief Scroll up/down for the number of specified lines.\r
997  *\r
998  * \param ul_lines number of lines to scroll.\r
999  */\r
1000 void ili93xx_scroll(int32_t ul_lines)\r
1001 {\r
1002         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1003                 ili93xx_write_register_word(ILI9325_VERTICAL_SCROLL_CTRL, ul_lines);\r
1004         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1005                 uint8_t paratable[2];\r
1006 \r
1007                 paratable[0] = (ul_lines >> 8) & 0xFF;\r
1008                 paratable[1] = ul_lines & 0xFF;\r
1009                 ili93xx_write_register(ILI9341_CMD_VERT_SCROLL_START_ADDRESS,\r
1010                                 paratable, 2);\r
1011         }\r
1012 }\r
1013 \r
1014 /**\r
1015  * \brief Vertical Scroll area definition for ili9341.\r
1016  *\r
1017  * \param us_tfa the top fixed area (the No. of lines)\r
1018  * \param us_vsa the height of the vetical scrolling area\r
1019  * \param us_bfa the bottom fixed area (the No. of lines)\r
1020  */\r
1021 void ili93xx_vscroll_area_define(uint16_t us_tfa, uint16_t us_vsa,\r
1022                 uint16_t us_bfa)\r
1023 {\r
1024         if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1025                 uint8_t paratable[6];\r
1026 \r
1027                 paratable[0] = (us_tfa >> 8) & 0xFF;\r
1028                 paratable[1] = us_tfa & 0xFF;\r
1029                 paratable[2] = (us_vsa >> 8) & 0xFF;\r
1030                 paratable[3] = us_vsa & 0xFF;\r
1031                 paratable[4] = (us_bfa >> 8) & 0xFF;\r
1032                 paratable[5] = us_bfa & 0xFF;\r
1033                 ili93xx_write_register(ILI9341_CMD_VERT_SCROLL_DEFINITION,\r
1034                                 paratable, 6);\r
1035         }\r
1036 }\r
1037 \r
1038 /**\r
1039  * \brief Enable the scrolling feature.\r
1040  */\r
1041 void ili93xx_enable_scroll(void)\r
1042 {\r
1043         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1044                 ili93xx_write_register_word(ILI9325_BASE_IMG_DISP_CTRL,\r
1045                                 ILI9325_BASE_IMG_DISP_CTRL_REV |\r
1046                                 ILI9325_BASE_IMG_DISP_CTRL_VLE);\r
1047         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1048                 /** no operation needed for ILI9341*/\r
1049         }\r
1050 }\r
1051 \r
1052 /**\r
1053  * \brief Disable the scrolling feature.\r
1054  */\r
1055 void ili93xx_disable_scroll(void)\r
1056 {\r
1057         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1058                 ili93xx_write_register_word(ILI9325_BASE_IMG_DISP_CTRL,\r
1059                                 ILI9325_BASE_IMG_DISP_CTRL_REV);\r
1060         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1061                 ili93xx_display_off();\r
1062                 ili93xx_write_register(ILI9341_CMD_NORMAL_DISP_MODE_ON, NULL, 0);\r
1063                 ili93xx_display_on();\r
1064         }\r
1065 }\r
1066 \r
1067 /**\r
1068  * \brief Set display direction.\r
1069  *\r
1070  * \param e_dd 0: horizontal direction, 1: vertical direction\r
1071  * \param e_shd: horizontal increase(0) or decrease(1)\r
1072  * \param e_scd: vertical increase(1) or decrease(0)\r
1073  */\r
1074 void ili93xx_set_display_direction(enum ili93xx_display_direction e_dd,\r
1075                 enum ili93xx_shift_direction e_shd,\r
1076                 enum ili93xx_scan_direction e_scd)\r
1077 {\r
1078         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1079                 if (e_dd == LANDSCAPE) {\r
1080                         ili93xx_write_register_word(ILI9325_ENTRY_MODE,\r
1081                                         ILI9325_ENTRY_MODE_BGR | ILI9325_ENTRY_MODE_TRI |\r
1082                                         ILI9325_ENTRY_MODE_DFM | ILI9325_ENTRY_MODE_ID(0x00)|\r
1083                                         ILI9325_ENTRY_MODE_AM);\r
1084                         g_ul_lcd_x_length = ILI93XX_LCD_HEIGHT;\r
1085                         g_ul_lcd_y_length = ILI93XX_LCD_WIDTH;\r
1086                 } else {\r
1087                         ili93xx_write_register_word(ILI9325_ENTRY_MODE,\r
1088                                         ILI9325_ENTRY_MODE_BGR | ILI9325_ENTRY_MODE_TRI |\r
1089                                         ILI9325_ENTRY_MODE_DFM | ILI9325_ENTRY_MODE_ID(0x01));\r
1090                         g_ul_lcd_x_length = ILI93XX_LCD_WIDTH;\r
1091                         g_ul_lcd_y_length = ILI93XX_LCD_HEIGHT;\r
1092                 }\r
1093 \r
1094                 if (e_shd == H_INCREASE) {\r
1095                         ili93xx_write_register_word(ILI9325_DRIVER_OUTPUT_CTRL1, 0x0000);\r
1096                 } else {\r
1097                         ili93xx_write_register_word(ILI9325_DRIVER_OUTPUT_CTRL1,\r
1098                                         ILI9325_DRIVER_OUTPUT_CTRL1_SS);\r
1099                 }\r
1100 \r
1101                 if (e_scd == V_INCREASE) {\r
1102                         ili93xx_write_register_word(ILI9325_DRIVER_OUTPUT_CTRL2,\r
1103                                         ILI9325_DRIVER_OUTPUT_CTRL2_NL(0x27));\r
1104                 } else {\r
1105                         ili93xx_write_register_word(ILI9325_DRIVER_OUTPUT_CTRL2,\r
1106                                         ILI9325_DRIVER_OUTPUT_CTRL2_GS |\r
1107                                         ILI9325_DRIVER_OUTPUT_CTRL2_NL(0x27));\r
1108                 }\r
1109         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1110                 if (e_dd == LANDSCAPE) {\r
1111                         uint8_t paratable[1];\r
1112                         paratable[0] = ILI9341_CMD_MEMORY_ACCESS_CONTROL_MV |\r
1113                                         ILI9341_CMD_MEMORY_ACCESS_CONTROL_BGR;\r
1114                         ili93xx_write_register(\r
1115                                         ILI9341_CMD_MEMORY_ACCESS_CONTROL,\r
1116                                         paratable, 1);\r
1117                         g_ul_lcd_x_length = ILI93XX_LCD_HEIGHT;\r
1118                         g_ul_lcd_y_length = ILI93XX_LCD_WIDTH;\r
1119                 } else {\r
1120                         uint8_t paratable[1];\r
1121                         paratable[0] = ILI9341_CMD_MEMORY_ACCESS_CONTROL_BGR |\r
1122                                         ILI9341_CMD_MEMORY_ACCESS_CONTROL_MX;\r
1123                         ili93xx_write_register(\r
1124                                         ILI9341_CMD_MEMORY_ACCESS_CONTROL,\r
1125                                         paratable, 1);\r
1126                         g_ul_lcd_x_length = ILI93XX_LCD_WIDTH;\r
1127                         g_ul_lcd_y_length = ILI93XX_LCD_HEIGHT;\r
1128                 }\r
1129         }\r
1130 }\r
1131 \r
1132 /**\r
1133  * \brief Draw a pixel on LCD.\r
1134  *\r
1135  * \param ul_x X coordinate of pixel.\r
1136  * \param ul_y Y coordinate of pixel.\r
1137  *\r
1138  * \return 0 if succeeds, otherwise fails.\r
1139  */\r
1140 uint32_t ili93xx_draw_pixel(uint32_t ul_x, uint32_t ul_y)\r
1141 {\r
1142         if ((ul_x >= g_ul_lcd_x_length) || (ul_y >= g_ul_lcd_y_length)) {\r
1143                 return 1;\r
1144         }\r
1145 \r
1146         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1147                 /** Set cursor */\r
1148                 ili93xx_set_cursor_position(ul_x, ul_y);\r
1149                 /** Prepare to write in GRAM */\r
1150                 ili93xx_write_ram_prepare();\r
1151                 ili93xx_write_ram(*g_ul_pixel_cache);\r
1152         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1153                 ili93xx_set_window(ul_x, ul_y, 0, 0);\r
1154                 /** Prepare to write in GRAM */\r
1155                 ili93xx_write_ram_prepare();\r
1156                 ili93xx_write_ram(*g_ul_pixel_cache);\r
1157         }\r
1158 \r
1159         return 0;\r
1160 }\r
1161 \r
1162 /**\r
1163  * \brief Get a pixel from LCD.\r
1164  *\r
1165  * \param ul_x X coordinate of pixel.\r
1166  * \param ul_y Y coordinate of pixel.\r
1167  *\r
1168  * \return the pixel color.\r
1169  */\r
1170 ili93xx_color_t ili93xx_get_pixel(uint32_t ul_x, uint32_t ul_y)\r
1171 {\r
1172         Assert(ul_x <= g_ul_lcd_x_length);\r
1173         Assert(ul_y <= g_ul_lcd_y_length);\r
1174 \r
1175         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1176                 /** Set cursor */\r
1177                 ili93xx_set_cursor_position(ul_x, ul_y);\r
1178                 /** Prepare to write in GRAM */\r
1179                 ili93xx_read_ram_prepare();\r
1180                 return ili93xx_read_ram();\r
1181         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1182                 ili93xx_set_window(ul_x, ul_y, 0, 0);\r
1183                 /** Prepare to write in GRAM */\r
1184                 ili93xx_read_ram_prepare();\r
1185                 return ili93xx_read_ram();\r
1186         }\r
1187 \r
1188         return 0;\r
1189 }\r
1190 \r
1191 /**\r
1192  * \brief Draw a line on LCD, which is not horizontal or vertical.\r
1193  *\r
1194  * \param ul_x1 X coordinate of line start.\r
1195  * \param ul_y1 Y coordinate of line start.\r
1196  * \param ul_x2 X coordinate of line end.\r
1197  * \param ul_y2 Y coordinate of line endl.\r
1198  */\r
1199 static void ili93xx_draw_line_bresenham(uint32_t ul_x1, uint32_t ul_y1,\r
1200                 uint32_t ul_x2, uint32_t ul_y2)\r
1201 {\r
1202         int dx, dy;\r
1203         int i;\r
1204         int xinc, yinc, cumul;\r
1205         int x, y;\r
1206 \r
1207         x = ul_x1;\r
1208         y = ul_y1;\r
1209         dx = ul_x2 - ul_x1;\r
1210         dy = ul_y2 - ul_y1;\r
1211         xinc = (dx > 0) ? 1 : -1;\r
1212         yinc = (dy > 0) ? 1 : -1;\r
1213         dx = abs(ul_x2 - ul_x1);\r
1214         dy = abs(ul_y2 - ul_y1);\r
1215 \r
1216         ili93xx_draw_pixel(x, y);\r
1217 \r
1218         if (dx > dy) {\r
1219                 cumul = dx >> 1;\r
1220 \r
1221                 for (i = 1; i <= dx; i++) {\r
1222                         x += xinc;\r
1223                         cumul += dy;\r
1224 \r
1225                         if (cumul >= dx) {\r
1226                                 cumul -= dx;\r
1227                                 y += yinc;\r
1228                         }\r
1229 \r
1230                         ili93xx_draw_pixel(x, y);\r
1231                 }\r
1232         } else {\r
1233                 cumul = dy >> 1;\r
1234 \r
1235                 for (i = 1; i <= dy; i++) {\r
1236                         y += yinc;\r
1237                         cumul += dx;\r
1238 \r
1239                         if (cumul >= dy) {\r
1240                                 cumul -= dy;\r
1241                                 x += xinc;\r
1242                         }\r
1243 \r
1244                         ili93xx_draw_pixel(x, y);\r
1245                 }\r
1246         }\r
1247 }\r
1248 \r
1249 /**\r
1250  * \brief Draw a line on LCD.\r
1251  *\r
1252  * \param ul_x1 X coordinate of line start.\r
1253  * \param ul_y1 Y coordinate of line start.\r
1254  * \param ul_x2 X coordinate of line end.\r
1255  * \param ul_y2 Y coordinate of line end.\r
1256  */\r
1257 void ili93xx_draw_line(uint32_t ul_x1, uint32_t ul_y1,\r
1258                 uint32_t ul_x2, uint32_t ul_y2)\r
1259 {\r
1260         if ((ul_y1 == ul_y2) || (ul_x1 == ul_x2)) {\r
1261                 ili93xx_draw_filled_rectangle(ul_x1, ul_y1, ul_x2, ul_y2);\r
1262         } else {\r
1263                 ili93xx_draw_line_bresenham(ul_x1, ul_y1, ul_x2, ul_y2);\r
1264         }\r
1265 }\r
1266 \r
1267 /**\r
1268  * \brief Draw a rectangle on LCD.\r
1269  *\r
1270  * \param ul_x1 X coordinate of upper-left corner on LCD.\r
1271  * \param ul_y1 Y coordinate of upper-left corner on LCD.\r
1272  * \param ul_x2 X coordinate of lower-right corner on LCD.\r
1273  * \param ul_y2 Y coordinate of lower-right corner on LCD.\r
1274  */\r
1275 void ili93xx_draw_rectangle(uint32_t ul_x1, uint32_t ul_y1,\r
1276                 uint32_t ul_x2, uint32_t ul_y2)\r
1277 {\r
1278         ili93xx_check_box_coordinates(&ul_x1, &ul_y1, &ul_x2, &ul_y2);\r
1279 \r
1280         ili93xx_draw_filled_rectangle(ul_x1, ul_y1, ul_x2, ul_y1);\r
1281         ili93xx_draw_filled_rectangle(ul_x1, ul_y2, ul_x2, ul_y2);\r
1282 \r
1283         ili93xx_draw_filled_rectangle(ul_x1, ul_y1, ul_x1, ul_y2);\r
1284         ili93xx_draw_filled_rectangle(ul_x2, ul_y1, ul_x2, ul_y2);\r
1285 }\r
1286 \r
1287 /**\r
1288  * \brief Draw a filled rectangle on LCD.\r
1289  *\r
1290  * \param ul_x1 X coordinate of upper-left corner on LCD.\r
1291  * \param ul_y1 Y coordinate of upper-left corner on LCD.\r
1292  * \param ul_x2 X coordinate of lower-right corner on LCD.\r
1293  * \param ul_y2 Y coordinate of lower-right corner on LCD.\r
1294  */\r
1295 void ili93xx_draw_filled_rectangle(uint32_t ul_x1, uint32_t ul_y1,\r
1296                 uint32_t ul_x2, uint32_t ul_y2)\r
1297 {\r
1298         uint32_t size, blocks;\r
1299 \r
1300         /** Swap coordinates if necessary */\r
1301         ili93xx_check_box_coordinates(&ul_x1, &ul_y1, &ul_x2, &ul_y2);\r
1302 \r
1303         /** Determine the refresh window area */\r
1304         ili93xx_set_window(ul_x1, ul_y1, (ul_x2 - ul_x1) + 1,\r
1305                         (ul_y2 - ul_y1) + 1);\r
1306 \r
1307         /** Set cursor */\r
1308         ili93xx_set_cursor_position(ul_x1, ul_y1);\r
1309 \r
1310         /** Prepare to write in Graphic RAM */\r
1311         ili93xx_write_ram_prepare();\r
1312 \r
1313         size = (ul_x2 - ul_x1 + 1) * (ul_y2 - ul_y1 + 1);\r
1314 \r
1315         /** Send pixels blocks => one SPI IT / block */\r
1316         blocks = size / LCD_DATA_CACHE_SIZE;\r
1317         while (blocks--) {\r
1318                 ili93xx_write_ram_buffer(g_ul_pixel_cache,\r
1319                                                                 LCD_DATA_CACHE_SIZE);\r
1320         }\r
1321 \r
1322         /** Send remaining pixels */\r
1323         ili93xx_write_ram_buffer(g_ul_pixel_cache,\r
1324                                         size % LCD_DATA_CACHE_SIZE);\r
1325 \r
1326         /** Reset the refresh window area */\r
1327         ili93xx_set_window(0, 0, g_ul_lcd_x_length, g_ul_lcd_y_length);\r
1328 }\r
1329 \r
1330 /**\r
1331  * \brief Draw a circle on LCD.\r
1332  *\r
1333  * \param ul_x X coordinate of circle center.\r
1334  * \param ul_y Y coordinate of circle center.\r
1335  * \param ul_r circle radius.\r
1336  *\r
1337  * \return 0 if succeeds, otherwise fails.\r
1338  */\r
1339 uint32_t ili93xx_draw_circle(uint32_t ul_x, uint32_t ul_y, uint32_t ul_r)\r
1340 {\r
1341         int32_t d;\r
1342         uint32_t curX;\r
1343         uint32_t curY;\r
1344 \r
1345         if (ul_r == 0) {\r
1346                 return 1;\r
1347         }\r
1348 \r
1349         d = 3 - (ul_r << 1);\r
1350         curX = 0;\r
1351         curY = ul_r;\r
1352 \r
1353         while (curX <= curY) {\r
1354                 ili93xx_draw_pixel(ul_x + curX, ul_y + curY);\r
1355                 ili93xx_draw_pixel(ul_x + curX, ul_y - curY);\r
1356                 ili93xx_draw_pixel(ul_x - curX, ul_y + curY);\r
1357                 ili93xx_draw_pixel(ul_x - curX, ul_y - curY);\r
1358                 ili93xx_draw_pixel(ul_x + curY, ul_y + curX);\r
1359                 ili93xx_draw_pixel(ul_x + curY, ul_y - curX);\r
1360                 ili93xx_draw_pixel(ul_x - curY, ul_y + curX);\r
1361                 ili93xx_draw_pixel(ul_x - curY, ul_y - curX);\r
1362 \r
1363                 if (d < 0) {\r
1364                         d += (curX << 2) + 6;\r
1365                 } else {\r
1366                         d += ((curX - curY) << 2) + 10;\r
1367                         curY--;\r
1368                 }\r
1369 \r
1370                 curX++;\r
1371         }\r
1372 \r
1373         return 0;\r
1374 }\r
1375 \r
1376 /**\r
1377  * \brief Draw a filled circle on LCD.\r
1378  *\r
1379  * \param ul_x X coordinate of circle center.\r
1380  * \param ul_y Y coordinate of circle center.\r
1381  * \param ul_r circle radius.\r
1382  *\r
1383  * \return 0 if succeeds, otherwise fails.\r
1384  */\r
1385 uint32_t ili93xx_draw_filled_circle(uint32_t ul_x, uint32_t ul_y, uint32_t ul_r)\r
1386 {\r
1387         signed int d;       /* Decision Variable */\r
1388         uint32_t dwCurX;    /* Current X Value */\r
1389         uint32_t dwCurY;    /* Current Y Value */\r
1390         uint32_t dwXmin, dwYmin;\r
1391 \r
1392         if (ul_r == 0) {\r
1393                 return 1;\r
1394         }\r
1395 \r
1396         d = 3 - (ul_r << 1);\r
1397         dwCurX = 0;\r
1398         dwCurY = ul_r;\r
1399 \r
1400         while (dwCurX <= dwCurY) {\r
1401                 dwXmin = (dwCurX > ul_x) ? 0 : ul_x - dwCurX;\r
1402                 dwYmin = (dwCurY > ul_y) ? 0 : ul_y - dwCurY;\r
1403                 ili93xx_draw_filled_rectangle(dwXmin, dwYmin, ul_x + dwCurX,\r
1404                                 dwYmin);\r
1405                 ili93xx_draw_filled_rectangle(dwXmin, ul_y + dwCurY,\r
1406                                 ul_x + dwCurX, ul_y + dwCurY);\r
1407                 dwXmin = (dwCurY > ul_x) ? 0 : ul_x - dwCurY;\r
1408                 dwYmin = (dwCurX > ul_y) ? 0 : ul_y - dwCurX;\r
1409                 ili93xx_draw_filled_rectangle(dwXmin, dwYmin, ul_x + dwCurY,\r
1410                                 dwYmin);\r
1411                 ili93xx_draw_filled_rectangle(dwXmin, ul_y + dwCurX,\r
1412                                 ul_x + dwCurY, ul_y + dwCurX);\r
1413 \r
1414                 if (d < 0) {\r
1415                         d += (dwCurX << 2) + 6;\r
1416                 } else {\r
1417                         d += ((dwCurX - dwCurY) << 2) + 10;\r
1418                         dwCurY--;\r
1419                 }\r
1420 \r
1421                 dwCurX++;\r
1422         }\r
1423 \r
1424         return 0;\r
1425 }\r
1426 \r
1427 /**\r
1428  * \brief Draw an ASCII character on LCD.\r
1429  *\r
1430  * \param ul_x X coordinate of character upper-left corner.\r
1431  * \param ul_y Y coordinate of character upper-left corner.\r
1432  * \param uc_c character to print.\r
1433  */\r
1434 static void ili93xx_draw_char(uint32_t ul_x, uint32_t ul_y, uint8_t uc_c)\r
1435 {\r
1436         uint32_t row, col;\r
1437         uint32_t offset, offset0, offset1;\r
1438 \r
1439         /**\r
1440          * Compute offset according of the specified ASCII character\r
1441          *  Note: the first 32 characters of the ASCII table are not handled\r
1442          */\r
1443         offset = ((uint32_t)uc_c - 0x20) * 20;\r
1444 \r
1445         for (col = 0; col < 10; col++) {\r
1446                 /** Compute the first and second byte offset of a column */\r
1447                 offset0 = offset + col * 2;\r
1448                 offset1 = offset0 + 1;\r
1449 \r
1450                 /**\r
1451                  * Draw pixel on screen depending on the corresponding bit value\r
1452                  * from the charset\r
1453                  */\r
1454                 for (row = 0; row < 8; row++) {\r
1455                         if ((p_uc_charset10x14[offset0] >> (7 - row)) & 0x1) {\r
1456                                 ili93xx_draw_pixel(ul_x + col, ul_y + row);\r
1457                         }\r
1458                 }\r
1459 \r
1460                 for (row = 0; row < 6; row++) {\r
1461                         if ((p_uc_charset10x14[offset1] >> (7 - row)) & 0x1) {\r
1462                                 ili93xx_draw_pixel(ul_x + col, ul_y + row + 8);\r
1463                         }\r
1464                 }\r
1465         }\r
1466 }\r
1467 \r
1468 /**\r
1469  * \brief Draw a string on LCD.\r
1470  *\r
1471  * \param ul_x X coordinate of string top-left corner.\r
1472  * \param ul_y Y coordinate of string top-left corner.\r
1473  * \param p_str String to display.\r
1474  */\r
1475 void ili93xx_draw_string(uint32_t ul_x, uint32_t ul_y, const uint8_t *p_str)\r
1476 {\r
1477         uint32_t xorg = ul_x;\r
1478 \r
1479         while (*p_str != 0) {\r
1480                 /** If newline, jump to the next line (font height + 2) */\r
1481                 if (*p_str == '\n') {\r
1482                         ul_y += gfont.height + 2;\r
1483                         ul_x = xorg;\r
1484                 } else {\r
1485                         /**\r
1486                          * Draw the character and place cursor right after (font\r
1487                          * width + 2)\r
1488                          */\r
1489                         ili93xx_draw_char(ul_x, ul_y, *p_str);\r
1490                         ul_x += gfont.width + 2;\r
1491                 }\r
1492 \r
1493                 p_str++;\r
1494         }\r
1495 }\r
1496 \r
1497 /**\r
1498  * \brief Draw a pixmap on LCD.\r
1499  *\r
1500  * \param ul_x X coordinate of upper-left corner on LCD.\r
1501  * \param ul_y Y coordinate of upper-left corner on LCD.\r
1502  * \param ul_width width of the picture.\r
1503  * \param ul_height height of the picture.\r
1504  * \param p_ul_pixmap pixmap of the image.\r
1505  */\r
1506 void ili93xx_draw_pixmap(uint32_t ul_x, uint32_t ul_y, uint32_t ul_width,\r
1507                 uint32_t ul_height, const ili93xx_color_t *p_ul_pixmap)\r
1508 {\r
1509         uint32_t size;\r
1510         uint32_t dwX1, dwY1, dwX2, dwY2;\r
1511         dwX1 = ul_x;\r
1512         dwY1 = ul_y;\r
1513         dwX2 = ul_x + ul_width;\r
1514         dwY2 = ul_y + ul_height;\r
1515 \r
1516         /** Swap coordinates if necessary */\r
1517         ili93xx_check_box_coordinates(&dwX1, &dwY1, &dwX2, &dwY2);\r
1518 \r
1519         /** Determine the refresh window area */\r
1520         ili93xx_set_window(dwX1, dwY1, (dwX2 - dwX1 + 1), (dwY2 - dwY1 + 1));\r
1521 \r
1522         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1523                 /** Set cursor */\r
1524                 ili93xx_set_cursor_position(dwX1, dwY1);\r
1525                 /** Prepare to write in GRAM */\r
1526                 ili93xx_write_ram_prepare();\r
1527 \r
1528                 size = (dwX2 - dwX1) * (dwY2 - dwY1);\r
1529 \r
1530                 ili93xx_write_ram_buffer(p_ul_pixmap, size);\r
1531 \r
1532                 /** Reset the refresh window area */\r
1533                 ili93xx_set_window(0, 0, g_ul_lcd_x_length, g_ul_lcd_y_length);\r
1534         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1535                 /** Prepare to write in GRAM */\r
1536                 ili93xx_write_ram_prepare();\r
1537 \r
1538                 size = (dwX2 - dwX1) * (dwY2 - dwY1);\r
1539 \r
1540                 ili93xx_write_ram_buffer(p_ul_pixmap, size);\r
1541 \r
1542                 /** Reset the refresh window area */\r
1543                 ili93xx_set_window(0, 0, g_ul_lcd_x_length, g_ul_lcd_y_length);\r
1544         }\r
1545 }\r
1546 \r
1547 /**\r
1548  * \internal\r
1549  * \brief Helper function to send the drawing limits (boundaries) to the display\r
1550  *\r
1551  * This function is used to send the currently set upper-left and lower-right\r
1552  * drawing limits to the display, as set through the various limit functions.\r
1553  *\r
1554  * \param send_end_limits  True to also send the lower-right drawing limits\r
1555  */\r
1556 static inline void ili93xx_send_draw_limits(const bool send_end_limits)\r
1557 {\r
1558         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1559                 /** Set Horizontal Address Start Position */\r
1560                 ili93xx_write_register_word(ILI9325_HORIZONTAL_ADDR_START,\r
1561                                 (uint16_t)limit_start_x);\r
1562 \r
1563                 if (send_end_limits) {\r
1564                         /** Set Horizontal Address End Position */\r
1565                         ili93xx_write_register_word(ILI9325_HORIZONTAL_ADDR_END,\r
1566                                         (uint16_t)(limit_end_x));\r
1567                 }\r
1568 \r
1569                 /** Set Vertical Address Start Position */\r
1570                 ili93xx_write_register_word(ILI9325_VERTICAL_ADDR_START,\r
1571                                 (uint16_t)limit_start_y);\r
1572                 if (send_end_limits) {\r
1573                         /** Set Vertical Address End Position */\r
1574                         ili93xx_write_register_word(ILI9325_VERTICAL_ADDR_END,\r
1575                                         (uint16_t)(limit_end_y));\r
1576                 }\r
1577 \r
1578                 /** GRAM Horizontal/Vertical Address Set (R20h, R21h) */\r
1579                 ili93xx_write_register_word(ILI9325_HORIZONTAL_GRAM_ADDR_SET,\r
1580                                 limit_start_x);\r
1581                 ili93xx_write_register_word(ILI9325_VERTICAL_GRAM_ADDR_SET,\r
1582                                 limit_start_y);\r
1583 \r
1584         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1585                 /** Set Horizontal Address Start Position */\r
1586                 ili93xx_write_register_word(ILI9341_CMD_COLUMN_ADDRESS_SET,\r
1587                                 (uint16_t)limit_start_x);\r
1588 \r
1589                 if (send_end_limits) {\r
1590                         /** Set Horizontal Address End Position */\r
1591                         ili93xx_write_register_word(\r
1592                                         ILI9341_CMD_COLUMN_ADDRESS_SET,\r
1593                                         (uint16_t)(limit_end_x));\r
1594                 }\r
1595 \r
1596                 ili93xx_write_register(0, NULL, 0);\r
1597 \r
1598                 /** Set Vertical Address Start Position */\r
1599                 ili93xx_write_register_word(ILI9341_CMD_PAGE_ADDRESS_SET,\r
1600                                 (uint16_t)limit_start_y);\r
1601                 if (send_end_limits) {\r
1602                         /** Set Vertical Address End Position */\r
1603                         ili93xx_write_register_word(\r
1604                                         ILI9341_CMD_PAGE_ADDRESS_SET,\r
1605                                         (uint16_t)(limit_end_y));\r
1606                 }\r
1607 \r
1608                 ili93xx_write_register(0, NULL, 0);\r
1609         }\r
1610 }\r
1611 \r
1612 /**\r
1613  * \brief Set the display top left drawing limit\r
1614  *\r
1615  * Use this function to set the top left limit of the drawing limit box.\r
1616  *\r
1617  * \param x The x coordinate of the top left corner\r
1618  * \param y The y coordinate of the top left corner\r
1619  */\r
1620 void ili93xx_set_top_left_limit(ili93xx_coord_t x, ili93xx_coord_t y)\r
1621 {\r
1622         limit_start_x = x;\r
1623         limit_start_y = y;\r
1624 \r
1625         ili93xx_send_draw_limits(false);\r
1626 }\r
1627 \r
1628 /**\r
1629  * \brief Set the display bottom right drawing limit\r
1630  *\r
1631  * Use this function to set the bottom right corner of the drawing limit box.\r
1632  *\r
1633  * \param x The x coordinate of the bottom right corner\r
1634  * \param y The y coordinate of the bottom right corner\r
1635  */\r
1636 void ili93xx_set_bottom_right_limit(ili93xx_coord_t x, ili93xx_coord_t y)\r
1637 {\r
1638         limit_end_x = x;\r
1639         limit_end_y = y;\r
1640 \r
1641         ili93xx_send_draw_limits(true);\r
1642 }\r
1643 \r
1644 /**\r
1645  * \brief Set the full display drawing limits\r
1646  *\r
1647  * Use this function to set the full drawing limit box.\r
1648  *\r
1649  * \param start_x The x coordinate of the top left corner\r
1650  * \param start_y The y coordinate of the top left corner\r
1651  * \param end_x The x coordinate of the bottom right corner\r
1652  * \param end_y The y coordinate of the bottom right corner\r
1653  */\r
1654 void ili93xx_set_limits(ili93xx_coord_t start_x, ili93xx_coord_t start_y,\r
1655                 ili93xx_coord_t end_x, ili93xx_coord_t end_y)\r
1656 {\r
1657         limit_start_x = start_x;\r
1658         limit_start_y = start_y;\r
1659         limit_end_x = end_x;\r
1660         limit_end_y = end_y;\r
1661 \r
1662         ili93xx_send_draw_limits(true);\r
1663 }\r
1664 \r
1665 /**\r
1666  * \brief Read a single color from the graphical memory\r
1667  *\r
1668  * Use this function to read a color from the graphical memory of the\r
1669  * controller.\r
1670  *\r
1671  * \retval ili93xx_color_t The read color pixel\r
1672  */\r
1673 ili93xx_color_t ili93xx_read_gram(void)\r
1674 {\r
1675         uint8_t value[3];\r
1676         ili93xx_color_t color;\r
1677 \r
1678         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1679                 LCD_IR(0);\r
1680                 /** Write Data to GRAM (R22h) */\r
1681                 LCD_IR(ILI9325_GRAM_DATA_REG);\r
1682                 /** two dummy read */\r
1683                 value[0] = LCD_RD();\r
1684                 value[1] = LCD_RD();\r
1685                 /** data upper byte */\r
1686                 value[0] = LCD_RD();\r
1687                 /** data lower byte */\r
1688                 value[1] = LCD_RD();\r
1689 \r
1690                 /** Convert RGB565 to RGB888 */\r
1691                 /** For BGR format */\r
1692                 color = ((value[0] & 0xF8)) |\r
1693                                 ((value[0] & 0x07) << 13) | ((value[1] & 0xE0) << 5) |\r
1694                                 ((value[1] & 0x1F) << 19);\r
1695         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1696                 LCD_IR(0);\r
1697                 /** Write Data to GRAM (R2Eh) */\r
1698                 LCD_IR(ILI9341_CMD_MEMORY_READ);\r
1699                 /** dummy read */\r
1700                 value[0] = LCD_RD();\r
1701                 /** the highest byte - R byte*/\r
1702                 value[0] = LCD_RD();\r
1703                 /** the middle byte - G byte*/\r
1704                 value[1] = LCD_RD();\r
1705                 /** the lowest byte - B byte*/\r
1706                 value[2] = LCD_RD();\r
1707                 /** combine R, G, B byte to a color value */\r
1708                 color = (value[0] << 16) | (value[1] << 8) | value[2];\r
1709         }\r
1710         return color;\r
1711 }\r
1712 \r
1713 /**\r
1714  * \brief Write the graphical memory with a single color pixel\r
1715  *\r
1716  * Use this function to write a single color pixel to the controller memory.\r
1717  *\r
1718  * \param color The color pixel to write to the screen\r
1719  */\r
1720 void ili93xx_write_gram(ili93xx_color_t color)\r
1721 {\r
1722         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1723                 LCD_IR(0);\r
1724                 /** Write Data to GRAM (R22h) */\r
1725                 LCD_IR(ILI9325_GRAM_DATA_REG);\r
1726         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1727                 /** memory write command (R2Ch)*/\r
1728                 LCD_IR(ILI9341_CMD_MEMORY_WRITE);\r
1729                 LCD_IR(0);\r
1730                 LCD_IR(ILI9341_CMD_WRITE_MEMORY_CONTINUE);\r
1731         }\r
1732         LCD_WD((color >> 16) & 0xFF);\r
1733         LCD_WD((color >> 8) & 0xFF);\r
1734         LCD_WD(color & 0xFF);\r
1735 }\r
1736 \r
1737 /**\r
1738  * \brief Copy pixels from SRAM to the screen\r
1739  *\r
1740  * Used to copy a large quantitative of data to the screen in one go.\r
1741  *\r
1742  * \param pixels Pointer to the pixel data\r
1743  * \param count Number of pixels to copy to the screen\r
1744  */\r
1745 void ili93xx_copy_pixels_to_screen(const ili93xx_color_t *pixels,\r
1746                 uint32_t count)\r
1747 {\r
1748         /** Sanity check to make sure that the pixel count is not zero */\r
1749         Assert(count > 0);\r
1750 \r
1751         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1752                 LCD_IR(0);\r
1753                 LCD_IR(ILI9325_GRAM_DATA_REG);\r
1754         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1755                 LCD_IR(ILI9341_CMD_MEMORY_WRITE);\r
1756                 LCD_IR(0);\r
1757                 LCD_IR(ILI9341_CMD_WRITE_MEMORY_CONTINUE);\r
1758         }\r
1759 \r
1760         while (count--) {\r
1761                 LCD_WD((*pixels >> 16) & 0xFF);\r
1762                 LCD_WD((*pixels >> 8) & 0xFF);\r
1763                 LCD_WD(*pixels & 0xFF);\r
1764                 pixels++;\r
1765         }\r
1766 }\r
1767 \r
1768 /**\r
1769  * \brief Copy pixels from SRAM to the screen\r
1770  *\r
1771  * Used to copy a large quantitative of data to the screen in one go.\r
1772  *\r
1773  * \param pixels Pointer to the pixel data\r
1774  * \param count Number of pixels to copy to the screen\r
1775  */\r
1776 void ili93xx_copy_raw_pixel_24bits_to_screen(const uint8_t *raw_pixels,\r
1777                 uint32_t count)\r
1778 {\r
1779         ili93xx_color_t pixels;\r
1780 \r
1781         /** Sanity check to make sure that the pixel count is not zero */\r
1782         Assert(count > 0);\r
1783 \r
1784         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1785                 LCD_IR(0);\r
1786                 LCD_IR(ILI9325_GRAM_DATA_REG);\r
1787         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1788                 LCD_IR(ILI9341_CMD_MEMORY_WRITE);\r
1789                 LCD_IR(0);\r
1790                 LCD_IR(ILI9341_CMD_WRITE_MEMORY_CONTINUE);\r
1791         }\r
1792         while (count--) {\r
1793                 pixels = (*raw_pixels)  |\r
1794                                 (*(raw_pixels +1)) << 8 |\r
1795                                 (*(raw_pixels + 2)) << 16;\r
1796                 LCD_WD((pixels >> 16) & 0xFF);\r
1797                 LCD_WD((pixels >> 8) & 0xFF);\r
1798                 LCD_WD(pixels & 0xFF);\r
1799                 raw_pixels += 3;\r
1800         }\r
1801 }\r
1802 \r
1803 /**\r
1804  * \brief Set a given number of pixels to the same color\r
1805  *\r
1806  * Use this function to write a certain number of pixels to the same color\r
1807  * within a set limit.\r
1808  *\r
1809  * \param color The color to write to the display\r
1810  * \param count The number of pixels to write with this color\r
1811  */\r
1812 void ili93xx_duplicate_pixel(const ili93xx_color_t color, uint32_t count)\r
1813 {\r
1814         /** Sanity check to make sure that the pixel count is not zero */\r
1815         Assert(count > 0);\r
1816 \r
1817         if (g_uc_device_type == DEVICE_TYPE_ILI9325) {\r
1818                 /** Write Data to GRAM (R22h) */\r
1819                 LCD_IR(0);\r
1820                 LCD_IR(ILI9325_GRAM_DATA_REG);\r
1821         } else if (g_uc_device_type == DEVICE_TYPE_ILI9341) {\r
1822                 LCD_IR(ILI9341_CMD_MEMORY_WRITE);\r
1823                 LCD_IR(0);\r
1824                 LCD_IR(ILI9341_CMD_WRITE_MEMORY_CONTINUE);\r
1825         }\r
1826 \r
1827         while (count--) {\r
1828                 LCD_WD((color >> 16) & 0xFF);\r
1829                 LCD_WD((color >> 8) & 0xFF);\r
1830                 LCD_WD(color & 0xFF);\r
1831         }\r
1832 }\r
1833 \r
1834 /**\r
1835  * \brief Copy pixels from the screen to a pixel buffer\r
1836  *\r
1837  * Use this function to copy pixels from the display to an internal SRAM buffer.\r
1838  *\r
1839  * \param pixels Pointer to the pixel buffer to read to\r
1840  * \param count Number of pixels to read\r
1841  */\r
1842 void ili93xx_copy_pixels_from_screen(ili93xx_color_t *pixels, uint32_t count)\r
1843 {\r
1844         /** Remove warnings */\r
1845         UNUSED(pixels);\r
1846         UNUSED(count);\r
1847 }\r
1848 \r
1849 /**\r
1850  * \}\r
1851  */\r