-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLightPCD8544.h
executable file
·158 lines (112 loc) · 4.14 KB
/
LightPCD8544.h
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
/*############################################################################################
LightLCD
Lightweight library for various LCD
Author: Daniele Colanardi
License: BSD, see LICENSE file
Inspired by Adafruit_PCD8544 library.
############################################################################################*/
#ifndef _LIGHT_PCD8544_H
#define _LIGHT_PCD8544_H
#include "LightLCD.h"
#include <SPI.h>
#define PCD8544
#define PCD8544_POWERDOWN 0x04
#define PCD8544_ENTRYMODE 0x02
#define PCD8544_EXTENDEDINSTRUCTION 0x01
#define PCD8544_DISPLAYBLANK 0x0
#define PCD8544_DISPLAYNORMAL 0x4
#define PCD8544_DISPLAYALLON 0x1
#define PCD8544_DISPLAYINVERTED 0x5
#define PCD8544_FUNCTIONSET 0x20
#define PCD8544_DISPLAYCONTROL 0x08
#define PCD8544_SETYADDR 0x40
#define PCD8544_SETXADDR 0x80
#define PCD8544_SETTEMP 0x04
#define PCD8544_SETBIAS 0x10
#define PCD8544_SETVOP 0x80
class LightPCD8544 : public LightLCD {
public:
LightPCD8544(uint8_t DC, uint8_t CS) : dc(DC), cs(CS) {}
void begin() {
// set pin directions
pinMode(dc, OUTPUT);
pinMode(cs, OUTPUT);
//pinMode(SS, OUTPUT);
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV16);
// Enter extended instruction mode
command(PCD8544_FUNCTIONSET | PCD8544_EXTENDEDINSTRUCTION );
// LCD bias select (4 is optimal?)
command(PCD8544_SETBIAS | 0x4);
// Set contrast
//if (contrast > 0x7f)
// contrast = 0x7f;
//command(PCD8544_SETVOP | contrast);
// Return to normal instruction mode
command(PCD8544_FUNCTIONSET);
// Set display to not Inverted
command(PCD8544_DISPLAYCONTROL | PCD8544_DISPLAYNORMAL);
// Clear the buffer to init it.
clear();
// Show a blank screen
update();
}
void setContrast(uint8_t val) {
if (val > 0x7f)
val = 0x7f;
command(PCD8544_FUNCTIONSET | PCD8544_EXTENDEDINSTRUCTION );
command(PCD8544_SETVOP | val);
command(PCD8544_FUNCTIONSET);
}
void clear() {
memset(buffer, 0, 84 * 48 / 8);
resetLimits(true);
cursor_y = cursor_x = 0;
}
void update() {
if(limits.y0 == limits.y1)
return;
for(uint8_t y = limits.y0 / 8; y <= (limits.y1 - 1) / 8; y++) {
command(PCD8544_SETYADDR | y);
command(PCD8544_SETXADDR | limits.x0);
digitalWrite(dc, HIGH);
// Activate chip
digitalWrite(cs, LOW);
for(uint8_t x = limits.x0; x < limits.x1; x++)
SPI.transfer(buffer[(width() * y) + x]);
//SPI.transfer(0xFF);
// Disable chip
digitalWrite(cs, HIGH);
}
command(PCD8544_SETYADDR); // no idea why this is necessary but it is to finish the last byte?
resetLimits(false);
}
void drawPixel(uint8_t x, uint8_t y, uint8_t color) {
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
return;
//bitWrite(buffer[x + (y / 8) * width()], y % 8, color);
if (color)
buffer[x + (y / 8)*width()] |= _BV(y%8);
else
buffer[x + (y / 8)*width()] &= ~_BV(y%8);
expandLimits(x, y);
}
void invertDisplay(uint8_t i) {
command(PCD8544_DISPLAYCONTROL | (i ? PCD8544_DISPLAYINVERTED : PCD8544_DISPLAYNORMAL));
}
int width() { return 84; }
int height() { return 48; }
protected:
uint8_t dc, cs;
uint8_t buffer[84 * 48 / 8];
void command(uint8_t c) {
// Signal DATA mode
digitalWrite(dc, LOW);
// Enable chip
digitalWrite(cs, LOW);
SPI.transfer(c);
// Disable chip
digitalWrite(cs, HIGH);
}
};
#endif