OSDN Git Service

Step 10 added.
[kozos-expbrd/kozos_expbrd.git] / firm / junk / 08 / os / lcd.c
1 #include "lcd.h"
2 #include "defines.h"
3
4 static const uint8 FONT_X = 5;
5 static const uint8 FONT_Y = 7;
6 static const uint16 FONT_MIN_CODE = 0x20;
7 static const uint16 FONT_MAX_CODE = 0x7F;
8
9 #define swap(a,b) {int c=a;a=b;b=c;}
10 #define abs(n) (((int)(n) < 0) ? ((int)(n) * (-1)) : (n))
11
12 #define H8_3069F_P4DDR  ((volatile uint8 *)0xFEE003)
13 #define H8_3069F_P4DR   ((volatile uint8 *)0xFFFFD3)
14 #define H8_3069F_CSCR   ((volatile uint8 *)0xFEE01F)
15
16 #define LCD_ADDR_LEFT   ((volatile uint8 *)0x800000)
17 #define LCD_ADDR_RIGHT  ((volatile uint8 *)0xA00000)
18 #define LCD_AOFS_CMD    (0)
19 #define LCD_AOFS_DAT    (1 << 3)
20
21 #define BIT_LCD_RES     (1 << 7)
22 #define BIT_SDC_CS      (1 << 0)
23
24 #define LCD1_CMD(VAL) \
25   do { \
26     *(LCD_ADDR_LEFT + LCD_AOFS_CMD) = (VAL); \
27   } while (0)
28
29 #define LCD1_DAT_WRITE(VAL) \
30   do { \
31     *(LCD_ADDR_LEFT + LCD_AOFS_DAT) = (VAL); \
32   } while (0)
33
34 #define LCD1_DAT_READ() (*(LCD_ADDR_LEFT + LCD_AOFS_DAT))
35
36 #define LCD2_CMD(VAL) \
37   do { \
38     *(LCD_ADDR_RIGHT + LCD_AOFS_CMD) = (VAL); \
39   } while (0)
40
41 #define LCD2_DAT_WRITE(VAL) \
42   do { \
43     *(LCD_ADDR_RIGHT + LCD_AOFS_DAT) = (VAL); \
44   } while (0)
45
46 #define LCD2_DAT_READ() (*(LCD_ADDR_RIGHT + LCD_AOFS_DAT))
47
48 static const uint8 font5x7_data[] = {
49   0x00, 0x00, 0x00, 0x00, 0x00, // (white space)
50   0x00, 0x00, 0x5F, 0x00, 0x00, // !
51   0x00, 0x07, 0x00, 0x07, 0x00, // "
52   0x14, 0x7F, 0x14, 0x7F, 0x14, // #
53   0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
54   0x23, 0x13, 0x08, 0x64, 0x62, // %
55   0x36, 0x49, 0x55, 0x22, 0x50, // &
56   0x00, 0x05, 0x03, 0x00, 0x00, // '
57   0x00, 0x1C, 0x22, 0x41, 0x00, // (
58   0x00, 0x41, 0x22, 0x1C, 0x00, // )
59   0x08, 0x2A, 0x1C, 0x2A, 0x08, // *
60   0x08, 0x08, 0x3E, 0x08, 0x08, // +
61   0x00, 0x50, 0x30, 0x00, 0x00, // ,
62   0x08, 0x08, 0x08, 0x08, 0x08, // -
63   0x00, 0x60, 0x60, 0x00, 0x00, // .
64   0x20, 0x10, 0x08, 0x04, 0x02, // /
65   0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
66   0x00, 0x42, 0x7F, 0x40, 0x00, // 1
67   0x42, 0x61, 0x51, 0x49, 0x46, // 2
68   0x21, 0x41, 0x45, 0x4B, 0x31, // 3
69   0x18, 0x14, 0x12, 0x7F, 0x10, // 4
70   0x27, 0x45, 0x45, 0x45, 0x39, // 5
71   0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
72   0x01, 0x71, 0x09, 0x05, 0x03, // 7
73   0x36, 0x49, 0x49, 0x49, 0x36, // 8
74   0x06, 0x49, 0x49, 0x29, 0x1E, // 9
75   0x00, 0x36, 0x36, 0x00, 0x00, // :
76   0x00, 0x56, 0x36, 0x00, 0x00, // ;
77   0x00, 0x08, 0x14, 0x22, 0x41, // <
78   0x14, 0x14, 0x14, 0x14, 0x14, // =
79   0x41, 0x22, 0x14, 0x08, 0x00, // >
80   0x02, 0x01, 0x51, 0x09, 0x06, // ?
81   0x32, 0x49, 0x79, 0x41, 0x3E, // @
82   0x7E, 0x11, 0x11, 0x11, 0x7E, // A
83   0x7F, 0x49, 0x49, 0x49, 0x36, // B
84   0x3E, 0x41, 0x41, 0x41, 0x22, // C
85   0x7F, 0x41, 0x41, 0x22, 0x1C, // D
86   0x7F, 0x49, 0x49, 0x49, 0x41, // E
87   0x7F, 0x09, 0x09, 0x01, 0x01, // F
88   0x3E, 0x41, 0x41, 0x51, 0x32, // G
89   0x7F, 0x08, 0x08, 0x08, 0x7F, // H
90   0x00, 0x41, 0x7F, 0x41, 0x00, // I
91   0x20, 0x40, 0x41, 0x3F, 0x01, // J
92   0x7F, 0x08, 0x14, 0x22, 0x41, // K
93   0x7F, 0x40, 0x40, 0x40, 0x40, // L
94   0x7F, 0x02, 0x04, 0x02, 0x7F, // M
95   0x7F, 0x04, 0x08, 0x10, 0x7F, // N
96   0x3E, 0x41, 0x41, 0x41, 0x3E, // O
97   0x7F, 0x09, 0x09, 0x09, 0x06, // P
98   0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
99   0x7F, 0x09, 0x19, 0x29, 0x46, // R
100   0x46, 0x49, 0x49, 0x49, 0x31, // S
101   0x01, 0x01, 0x7F, 0x01, 0x01, // T
102   0x3F, 0x40, 0x40, 0x40, 0x3F, // U
103   0x1F, 0x20, 0x40, 0x20, 0x1F, // V
104   0x7F, 0x20, 0x18, 0x20, 0x7F, // W
105   0x63, 0x14, 0x08, 0x14, 0x63, // X
106   0x03, 0x04, 0x78, 0x04, 0x03, // Y
107   0x61, 0x51, 0x49, 0x45, 0x43, // Z
108   0x00, 0x00, 0x7F, 0x41, 0x41, // [
109   0x02, 0x04, 0x08, 0x10, 0x20, // /
110   0x41, 0x41, 0x7F, 0x00, 0x00, // ]
111   0x04, 0x02, 0x01, 0x02, 0x04, // ^
112   0x40, 0x40, 0x40, 0x40, 0x40, // _
113   0x00, 0x01, 0x02, 0x04, 0x00, // `
114   0x20, 0x54, 0x54, 0x54, 0x78, // a
115   0x7F, 0x48, 0x44, 0x44, 0x38, // b
116   0x38, 0x44, 0x44, 0x44, 0x20, // c
117   0x38, 0x44, 0x44, 0x48, 0x7F, // d
118   0x38, 0x54, 0x54, 0x54, 0x18, // e
119   0x08, 0x7E, 0x09, 0x01, 0x02, // f
120   0x08, 0x14, 0x54, 0x54, 0x3C, // g
121   0x7F, 0x08, 0x04, 0x04, 0x78, // h
122   0x00, 0x44, 0x7D, 0x40, 0x00, // i
123   0x20, 0x40, 0x44, 0x3D, 0x00, // j
124   0x00, 0x7F, 0x10, 0x28, 0x44, // k
125   0x00, 0x41, 0x7F, 0x40, 0x00, // l
126   0x7C, 0x04, 0x18, 0x04, 0x78, // m
127   0x7C, 0x08, 0x04, 0x04, 0x78, // n
128   0x38, 0x44, 0x44, 0x44, 0x38, // o
129   0x7C, 0x14, 0x14, 0x14, 0x08, // p
130   0x08, 0x14, 0x14, 0x18, 0x7C, // q
131   0x7C, 0x08, 0x04, 0x04, 0x08, // r
132   0x48, 0x54, 0x54, 0x54, 0x20, // s
133   0x04, 0x3F, 0x44, 0x40, 0x20, // t
134   0x3C, 0x40, 0x40, 0x20, 0x7C, // u
135   0x1C, 0x20, 0x40, 0x20, 0x1C, // v
136   0x3C, 0x40, 0x30, 0x40, 0x3C, // w
137   0x44, 0x28, 0x10, 0x28, 0x44, // x
138   0x0C, 0x50, 0x50, 0x50, 0x3C, // y
139   0x44, 0x64, 0x54, 0x4C, 0x44, // z
140   0x00, 0x08, 0x36, 0x41, 0x00, // {
141   0x00, 0x00, 0x7F, 0x00, 0x00, // |
142   0x00, 0x41, 0x36, 0x08, 0x00, // }
143   0x08, 0x08, 0x2A, 0x1C, 0x08, // ->
144   0x08, 0x1C, 0x2A, 0x08, 0x08  // <-
145 };
146
147 void lcd_init(void)
148 {
149   *H8_3069F_P4DDR = BIT_LCD_RES | BIT_SDC_CS;
150
151   /*
152    * L->H : 68K mode.
153    */
154   *H8_3069F_P4DR &= ~BIT_LCD_RES;
155   asm volatile ("nop");
156   asm volatile ("nop");
157   asm volatile ("nop");
158   asm volatile ("nop");
159   *H8_3069F_P4DR |= BIT_LCD_RES;
160
161   *H8_3069F_CSCR = 0x3F;
162
163   LCD1_CMD(0xE2);   // Reset
164   LCD1_CMD(0xA4);   // Static Drive Off
165   LCD1_CMD(0xC0);   // Display Start Line
166   LCD1_CMD(0xAF);   // Display On
167   LCD1_CMD(0xB8);   // Page Address Setup
168   LCD1_CMD(0x00);   // Column Address
169
170   LCD2_CMD(0xE2);   // Reset
171   LCD2_CMD(0xA4);   // Static Drive Off
172   LCD2_CMD(0xC0);   // Display Start Line
173   LCD2_CMD(0xAF);   // Display On
174   LCD2_CMD(0xB8);   // Page Address Setup
175   LCD2_CMD(0x00);   // Column Address
176 }
177
178 void lcd_clear(void)
179 {
180   int p, c;
181
182   for (p = 0; p <= 3; p++) {
183     LCD1_CMD(0xB8 | (p & 0x03));  // Page Address Setup
184     LCD1_CMD(0x00 | (0 & 0x7F));  // Column Address
185     for (c = 0; c < 62; c++) {
186       LCD1_DAT_WRITE(0);
187     }
188
189     LCD2_CMD(0xB8 | (p & 0x03));  // Page Address Setup
190     LCD2_CMD(0x00 | (0 & 0x7F));  // Column Address
191     for (c = 0; c < 62; c++) {
192       LCD2_DAT_WRITE(0);
193     }
194   }
195 }
196
197 void lcd_set_pixel(int x, int y, int reverse)
198 {
199   volatile uint8 dat;
200   int p, c;
201
202   if (x <= 60) {
203     p = y / 8;
204     c = x;
205     LCD1_CMD(0xB8 | (p & 0x03));  // Page Address Setup
206     LCD1_CMD(0x00 | (c & 0x7F));  // Column Address
207     LCD1_CMD(0xE0);
208     dat = LCD1_DAT_READ();    // Dummy Read
209     dat = LCD1_DAT_READ();    // Real Read
210     if (reverse) {
211       dat |= (1 << (y % 8));
212     } else {
213       dat &= ~(1 << (y % 8));
214     }
215     LCD1_DAT_WRITE(dat);
216     LCD1_CMD(0xEE);
217   } else {
218     p = y / 8;
219     c = x - 61;
220     LCD2_CMD(0xB8 | (p & 0x03));  // Page Address Setup
221     LCD2_CMD(0x00 | (c & 0x7F));  // Column Address
222     LCD2_CMD(0xE0);
223     dat = LCD2_DAT_READ();    // Dummy Read
224     dat = LCD2_DAT_READ();    // Real Read
225     if (reverse) {
226       dat |= (1 << (y % 8));
227     } else {
228       dat &= ~(1 << (y % 8));
229     }
230     LCD2_DAT_WRITE(dat);
231     LCD2_CMD(0xEE);
232   }
233 }
234
235 void lcd_draw_line(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 reverse)
236 {
237   int x;
238   /*
239    * Bresenham's line algorithm
240    */
241   uint8 steep = abs(y2 - y1) > abs(x2 - x1);
242   if (steep) {
243     swap(x1, y1);
244     swap(x2, y2);
245   }
246   if (x1 > x2) {
247     swap(x1, x2);
248     swap(y1, y2);
249   }
250   int deltax = x2 - x1;
251   int deltay = abs(y2 - y1);
252   int error = deltax / 2;
253   int ystep;
254   int y = y1;
255   if (y1 < y2) {
256     ystep = 1;
257   } else {
258     ystep = -1;
259   }
260   for (x = x1; x <= x2; x++) {
261     if (steep) {
262       if (reverse) {
263         lcd_set_pixel(y, x, 0);
264       } else {
265         lcd_set_pixel(y, x, 1);
266       }
267     } else {
268       if (reverse) {
269         lcd_set_pixel(x, y, 0);
270       } else {
271         lcd_set_pixel(x, y, 1);
272       }
273     }
274     error = error - deltay;
275     if (error < 0) {
276       y = y + ystep;
277       error = error + deltax;
278     }
279   }
280 }
281
282 void lcd_draw_box(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 reverse)
283 {
284   int x, y;
285   for (x = x1; x <= x2; x++) {
286     if (reverse) {
287       lcd_set_pixel(x, y1, 0);
288       lcd_set_pixel(x, y2, 0);
289     } else {
290       lcd_set_pixel(x, y1, 1);
291       lcd_set_pixel(x, y2, 1);
292     }
293   }
294   for (y = y1; y <= y2; y++) {
295     if (reverse) {
296       lcd_set_pixel(x1, y, 0);
297       lcd_set_pixel(x2, y, 0);
298     } else {
299       lcd_set_pixel(x1, y, 1);
300       lcd_set_pixel(x2, y, 1);
301     }
302   }
303 }
304
305 void lcd_fill_box(uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 reverse)
306 {
307   int x, y;
308   for (x = x1; x <= x2; x++) {
309     for (y = y1; y <= y2; y++) {
310       if (reverse) {
311         lcd_set_pixel(x, y, 0);
312       } else {
313         lcd_set_pixel(x, y, 1);
314       }
315     }
316   }
317 }
318
319 void lcd_draw_string(uint8 x, uint8 y, char *str, uint8 reverse)
320 {
321   char *p = str;
322   int cnt = 0;
323   while (*p) {
324     lcd_draw_char(x + (FONT_X * cnt), y, *p, reverse);
325     p++;
326     cnt++;
327   }
328 }
329
330 void lcd_draw_char(uint8 x, uint8 y, char c, uint8 reverse)
331 {
332   int i, j;
333   if ((FONT_MIN_CODE <= c) &&(c <= FONT_MAX_CODE)) {
334     int aofs = (c - FONT_MIN_CODE) * FONT_X;
335     for (i = 0; i < FONT_X; i++) {
336       uint8 pat = font5x7_data[aofs + i];
337       for (j = 0; j < FONT_Y; j++) {
338         if (pat & (1 << j)) {
339           if (reverse) {
340             lcd_set_pixel(x + i, y + j, 0);
341           } else {
342             lcd_set_pixel(x + i, y + j, 1);
343           }
344         } else {
345           if (reverse) {
346             lcd_set_pixel(x + i, y + j, 1);
347           } else {
348             lcd_set_pixel(x + i, y + j, 0);
349           }
350         }
351       }
352     }
353   } else {
354     for (i = 0; i < FONT_X; i++) {
355       uint8 pat = (i % 2) ? 0x55 : 0xAA;
356       for (j = 0; j < FONT_Y; j++) {
357         if (pat & (1 << j)) {
358           if (reverse) {
359             lcd_set_pixel(x + i, y + j, 0);
360           } else {
361             lcd_set_pixel(x + i, y + j, 1);
362           }
363         } else {
364           if (reverse) {
365             lcd_set_pixel(x + i, y + j, 1);
366           } else {
367             lcd_set_pixel(x + i, y + j, 0);
368           }
369         }
370       }
371     }
372   }
373 }
374
375 void lcd_draw_checkbox(
376     uint16 x1, uint16 y1, uint16 x2, uint16 y2, uint8 state, uint8 reverse)
377 {
378   lcd_draw_box(x1, y1, x2, y2, reverse);
379   if (state) {
380     lcd_draw_line(x1, y1, x2, y2, reverse);
381     lcd_draw_line(x1, y2, x2, y1, reverse);
382   }
383 }
384
385 void lcd_draw_progressbar(
386     uint16 x1, uint16 y1, uint16 x2, uint16 y2,
387     int min, int max, int value, uint8 reverse)
388 {
389   lcd_draw_box(x1, y1, x2, y2, reverse);
390   if ((value < min) || (max < value)) {
391     return;
392   }
393   int tmp_max = max - min;
394   int tmp_val = value - min;
395   int pix = ((x2 - x1) * tmp_val) / tmp_max;
396   lcd_fill_box(x1 + 1, y1 + 1, x1 + pix - 1, y2 - 1, reverse);
397   lcd_fill_box(x1 + pix, y1 + 1, x2 - 1, y2 - 1, !reverse);
398 }
399