/[projet1]/public/oric/hardware/cumulus/fw_dbug/6610.c
Defence Force logotype

Contents of /public/oric/hardware/cumulus/fw_dbug/6610.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1084 - (show annotations)
Sun Jan 19 15:34:29 2014 UTC (5 years, 10 months ago) by dbug
File MIME type: text/plain
File size: 15969 byte(s)
Added an option to switch between two graphical styles.
1 /* Cumulus 18F46K20 Firmware
2 * Nokia 6610 LCD Controller Driver
3 * Copyright 2010 Retromaster.
4 *
5 * This file is part of Cumulus Firmware.
6 *
7 * Cumulus Firmware is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License,
10 * or any later version.
11 *
12 * Cumulus Firmware is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Cumulus Firmware. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "global.h"
22 #include "6610.h"
23
24 #include "delays.h"
25 #include "string.h"
26
27 #include "fonts.h"
28
29 /*
30 Common specs of the modules S1D15G10 and PCF8833.
31 - Resolution: 130x130
32
33 This display has 130x130 pixels with 12bpp (4096 colors) and uses a 9 bit SPI interface.
34 This driver supports only 12bpp (the controller supports also 8bpp and 16bpp).
35
36 Controller compatibility
37 The Nokia 6100 (knockoff) display comes with two different controller which are not fully compatible with each other: NXP PCF8833 and Epson S1D15G10. A possible way to distinguish them is that displays with the NXP controller likely have a brown flexible PCB and Epson a green flexible PCB.
38
39 http://www.xcore.com/projects/nokia-6100-display-driver-pcf8833-controller
40
41 The encoding of 2 pixels is interlaced on 3 bytes:
42 rrrr gggg RED and GREEN for 1st pixel
43 bbbb rrrr BLUE of 1st pixel and RED of 2nd pixel
44 gggg bbbb GREEN and BLUE of 2nd pixel
45
46
47 */
48
49 static const rom uint8_t reverse_table[16] =
50 {
51 0b0000,
52 0b1000,
53 0b0100,
54 0b1100,
55 0b0010,
56 0b1010,
57 0b0110,
58 0b1110,
59 0b0001,
60 0b1001,
61 0b0101,
62 0b1101,
63 0b0011,
64 0b1011,
65 0b0111,
66 0b1111
67 };
68
69
70 static const rom color_set Colors[_ui_style_count][_element_count]=
71 {
72 {
73 // Retromaster default
74 { {0xF, 0xF, 0xF},{0x0, 0x0, 0x8} },
75 { {0x0, 0x0, 0x0},{0xF, 0xF, 0xF} },
76 { {0xF, 0xF, 0xF},{0x0, 0x0, 0x8} },
77 { {0xF, 0xF, 0x0},{0x0, 0x0, 0x8} },
78 { {0x0, 0x8, 0x0},{0xF, 0xF, 0xF} },
79 { {0x8, 0x0, 0x0},{0xF, 0xF, 0xF} },
80 { {0xF, 0xF, 0xF},{0x0, 0x0, 0x8} },
81 { {0xF, 0xF, 0xF},{0x8, 0x0, 0x0} }
82 },
83
84 {
85 // Defence Force grey
86 { {0xF, 0xF, 0xF},{0x0, 0x0, 0x0} },
87 { {0x0, 0x0, 0x0},{0x7, 0x7, 0x7} },
88 { {0xF, 0xF, 0xF},{0x0, 0x0, 0x0} },
89 { {0xF, 0xF, 0x0},{0x0, 0x0, 0x0} },
90 { {0x0, 0x8, 0x0},{0x7, 0x7, 0x7} },
91 { {0x8, 0x0, 0x0},{0x7, 0x7, 0x7} },
92 { {0xF, 0xF, 0xF},{0x0, 0x0, 0x0} },
93 { {0xF, 0x7, 0x0},{0x1, 0x1, 0x1} }
94 }
95 };
96
97 ui_style UiStyle=SETUP_VISUAL;
98
99
100 #pragma udata
101 /* Debugging */
102 uint8_t debug_line_cntr;
103 uint8_t debug_msg_cntr;
104
105 /* Text attributes */
106 static uint8_t invert_mode;
107 static rom uint8_t* font;
108 static uint8_t font_width;
109 static uint8_t font_height;
110 static uint8_t font_draw_height;
111 static uint8_t fill_patterns[12];
112
113 #pragma code
114
115 /* Initialize EUSART module used for 9-bit SPI transmission. */
116 static void init_EUSART(void)
117 {
118 /* Set baud rate */
119 BAUDCONbits.CKTXP = 1;
120 BAUDCONbits.BRG16 = 0;
121 SPBRGH = 0;
122 SPBRG = 1;
123
124 /* Set TRIS bits */
125 TRISCbits.TRISC6 = 1;
126 TRISCbits.TRISC7 = 1;
127
128 /* Synchronous Master mode */
129 TXSTAbits.SYNC = 1;
130 TXSTAbits.CSRC = 1;
131 RCSTAbits.SPEN = 1;
132
133 /* Receive disabled, transmit enabled */
134 RCSTAbits.SREN = 0;
135 RCSTAbits.CREN = 0;
136 TXSTAbits.TXEN = 1;
137
138 /* 9-bit transmission */
139 TXSTAbits.TX9 = 1;
140 }
141
142 /* Write given command byte to LCD */
143 static void n6610_write_command(uint8_t command)
144 {
145 uint8_t value;
146
147 /* Move highest bit into TX9D */
148 if (command & 0x80)
149 TXSTAbits.TX9D = 1;
150 else
151 TXSTAbits.TX9D = 0;
152
153 /* Command byte */
154 value = (command << 1);
155
156 /* Wait until EUSART transmitter is free */
157 while (!TXSTAbits.TRMT);
158 TXREG = value;
159 }
160
161 /* Write given data byte to LCD */
162 static void n6610_write_data(uint8_t data)
163 {
164 uint8_t value;
165
166 /* Move highest bit into TX9D */
167 if (data & 0x80)
168 TXSTAbits.TX9D = 1;
169 else
170 TXSTAbits.TX9D = 0;
171
172 /* Data byte */
173 value = (data << 1) | 1;
174
175 /* Wait until EUSART transmitter is free */
176 while (!TXSTAbits.TRMT);
177 TXREG = value;
178 }
179
180 #ifdef PCF8833
181
182 /* Initialize LCD controller */
183 void n6610_init(void)
184 {
185 /* Initialize EUSART module for 9-bit synchronous transmission */
186 init_EUSART();
187
188 /* Setup RST and CS pins */
189 TRISCbits.TRISC0 = 0;
190 TRISCbits.TRISC1 = 0;
191
192 /* Reset */
193 PORTCbits.RC1 = 0;
194 Delay1KTCYx(1000);
195 PORTCbits.RC1 = 1;
196 Delay1KTCYx(1000);
197
198 /* Chip Select */
199 PORTCbits.RC0 = 0;
200
201 /* Sleep out (command 0x11) */
202 n6610_write_command(SLEEPOUT);
203
204 /* Color Interface Pixel Format (command 0x3A) */
205 n6610_write_command(COLMOD);
206 n6610_write_data(0xC0); /* 0x03 = 12 bits-per-pixel */
207
208 /* Memory access controller (command 0x36). */
209 n6610_write_command(MADCTL);
210 n6610_write_data(0x06); /* 0xE0 = mirror y, vertical, reverse rgb */
211
212 /* Write contrast (command 0x25) */
213 n6610_write_command(SETCON);
214 n6610_write_data(0x22); /* contrast 0x40 */
215 Delay1KTCYx(2);
216
217 /* Display On (command 0x29) */
218 n6610_write_command(DISPON);
219
220 /* Debugging */
221 debug_line_cntr = 0;
222 debug_msg_cntr = 0;
223
224 /* Text attributes */
225 n6610_set_invert_mode(0);
226 n6610_set_color(0xF, 0xF, 0xF, 0x0, 0x0, 0x0);
227 n6610_set_font(FONT_6X8);
228 }
229 #endif
230
231
232 #ifdef S1D15G10
233
234 /* Initialize LCD controller */
235 void n6610_init(void)
236 {
237 /* Initialize EUSART module for 9-bit synchronous transmission */
238 init_EUSART();
239
240 /* Setup RST and CS pins */
241 TRISCbits.TRISC0 = 0;
242 TRISCbits.TRISC1 = 0;
243
244 /* Reset */
245 PORTCbits.RC1 = 0;
246 Delay1KTCYx(1000);
247 PORTCbits.RC1 = 1;
248 Delay1KTCYx(1000);
249
250 /* Chip Select */
251 PORTCbits.RC0 = 0;
252
253 /* Display control */
254 n6610_write_command(DISCTL);
255 n6610_write_data(0x00); // P1: 0x00 = 2 divisions, switching period=8 (default)
256 n6610_write_data(0x04); // P2: 0x20 = nlines/4 - 1 = 132/4 - 1 = 32)
257 n6610_write_data(0x00); // P3: 0x00 = no inversely highlighted lines
258
259 /* COM scan */
260 n6610_write_command(COMSCN);
261 n6610_write_data(0x80); // P1: 0x01 = Scan 1->80, 160<-81
262
263 /* Internal oscilator ON */
264 n6610_write_command(OSCON);
265
266 /* Sleep out */
267 n6610_write_command(SLPOUT);
268
269 /* Power control */
270 n6610_write_command(PWRCTR);
271 n6610_write_data(0xF0); // reference voltage regulator on, circuit voltage follower on, BOOST ON
272
273 /* Inverse display */
274 n6610_write_command(DISINV);
275
276 /* Data control */
277 n6610_write_command(DATCTL);
278 n6610_write_data(0x60); // P1: 0x05 = page address normal, col address inverted, address scan in page direction
279 n6610_write_data(0x00); // P2: 0x00 = RGB sequence (default value)
280 n6610_write_data(0x40); // P3: 0x02 = Grayscale -> 16 (selects 12-bit color, type A)
281
282 /* Voltage control (contrast setting) */
283 n6610_write_command(VOLCTR);
284 n6610_write_data(0x24); // P1 = 32 volume value (adjust this setting for your display 0 .. 63)
285 n6610_write_data(0xC0); // P2 = 3 resistance ratio (determined by experiment)
286
287 /* allow power supply to stabilize */
288 Delay1KTCYx(100);
289
290 /* turn on the display */
291 n6610_write_command(DISON);
292
293 /* Debugging */
294 debug_line_cntr = 0;
295 debug_msg_cntr = 0;
296
297 /* Text attributes */
298 n6610_set_invert_mode(0);
299 n6610_set_color(0xF, 0xF, 0xF, 0x0, 0x0, 0x0);
300 n6610_set_font(FONT_6X8);
301 }
302 #endif
303
304 static uint8_t reverse_bits(uint8_t value)
305 {
306 uint8_t rev;
307
308 rev = reverse_table[value & 0x0F] << 4;
309 rev |= reverse_table[(value & 0xF0) >> 4];
310
311 return rev;
312 }
313
314 /* Draws given area with given color. Area width must be multiple of 2. */
315 void n6610_fill_area(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
316 {
317 uint8_t i, j, v1, v2, v3;
318
319 x = (x & 0xFE);
320 w = (w & 0xFE);
321
322 /* Page address set */
323 n6610_write_command(CASET);
324 n6610_write_data(reverse_bits(x));
325 n6610_write_data(reverse_bits(x + w - 1));
326
327 /* Column address set */
328 n6610_write_command(PASET);
329 n6610_write_data(reverse_bits(y));
330 n6610_write_data(reverse_bits(y + h - 1));
331
332 /* Fill memory */
333 n6610_write_command(RAMWR);
334
335 for (i = 0; i < w / 2; i++)
336 {
337 for (j = 0; j < h; j++)
338 {
339 n6610_write_data(fill_patterns[0]);
340 n6610_write_data(fill_patterns[1]);
341 n6610_write_data(fill_patterns[2]);
342 }
343 }
344 }
345
346 /* Draws given character in b/w using the 6x8 Font. */
347 void n6610_draw_char(uint8_t x, uint8_t y, char c)
348 {
349 uint8_t i, j, v;
350 rom unsigned char* char_base;
351
352 c -= 31;
353
354 x = (x & 0xFE) | 0x01;
355
356 /* Page address set */
357 n6610_write_command(CASET);
358 n6610_write_data(reverse_bits(x + 1));
359 n6610_write_data(reverse_bits(x + font_width));
360
361 /* Column address set */
362 n6610_write_command(PASET);
363 n6610_write_data(reverse_bits(y));
364 n6610_write_data(reverse_bits(y + font_height - 1));
365
366 /* Fill memory */
367 n6610_write_command(RAMWR);
368
369 char_base = font + ((uint16_t) c) * font_height;
370 for (i = 0; i < font_draw_height; i++)
371 {
372 v = char_base[i];
373 if (invert_mode)
374 v = ~v;
375
376 for (j = 0; j < font_width / 2; j++)
377 {
378 switch (v & 0xC0)
379 {
380 case 0x00:
381 n6610_write_data(fill_patterns[0]);
382 n6610_write_data(fill_patterns[1]);
383 n6610_write_data(fill_patterns[2]);
384 break;
385 case 0x40:
386 n6610_write_data(fill_patterns[3]);
387 n6610_write_data(fill_patterns[4]);
388 n6610_write_data(fill_patterns[5]);
389 break;
390 case 0x80:
391 n6610_write_data(fill_patterns[6]);
392 n6610_write_data(fill_patterns[7]);
393 n6610_write_data(fill_patterns[8]);
394 break;
395 case 0xC0:
396 n6610_write_data(fill_patterns[9]);
397 n6610_write_data(fill_patterns[10]);
398 n6610_write_data(fill_patterns[11]);
399 break;
400 }
401
402 v = v << 2;
403 }
404 }
405 }
406
407 /* Draws given string in b/w using the 6x8 font */
408 void n6610_draw_rom_str(uint8_t x, uint8_t y, const far rom char* c)
409 {
410 while (*c)
411 {
412 n6610_draw_char(x, y, *c);
413 c++;
414 x += font_width;
415 }
416 }
417
418 /* Draws given string in b/w using the 6x8 font */
419 void n6610_draw_ram_str(uint8_t x, uint8_t y, const char* c)
420 {
421 while (*c)
422 {
423 n6610_draw_char(x, y, *c);
424 c++;
425 x += font_width;
426 }
427 }
428
429 /* Hex conversion lookup */
430 #pragma romdata
431 rom char hex_lookup[16] ={
432 '0', '1', '2', '3',
433 '4', '5', '6', '7',
434 '8', '9', 'A', 'B',
435 'C', 'D', 'E', 'F'
436 };
437
438 #pragma code
439
440 /* Puts a debugging message on video output */
441 void n6610_debug_message_ram(const char* msg)
442 {
443 int8_t j;
444 uint8_t val;
445
446 n6610_draw_ram_str(16, debug_line_cntr * 8 + 2, msg);
447
448 /* Print out value in hex */
449 val = debug_msg_cntr;
450 for (j = 1; j >= 0; j--)
451 {
452 n6610_draw_char(j * 6 + 2, debug_line_cntr * 8 + 2, hex_lookup[val & 0xF]);
453 val = val >> 4;
454 }
455
456 /* Next line */
457 debug_msg_cntr++;
458 debug_line_cntr++;
459 if (debug_line_cntr >= 16)
460 debug_line_cntr = 0;
461 //debug_line_cntr = 15;
462 }
463
464 /* Puts a debugging message on video output */
465 void n6610_debug_message(const far rom char* msg)
466 {
467 int8_t j;
468 uint8_t val;
469
470 n6610_draw_rom_str(16, debug_line_cntr * 8 + 2, msg);
471
472 /* Print out value in hex */
473 val = debug_msg_cntr;
474 for (j = 1; j >= 0; j--)
475 {
476 n6610_draw_char(j * 6 + 2, debug_line_cntr * 8 + 2, hex_lookup[val & 0xF]);
477 //n6610_draw_char(j * 6, debug_line_cntr * 8, '0');
478 val = val >> 4;
479 }
480
481 /* Next line */
482 debug_msg_cntr++;
483 debug_line_cntr++;
484 if (debug_line_cntr >= 16)
485 debug_line_cntr = 0;
486 //debug_line_cntr = 15;
487 }
488
489 /* Puts a debugging message on video output */
490 void n6610_debug_long(uint32_t val)
491 {
492 uint8_t j;
493
494 /* Print out value in hex */
495 for (j = 0; j < 8; j++)
496 {
497 n6610_draw_char((7 - j) * 6 + 2, debug_line_cntr * 8 + 2, hex_lookup[val & 0xF]);
498 //n6610_draw_char((7 - j) * 6, debug_line_cntr * 8, '0');
499 val = val >> 4;
500 }
501
502 /* Next line */
503 debug_line_cntr++;
504 if (debug_line_cntr >= 16)
505 debug_line_cntr = 0;
506 }
507
508 /* Puts a debugging message on video output */
509 void n6610_debug(const far rom char* msg, uint8_t val)
510 {
511 uint8_t start;
512 int8_t j;
513
514 // Draw string.
515 n6610_draw_rom_str(16, debug_line_cntr * 8 + 2, msg);
516
517 // Determine length of message.
518 start = strlenpgm(msg) * 6 + 16;
519
520 /* Print out value in hex */
521 for (j = 1; j >= 0; j--)
522 {
523 n6610_draw_char(j * 6 + start, debug_line_cntr * 8 + 2, hex_lookup[val & 0xF]);
524 //n6610_draw_char(j * 6, debug_line_cntr * 8, '0');
525 val = val >> 4;
526 }
527
528 /* Print out value in hex */
529 val = debug_msg_cntr;
530 for (j = 1; j >= 0; j--)
531 {
532 n6610_draw_char(j * 6 + 2, debug_line_cntr * 8 + 2, hex_lookup[val & 0xF]);
533 //n6610_draw_char(j * 6, debug_line_cntr * 8, '0');
534 val = val >> 4;
535 }
536
537 /* Next line */
538 debug_msg_cntr++;
539 debug_line_cntr++;
540 if (debug_line_cntr >= 16)
541 debug_line_cntr = 0;
542 }
543
544 void n6610_debug_message_short(const far rom char* msg, uint16_t val)
545 {
546 uint8_t start;
547 int8_t j;
548
549 // Draw string.
550 n6610_draw_rom_str(16, debug_line_cntr * 8 + 2, msg);
551
552 // Determine length of message.
553 start = strlenpgm(msg) * 6 + 16;
554
555 /* Print out value in hex */
556 for (j = 3; j >= 0; j--)
557 {
558 n6610_draw_char(j * 6 + start, debug_line_cntr * 8 + 2, hex_lookup[val & 0xF]);
559 //n6610_draw_char(j * 6, debug_line_cntr * 8, '0');
560 val = val >> 4;
561 }
562
563 /* Print out value in hex */
564 val = debug_msg_cntr;
565 for (j = 1; j >= 0; j--)
566 {
567 n6610_draw_char(j * 6 + 2, debug_line_cntr * 8 + 2, hex_lookup[val & 0xF]);
568 //n6610_draw_char(j * 6, debug_line_cntr * 8, '0');
569 val = val >> 4;
570 }
571
572 /* Next line */
573 debug_msg_cntr++;
574 debug_line_cntr++;
575 if (debug_line_cntr >= 16)
576 debug_line_cntr = 0;
577 }
578
579 void n6610_set_invert_mode(uint8_t mode)
580 {
581 invert_mode = mode;
582 }
583
584 void n6610_set_font(uint8_t font_id)
585 {
586 if (font_id == FONT_8X14)
587 {
588 font = (rom uint8_t*) _FONT8X16;
589 font_height = 16;
590 font_draw_height = 14;
591 font_width = 8;
592 }
593 else if (font_id == FONT_8X16)
594 {
595 font = (rom uint8_t*) _FONT8X16;
596 font_height = 16;
597 font_draw_height = 16;
598 font_width = 8;
599 }
600 else
601 {
602 font = (rom uint8_t*) _FONT6X8;
603 font_height = 8;
604 font_draw_height = 8;
605 font_width = 6;
606 }
607 }
608
609 void n6610_set_color(uint8_t fr, uint8_t fg, uint8_t fb, uint8_t br, uint8_t bg, uint8_t bb)
610 {
611 br = reverse_table[br & 0x0F];
612 bg = reverse_table[bg & 0x0F];
613 bb = reverse_table[bb & 0x0F];
614 fr = reverse_table[fr & 0x0F];
615 fg = reverse_table[fg & 0x0F];
616 fb = reverse_table[fb & 0x0F];
617
618 fill_patterns[0] = (bg << 4) + br;
619 fill_patterns[1] = (br << 4) + bb;
620 fill_patterns[2] = (bb << 4) + bg;
621
622 fill_patterns[3] = (bg << 4) + br;
623 fill_patterns[4] = (fr << 4) + bb;
624 fill_patterns[5] = (fb << 4) + fg;
625
626 fill_patterns[6] = (fg << 4) + fr;
627 fill_patterns[7] = (br << 4) + fb;
628 fill_patterns[8] = (bb << 4) + bg;
629
630 fill_patterns[9] = (fg << 4) + fr;
631 fill_patterns[10] = (fr << 4) + fb;
632 fill_patterns[11] = (fb << 4) + fg;
633 }
634
635
636
637
638 void n6610_use_color(ui_element element)
639 {
640 const rom color_set* colors=&Colors[UiStyle][element];
641
642 n6610_set_color(
643 colors->foreground.red,
644 colors->foreground.green,
645 colors->foreground.blue,
646 colors->background.red,
647 colors->background.green,
648 colors->background.blue);
649 }
650
651 void n6610_cycle_style()
652 {
653 UiStyle = UiStyle + 1;
654 if (UiStyle >= _ui_style_count)
655 {
656 UiStyle = 0;
657 }
658 }

  ViewVC Help
Powered by ViewVC 1.1.26