-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathdogm-graphic.c
348 lines (322 loc) · 13.3 KB
/
dogm-graphic.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
/******************************************************************************
* Display Library
* for EA-DOGS102 GLCD (102px x 64px)
* EA-DOGM128 GLCD (128px x 64px)
* EA-DOGM132 GLCD (132px x 32px)
* EA-DOGL128 GLCD (128px x 64px)
* EA-DOGXL160 GLCD (160px x 104px)
* EA-DOGXL240 GLCD (240px x 128px)
*
* Provides all basic functions to access the display
* Since no graphics ram is used, the memory footprint is rather small but
* also does not allow to change single pixels. Data written to the LCD can
* not be read back!
* Text can be displayed using the attached font generator containing several
* character sets and font variants.
* Thanks to Oliver Schwaneberg for adding several functions to this library!
*
* Author: Jan Michel (jan at mueschelsoft dot de)
* License: GNU General Public License, version 3
* Version: v0.96 April 2017
* ****************************************************************************
* New features in v0.96
* - added support for EA-DOGXL240 display
* New features in v0.95
* - added initialization for top-view
* - automatic shifting column addresses (e.g. top-view)
* New features in v0.94
* - corrected order of arguments in lcd_clear_area_xy()
* - added command definitions for DOGXL160
* - cleaned up dogm_graphic.h command area
* New features in v0.93
* - modified initialization for DOGM128 and DOGS102
* New features in v0.92
* - Added initialization for DOGS102 and DOGL128
* New features in v0.91
* - Control of chip select pin
* - backlight & chip select are optional - can be turned of in header file
* - added function lcd_draw_image_P
* - added function lcd_draw_image_xy_P
* - added function lcd_clear_area
* - added SPI initialization
*****************************************************************************/
#include "dogm-graphic.h"
//=============================================================================
//keeping track of current position in ram - necessary for big fonts & bitmaps
//=============================================================================
uint8_t lcd_current_page = 0;
uint8_t lcd_current_column = 0;
/******************************************************************************
* Changes the internal cursor by s pages
* s - number of pages to move
*/
uint8_t lcd_inc_page(int8_t s) {
uint8_t p = lcd_current_page;
p += s;
p %= LCD_RAM_PAGES; //all lcd have lcd_ram_pages which is power of two
lcd_current_page = p;
return p;
}
/******************************************************************************
* Changes the internal cursor by s columns, including wrapping (if selected)
* s - number of columns to move
*/
uint8_t lcd_inc_column(int16_t s) {
uint16_t c = lcd_current_column;
c += s;
#if LCD_WRAP_AROUND == 1
while (c >= LCD_WIDTH) {
if (s > 0) lcd_inc_page(1);
else lcd_inc_page(-1);
if (s > 0) c -= LCD_WIDTH;
else c += LCD_WIDTH;
}
#endif
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(uint8_t page, uint8_t column) {
LCD_GOTO_ADDRESS(page,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(int8_t pages, int16_t columns) {
lcd_moveto_xy(lcd_inc_page(pages),lcd_inc_column(columns));
}
//=============================================================================
//Basic Byte Access to Display
//=============================================================================
/******************************************************************************
* Writes one data byte
* data - the data byte
*/
void lcd_data(uint8_t data) {
LCD_SELECT();
LCD_DRAM();
spi_write(data);
LCD_UNSELECT();
lcd_inc_column(1);
}
/******************************************************************************
* Writes one command byte
* cmd - the command byte
*/
void lcd_command(uint8_t cmd) {
LCD_SELECT();
LCD_CMD();
spi_write(cmd);
LCD_UNSELECT();
}
//=============================================================================
//Puts raw data from Flash to the Display
//=============================================================================
#if LCD_INCLUDE_GRAPHIC_FUNCTIONS >= 1
/******************************************************************************
* This function draws a bitmap from the current position on the screen.
* Parameters:
* progmem_image - prog_uint8_t array of columns aka the bitmap image
* pages - height of image in pages
* columns - width of image in pixels (or columns)
* style - Bit2: sets inverse mode
*/
void lcd_draw_image_P(PGM_VOID_P progmem_image, uint8_t pages, uint8_t columns, uint8_t style) {
uint8_t i,j = 0;
uint8_t inv = (style & INVERT_BIT);
while(j<pages && (lcd_get_position_page() < LCD_RAM_PAGES)) {
for (i=0; i<columns && (lcd_get_position_column() < LCD_WIDTH); i++) {
uint8_t tmp = pgm_read_byte(progmem_image++);
if(!inv)
lcd_data(tmp);
else
lcd_data(~tmp);
}
if(++j != pages && lcd_get_position_column() != 0)
lcd_move_xy(1,-columns);
}
}
/******************************************************************************
* This function draws a bitmap at any xy-position on the screen.
* Be aware that some pixels are deleted due to memory organization!
* Parameters:
* progmem_image - prog_uint8_t array of columns aka the bitmap image
* x - x start coordinate on the screen (in pixel)
* y - y start coordinate on the screen (in pixel)
* pages - height of image in pages
* columns - width of image in pixels
* style - Bit2: sets inverse mode
*/
void lcd_draw_image_xy_P(PGM_VOID_P progmem_image, uint8_t x, uint8_t y, uint8_t pages, uint8_t columns, uint8_t style) {
uint16_t i,j;
uint8_t data = 0;
uint8_t inv = style & INVERT_BIT;
uint8_t offset = y & 0x7; //Optimized modulo 8
//If there is an offset, we must use an additional page
if(offset)
pages++;
//If there is not enough vertical space -> cut image
if(pages > LCD_RAM_PAGES - lcd_get_position_page())
pages = LCD_RAM_PAGES - lcd_get_position_page();
//Goto starting point and draw
lcd_moveto_xy((y>>3), x);
for (j=0; j<pages; j++) {
for (i=0; i<columns && (lcd_get_position_column() < LCD_WIDTH); i++){
data = 0;
if (!offset || j+1 != pages)
data = pgm_read_byte(progmem_image+j*columns + i) << offset;
if(j > 0 && offset)
data |= pgm_read_byte(progmem_image+(j-1)*columns + i) >> (8-offset);
if(inv) lcd_data(~data);
else lcd_data(data);
}
if(j+1 != pages)
lcd_move_xy(1,-columns);
}
}
#endif
/******************************************************************************
* This function clears an area of the screen
* pages - height of area in pages
* columns - width of area in pixels
* style - Bit2: sets inverse mode
* Cursor is moved to start of area after clear
*/
void lcd_clear_area(uint8_t pages, uint8_t columns, uint8_t style) {
uint8_t i,j,max;
uint8_t inv = (style & INVERT_BIT)?0xFF:0;
if(pages > (max = LCD_RAM_PAGES - lcd_get_position_page()))
pages = max;
if(columns > (max = LCD_WIDTH - lcd_get_position_column()))
columns = max;
for(j=0; j<pages; j++) {
for(i=0; i<columns; i++) {
lcd_data(inv);
}
lcd_move_xy(1,-columns);
}
lcd_move_xy(-pages,0);
}
/******************************************************************************
* This function clears an area of the screen starting at the given coordinates
* pages - height of area in pages
* columns - width of area in pixels
* style - style modifier
* col - column of upper left corner
* page - page of upper left corner
* Cursor is moved to start of area after clear
*/
void lcd_clear_area_xy(uint8_t pages, uint8_t columns, uint8_t style, uint8_t page, uint8_t col) {
lcd_moveto_xy(page,col);
lcd_clear_area(pages,columns,style);
}
/******************************************************************************
* This function sets the display contrast
* value - contrast level in percent (0 to 100)
*/
#if DISPLAY_TYPE == 240
void lcd_set_contrast(uint8_t value) {
uint8_t x = (uint8_t)((uint16_t)value*255/100); // calculate 0-255 value from percent
LCD_SET_POTI(x);
}
#endif
/******************************************************************************
* Initializes the display in 4x booster for 2.4-3.3V supply voltage
* scheme according to datasheet
* Suitable for all DOGS, DOGM, DOGL and DOGXL displays
* in both bottom or top-view orientation.
*/
void lcd_init() {
LCD_SET_PIN_DIRECTIONS(); //set outputs
LCD_INIT_SPI(); //Initialize SPI Interface
LCD_RESET(); //Apply Reset to the Display Controller
//Load settings
#if DISPLAY_TYPE == 240
//LCD_SYSTEM_RESET; // software reset
//_delay_ms(5); // Gib dem Display ein bisschen Zeit für den Reset
LCD_SET_COM_END(127); // set last COM electrode
LCD_SET_PARTIAL_DISPLAY(0, 127); // set partial display start and end
LCD_SET_POTI(0x8F); // set Contrast to mid range lvl
LCD_SET_MAPPING_CTRL(2); // set mapping control to "bottom view"
LCD_SET_LINE_RATE(11); // set line rate to 9.4 kilo lines per second
LCD_SET_TEMP_COMP(1); // set tmep compensation to -0.10%
LCD_SWITCH_ON(); // set display enable (0xA9)
LCD_SET_DISPLAY_PATTERN(1); // set display pattern (0xD1)
LCD_SET_RAM_ADDR_CTRL(1); // set auto-increment
#endif
#if DISPLAY_TYPE == 160
LCD_SET_COM_END(103); //set last COM electrode
#if ORIENTATION_UPSIDEDOWN == 0
LCD_SET_BOTTOM_VIEW(); //6 o'clock mode, normal orientation
#else
LCD_SET_TOP_VIEW(); //12 o'clock mode, reversed orientation
#endif
LCD_SET_START_LINE(0); //set scrolling to 0
LCD_SET_PANEL_LOAD(3); //set panel loading to 28-38nF
LCD_SET_BIAS_RATIO(3); //set bias ratio
LCD_SET_VOLTAGE_BIAS(0x5F); //set Vbias potentiometer for contrast
LCD_SET_RAM_ADDR_CTRL(1); //set auto-increment
#endif
#if DISPLAY_TYPE == 132
LCD_SET_FIRST_LINE(0); //first bit in RAM is on the first line of the LCD
#if ORIENTATION_UPSIDEDOWN == 0
LCD_SET_BOTTOM_VIEW(); //6 o'clock mode, normal orientation
LCD_ORIENTATION_NORMAL();
#else
LCD_SET_TOP_VIEW(); //12 o'clock mode, reversed orientation
LCD_ORIENTATION_UPSIDEDOWN();
#endif
LCD_SHOW_ALL_PIXELS_OFF(); //Normal Pixel mode
LCD_SET_MODE_POSITIVE(); //positive display
LCD_SET_BIAS_RATIO_1_9(); //bias 1/9
LCD_SET_POWER_CONTROL(7); //power control mode: all features on
LCD_SET_BIAS_VOLTAGE(3); //set voltage regulator R/R
LCD_SET_VOLUME_MODE(0x1F); //volume mode set
LCD_SET_INDICATOR_OFF(); //switch indicator off, no blinking
#endif
#if DISPLAY_TYPE == 128
LCD_SET_FIRST_LINE(0); //first bit in RAM is on the first line of the LCD
#if ORIENTATION_UPSIDEDOWN == 0
LCD_SET_BOTTOM_VIEW(); //6 o'clock mode, normal orientation
LCD_ORIENTATION_NORMAL();
#else
LCD_SET_TOP_VIEW(); //12 o'clock mode, reversed orientation
LCD_ORIENTATION_UPSIDEDOWN();
#endif
LCD_SHOW_ALL_PIXELS_OFF(); //Normal Pixel mode
LCD_SET_MODE_POSITIVE(); //positive display
LCD_SET_BIAS_RATIO_1_7(); //bias 1/7
LCD_SET_POWER_CONTROL(7); //power control mode: all features on
LCD_SET_BIAS_VOLTAGE(7); //set voltage regulator R/R
LCD_SET_VOLUME_MODE(0x06); //volume mode set
LCD_SET_INDICATOR_OFF(); //switch indicator off, no blinking
#endif
#if DISPLAY_TYPE == 102
LCD_SET_FIRST_LINE(0); //first bit in RAM is on the first line of the LCD
#if ORIENTATION_UPSIDEDOWN == 0
LCD_SET_BOTTOM_VIEW(); //6 o'clock mode, normal orientation
LCD_ORIENTATION_NORMAL();
#else
LCD_SET_TOP_VIEW(); //12 o'clock mode, reversed orientation
LCD_ORIENTATION_UPSIDEDOWN();
#endif
LCD_SHOW_ALL_PIXELS_OFF(); //Normal Pixel mode
LCD_SET_MODE_POSITIVE(); //positive display
LCD_SET_BIAS_RATIO_1_9(); //bias 1/9
LCD_SET_POWER_CONTROL(7); //power control mode: all features on
LCD_SET_BIAS_VOLTAGE(7); //set voltage regulator R/R
LCD_SET_VOLUME_MODE(0x9); //volume mode set
LCD_SET_ADV_PROG_CTRL(LCD_TEMPCOMP_HIGH);
#endif
lcd_clear_area_xy(LCD_RAM_PAGES,LCD_WIDTH,NORMAL,0,0); //clear display content
LCD_SWITCH_ON(); //Switch display on
return;
}