1 | //-------------------------------------------------------------------------------------------------
|
2 | //
|
3 | //-------------------------------------------------------------------------------------------------
|
4 | #include <avr/io.h>
|
5 |
|
6 | //#define INTERFACE_8_BIT
|
7 |
|
8 | // save program memory -> we do not use _delay_us()
|
9 | // 1 nop per MHz (adapt if needed)
|
10 | #define DELAY_1US \
|
11 | { \
|
12 | __asm__ __volatile__("nop"); \
|
13 | __asm__ __volatile__("nop"); \
|
14 | __asm__ __volatile__("nop"); \
|
15 | __asm__ __volatile__("nop"); \
|
16 | __asm__ __volatile__("nop"); \
|
17 | __asm__ __volatile__("nop"); \
|
18 | __asm__ __volatile__("nop"); \
|
19 | __asm__ __volatile__("nop"); \
|
20 | __asm__ __volatile__("nop"); \
|
21 | __asm__ __volatile__("nop"); \
|
22 | __asm__ __volatile__("nop"); \
|
23 | __asm__ __volatile__("nop"); \
|
24 | }
|
25 |
|
26 |
|
27 |
|
28 | #define CMD_DISPLAY_CLEAR 0x01
|
29 | #define CMD_RETURN_HOME 0x02
|
30 | #define CMD_ENTRY_MODE 0x04
|
31 | #define CMD_DISPLAY_CONTROL 0x08
|
32 | #define CMD_CURSOR_CONTROL 0x10
|
33 | #define CMD_FUNCTION_SET 0x20
|
34 | #define CMD_SET_CGRAM_ADR 0x40
|
35 | #define CMD_SET_DDRAM_ADR 0x80
|
36 |
|
37 | #define CMDE_STANDBY 0x01
|
38 | #define CMDE_SCROLL_SEL 0x02
|
39 | #define CMDE_REVERSE_LINE 0x04
|
40 | #define CMDE_SET_SCROLL_ADR 0x40
|
41 | #define CMDE_SET_GDRAM_ADR 0x80
|
42 |
|
43 | #define BIT_ID 0x02
|
44 | #define BIT_S 0x01
|
45 | #define BIT_D 0x04
|
46 | #define BIT_C 0x02
|
47 | #define BIT_B 0x01
|
48 | #define BIT_SC 0x08
|
49 | #define BIT_SR 0x01
|
50 | #define BIT_RL 0x04
|
51 | #define BIT_DL 0x10
|
52 | #define BIT_RE 0x04
|
53 | #define BIT_G 0x02
|
54 | #define BIT_BUSY 0x80
|
55 |
|
56 | #define MASK_CGRAM_ADR 0x3F
|
57 | #define MASK_DDRAM_ADR 0x3F
|
58 | #define MASK_SCROLL_ADR 0x3F
|
59 | #define MASK_GDRAM_ADR_HOR 0x0F
|
60 | #define MASK_GDRAM_ADR_VER 0x3F
|
61 |
|
62 | #define PORT_BL PORTA
|
63 | #define DDR_BL DDRA
|
64 | #define BIT_BL PA0
|
65 | //#define BL_PIN_USED
|
66 |
|
67 | #ifdef INTERFACE_8_BIT
|
68 | #define PORT_D0 PORTD
|
69 | #define PIN_D0 PIND
|
70 | #define DDR_D0 DDRD
|
71 | #define BIT_D0 PC1
|
72 |
|
73 | #define PORT_D1 PORTD
|
74 | #define PIN_D1 PIND
|
75 | #define DDR_D1 DDRD
|
76 | #define BIT_D1 PD3
|
77 |
|
78 | #define PORT_D2 PORTD
|
79 | #define PIN_D2 PIND
|
80 | #define DDR_D2 DDRD
|
81 | #define BIT_D2 PD0
|
82 |
|
83 | #define PORT_D3 PORTD
|
84 | #define PIN_D3 PIND
|
85 | #define DDR_D3 DDRD
|
86 | #define BIT_D3 PD4
|
87 | #endif
|
88 |
|
89 | #define PORT_D4 PORTC
|
90 | #define PIN_D4 PINC
|
91 | #define DDR_D4 DDRC
|
92 | #define BIT_D4 PC0
|
93 |
|
94 | #define PORT_D5 PORTC
|
95 | #define PIN_D5 PINC
|
96 | #define DDR_D5 DDRC
|
97 | #define BIT_D5 PC1
|
98 |
|
99 | #define PORT_D6 PORTC
|
100 | #define PIN_D6 PINC
|
101 | #define DDR_D6 DDRC
|
102 | #define BIT_D6 PC2
|
103 |
|
104 | #define PORT_D7 PORTC
|
105 | #define PIN_D7 PINC
|
106 | #define DDR_D7 DDRC
|
107 | #define BIT_D7 PC3
|
108 |
|
109 | #define PORT_E PORTB
|
110 | #define DDR_E DDRB
|
111 | #define BIT_E PB2
|
112 |
|
113 | #define PORT_RW PORTB
|
114 | #define DDR_RW DDRB
|
115 | #define BIT_RW PB3
|
116 |
|
117 | #define PORT_RS PORTB
|
118 | #define DDR_RS DDRB
|
119 | #define BIT_RS PB1
|
120 |
|
121 | #define PORT_RES PORTB
|
122 | #define DDR_RES DDRB
|
123 | #define BIT_RES PB1
|
124 | //#define RESET_PIN_USED
|
125 |
|
126 | #define RS_DATA 1
|
127 | #define RS_CMD 0
|
128 |
|
129 |
|
130 | static uint8_t G_ExtendedMode = 0;
|
131 |
|
132 | static void RS (uint8_t val)
|
133 | {
|
134 | if (val)
|
135 | PORT_RS |= (1<<BIT_RS);
|
136 | else
|
137 | PORT_RS &= ~(1<<BIT_RS);
|
138 | }
|
139 |
|
140 | static void E (uint8_t val)
|
141 | {
|
142 | if (val)
|
143 | PORT_E |= (1<<BIT_E);
|
144 | else
|
145 | PORT_E &= ~(1<<BIT_E);
|
146 | }
|
147 |
|
148 | static void RW (uint8_t val)
|
149 | {
|
150 | if (val)
|
151 | PORT_RW |= (1<<BIT_RW);
|
152 | else
|
153 | PORT_RW &= ~(1<<BIT_RW);
|
154 | }
|
155 |
|
156 | #ifdef RESET_PIN_USED
|
157 | static void RES (uint8_t val)
|
158 | {
|
159 | if (val)
|
160 | PORT_RES |= (1<<BIT_RES);
|
161 | else
|
162 | PORT_RES &= ~(1<<BIT_RES);
|
163 | }
|
164 | #endif
|
165 |
|
166 | #ifdef BL_PIN_USED
|
167 | static void Backlight (uint8_t val)
|
168 | {
|
169 | if (val)
|
170 | PORT_BL |= (1<<BIT_BL);
|
171 | else
|
172 | PORT_BL &= ~(1<<BIT_BL);
|
173 | }
|
174 | #endif
|
175 |
|
176 | __attribute__ ((noinline)) void Delay (uint32_t dval)
|
177 | {
|
178 | while (dval--)
|
179 | DELAY_1US;
|
180 | }
|
181 |
|
182 | //-------------------------------------------------------------------------------------------------
|
183 | //
|
184 | //-------------------------------------------------------------------------------------------------
|
185 |
|
186 | static void GLCD_InitPorts(void)
|
187 | {
|
188 | RS(0);
|
189 | RW(1);
|
190 | E(0);
|
191 | #ifdef RESET_PIN_USED
|
192 | RES(1);
|
193 | DDR_RES |= (1<<BIT_RES);
|
194 | #endif
|
195 |
|
196 | DDR_E |= (1<<BIT_E);
|
197 | DDR_RW |= (1<<BIT_RW);
|
198 | DDR_RS |= (1<<BIT_RS);
|
199 |
|
200 | #ifdef INTERFACE_8_BIT
|
201 | DDR_D0 &= ~(1<<BIT_D0);
|
202 | DDR_D1 &= ~(1<<BIT_D1);
|
203 | DDR_D2 &= ~(1<<BIT_D2);
|
204 | DDR_D3 &= ~(1<<BIT_D3);
|
205 | #endif
|
206 | DDR_D4 &= ~(1<<BIT_D4);
|
207 | DDR_D5 &= ~(1<<BIT_D5);
|
208 | DDR_D6 &= ~(1<<BIT_D6);
|
209 | DDR_D7 &= ~(1<<BIT_D7);
|
210 | }
|
211 |
|
212 | static void SetDataOutput (void)
|
213 | {
|
214 | #ifdef INTERFACE_8_BIT
|
215 | DDR_D0 |= (1<<BIT_D0);
|
216 | DDR_D1 |= (1<<BIT_D1);
|
217 | DDR_D2 |= (1<<BIT_D2);
|
218 | DDR_D3 |= (1<<BIT_D3);
|
219 | #endif
|
220 | DDR_D4 |= (1<<BIT_D4);
|
221 | DDR_D5 |= (1<<BIT_D5);
|
222 | DDR_D6 |= (1<<BIT_D6);
|
223 | DDR_D7 |= (1<<BIT_D7);
|
224 | }
|
225 |
|
226 | static void SetDataInput (void)
|
227 | {
|
228 | #ifdef INTERFACE_8_BIT
|
229 | DDR_D0 &= ~(1<<BIT_D0);
|
230 | DDR_D1 &= ~(1<<BIT_D1);
|
231 | DDR_D2 &= ~(1<<BIT_D2);
|
232 | DDR_D3 &= ~(1<<BIT_D3);
|
233 | #endif
|
234 | DDR_D4 &= ~(1<<BIT_D4);
|
235 | DDR_D5 &= ~(1<<BIT_D5);
|
236 | DDR_D6 &= ~(1<<BIT_D6);
|
237 | DDR_D7 &= ~(1<<BIT_D7);
|
238 | }
|
239 |
|
240 | static void DataOut (uint8_t data)
|
241 | {
|
242 | #ifdef INTERFACE_8_BIT
|
243 | if (data&0x01) PORT_D0 |= (1<<BIT_D0); else PORT_D0 &= ~(1<<BIT_D0);
|
244 | if (data&0x02) PORT_D1 |= (1<<BIT_D1); else PORT_D1 &= ~(1<<BIT_D1);
|
245 | if (data&0x04) PORT_D2 |= (1<<BIT_D2); else PORT_D2 &= ~(1<<BIT_D2);
|
246 | if (data&0x08) PORT_D3 |= (1<<BIT_D3); else PORT_D3 &= ~(1<<BIT_D3);
|
247 | if (data&0x10) PORT_D4 |= (1<<BIT_D4); else PORT_D4 &= ~(1<<BIT_D4);
|
248 | if (data&0x20) PORT_D5 |= (1<<BIT_D5); else PORT_D5 &= ~(1<<BIT_D5);
|
249 | if (data&0x40) PORT_D6 |= (1<<BIT_D6); else PORT_D6 &= ~(1<<BIT_D6);
|
250 | if (data&0x80) PORT_D7 |= (1<<BIT_D7); else PORT_D7 &= ~(1<<BIT_D7);
|
251 | #else
|
252 | if (data&0x01) PORT_D4 |= (1<<BIT_D4); else PORT_D4 &= ~(1<<BIT_D4);
|
253 | if (data&0x02) PORT_D5 |= (1<<BIT_D5); else PORT_D5 &= ~(1<<BIT_D5);
|
254 | if (data&0x04) PORT_D6 |= (1<<BIT_D6); else PORT_D6 &= ~(1<<BIT_D6);
|
255 | if (data&0x08) PORT_D7 |= (1<<BIT_D7); else PORT_D7 &= ~(1<<BIT_D7);
|
256 | #endif
|
257 | SetDataOutput();
|
258 | }
|
259 |
|
260 |
|
261 | static uint8_t DataIn (void)
|
262 | {
|
263 | uint8_t data=0;
|
264 |
|
265 | #ifdef INTERFACE_8_BIT
|
266 | PORT_D0 &= ~(1<<BIT_D0);
|
267 | PORT_D1 &= ~(1<<BIT_D1);
|
268 | PORT_D2 &= ~(1<<BIT_D2);
|
269 | PORT_D3 &= ~(1<<BIT_D3);
|
270 | #endif
|
271 | PORT_D4 &= ~(1<<BIT_D4);
|
272 | PORT_D5 &= ~(1<<BIT_D5);
|
273 | PORT_D6 &= ~(1<<BIT_D6);
|
274 | PORT_D7 &= ~(1<<BIT_D7);
|
275 |
|
276 | SetDataInput();
|
277 |
|
278 | data = (data<<1) | ((PIN_D7>>BIT_D7)&1);
|
279 | data = (data<<1) | ((PIN_D6>>BIT_D6)&1);
|
280 | data = (data<<1) | ((PIN_D5>>BIT_D5)&1);
|
281 | data = (data<<1) | ((PIN_D4>>BIT_D4)&1);
|
282 | #ifdef INTERFACE_8_BIT
|
283 | data = (data<<1) | ((PIN_D3>>BIT_D3)&1);
|
284 | data = (data<<1) | ((PIN_D2>>BIT_D2)&1);
|
285 | data = (data<<1) | ((PIN_D1>>BIT_D1)&1);
|
286 | data = (data<<1) | ((PIN_D0>>BIT_D0)&1);
|
287 | #endif
|
288 |
|
289 | return(data);
|
290 | }
|
291 |
|
292 |
|
293 | //-------------------------------------------------------------------------------------------------
|
294 | // Read
|
295 | //-------------------------------------------------------------------------------------------------
|
296 | static uint8_t GLCD_rawRead(uint8_t regsel)
|
297 | {
|
298 | uint8_t tmp;
|
299 |
|
300 | E(0);
|
301 | SetDataInput();
|
302 | RS(regsel);
|
303 | RW(1);
|
304 | Delay(1);
|
305 | E(1);
|
306 | Delay(1);
|
307 | tmp = DataIn();
|
308 | E(0);
|
309 | Delay(1);
|
310 | #ifndef INTERFACE_8_BIT
|
311 | E(1);
|
312 | Delay(1);
|
313 | tmp <<= 4;
|
314 | tmp |= DataIn();
|
315 | E(0);
|
316 | Delay(1);
|
317 | #endif
|
318 |
|
319 | return tmp;
|
320 | }
|
321 |
|
322 | //-------------------------------------------------------------------------------------------------
|
323 | // Wait Busy
|
324 | //-------------------------------------------------------------------------------------------------
|
325 | static void GLCD_WaitBusy(void)
|
326 | {
|
327 | while(GLCD_rawRead(0)&BIT_BUSY);
|
328 | }
|
329 |
|
330 | //-------------------------------------------------------------------------------------------------
|
331 | // Read
|
332 | //-------------------------------------------------------------------------------------------------
|
333 | static uint8_t GLCD_Read(uint8_t regsel)
|
334 | {
|
335 | uint8_t tmp;
|
336 |
|
337 | E(0);
|
338 | SetDataInput();
|
339 | RS(regsel);
|
340 | RW(1);
|
341 | Delay(1);
|
342 | E(1);
|
343 | Delay(1);
|
344 | tmp = DataIn();
|
345 | E(0);
|
346 | Delay(1);
|
347 | #ifndef INTERFACE_8_BIT
|
348 | E(1);
|
349 | Delay(1);
|
350 | tmp <<= 4;
|
351 | tmp |= DataIn();
|
352 | E(0);
|
353 | Delay(1);
|
354 | #endif
|
355 | GLCD_WaitBusy();
|
356 |
|
357 | return tmp;
|
358 | }
|
359 |
|
360 | //-------------------------------------------------------------------------------------------------
|
361 | // Write
|
362 | //-------------------------------------------------------------------------------------------------
|
363 | static void GLCD_Write(uint8_t regsel, uint8_t val)
|
364 | {
|
365 | SetDataOutput();
|
366 | RS(regsel);
|
367 | RW(0);
|
368 | #ifdef INTERFACE_8_BIT
|
369 | DataOut(val);
|
370 | Delay(1);
|
371 | E(1);
|
372 | Delay(1);
|
373 | E(0);
|
374 | #else
|
375 | DataOut(val>>4);
|
376 | Delay(1);
|
377 | E(1);
|
378 | Delay(1);
|
379 | E(0);
|
380 | DataOut(val&0xF);
|
381 | Delay(1);
|
382 | E(1);
|
383 | Delay(1);
|
384 | E(0);
|
385 | #endif
|
386 | RW(1);
|
387 | RS(1);
|
388 | SetDataInput();
|
389 |
|
390 | GLCD_WaitBusy();
|
391 |
|
392 | }
|
393 | //-------------------------------------------------------------------------------------------------
|
394 | // BasicMode
|
395 | //-------------------------------------------------------------------------------------------------
|
396 | static void GLCD_SetBasicMode(void)
|
397 | {
|
398 | if (G_ExtendedMode)
|
399 | {
|
400 | #ifdef INTERFACE_8_BIT
|
401 | GLCD_Write(RS_CMD,CMD_FUNCTION_SET|BIT_DL);
|
402 | #else
|
403 | GLCD_Write(RS_CMD,CMD_FUNCTION_SET);
|
404 | #endif
|
405 | G_ExtendedMode = 0;
|
406 | }
|
407 | }
|
408 |
|
409 | //-------------------------------------------------------------------------------------------------
|
410 | // ExtendedMode
|
411 | //-------------------------------------------------------------------------------------------------
|
412 | static void GLCD_SetExtendedMode(void)
|
413 | {
|
414 | if (!G_ExtendedMode)
|
415 | {
|
416 | #ifdef INTERFACE_8_BIT
|
417 | GLCD_Write(RS_CMD,CMD_FUNCTION_SET|BIT_DL|BIT_RE|BIT_G);
|
418 | #else
|
419 | GLCD_Write(RS_CMD,CMD_FUNCTION_SET|BIT_RE|BIT_G);
|
420 | #endif
|
421 | G_ExtendedMode = 1;
|
422 | }
|
423 | }
|
424 |
|
425 | //-------------------------------------------------------------------------------------------------
|
426 | // ClearTXT
|
427 | //-------------------------------------------------------------------------------------------------
|
428 | void GLCD_ClearTXT(void)
|
429 | {
|
430 | GLCD_SetBasicMode();
|
431 | GLCD_Write(RS_CMD,CMD_DISPLAY_CLEAR);
|
432 | GLCD_WaitBusy();
|
433 | }
|
434 |
|
435 | //-------------------------------------------------------------------------------------------------
|
436 | // ClearGFX
|
437 | //-------------------------------------------------------------------------------------------------
|
438 | void GLCD_ClearGFX(void)
|
439 | {
|
440 | uint8_t x,y;
|
441 |
|
442 | GLCD_SetExtendedMode();
|
443 | GLCD_Write(RS_CMD,CMDE_SET_GDRAM_ADR);
|
444 | GLCD_Write(RS_CMD,CMDE_SET_GDRAM_ADR);
|
445 |
|
446 | for (y=0;y<64;y++)
|
447 | {
|
448 | GLCD_Write(RS_CMD,CMDE_SET_GDRAM_ADR|(MASK_GDRAM_ADR_VER&y));
|
449 | GLCD_Write(RS_CMD,CMDE_SET_GDRAM_ADR);
|
450 | for (x=0;x<32;x++)
|
451 | GLCD_Write(RS_DATA,0x0);
|
452 | }
|
453 | }
|
454 |
|
455 | //-------------------------------------------------------------------------------------------------
|
456 | // SetPixel
|
457 | //-------------------------------------------------------------------------------------------------
|
458 | void GLCD_SetPixel(uint8_t x,uint8_t y, uint8_t color)
|
459 | {
|
460 | uint8_t subpos;
|
461 | uint8_t pix;
|
462 | uint8_t pixel_low;
|
463 | uint8_t pixel_high;
|
464 |
|
465 | GLCD_SetExtendedMode();
|
466 | GLCD_Write(RS_CMD,CMDE_SET_GDRAM_ADR|(MASK_GDRAM_ADR_VER&y));
|
467 | GLCD_Write(RS_CMD,CMDE_SET_GDRAM_ADR|(MASK_GDRAM_ADR_HOR&(x>>4)));
|
468 | GLCD_Read(RS_DATA);
|
469 | pixel_high = GLCD_Read(RS_DATA);
|
470 | pixel_low = GLCD_Read(RS_DATA);
|
471 |
|
472 | subpos = x & 0x0F;
|
473 | GLCD_Write(RS_CMD,CMDE_SET_GDRAM_ADR|(MASK_GDRAM_ADR_VER&y));
|
474 | GLCD_Write(RS_CMD,CMDE_SET_GDRAM_ADR|(MASK_GDRAM_ADR_HOR&(x>>4)));
|
475 |
|
476 | if (subpos < 8)
|
477 | {
|
478 | pix = color ? (1<<(7-subpos))|pixel_high : (~(1<<(7-subpos)))&pixel_high;
|
479 | GLCD_Write(RS_DATA,pix);
|
480 | GLCD_Write(RS_DATA,pixel_low);
|
481 | }
|
482 | else
|
483 | {
|
484 | pix = color ? (1<<(15-subpos))|pixel_low : (~(1<<(7-subpos)))&pixel_low;
|
485 | GLCD_Write(RS_DATA,pixel_high);
|
486 | GLCD_Write(RS_DATA,pix);
|
487 | }
|
488 | }
|
489 |
|
490 | //-------------------------------------------------------------------------------------------------
|
491 | // Vertical Offset
|
492 | //-------------------------------------------------------------------------------------------------
|
493 | void GLCD_VerticalOffset(uint8_t offs)
|
494 | {
|
495 | GLCD_SetExtendedMode();
|
496 |
|
497 |
|
498 | GLCD_Write(RS_CMD,CMDE_SCROLL_SEL|BIT_SR);
|
499 | GLCD_Write(RS_CMD,CMDE_SET_SCROLL_ADR|(MASK_SCROLL_ADR&offs));
|
500 | GLCD_Write(RS_CMD,CMDE_SCROLL_SEL);
|
501 | GLCD_WaitBusy();
|
502 | }
|
503 |
|
504 |
|
505 |
|
506 | //-------------------------------------------------------------------------------------------------
|
507 | //
|
508 | //-------------------------------------------------------------------------------------------------
|
509 | void GLCD_WriteString(uint8_t x, uint8_t y,char * s)
|
510 | {
|
511 | GLCD_SetBasicMode();
|
512 | GLCD_Write(RS_CMD,CMD_SET_DDRAM_ADR|(y*16+(x&0x1E)));
|
513 | if (x&1)
|
514 | GLCD_Write(RS_DATA,' ');
|
515 | while(*s)
|
516 | {
|
517 | GLCD_Write(RS_DATA,*s);
|
518 | s++;
|
519 | }
|
520 | }
|
521 |
|
522 |
|
523 |
|
524 | //-------------------------------------------------------------------------------------------------
|
525 | //
|
526 | //-------------------------------------------------------------------------------------------------
|
527 | void GLCD_Init(void)
|
528 | {
|
529 | GLCD_InitPorts();
|
530 |
|
531 | #ifdef RESET_PIN_USED
|
532 | RES(0);
|
533 | Delay(10000);
|
534 | RES(1);
|
535 | #endif
|
536 |
|
537 | Delay(100000);
|
538 |
|
539 | #ifdef INTERFACE_8_BIT
|
540 | GLCD_Write(RS_CMD,CMD_FUNCTION_SET|BIT_DL);
|
541 | GLCD_Write(RS_CMD,CMD_FUNCTION_SET|BIT_DL);
|
542 | #else
|
543 | GLCD_Write(RS_CMD,CMD_FUNCTION_SET);
|
544 | GLCD_Write(RS_CMD,CMD_FUNCTION_SET);
|
545 | #endif
|
546 | GLCD_Write(RS_CMD,CMD_DISPLAY_CONTROL|BIT_D);
|
547 | Delay(100);
|
548 | GLCD_Write(RS_CMD,CMD_DISPLAY_CLEAR);
|
549 | Delay(100);
|
550 | GLCD_Write(RS_CMD,CMD_ENTRY_MODE|BIT_ID);
|
551 | Delay(100);
|
552 | G_ExtendedMode = 0;
|
553 | }
|