User | Revision | Line number | New contents of line |
simon |
0:cc002f2fad97
|
1
|
/* mbed Embedded Artists QVGA LCD Display Library
|
simon |
0:cc002f2fad97
|
2
|
* Copyright (c) 2007-2009 sford
|
simon |
0:cc002f2fad97
|
3
|
* Released under the MIT License: http://mbed.org/license/mit
|
simon |
0:cc002f2fad97
|
4
|
*/
|
simon |
0:cc002f2fad97
|
5
|
|
simon |
0:cc002f2fad97
|
6
|
#include "EA_QVGALCD.h"
|
simon |
0:cc002f2fad97
|
7
|
|
simon |
0:cc002f2fad97
|
8
|
EA_QVGALCD::EA_QVGALCD(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst) : _spi(mosi, miso, sclk), _cs(cs), _rst(rst) {
|
simon |
0:cc002f2fad97
|
9
|
|
simon |
0:cc002f2fad97
|
10
|
_spi.frequency(15000000);
|
simon |
0:cc002f2fad97
|
11
|
_spi.format(9);
|
simon |
0:cc002f2fad97
|
12
|
_cs = 1;
|
simon |
0:cc002f2fad97
|
13
|
_rst = 0;
|
simon |
0:cc002f2fad97
|
14
|
wait(0.001);
|
simon |
0:cc002f2fad97
|
15
|
_rst = 1;
|
simon |
0:cc002f2fad97
|
16
|
wait(0.001);
|
simon |
0:cc002f2fad97
|
17
|
|
simon |
0:cc002f2fad97
|
18
|
// 3-wire SPI Format (see 7.1 c)
|
simon |
0:cc002f2fad97
|
19
|
// =================
|
simon |
0:cc002f2fad97
|
20
|
//
|
simon |
0:cc002f2fad97
|
21
|
// The 3-wire spi format uses 9-bit messages of the form:
|
simon |
0:cc002f2fad97
|
22
|
//
|
simon |
0:cc002f2fad97
|
23
|
// [Data/nControl D7 D6 D5 D4 D3 D2 D1 D0]
|
simon |
0:cc002f2fad97
|
24
|
// (first) (last)
|
simon |
0:cc002f2fad97
|
25
|
//
|
simon |
0:cc002f2fad97
|
26
|
// Most commands and data are 16-bit, so are achieved by sending two
|
simon |
0:cc002f2fad97
|
27
|
// command messages, [ CommandMSB | CommandLSB ], or two data messages
|
simon |
0:cc002f2fad97
|
28
|
// [ DataMSB | DataLSB ].
|
simon |
0:cc002f2fad97
|
29
|
//
|
simon |
0:cc002f2fad97
|
30
|
// Controlling the Display
|
simon |
0:cc002f2fad97
|
31
|
// =======================
|
simon |
0:cc002f2fad97
|
32
|
//
|
simon |
0:cc002f2fad97
|
33
|
// The Index Register is used to setup which configuration register is
|
simon |
0:cc002f2fad97
|
34
|
// modified. This address is changed by sending a command message:
|
simon |
0:cc002f2fad97
|
35
|
//
|
simon |
0:cc002f2fad97
|
36
|
// command [ 0 | index[7:0] ]
|
simon |
0:cc002f2fad97
|
37
|
//
|
simon |
0:cc002f2fad97
|
38
|
// The data that follows update the register.
|
simon |
0:cc002f2fad97
|
39
|
//
|
simon |
0:cc002f2fad97
|
40
|
//
|
simon |
0:cc002f2fad97
|
41
|
// 0x07 - Display Control
|
simon |
0:cc002f2fad97
|
42
|
// ======================
|
simon |
0:cc002f2fad97
|
43
|
//
|
simon |
0:cc002f2fad97
|
44
|
// [ 0 0 0 PT1 PT0 VLE2 VLE1 SPT | 0 0 GON DTE CM 0 D1 D0 ]
|
simon |
0:cc002f2fad97
|
45
|
// where:
|
simon |
0:cc002f2fad97
|
46
|
// PT[1:0] - ? (0)
|
simon |
0:cc002f2fad97
|
47
|
// VLE[2:1] - ? (0)
|
simon |
0:cc002f2fad97
|
48
|
// SPT - ? (0)
|
simon |
0:cc002f2fad97
|
49
|
// CM - 8 colour mode enable
|
simon |
0:cc002f2fad97
|
50
|
// GON - 0 = Gate-off level VGH
|
simon |
0:cc002f2fad97
|
51
|
// DTE - 0 = All gate outputs become VGL
|
simon |
0:cc002f2fad97
|
52
|
// 1 = Selected gate outputs become VGH
|
simon |
0:cc002f2fad97
|
53
|
// D[1:0] - D1 = Display enable
|
simon |
0:cc002f2fad97
|
54
|
// D0 = Display operating
|
simon |
0:cc002f2fad97
|
55
|
|
simon |
0:cc002f2fad97
|
56
|
// 15.5 On Sequence
|
simon |
0:cc002f2fad97
|
57
|
//
|
simon |
0:cc002f2fad97
|
58
|
// -> Set R07h: GON =1, DTE = 0, D[1:0] = 01
|
simon |
0:cc002f2fad97
|
59
|
_cs = 0;
|
simon |
0:cc002f2fad97
|
60
|
config(0x7
|
simon |
0:cc002f2fad97
|
61
|
, 1 << 5 // GON
|
simon |
0:cc002f2fad97
|
62
|
| 0 << 4 // DTE
|
simon |
0:cc002f2fad97
|
63
|
| 0 << 3 // CM
|
simon |
0:cc002f2fad97
|
64
|
| 1 << 0 // D[1:0] = 01 - operate, but disp off
|
simon |
0:cc002f2fad97
|
65
|
);
|
simon |
0:cc002f2fad97
|
66
|
// -> Set R00h to 0001h
|
simon |
0:cc002f2fad97
|
67
|
// R00h [ 00000000 | 0000000 OSCEN ]
|
simon |
0:cc002f2fad97
|
68
|
// OSCEN - 1 = oscillator enabled
|
simon |
0:cc002f2fad97
|
69
|
|
simon |
0:cc002f2fad97
|
70
|
config(0x0, 1);
|
simon |
0:cc002f2fad97
|
71
|
|
simon |
0:cc002f2fad97
|
72
|
// -> Set R07h: GON = 1, DTE = 0, D[1:0] = 11
|
simon |
0:cc002f2fad97
|
73
|
|
simon |
0:cc002f2fad97
|
74
|
config(0x7
|
simon |
0:cc002f2fad97
|
75
|
, 1 << 5 // GON
|
simon |
0:cc002f2fad97
|
76
|
| 1 << 4 // DTE
|
simon |
0:cc002f2fad97
|
77
|
| 0 << 3 // CM
|
simon |
0:cc002f2fad97
|
78
|
| 3 << 0 // D[1:0] = 3 - operate, display on
|
simon |
0:cc002f2fad97
|
79
|
);
|
simon |
0:cc002f2fad97
|
80
|
|
simon |
0:cc002f2fad97
|
81
|
// -> Set R10h at 0000h : Exit sleep mode
|
simon |
0:cc002f2fad97
|
82
|
// R10h [ 00000000 | 0000000 SLP ]
|
simon |
0:cc002f2fad97
|
83
|
// SLP = enter sleep mode (retain but no function)
|
simon |
0:cc002f2fad97
|
84
|
|
simon |
0:cc002f2fad97
|
85
|
config(0x10, 0);
|
simon |
0:cc002f2fad97
|
86
|
|
simon |
0:cc002f2fad97
|
87
|
// -> wait 30ms
|
simon |
0:cc002f2fad97
|
88
|
wait(0.030);
|
simon |
0:cc002f2fad97
|
89
|
|
simon |
0:cc002f2fad97
|
90
|
// -> LCD driver AC setting (R02h)
|
simon |
0:cc002f2fad97
|
91
|
config(0x02, 0x0600);
|
simon |
0:cc002f2fad97
|
92
|
config(0x01, 0x2b3f); // 1011
|
simon |
0:cc002f2fad97
|
93
|
config(0x25, 0xa000); // 70Hz freq
|
simon |
0:cc002f2fad97
|
94
|
|
simon |
0:cc002f2fad97
|
95
|
// -> Entry Mode setting (R11h)
|
simon |
0:cc002f2fad97
|
96
|
// R11h [ VSMode DFM1 DFM0 TRANS OEDef WMode DMode1 DMode0 | TY1 TY0 ID1 ID0 AM LG2 LG1 LG0 ]
|
simon |
0:cc002f2fad97
|
97
|
// VSMode = freq dependant on VSYNC
|
simon |
0:cc002f2fad97
|
98
|
// DFM[1:0] colour display mode 11 - 65k, 10 - 262k
|
simon |
0:cc002f2fad97
|
99
|
// TRANS - allow transparent display
|
simon |
0:cc002f2fad97
|
100
|
// OEDef:
|
simon |
0:cc002f2fad97
|
101
|
// When OEDef = 1, OE defines the display window.
|
simon |
0:cc002f2fad97
|
102
|
// When OEDef = 0, the display window is defined by R4Eh and R4Fh.
|
simon |
0:cc002f2fad97
|
103
|
// WMode: Select the source of data to write in the RAM.
|
simon |
0:cc002f2fad97
|
104
|
// 0 Normal data bus (POR)
|
simon |
0:cc002f2fad97
|
105
|
// 1 Generic interface
|
simon |
0:cc002f2fad97
|
106
|
// Dmode - where to show from (0 = ram)
|
simon |
0:cc002f2fad97
|
107
|
// TY - 262k mode options
|
simon |
0:cc002f2fad97
|
108
|
// ID[1:0] [ VERTICAL HORIZONTAL ] increment = 1 decrement = 0
|
simon |
0:cc002f2fad97
|
109
|
// AM - 0 = horizontal display, 1 = vertical
|
simon |
0:cc002f2fad97
|
110
|
// LG - do maths n written data
|
simon |
0:cc002f2fad97
|
111
|
|
simon |
0:cc002f2fad97
|
112
|
config(0x11
|
simon |
0:cc002f2fad97
|
113
|
, 0 << 15 // VSMode
|
simon |
0:cc002f2fad97
|
114
|
| 3 << 13 // DFM[1:0]
|
simon |
0:cc002f2fad97
|
115
|
| 0 << 12 // TRANS
|
simon |
0:cc002f2fad97
|
116
|
| 1 << 11 // OEDef
|
simon |
0:cc002f2fad97
|
117
|
| 0 << 10 // WMode
|
simon |
0:cc002f2fad97
|
118
|
| 0 << 8 // DMode[1:0]
|
simon |
0:cc002f2fad97
|
119
|
| 0 << 6 // TY[1:0]
|
simon |
0:cc002f2fad97
|
120
|
| 3 << 4 // ID[1:0]
|
simon |
0:cc002f2fad97
|
121
|
| 0 << 3 // AM
|
simon |
0:cc002f2fad97
|
122
|
| 0 << 0 // LG[2:0]
|
simon |
0:cc002f2fad97
|
123
|
);
|
simon |
0:cc002f2fad97
|
124
|
_cs = 1;
|
simon |
0:cc002f2fad97
|
125
|
|
simon |
0:cc002f2fad97
|
126
|
cls();
|
simon |
0:cc002f2fad97
|
127
|
}
|
simon |
0:cc002f2fad97
|
128
|
|
simon |
0:cc002f2fad97
|
129
|
void EA_QVGALCD::pixel(int x, int y, int colour) {
|
simon |
0:cc002f2fad97
|
130
|
window(x, y, 1, 1);
|
simon |
0:cc002f2fad97
|
131
|
putp(colour);
|
simon |
0:cc002f2fad97
|
132
|
}
|
simon |
0:cc002f2fad97
|
133
|
|
simon |
0:cc002f2fad97
|
134
|
int EA_QVGALCD::width() { return 240; }
|
simon |
0:cc002f2fad97
|
135
|
int EA_QVGALCD::height() { return 320; }
|
simon |
0:cc002f2fad97
|
136
|
|
simon |
0:cc002f2fad97
|
137
|
|
simon |
0:cc002f2fad97
|
138
|
void EA_QVGALCD::command(int value) {
|
simon |
0:cc002f2fad97
|
139
|
_spi.write(value & 0xFF);
|
simon |
0:cc002f2fad97
|
140
|
}
|
simon |
0:cc002f2fad97
|
141
|
|
simon |
0:cc002f2fad97
|
142
|
void EA_QVGALCD::data(int value) {
|
simon |
0:cc002f2fad97
|
143
|
_spi.write(value | 0x100);
|
simon |
0:cc002f2fad97
|
144
|
}
|
simon |
0:cc002f2fad97
|
145
|
|
simon |
0:cc002f2fad97
|
146
|
void EA_QVGALCD::config(int index, int value) {
|
simon |
0:cc002f2fad97
|
147
|
command(0);
|
simon |
0:cc002f2fad97
|
148
|
command(index);
|
simon |
0:cc002f2fad97
|
149
|
data(value >> 8);
|
simon |
0:cc002f2fad97
|
150
|
data(value);
|
simon |
0:cc002f2fad97
|
151
|
}
|
simon |
0:cc002f2fad97
|
152
|
|
simon |
0:cc002f2fad97
|
153
|
|
simon |
0:cc002f2fad97
|
154
|
void EA_QVGALCD::window(int x, int y, int w, int h) {
|
simon |
0:cc002f2fad97
|
155
|
_cs = 0;
|
simon |
0:cc002f2fad97
|
156
|
|
simon |
0:cc002f2fad97
|
157
|
int hstart = x;
|
simon |
0:cc002f2fad97
|
158
|
int hend = x + w - 1;
|
simon |
0:cc002f2fad97
|
159
|
int vstart = y;
|
simon |
0:cc002f2fad97
|
160
|
int vend = y + h - 1;
|
simon |
0:cc002f2fad97
|
161
|
config(0x44, (hend << 8) | hstart);
|
simon |
0:cc002f2fad97
|
162
|
config(0x45, vstart);
|
simon |
0:cc002f2fad97
|
163
|
config(0x46, vend);
|
simon |
0:cc002f2fad97
|
164
|
|
simon |
0:cc002f2fad97
|
165
|
config(0x4E, hstart & 0xFF);
|
simon |
0:cc002f2fad97
|
166
|
config(0x4F, vstart & 0x1FF);
|
simon |
0:cc002f2fad97
|
167
|
command(0);
|
simon |
0:cc002f2fad97
|
168
|
command(0x22);
|
simon |
0:cc002f2fad97
|
169
|
|
simon |
0:cc002f2fad97
|
170
|
_cs = 1;
|
simon |
0:cc002f2fad97
|
171
|
}
|
simon |
0:cc002f2fad97
|
172
|
|
simon |
0:cc002f2fad97
|
173
|
void EA_QVGALCD::putp(int colour) {
|
simon |
0:cc002f2fad97
|
174
|
_cs = 0;
|
simon |
0:cc002f2fad97
|
175
|
int top = ((colour >> (8+8)) & 0xF8) // r7-3
|
simon |
0:cc002f2fad97
|
176
|
| ((colour >> (5+8)) & 0x07); // g7-5
|
simon |
0:cc002f2fad97
|
177
|
int bottom = ((colour >> 5) & 0xE0) // g4-2
|
simon |
0:cc002f2fad97
|
178
|
| ((colour >> 3) & 0x1F); // b7-3
|
simon |
0:cc002f2fad97
|
179
|
|
simon |
0:cc002f2fad97
|
180
|
data(top);
|
simon |
0:cc002f2fad97
|
181
|
data(bottom);
|
simon |
0:cc002f2fad97
|
182
|
_cs = 1;
|
simon |
0:cc002f2fad97
|
183
|
}
|
simon |
0:cc002f2fad97
|
184
|
|