/
GLCD_SPI_LPC1700.c
607 lines (481 loc) · 26.3 KB
/
GLCD_SPI_LPC1700.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
/******************************************************************************/
/* GLCD_SPI_LPC1700.c: LPC1700 low level Graphic LCD (320x240 pixels) driven */
/* with SPI functions */
/******************************************************************************/
/* This file is part of the uVision/ARM development tools. */
/* Copyright (c) 2005-2009 Keil Software. All rights reserved. */
/* This software may only be used under the terms of a valid, current, */
/* end user licence from KEIL for a compatible version of KEIL software */
/* development tools. Nothing else gives you the right to use this software. */
/******************************************************************************/
#include <lpc17xx.h>
#include "GLCD.h"
#include "Font_24x16.h"
/*********************** Hardware specific configuration **********************/
/* SPI Interface: SPI3
PINS:
- CS = P0.6 (GPIO pin)
- RS = GND
- WR/SCK = P0.7 (SCK1)
- RD = GND
- SDO = P0.8 (MISO1)
- SDI = P0.9 (MOSI1) */
#define PIN_CS (1 << 6)
/* SPI_SR - bit definitions */
#define TFE 0x01
#define RNE 0x04
#define BSY 0x10
/*------------------------- Speed dependant settings -------------------------*/
/* If processor works on high frequency delay has to be increased, it can be
increased by factor 2^N by this constant */
#define DELAY_2N 18
/*---------------------- Graphic LCD size definitions ------------------------*/
#define WIDTH 320 /* Screen Width (in pixels) */
#define HEIGHT 240 /* Screen Hight (in pixels) */
#define BPP 16 /* Bits per pixel */
#define BYPP ((BPP+7)/8) /* Bytes per pixel */
/*--------------- Graphic LCD interface hardware definitions -----------------*/
/* Pin CS setting to 0 or 1 */
#define LCD_CS(x) ((x) ? (LPC_GPIO0->FIOSET = PIN_CS) : (LPC_GPIO0->FIOCLR = PIN_CS));
#define SPI_START (0x70) /* Start byte for SPI transfer */
#define SPI_RD (0x01) /* WR bit 1 within start */
#define SPI_WR (0x00) /* WR bit 0 within start */
#define SPI_DATA (0x02) /* RS bit 1 within start byte */
#define SPI_INDEX (0x00) /* RS bit 0 within start byte */
/*---------------------------- Global variables ------------------------------*/
/******************************************************************************/
static volatile unsigned short TextColor = Black, BackColor = White;
/************************ Local auxiliary functions ***************************/
/*******************************************************************************
* Delay in while loop cycles *
* Parameter: cnt: number of while cycles to delay *
* Return: *
*******************************************************************************/
static void delay (int cnt) {
cnt <<= DELAY_2N;
while (cnt--);
}
/*******************************************************************************
* Send 1 byte over serial communication *
* Parameter: byte: byte to be sent *
* Return: byte read while sending *
*******************************************************************************/
static __INLINE unsigned char spi_send (unsigned char byte) {
LPC_SSP1->DR = byte;
while (!(LPC_SSP1->SR & RNE)); /* Wait for send to finish */
return (LPC_SSP1->DR);
}
/*******************************************************************************
* Write command to LCD controller *
* Parameter: c: command to be written *
* Return: *
*******************************************************************************/
static __INLINE void wr_cmd (unsigned char c) {
LCD_CS(0)
spi_send(SPI_START | SPI_WR | SPI_INDEX); /* Write : RS = 0, RW = 0 */
spi_send(0);
spi_send(c);
LCD_CS(1)
}
/*******************************************************************************
* Write data to LCD controller *
* Parameter: c: data to be written *
* Return: *
*******************************************************************************/
static __INLINE void wr_dat (unsigned short c) {
LCD_CS(0)
spi_send(SPI_START | SPI_WR | SPI_DATA); /* Write : RS = 1, RW = 0 */
spi_send((c >> 8)); /* Write D8..D15 */
spi_send((c & 0xFF)); /* Write D0..D7 */
LCD_CS(1)
}
/*******************************************************************************
* Start of data writing to LCD controller *
* Parameter: *
* Return: *
*******************************************************************************/
static __INLINE void wr_dat_start (void) {
LCD_CS(0)
spi_send(SPI_START | SPI_WR | SPI_DATA); /* Write : RS = 1, RW = 0 */
}
/*******************************************************************************
* Stop of data writing to LCD controller *
* Parameter: *
* Return: *
*******************************************************************************/
static __INLINE void wr_dat_stop (void) {
LCD_CS(1)
}
/*******************************************************************************
* Data writing to LCD controller *
* Parameter: c: data to be written *
* Return: *
*******************************************************************************/
static __INLINE void wr_dat_only (unsigned short c) {
spi_send((c >> 8)); /* Write D8..D15 */
spi_send((c & 0xFF)); /* Write D0..D7 */
}
/*******************************************************************************
* Read data from LCD controller *
* Parameter: *
* Return: read data *
*******************************************************************************/
static __INLINE unsigned short rd_dat (void) {
unsigned short val = 0;
LCD_CS(0)
spi_send(SPI_START | SPI_RD | SPI_DATA); /* Read: RS = 1, RW = 1 */
spi_send(0); /* Dummy read */
val = spi_send(0); /* Read D8..D15 */
val <<= 8;
val |= spi_send(0); /* Read D0..D7 */
LCD_CS(1)
return (val);
}
/*******************************************************************************
* Write to LCD register *
* Parameter: reg: register to be read *
* val: value to write to register *
*******************************************************************************/
static __INLINE void wr_reg (unsigned char reg, unsigned short val) {
wr_cmd(reg);
wr_dat(val);
}
/*******************************************************************************
* Read from LCD register *
* Parameter: reg: register to be read *
* Return: value read from register *
*******************************************************************************/
static unsigned short rd_reg (unsigned char reg) {
wr_cmd(reg);
return (rd_dat());
}
/************************ Exported functions **********************************/
/*******************************************************************************
* Initialize the Graphic LCD controller *
* Parameter: *
* Return: *
*******************************************************************************/
void GLCD_Init (void) {
static unsigned short driverCode;
/* Enable clock for SSP1, clock = CCLK / 2 */
LPC_SC->PCONP |= 0x00000400;
LPC_SC->PCLKSEL0 |= 0x00200000;
/* Configure the LCD Control pins */
LPC_PINCON->PINSEL9 &= 0xF0FFFFFF;
LPC_GPIO4->FIODIR |= 0x30000000;
LPC_GPIO4->FIOSET = 0x20000000;
/* SSEL1 is GPIO output set to high */
LPC_GPIO0->FIODIR |= 0x00000040;
LPC_GPIO0->FIOSET = 0x00000040;
LPC_PINCON->PINSEL0 &= 0xFFF03FFF;
LPC_PINCON->PINSEL0 |= 0x000A8000;
/* Enable SPI in Master Mode, CPOL=1, CPHA=1 */
/* Max. 25 MBit used for Data Transfer @ 100MHz */
LPC_SSP1->CR0 = 0xC7;
LPC_SSP1->CPSR = 0x02;
LPC_SSP1->CR1 = 0x02;
delay(5); /* Delay 50 ms */
driverCode = rd_reg(0x00);
/* Start Initial Sequence --------------------------------------------------*/
wr_reg(0x01, 0x0100); /* Set SS bit */
wr_reg(0x02, 0x0700); /* Set 1 line inversion */
wr_reg(0x04, 0x0000); /* Resize register */
wr_reg(0x08, 0x0207); /* 2 lines front, 7 back porch */
wr_reg(0x09, 0x0000); /* Set non-disp area refresh cyc ISC */
wr_reg(0x0A, 0x0000); /* FMARK function */
wr_reg(0x0C, 0x0000); /* RGB interface setting */
wr_reg(0x0D, 0x0000); /* Frame marker Position */
wr_reg(0x0F, 0x0000); /* RGB interface polarity */
/* Power On sequence -------------------------------------------------------*/
wr_reg(0x10, 0x0000); /* Reset Power Control 1 */
wr_reg(0x11, 0x0000); /* Reset Power Control 2 */
wr_reg(0x12, 0x0000); /* Reset Power Control 3 */
wr_reg(0x13, 0x0000); /* Reset Power Control 4 */
delay(20); /* Discharge cap power voltage (200ms)*/
wr_reg(0x10, 0x12B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
wr_reg(0x11, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */
delay(5); /* Delay 50 ms */
wr_reg(0x12, 0x01BD); /* VREG1OUT voltage */
delay(5); /* Delay 50 ms */
wr_reg(0x13, 0x1400); /* VDV[4:0] for VCOM amplitude */
wr_reg(0x29, 0x000E); /* VCM[4:0] for VCOMH */
delay(5); /* Delay 50 ms */
wr_reg(0x20, 0x0000); /* GRAM horizontal Address */
wr_reg(0x21, 0x0000); /* GRAM Vertical Address */
/* Adjust the Gamma Curve --------------------------------------------------*/
if (driverCode == 0x5408) { /* LCD with touch */
wr_reg(0x30, 0x0B0D);
wr_reg(0x31, 0x1923);
wr_reg(0x32, 0x1C26);
wr_reg(0x33, 0x261C);
wr_reg(0x34, 0x2419);
wr_reg(0x35, 0x0D0B);
wr_reg(0x36, 0x1006);
wr_reg(0x37, 0x0610);
wr_reg(0x38, 0x0706);
wr_reg(0x39, 0x0304);
wr_reg(0x3A, 0x0E05);
wr_reg(0x3B, 0x0E01);
wr_reg(0x3C, 0x010E);
wr_reg(0x3D, 0x050E);
wr_reg(0x3E, 0x0403);
wr_reg(0x3F, 0x0607);
}
if (driverCode == 0xC990) { /* LCD without touch */
wr_reg(0x30, 0x0006);
wr_reg(0x31, 0x0101);
wr_reg(0x32, 0x0003);
wr_reg(0x35, 0x0106);
wr_reg(0x36, 0x0B02);
wr_reg(0x37, 0x0302);
wr_reg(0x38, 0x0707);
wr_reg(0x39, 0x0007);
wr_reg(0x3C, 0x0600);
wr_reg(0x3D, 0x020B);
}
/* Set GRAM area -----------------------------------------------------------*/
wr_reg(0x50, 0x0000); /* Horizontal GRAM Start Address */
wr_reg(0x51, (HEIGHT-1)); /* Horizontal GRAM End Address */
wr_reg(0x52, 0x0000); /* Vertical GRAM Start Address */
wr_reg(0x53, (WIDTH-1)); /* Vertical GRAM End Address */
wr_reg(0x60, 0xA700); /* Gate Scan Line */
if (driverCode == 0x5408) /* LCD with touch */
wr_reg(0x60, 0xA700); /* Gate Scan Line */
if (driverCode == 0xC990) /* LCD without touch */
wr_reg(0x60, 0x2700); /* Gate Scan Line */
wr_reg(0x61, 0x0001); /* NDL,VLE, REV */
wr_reg(0x6A, 0x0000); /* Set scrolling line */
/* Partial Display Control -------------------------------------------------*/
wr_reg(0x80, 0x0000);
wr_reg(0x81, 0x0000);
wr_reg(0x82, 0x0000);
wr_reg(0x83, 0x0000);
wr_reg(0x84, 0x0000);
wr_reg(0x85, 0x0000);
/* Panel Control -----------------------------------------------------------*/
wr_reg(0x90, 0x0010);
wr_reg(0x92, 0x0000);
wr_reg(0x93, 0x0003);
wr_reg(0x95, 0x0110);
wr_reg(0x97, 0x0000);
wr_reg(0x98, 0x0000);
/* Set GRAM write direction
I/D=10 (Horizontal : increment, Vertical : increment)
AM=1 (address is updated in vertical writing direction) */
wr_reg(0x03, 0x1038);
wr_reg(0x07, 0x0137); /* 262K color and display ON */
LPC_GPIO4->FIOSET = 0x10000000;
}
/*******************************************************************************
* Set draw window region to whole screen *
* Parameter: *
* Return: *
*******************************************************************************/
void GLCD_WindowMax (void) {
wr_reg(0x50, 0); /* Horizontal GRAM Start Address */
wr_reg(0x51, HEIGHT-1); /* Horizontal GRAM End Address (-1) */
wr_reg(0x52, 0); /* Vertical GRAM Start Address */
wr_reg(0x53, WIDTH-1); /* Vertical GRAM End Address (-1) */
}
/*******************************************************************************
* Draw a pixel in foreground color *
* Parameter: x: horizontal position *
* y: vertical position *
* Return: *
*******************************************************************************/
void GLCD_PutPixel (unsigned int x, unsigned int y) {
wr_reg(0x20, y);
wr_reg(0x21, WIDTH-1-x);
wr_cmd(0x22);
wr_dat(TextColor);
}
/*******************************************************************************
* Set foreground color *
* Parameter: color: foreground color *
* Return: *
*******************************************************************************/
void GLCD_SetTextColor (unsigned short color) {
TextColor = color;
}
/*******************************************************************************
* Set background color *
* Parameter: color: background color *
* Return: *
*******************************************************************************/
void GLCD_SetBackColor (unsigned short color) {
BackColor = color;
}
/*******************************************************************************
* Clear display *
* Parameter: color: display clearing color *
* Return: *
*******************************************************************************/
void GLCD_Clear (unsigned short color) {
unsigned int i;
GLCD_WindowMax();
wr_reg(0x20, 0);
wr_reg(0x21, 0);
wr_cmd(0x22);
wr_dat_start();
for(i = 0; i < (WIDTH*HEIGHT); i++)
wr_dat_only(color);
wr_dat_stop();
}
/*******************************************************************************
* Draw character on given position *
* Parameter: x: horizontal position *
* y: vertical position *
* c: pointer to character bitmap *
* Return: *
*******************************************************************************/
void GLCD_DrawChar (unsigned int x, unsigned int y, unsigned short *c) {
int idx = 0, i, j;
x = WIDTH-x-CHAR_W;
wr_reg(0x50, y); /* Horizontal GRAM Start Address */
wr_reg(0x51, y+CHAR_H-1); /* Horizontal GRAM End Address (-1) */
wr_reg(0x52, x); /* Vertical GRAM Start Address */
wr_reg(0x53, x+CHAR_W-1); /* Vertical GRAM End Address (-1) */
wr_reg(0x20, y);
wr_reg(0x21, x);
wr_cmd(0x22);
wr_dat_start();
for (j = 0; j < CHAR_H; j++) {
for (i = CHAR_W-1; i >= 0; i--) {
if((c[idx] & (1 << i)) == 0x00) {
wr_dat_only(BackColor);
} else {
wr_dat_only(TextColor);
}
}
c++;
}
wr_dat_stop();
}
/*******************************************************************************
* Disply character on given line *
* Parameter: ln: line number *
* col: column number *
* c: ascii character *
* Return: *
*******************************************************************************/
void GLCD_DisplayChar (unsigned int ln, unsigned int col, unsigned char c) {
c -= 32;
GLCD_DrawChar(col * CHAR_W, ln * CHAR_H, (unsigned short *)&Font_24x16[c * CHAR_H]);
}
/*******************************************************************************
* Disply string on given line *
* Parameter: ln: line number *
* col: column number *
* s: pointer to string *
* Return: *
*******************************************************************************/
void GLCD_DisplayString (unsigned int ln, unsigned int col, unsigned char *s) {
GLCD_WindowMax();
while (*s) {
GLCD_DisplayChar(ln, col++, *s++);
}
}
/*******************************************************************************
* Clear given line *
* Parameter: ln: line number *
* Return: *
*******************************************************************************/
void GLCD_ClearLn (unsigned int ln) {
GLCD_WindowMax();
GLCD_DisplayString(ln, 0, " ");
}
/*******************************************************************************
* Draw bargraph *
* Parameter: x: horizontal position *
* y: vertical position *
* w: maximum width of bargraph (in pixels) *
* val: value of active bargraph (in 1/1024) *
* Return: *
*******************************************************************************/
void GLCD_Bargraph (unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned int val) {
int i,j;
x = WIDTH-x-w;
wr_reg(0x50, y); /* Horizontal GRAM Start Address */
wr_reg(0x51, y+CHAR_H-1); /* Horizontal GRAM End Address (-1) */
wr_reg(0x52, x); /* Vertical GRAM Start Address */
wr_reg(0x53, x+w-1); /* Vertical GRAM End Address (-1) */
val = (val * w) >> 10; /* Scale value for 24x12 characters */
wr_reg(0x20, y);
wr_reg(0x21, x);
wr_cmd(0x22);
wr_dat_start();
for (i = 0; i < h; i++) {
for (j = w-1; j >= 0; j--) {
if(j >= val) {
wr_dat_only(BackColor);
} else {
wr_dat_only(TextColor);
}
}
}
wr_dat_stop();
}
/*******************************************************************************
* Display graphical bitmap image at position x horizontally and y vertically *
* (This function is optimized for 16 bits per pixel format, it has to be *
* adapted for any other bits per pixel format) *
* Parameter: x: horizontal position *
* y: vertical position *
* w: width of bitmap *
* h: height of bitmap *
* bitmap: address at which the bitmap data resides *
* Return: *
*******************************************************************************/
void GLCD_Bitmap (unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned char *bitmap) {
unsigned int i, j;
unsigned short *bitmap_ptr = (unsigned short *)bitmap;
x = WIDTH-x-w;
wr_reg(0x50, y); /* Horizontal GRAM Start Address */
wr_reg(0x51, y+h-1); /* Horizontal GRAM End Address (-1) */
wr_reg(0x52, x); /* Vertical GRAM Start Address */
wr_reg(0x53, x+w-1); /* Vertical GRAM End Address (-1) */
wr_reg(0x20, y);
wr_reg(0x21, x);
wr_cmd(0x22);
wr_dat_start();
for (j = 0; j < h; j++) {
bitmap_ptr += w-1;
for (i = 0; i < w; i++) {
wr_dat_only(*bitmap_ptr--);
}
bitmap_ptr += w+1;
}
wr_dat_stop();
}
/*******************************************************************************
* Display graphical bmp file image at position x horizontally and y vertically *
* (This function is optimized for 16 bits per pixel format, it has to be *
* adapted for any other bits per pixel format) *
* Parameter: x: horizontal position *
* y: vertical position *
* w: width of bitmap *
* h: height of bitmap *
* bmp: address at which the bmp data resides *
* Return: *
*******************************************************************************/
void GLCD_Bmp (unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned char *bmp) {
unsigned int i, j;
unsigned short *bitmap_ptr = (unsigned short *)bmp;
x = WIDTH-x-w;
wr_reg(0x50, y); /* Horizontal GRAM Start Address */
wr_reg(0x51, y+h-1); /* Horizontal GRAM End Address (-1) */
wr_reg(0x52, x); /* Vertical GRAM Start Address */
wr_reg(0x53, x+w-1); /* Vertical GRAM End Address (-1) */
wr_reg(0x20, y);
wr_reg(0x21, x);
wr_cmd(0x22);
wr_dat_start();
bitmap_ptr += (h*w)-1;
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
wr_dat_only(*bitmap_ptr--);
}
}
wr_dat_stop();
}
/******************************************************************************/