Landtiger LPC1768 C BigLib 1
A self made, custom C library for the LandTiger board.
 
Loading...
Searching...
No Matches
glcd_lowlevel.c
Go to the documentation of this file.
1#include "glcd_lowlevel.h"
2#include "glcd_types.h"
3
4#include <LPC17xx.h>
5
6// PRIVATE DEFINES & TYPES
7
17#define PIN_EN (1 << 19)
18#define PIN_LE (1 << 20)
19#define PIN_DIR (1 << 21)
20#define PIN_CS (1 << 22)
21#define PIN_RS (1 << 23)
22#define PIN_WR (1 << 24)
23#define PIN_RD (1 << 25)
24
25#define LCD_EN(x) ((x) ? (LPC_GPIO0->FIOSET = PIN_EN) : (LPC_GPIO0->FIOCLR = PIN_EN))
26#define LCD_LE(x) ((x) ? (LPC_GPIO0->FIOSET = PIN_LE) : (LPC_GPIO0->FIOCLR = PIN_LE))
27#define LCD_DIR(x) ((x) ? (LPC_GPIO0->FIOSET = PIN_DIR) : (LPC_GPIO0->FIOCLR = PIN_DIR))
28#define LCD_CS(x) ((x) ? (LPC_GPIO0->FIOSET = PIN_CS) : (LPC_GPIO0->FIOCLR = PIN_CS))
29#define LCD_RS(x) ((x) ? (LPC_GPIO0->FIOSET = PIN_RS) : (LPC_GPIO0->FIOCLR = PIN_RS))
30#define LCD_WR(x) ((x) ? (LPC_GPIO0->FIOSET = PIN_WR) : (LPC_GPIO0->FIOCLR = PIN_WR))
31#define LCD_RD(x) ((x) ? (LPC_GPIO0->FIOSET = PIN_RD) : (LPC_GPIO0->FIOCLR = PIN_RD))
32
33#ifdef GLCD_REQUIRES_DELAY
34#define DELAY_COUNT(count) for (u16 i = count; i > 0; i--)
35
36#define DELAY_MS(ms) \
37 for (u16 i = 0; i < ms; i++) \
38 for (u16 j = 0; j < 1141; j++)
39#else
40#define DELAY_COUNT(count)
41#define DELAY_MS(ms)
42#endif
43
44// PRIVATE TYPES
45
48{
49 ILI9320, // 0x9320
50 ILI9325, // 0x9325
51 ILI9328, // 0x9328
52 ILI9331, // 0x9331
53 SSD1298, // 0x8999
54 SSD1289, // 0x8989
55 ST7781, // 0x7783
56 LGDP4531, // 0x4531
57 SPFD5408B, // 0x5408
58 R61505U, // 0x1505 0x0505
59 HX8346A, // 0x0046
60 HX8347D, // 0x0047
61 HX8347A, // 0x0047
62 LGDP4535, // 0x4535
63 SSD2119 // 3.5 LCD 0x9919
64};
65
66// VARIABLES
67
70
73
76
77// PRIVATE FUNCTIONS
78
84// Low bits and high bits need to be sent separately, with specific timings.
85_PRIVATE inline void send(u16 halfw)
86{
87 LPC_GPIO2->FIODIR |= 0xFF; /* P2.0...P2.7 Output */
88 LCD_DIR(1); /* Interface A->B */
89 LCD_EN(0); /* Enable 2A->2B */
90 LPC_GPIO2->FIOPIN = halfw; /* Write D0..D7 */
91 LCD_LE(1);
92 LCD_LE(0); /* latch D0..D7 */
93 LPC_GPIO2->FIOPIN = halfw >> 8; /* Write D8..D15 */
94}
95
98_PRIVATE inline u16 recv(void)
99{
100 u16 value;
101
102 LPC_GPIO2->FIODIR &= ~(0xFF); /* P2.0...P2.7 Input */
103 LCD_DIR(0); /* Interface B->A */
104 LCD_EN(0); /* Enable 2B->2A */
105 DELAY_COUNT(30); /* delay some times */
106 value = LPC_GPIO2->FIOPIN0; /* Read D8..D15 */
107 LCD_EN(1); /* Enable 1B->1A */
108 DELAY_COUNT(30); /* delay some times */
109 value = (value << 8) | LPC_GPIO2->FIOPIN0; /* Read D0..D7 */
110 LCD_DIR(1);
111
112 return value;
113}
114
119{
120 LCD_CS(0);
121 LCD_RS(0);
122 LCD_RD(1);
123 send(index);
124 DELAY_COUNT(22);
125 LCD_WR(0);
126 DELAY_COUNT(1);
127 LCD_WR(1);
128 LCD_CS(1);
129}
130
138{
139 LCD_CS(0);
140 LCD_RS(1);
141 send(data);
142 LCD_WR(0);
143 DELAY_COUNT(1);
144 LCD_WR(1);
145 LCD_CS(1);
146}
147
155{
156 LCD_CS(0);
157 LCD_RS(1);
158 LCD_WR(1);
159 LCD_RD(0);
160 const u16 value = recv();
161 LCD_RD(1);
162 LCD_CS(1);
163 return value;
164}
165
169_PRIVATE void write_to(u16 reg, u16 data)
170{
172 do_write(data);
173}
174
179{
181 return do_read();
182}
183
189{
191 {
192 // Swap X and Y if orientation is 90 or 270 degrees
193 u16 tmp = x;
194 x = y;
195 y = (LCDMaxX - 1) - tmp;
196 }
197
198 switch (s_model_code)
199 {
200 default: /* 0x9320 0x9325 0x9328 0x9331 0x5408 0x1505 0x0505 0x7783 0x4531 0x4535 */
201 write_to(0x0020, x); // 0x20 = GRAM Address Set (Horizontal Address)
202 write_to(0x0021, y); // 0x21 = GRAM Address Set (Vertical Address)
203 break;
204
205 case SSD1298: /* 0x8999 */
206 case SSD1289: /* 0x8989 */
207 write_to(0x004e, x);
208 write_to(0x004f, y);
209 break;
210
211 case HX8346A: /* 0x0046 */
212 case HX8347A: /* 0x0047 */
213 case HX8347D: /* 0x0047 */
214 write_to(0x02, x >> 8);
215 write_to(0x03, x);
216
217 write_to(0x06, y >> 8);
218 write_to(0x07, y);
219 break;
220
221 case SSD2119: /* 3.5 LCD 0x9919 */
222 break;
223 }
224}
225
226// PUBLIC FUNCTIONS
227
228void __LCD_LL_Init(u16 orientation)
229{
230 // Setting PINS as 00 (GPIO) in PINSEL0 (bit 6 to 25) for P0.19 to P0.25
231 // 0000 0011 1111 1111 1111 1111 1100 0000
232 LPC_PINCON->PINSEL1 &= ~(0x03FFFFC0);
233
234 // Setting 00 in PINSEL4 (bit 0 to 15) for P2.0 to P2.7
235 // 0000 0000 0000 0000 1111 1111 1111 1111
236 LPC_PINCON->PINSEL4 &= ~(0x0000FFFF);
237
238 /* EN = P0.19 , LE = P0.20 , DIR = P0.21 , CS = P0.22 , RS = P0.23 , RS = P0.23 */
239 /* RS = P0.23 , WR = P0.24 , RD = P0.25 , DB[0.7] = P2.0...P2.7 , DB[8.15]= P2.0...P2.7 */
240 LPC_GPIO0->FIODIR |= 0x03f80000;
241 LPC_GPIO0->FIOSET = 0x03f80000;
242
243 s_orientation = orientation;
244 if (orientation == LCD_ORIENT_VER || orientation == LCD_ORIENT_VER_INV)
245 {
246 LCDMaxX = 240;
247 LCDMaxY = 320;
248 }
249 else
250 {
251 LCDMaxX = 320;
252 LCDMaxY = 240;
253 }
254
255 DELAY_MS(100);
256 const u16 code = read_from(0x0000);
257 if (code == 0x9325 || code == 0x9328)
258 {
260 write_to(0x00e7, 0x0010); // Test Register
261 write_to(0x0000, 0x0001); // Starts internal OSC
262 write_to(0x0001, 0x0100); // Output driver control
263
264 write_to(0x0002, 0x0700); // LCD Driver Waveform Control
265 write_to(0x0003, (1 << 12) | (1 << 5) | (1 << 4) | (0 << 3)); // Entry mode
266 write_to(0x0004, 0x0000); // Resizing Function
267 write_to(0x0008, 0x0207); // Back and Front porch periods
268 write_to(0x0009, 0x0000); // Non-Display Area refresh cycle
269 write_to(0x000a, 0x0000); // Frame cycle
270 write_to(0x000c, 0x0001);
271 write_to(0x000d, 0x0000);
272 write_to(0x000f, 0x0000);
273
274 // Power Control
275 write_to(0x0010, 0x0000);
276 write_to(0x0011, 0x0007);
277 write_to(0x0012, 0x0000);
278 write_to(0x0013, 0x0000);
279 DELAY_MS(50);
280 write_to(0x0010, 0x1590);
281 write_to(0x0011, 0x0227);
282 DELAY_MS(50);
283 write_to(0x0012, 0x009c);
284 DELAY_MS(50);
285 write_to(0x0013, 0x1900);
286 write_to(0x0029, 0x0023);
287
288 write_to(0x002b, 0x000e); // Frate rate & Color control
289 DELAY_MS(50);
290 write_to(0x0020, 0x0000); // GRAM horizontal Address
291 write_to(0x0021, 0x0000); // GRAM Vertical Address
292
293 DELAY_MS(50);
294 write_to(0x0030, 0x0007);
295 write_to(0x0031, 0x0707);
296 write_to(0x0032, 0x0006);
297 write_to(0x0035, 0x0704);
298 write_to(0x0036, 0x1f04);
299 write_to(0x0037, 0x0004);
300 write_to(0x0038, 0x0000);
301 write_to(0x0039, 0x0706);
302 write_to(0x003c, 0x0701);
303 write_to(0x003d, 0x000f);
304 DELAY_MS(50);
305 write_to(0x0050, 0x0000);
306 write_to(0x0051, 0x00ef);
307 write_to(0x0052, 0x0000);
308 write_to(0x0053, 0x013f);
309 write_to(0x0060, 0xa700);
310 write_to(0x0061, 0x0001);
311 write_to(0x006a, 0x0000);
312 write_to(0x0080, 0x0000);
313 write_to(0x0081, 0x0000);
314 write_to(0x0082, 0x0000);
315 write_to(0x0083, 0x0000);
316 write_to(0x0084, 0x0000);
317 write_to(0x0085, 0x0000);
318 write_to(0x0090, 0x0010);
319 write_to(0x0092, 0x0000);
320 write_to(0x0093, 0x0003);
321 write_to(0x0095, 0x0110);
322 write_to(0x0097, 0x0000);
323 write_to(0x0098, 0x0000);
324
325 // Display On Sequence
326 write_to(0x0007, 0x0133);
327 write_to(0x0020, 0x0000);
328 write_to(0x0021, 0x0000);
329 }
330
331 DELAY_MS(50);
332}
333
335{
336 u16 dummy;
337
338 set_gram_cursor(x, y);
339 init_rw_operation_at(0x0022); // Write GRAM
340
341 switch (s_model_code)
342 {
343 case ST7781:
344 case LGDP4531:
345 case LGDP4535:
346 case SSD1289:
347 case SSD1298:
348 dummy = do_read(); /* Empty read */
349 dummy = do_read();
350 return dummy;
351 case HX8347A:
352 case HX8347D: {
353 dummy = do_read(); /* Empty read */
354
355 const u8 red = do_read() >> 3;
356 const u8 green = do_read() >> 2;
357 const u8 blue = do_read() >> 3;
358 dummy = (u16)((red << 11) | (green << 5) | blue);
359 return dummy;
360 }
361 default: /* 0x9320 0x9325 0x9328 0x9331 0x5408 0x1505 0x0505 0x9919 */
362 dummy = do_read(); /* Empty read */
363 dummy = do_read();
364 return dummy;
365 }
366}
367
369{
370 set_gram_cursor(x, y);
371 write_to(0x0022, rgb565 & 0xFFFF);
372}
373
375{
376 // Sets the GRAM cursor to the top-left corner of the display
378 {
379 write_to(0x02, 0x00);
380 write_to(0x03, 0x00);
381 write_to(0x04, 0x00);
382 write_to(0x05, 0xEF);
383 write_to(0x06, 0x00);
384 write_to(0x07, 0x00);
385 write_to(0x08, 0x01);
386 write_to(0x09, 0x3F);
387 }
388 else
389 set_gram_cursor(0, 0);
390
391 init_rw_operation_at(0x0022); // Write GRAM
392 for (u32 index = 0; index < LCDMaxX * LCDMaxY; index++)
393 do_write(color & 0xFFFF);
394}
void __LCD_LL_FillScreen(u16 color)
_PRIVATE void send(u16 halfw)
Writes an half-word (16 bits) into the LCD's DB port.
_PRIVATE u16 s_orientation
The current orientation of the screen.
#define LCD_RD(x)
_DECL_EXTERNALLY u16 LCDMaxY
#define DELAY_MS(ms)
_PRIVATE void set_gram_cursor(u16 x, u16 y)
Sets the GRAM cursor to the specified coordinates, for writing data into the appropriate pixel in the...
#define LCD_DIR(x)
#define DELAY_COUNT(count)
void __LCD_LL_Init(u16 orientation)
u16 __LCD_LL_GetPointColor(u16 x, u16 y)
_PRIVATE void write_to(u16 reg, u16 data)
Writes a 16-bit value to the LCD controller, at the specified register.
#define LCD_EN(x)
_PRIVATE u8 s_model_code
The model code of the LCD controller.
_PRIVATE u16 read_from(u16 reg)
Reads an HW from the LCD controller, at the specified register.
_PRIVATE void init_rw_operation_at(u16 index)
Tells the LCD controller to initiate a R/W operation with the register at the index specified.
void __LCD_LL_SetPointColor(u16 rgb565, u16 x, u16 y)
#define LCD_WR(x)
#define LCD_CS(x)
LCDModel
Models.
@ ILI9320
@ SSD1298
@ ST7781
@ ILI9328
@ LGDP4535
@ HX8347A
@ R61505U
@ SSD1289
@ ILI9325
@ HX8346A
@ SSD2119
@ SPFD5408B
@ LGDP4531
@ ILI9331
@ HX8347D
_PRIVATE u16 do_read(void)
Reads an half-word (16 bits) from the LCD's DB port, from the register at the index selected with the...
#define LCD_LE(x)
_PRIVATE u16 recv(void)
Reads an half-word (16 bits) from the LCD's DB port.
_DECL_EXTERNALLY u16 LCDMaxX
The maximum X and Y coordinates of the screen.
_PRIVATE void do_write(u16 data)
Writes an half-word (16 bits) into the LCD's DB port, destined to the register at the index selected ...
#define LCD_RS(x)
@ LCD_ORIENT_VER_INV
Definition glcd_types.h:15
@ LCD_ORIENT_HOR
Definition glcd_types.h:14
@ LCD_ORIENT_VER
Definition glcd_types.h:13
@ LCD_ORIENT_HOR_INV
Definition glcd_types.h:16
uint8_t u8
Definition types.h:8
#define _PRIVATE
Definition types.h:37
uint16_t u16
Definition types.h:7
#define _DECL_EXTERNALLY
Definition types.h:36
uint32_t u32
Definition types.h:6