-
Notifications
You must be signed in to change notification settings - Fork 0
/
pcf8833u8_lcd.c
619 lines (519 loc) · 16.3 KB
/
pcf8833u8_lcd.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
608
609
610
611
612
613
614
615
616
617
618
619
#include <targets\AT91SAM7.h>
#include "pcf8833u8_lcd.h"
#include "bmp.h"
#include "fonts.h"
#include "math.h"
#define LCD_RESET_LOW PIOA_CODR = BIT2
#define LCD_RESET_HIGH PIOA_SODR = BIT2
void Delaya (unsigned long a) { while (--a!=0); }
void Delay_ (unsigned long a) {
volatile unsigned long d;
d=a;
while (--d!=0);
}
unsigned int i,j;
void WriteSpiCommand(unsigned int data){
data = (data & ~0x0100);
// Wait for the transfer to complete
while((SPI0_SR & SPI0_SR_TXEMPTY) == 0);
SPI0_TDR = data;
}
void WriteSpiData(unsigned int data){
data = (data | 0x0100);
// Wait for the transfer to complete
while((SPI0_SR & SPI0_SR_TXEMPTY) == 0);
SPI0_TDR = data;
}
void Backlight(unsigned char state) {
if(state == BL_ON)
PIOB_SODR = BIT20; // Set PB20 to HIGH
else
PIOB_CODR = BIT20; // Set PB20 to LOW
}
void SetContrast(unsigned char contrast) {
//#ifdef GE12
WriteSpiCommand(CONTRAST);
WriteSpiData(0x20+contrast); // contrast
// WriteSpiCommand(VOLCTR);
// WriteSpiData(32+contrast); // contrast
// WriteSpiData(3); // contrast
}
void SendLcd(int tryb, int data) // TEGO NIE MA W LCD.c
{
if (tryb==LCDCommand)
WriteSpiCommand(data);
else WriteSpiData(data);
}
void LCDSettings(void) {
LCD_RESET_LOW;
Delay_(10000);
LCD_RESET_HIGH;
Delay_(10000);
// Sleep out (command0x11)
WriteSpiCommand(SLEEPOUT);
// Inversion on(command 0x20)
WriteSpiCommand(INVERSIONOFF); // seems to be required for this controller
// Color Interface Pixel Format(command 0x3A)
WriteSpiCommand(PIXELFORMAT);
WriteSpiData(0x03); // 0x03 =12bits-per-pixel
// Write contrast (command 0x25)
WriteSpiCommand(CONTRAST);
WriteSpiData(0x40); // contrast 0x38
Delay_(10000);
// DisplayOn (command 0x29)
WriteSpiCommand(DISPLAYON);
// 6. Set Normal mode (my)
WriteSpiCommand(NORMALMODE);
// 7. Inversion off
WriteSpiCommand(INVERSIONOFF); // OFF?
// 8. Column address set
WriteSpiCommand(COLADDRSET);
WriteSpiData(0);
WriteSpiData(131);
// 9. Page address set
WriteSpiCommand(PAGEADDRSET);
WriteSpiData(0);
WriteSpiData(131);
// 10. Memory access controler
WriteSpiCommand(ACCESSCTRL);
WriteSpiData(0x08);
///// Display setting 1 end /////
///// Power supply ///////
// 1. Power control
WriteSpiCommand(PWRCTRL);
WriteSpiData(4); // Internal resistance, V1OUT -> high power mode, oscilator devision rate
// 2. Sleep out
WriteSpiCommand(SLEEPOUT);
// 3. Voltage control - voltage control and write contrast define LCD electronic volume
WriteSpiCommand(VOLTCTRL);
//WriteSpiData(0x7f); // full voltage control
//WriteSpiData(0x03); // must be "1"
Delaya(2000);
// 5. Temperature gradient
WriteSpiCommand(TEMPGRADIENT);
for(i=0; i<14; i++) {
WriteSpiData(0);
}
// 6. Booster voltage ON
WriteSpiCommand(BOOSTVON);
// Finally - Display On
WriteSpiCommand(DISPLAYON);
}
void InitLCD(void) {
// Pin for backlight
PIOB_SODR = BIT20; // Set PB20 to HIGH
PIOB_OER = BIT20; // Configure PB20 as output
// Reset pin
PIOA_SODR = BIT2; // Set PA2 to HIGH
PIOA_OER = BIT2; // Configure PA2 as output
// Init SPI0
//set functionality to pins:
//port0.12 -> NPCS0
//port0.16 -> MISO
//port0.17 -> MOSI
//port0.18 -> SPCK
PIOA_PDR = BIT12 | BIT16 | BIT17 | BIT18 | BIT13;
PIOA_ASR = BIT12 | BIT16 | BIT17 | BIT18 | BIT13;
PIOA_BSR = 0;
//enable the clock of SPI
PMC_PCER = PMC_PCER_SPI0;
// Fixed mode
SPI0_CR = 0x80; //SPI Enable, Sowtware reset
SPI0_CR = 0x01; //SPI Enable
SPI0_MR = 0x100E0011; //Master mode, fixed select, disable decoder, FDIV=1 (MCK), PCS=1110
SPI0_CSR0 = 0x01010C11; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/32*12 = 125kHz
SPI0_CSR1 = 0x01010502;
Delay_(10000);
LCDSettings();
}
void LCDWrite130x130bmp(int number) {
// Display OFF
WriteSpiCommand(DISPLAYOFF);
// WRITE MEMORY
WriteSpiCommand(MEMWRITE);
if(number == 0){
for(j=0; j<sizeof(bmp); j++) {
WriteSpiData(bmp[j]);
}
} else {
for(j=0; j<sizeof(bmp2); j++) {
WriteSpiData(bmp2[j]);
}
}
// Display On
WriteSpiCommand(DISPLAYON);
}
// *****************************************************************************
// LCDClearScreen.c
//
// Clears the LCD screen to single color (BLACK)
//
// Inputs: none
//
// Author: James P Lynch August 30, 2007
// *****************************************************************************
void LCDClearScreen(void) {
long i; // loop counter
// Row address set (command 0x2B)
WriteSpiCommand(PASET); //PASET NA PAGEADDRSET
WriteSpiData(0);
WriteSpiData(131);
// Column address set (command 0x2A)
WriteSpiCommand(CASET); //CASET na COLADDRSET
WriteSpiData(0);
WriteSpiData(131);
// set the display memory to BLACK
WriteSpiCommand(RAMWR); //RAMWR na MEMWRITE
for(i = 0; i < ((132 * 132) / 2); i++) {
WriteSpiData((WHITE >> 4) & 0xFF);
WriteSpiData(((WHITE & 0xF) << 4) | ((WHITE >> 8) & 0xF));
WriteSpiData(WHITE & 0xFF);
}
}
//
// *************************************************************************************
// LCDSetPixel.c
//
// Lights a single pixel in the specified color at the specified x and y addresses
//
// Inputs: x = row address (0 .. 131)
// y = column address (0 .. 131)
// color = 12-bit color value rrrrggggbbbb
// rrrr = 1111 full red
// :
// 0000 red is off
//
// gggg = 1111 full green
// :
// 0000 green is off
//
// bbbb = 1111 full blue
// :
// 0000 blue is off
//
// Returns: nothing
//
// Note: see lcd.h for some sample color settings
//
// Author: James P Lynch August 30, 2007
// *************************************************************************************
void LCDSetPixel(int x, int y, int color) {
// Row address set (command 0x2B)
WriteSpiCommand(PASET);
WriteSpiData(x);
WriteSpiData(x);
// Column address set (command 0x2A)
WriteSpiCommand(CASET);
WriteSpiData(y);
WriteSpiData(y);
// Now illuminate the pixel (2nd pixel will be ignored)
WriteSpiCommand(RAMWR);
WriteSpiData((color >> 4) & 0xFF);
WriteSpiData(((color & 0xF) << 4) | ((color >> 8) & 0xF));
WriteSpiData(color & 0xFF);
}
//
// *************************************************************************************************
// LCDSetLine.c
//
// Draws a line in the specified color from (x0,y0) to (x1,y1)
//
// Inputs: x = row address (0 .. 131)
// y = column address (0 .. 131)
// color = 12-bit color value rrrrggggbbbb
// rrrr = 1111 full red
// :
// 0000 red is off
//
// gggg = 1111 full green
// :
// 0000 green is off
//
// bbbb = 1111 full blue
// :
// 0000 blue is off
//
// Returns: nothing
//
// Note: good write-up on this algorithm in Wikipedia (search for Bresenham's line algorithm)
// see lcd.h for some sample color settings
//
// Authors: Dr. Leonard McMillan, Associate Professor UNC
// Jack Bresenham IBM, Winthrop University (Father of this algorithm, 1962)
//
// Note: taken verbatim from Professor McMillan's presentation:
// http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html
//
// ************************************************************************************************
void LCDSetLine(int x0, int y0, int x1, int y1, int color) {
int dy = y1 - y0;
int dx = x1 - x0;
int stepx, stepy;
if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
dy <<= 1; // dy is now 2*dy
dx <<= 1; // dx is now 2*dx
LCDSetPixel(x0, y0, color);
if (dx > dy) {
int fraction = dy - (dx >> 1); // same as 2*dy - dx
while (x0 != x1) {
if (fraction >= 0) {
y0 += stepy;
fraction -= dx; // same as fraction -= 2*dx
}
x0 += stepx;
fraction += dy; // same as fraction -= 2*dy
LCDSetPixel(x0, y0, color);
}
} else {
int fraction = dx - (dy >> 1);
while (y0 != y1) {
if (fraction >= 0) {
x0 += stepx;
fraction -= dy;
}
y0 += stepy;
fraction += dx;
LCDSetPixel(x0, y0, color);
}
}
}
// *****************************************************************************************
// LCDSetRect.c
//
// Draws a rectangle in the specified color from (x1,y1) to (x2,y2)
// Rectangle can be filled with a color if desired
//
// Inputs: x = row address (0 .. 131)
// y = column address (0 .. 131)
// fill = 0=no fill, 1-fill entire rectangle
// color = 12-bit color value for lines rrrrggggbbbb
// rrrr = 1111 full red
// :
// 0000 red is off
//
// gggg = 1111 full green
// :
// 0000 green is off
//
// bbbb = 1111 full blue
// :
// 0000 blue is off
//
// Returns: nothing
//
// Notes:
//
// The best way to fill a rectangle is to take advantage of the "wrap-around" featute
// built into the Epson S1D15G00 controller. By defining a drawing box, the memory can
// be simply filled by successive memory writes until all pixels have been illuminated.
//
// 1. Given the coordinates of two opposing corners (x0, y0) (x1, y1)
// calculate the minimums and maximums of the coordinates
//
// xmin = (x0 <= x1) ? x0 : x1;
// xmax = (x0 > x1) ? x0 : x1;
// ymin = (y0 <= y1) ? y0 : y1;
// ymax = (y0 > y1) ? y0 : y1;
//
// 2. Now set up the drawing box to be the desired rectangle
//
// WriteSpiCommand(PASET); // set the row boundaries
// WriteSpiData(xmin);
// WriteSpiData(xmax);
// WriteSpiCommand(CASET); // set the column boundaries
// WriteSpiData(ymin);
// WriteSpiData(ymax);
//
void LCDSetRect(int x0, int y0, int x1, int y1, unsigned char fill, int color) {
int xmin, xmax, ymin, ymax;
int i;
// check if the rectangle is to be filled
if (fill == FILL) {
// best way to create a filled rectangle is to define a drawing box
// and loop two pixels at a time
// calculate the min and max for x and y directions
xmin = (x0 <= x1) ? x0 : x1;
xmax = (x0 > x1) ? x0 : x1;
ymin = (y0 <= y1) ? y0 : y1;
ymax = (y0 > y1) ? y0 : y1;
// specify the controller drawing box according to those limits
// Row address set (command 0x2B)
WriteSpiCommand(PASET);
WriteSpiData(xmin);
WriteSpiData(xmax);
// Column address set (command 0x2A)
WriteSpiCommand(CASET);
WriteSpiData(ymin);
WriteSpiData(ymax);
// WRITE MEMORY
WriteSpiCommand(RAMWR);
// loop on total number of pixels / 2
for (i = 0; i < ((((xmax - xmin + 1) * (ymax - ymin + 1)) / 2) + 130); i++) {
// use the color value to output three data bytes covering two pixels
WriteSpiData((color >> 4) & 0xFF);
WriteSpiData(((color & 0xF) << 4) | ((color >> 8) & 0xF));
WriteSpiData(color & 0xFF);
}
} else {
// best way to draw un unfilled rectangle is to draw four lines
LCDSetLine(x0, y0, x1, y0, color);
LCDSetLine(x0, y1, x1, y1, color);
LCDSetLine(x0, y0, x0, y1, color);
LCDSetLine(x1, y0, x1, y1, color);
}
}
//
//
// // *************************************************************************************
// LCDSetCircle.c
//
// Draws a line in the specified color at center (x0,y0) with radius
//
// Inputs: x0 = row address (0 .. 131)
// y0 = column address (0 .. 131)
// radius = radius in pixels
// color = 12-bit color value rrrrggggbbbb
//
// Returns: nothing
//
// Author: Jack Bresenham IBM, Winthrop University (Father of this algorithm, 1962)
//
// Note: taken verbatim Wikipedia article on Bresenham's line algorithm
// http://www.wikipedia.org
//
// *************************************************************************************
//
void LCDSetCircle(int x0, int y0, int radius, int color) {
int f = 1 - radius;
int ddF_x = 0;
int ddF_y = -2 * radius;
int x = 0;
int y = radius;
LCDSetPixel(x0, y0 + radius, color);
LCDSetPixel(x0, y0 - radius, color);
LCDSetPixel(x0 + radius, y0, color);
LCDSetPixel(x0 - radius, y0, color);
while(x < y) {
if(f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x + 1;
LCDSetPixel(x0 + x, y0 + y, color);
LCDSetPixel(x0 - x, y0 + y, color);
LCDSetPixel(x0 + x, y0 - y, color);
LCDSetPixel(x0 - x, y0 - y, color);
LCDSetPixel(x0 + y, y0 + x, color);
LCDSetPixel(x0 - y, y0 + x, color);
LCDSetPixel(x0 + y, y0 - x, color);
LCDSetPixel(x0 - y, y0 - x, color);
}
}
//
void LCDPutChar(char c, int x, int y, int size, int fColor, int bColor) {
extern const unsigned char FONT6x8[97][8];
extern const unsigned char FONT8x8[97][8];
extern const unsigned char FONT8x16[97][16];
int i,j;
unsigned int nCols;
unsigned int nRows;
unsigned int nBytes;
unsigned char PixelRow;
unsigned char Mask;
unsigned int Word0;
unsigned int Word1;
unsigned char *pFont;
unsigned char *pChar;
unsigned char *FontTable[] = {(unsigned char *)FONT6x8, (unsigned char *)FONT8x8,
(unsigned char *)FONT8x16};
// get pointer to the beginning of the selected font table
pFont = (unsigned char *)FontTable[size];
// get the nColumns, nRows and nBytes
nCols = *pFont;
nRows = *(pFont + 1);
nBytes = *(pFont + 2);
// get pointer to the last byte of the desired character
pChar = pFont + (nBytes * (c - 0x1F)) + nBytes - 1;
// Row address set (command 0x2B)
WriteSpiCommand(PASET);
WriteSpiData(x);
WriteSpiData(x - nRows + 1);
// Column address set (command 0x2A)
WriteSpiCommand(CASET);
WriteSpiData(y);
WriteSpiData(y + nCols - 1);
// WRITE MEMORY
WriteSpiCommand(RAMWR);
// loop on each row, working backwards from the bottom to the top
for (i = nRows - 1; i >= 0; i--) {
// copy pixel row from font table and then decrement row
PixelRow = *pChar--;
// loop on each pixel in the row (left to right)
// Note: we do two pixels each loop
Mask = 0x80;
for (j = 0; j < nCols; j += 2) {
// if pixel bit set, use foreground color; else use the background color
// now get the pixel color for two successive pixels
if ((PixelRow & Mask) == 0)
Word0 = bColor;
else
Word0 = fColor;
Mask = Mask >> 1;
if ((PixelRow & Mask) == 0)
Word1 = bColor;
else
Word1 = fColor;
Mask = Mask >> 1;
// use this information to output three data bytes
WriteSpiData((Word0 >> 4) & 0xFF);
WriteSpiData(((Word0 & 0xF) << 4) | ((Word1 >> 8) & 0xF));
WriteSpiData(Word1 & 0xFF);
}
}
// terminate the Write Memory command
WriteSpiCommand(NOP);
}
//
//
// *************************************************************************************************
// LCDPutStr.c
//
// Draws a null-terminates character string at the specified (x,y) address, size and color
//
// Inputs: pString = pointer to character string to be displayed
// x = row address (0 .. 131)
// y = column address (0 .. 131)
// Size = font pitch (SMALL, MEDIUM, LARGE)
// fColor = 12-bit foreground color value rrrrggggbbbb
// bColor = 12-bit background color value rrrrggggbbbb
//
//
// Returns: nothing
//
// Notes: Here's an example to display "Hello World!" at address (20,20)
//
// LCDPutChar("Hello World!", 20, 20, LARGE, WHITE, BLACK);
//
//
// Author: James P Lynch August 30, 2007
// *************************************************************************************************
void LCDPutStr(char *pString, int x, int y, int Size, int fColor, int bColor) {
// loop until null-terminator is seen
while (*pString != 0x00) {
// draw the character
LCDPutChar(*pString++, x, y, Size, fColor, bColor);
// advance the y position
if (Size == SMALL)
y = y + 6;
else if (Size == MEDIUM)
y = y + 8;
else
y = y + 8;
// bail out if y exceeds 131
if (y > 131) break;
}
}