-
Notifications
You must be signed in to change notification settings - Fork 3
/
lcd-color-graphic.cpp
241 lines (199 loc) · 6.51 KB
/
lcd-color-graphic.cpp
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
/******************************************************************************
* Display Library
* for an LCD with ILI9341 driver in 16 Bit color mode using 4-wire SPI
* New features in v0.01
* - well... everything.
*****************************************************************************/
#include <SPI.h>
extern "C" {
#include "lcd-color-graphic.h"
#include "font.h"
}
void LCD_INIT_SPI() {
SPI.begin();
// SPI.setClockDivider(SPI_CLOCK_DIV2);
SPI.setFrequency(9000000);
}
void spi_write(uint8_t i) {
SPI.transfer(i);
}
/******************************************************************************
* Global variables for color handling
* Foreground is the normal drawing color
* Background is used as background, e.g. when writing fonts.
*/
color_t foreground = {.red=0x1F, .green=0x3F, .blue=0x1F};
color_t background = {.red=0, .green=0, .blue=0};
/******************************************************************************
* Initializes the display
*/
void lcd_init() {
LCD_SET_PIN_DIRECTIONS(); //set outputs
delay(1);
LCD_INIT_SPI(); //Initialize SPI Interface
delay(50);
LCD_RESET_ON(); //Apply Reset to the Display Controller
delay(100);
LCD_RESET_OFF();
delay(100);
LCD_SELECT(); //Switches chip select on
lcd_command(LCD_SLEEP_OUT); //Wake up LCD
delay(70);
return;
}
/******************************************************************************
* Sends a command to the display
*/
void lcd_command(uint8_t c) {
spi_wait_for_idle();
LCD_CMD();
spi_write(c);
}
/******************************************************************************
* Sends a command with one argument
*/
void lcd_command_1(uint8_t c, uint8_t data) {
lcd_command(c);
lcd_data(data);
}
/******************************************************************************
* Sends a data word to the display
*/
void lcd_data(uint8_t c) {
spi_wait_for_idle();
LCD_DATA();
spi_write(c);
}
/******************************************************************************
* Stores the main drawing color for later use
*/
void lcd_set_foreground(uint8_t r, uint8_t g, uint8_t b) {
foreground.red = r;
foreground.green = g;
foreground.blue = b;
}
/******************************************************************************
* Stores the background color for later use
*/
void lcd_set_background(uint8_t r, uint8_t g, uint8_t b) {
background.red = r;
background.green = g;
background.blue = b;
}
/******************************************************************************
* Sets the column range used for the next write operation
*/
void lcd_set_column(uint16_t start, uint16_t end) {
lcd_command(LCD_SET_COLUMN);
lcd_data(start >> 8);
lcd_data(start);
lcd_data(end >> 8);
lcd_data(end);
}
/******************************************************************************
* Sets the page range used for the next write operation
*/
void lcd_set_page(uint16_t start, uint16_t end) {
lcd_command(LCD_SET_PAGE);
lcd_data(start >> 8);
lcd_data(start);
lcd_data(end >> 8);
lcd_data(end);
}
/******************************************************************************
* Writes a pixel to the display using 16 Bit color mode
*/
void lcd_send_pixel(color_t c) {
lcd_data((c.red<<3) | (c.green>>3));
lcd_data((c.green<<5) | c.blue);
}
/******************************************************************************
* Sets a pixel at a given position
*/
void lcd_set_pixel_xy(uint16_t column, uint16_t page) {
lcd_set_page(page,page);
lcd_set_column(column,column);
lcd_command(LCD_WRITE_MEM);
lcd_send_pixel(foreground);
}
/******************************************************************************
* This function sets an area of the screen to a given color
* col0 - left edge of the area
* col1 - right edge of the area
* page0 - top edge of the area
* page1 - bottom edge of the area
* r,g,b - the color to be used
*/
void lcd_set_area_xy(uint16_t col0, uint16_t col1, uint16_t page0, uint16_t page1) {
lcd_set_column(col0,col1);
lcd_set_page(page0,page1);
lcd_command(LCD_WRITE_MEM);
for(uint16_t y = page0; y <= page1; y++)
for(uint16_t x = col0; x <= col1; x++) {
lcd_send_pixel(background);
}
}
//=============================================================================
//Compatibility functions to accept output of font generator
// Pages are counted in units of 8 pixels!
//=============================================================================
uint16_t lcd_current_page = 0;
uint16_t lcd_current_column = 0;
/******************************************************************************
* Changes the internal cursor by s pages
* s - number of pages to move
*/
uint16_t lcd_inc_page(int16_t s) {
uint16_t p = lcd_current_page;
p += s;
if (p > LCD_HEIGHT/8)
p = 0;
lcd_current_page = p;
return p;
}
/******************************************************************************
* Changes the internal cursor by s columns, including wrapping (if selected)
* s - number of columns to move
*/
uint16_t lcd_inc_column(int16_t s) {
uint16_t c = lcd_current_column;
c += s;
if (c > LCD_WIDTH)
c = 0;
lcd_current_column = c;
return c;
}
/******************************************************************************
* Moves the cursor to the given position
* pages - page to move to
* columns - column to move to
*/
void lcd_moveto_xy(uint16_t page, uint16_t column) {
lcd_current_column = column;
lcd_current_page = page;
}
/******************************************************************************
* Moves the cursor relative to the current position
* pages - number of pages to move
* columns - number of columns to move
*/
void lcd_move_xy(int16_t pages, int16_t columns) {
lcd_moveto_xy(lcd_inc_page(pages),lcd_inc_column(columns));
}
/******************************************************************************
* Takes a vertical byte from the font generator and prints it on the display
* b - Bit pattern to display
*/
void lcd_write_font_byte(uint8_t b) {
lcd_set_page(8*lcd_current_page,8*lcd_current_page+8);
lcd_set_column(lcd_current_column,lcd_current_column);
lcd_command(LCD_WRITE_MEM);
for(uint8_t i=0;i<8;i++) {
if(b&1)
lcd_send_pixel(foreground);
else
lcd_send_pixel(background);
b = b>>1;
}
lcd_inc_column(1);
}