3 * @author Shinichiro Nakamura
4 * @brief ディスプレイタスクの実装(task_display)
6 * ディスプレイタスクは有機ELディスプレイを制御するタスクである。
7 * ディスプレイの制御は以下のマクロを使って行うことができる。
10 * DISP_LINE(x1, y1, x2, y2, r, g, b);
11 * DISP_BOX(x1, y1, x2, y2, r, g, b);
12 * DISP_FILLBOX(x1, y1, x2, y2, r1, g1, b1, r2, g2, b2);
13 * DISP_TEXT(x, y, r, g, b, "text");
14 * DISP_BMPFILE("filename");
22 #include "kernel_cfg.h"
23 #include "task_display.h"
28 static const uint8_t FONT_X = 5;
29 static const uint8_t FONT_Y = 7;
30 static const uint16_t FONT_MIN_CODE = 0x20;
31 static const uint16_t FONT_MAX_CODE = 0x7F;
32 static const uint8_t font5x7_data[] = {
33 0x00, 0x00, 0x00, 0x00, 0x00, // (white space)
34 0x00, 0x00, 0x5F, 0x00, 0x00, // !
35 0x00, 0x07, 0x00, 0x07, 0x00, // "
36 0x14, 0x7F, 0x14, 0x7F, 0x14, // #
37 0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
38 0x23, 0x13, 0x08, 0x64, 0x62, // %
39 0x36, 0x49, 0x55, 0x22, 0x50, // &
40 0x00, 0x05, 0x03, 0x00, 0x00, // '
41 0x00, 0x1C, 0x22, 0x41, 0x00, // (
42 0x00, 0x41, 0x22, 0x1C, 0x00, // )
43 0x08, 0x2A, 0x1C, 0x2A, 0x08, // *
44 0x08, 0x08, 0x3E, 0x08, 0x08, // +
45 0x00, 0x50, 0x30, 0x00, 0x00, // ,
46 0x08, 0x08, 0x08, 0x08, 0x08, // -
47 0x00, 0x60, 0x60, 0x00, 0x00, // .
48 0x20, 0x10, 0x08, 0x04, 0x02, // /
49 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
50 0x00, 0x42, 0x7F, 0x40, 0x00, // 1
51 0x42, 0x61, 0x51, 0x49, 0x46, // 2
52 0x21, 0x41, 0x45, 0x4B, 0x31, // 3
53 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
54 0x27, 0x45, 0x45, 0x45, 0x39, // 5
55 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
56 0x01, 0x71, 0x09, 0x05, 0x03, // 7
57 0x36, 0x49, 0x49, 0x49, 0x36, // 8
58 0x06, 0x49, 0x49, 0x29, 0x1E, // 9
59 0x00, 0x36, 0x36, 0x00, 0x00, // :
60 0x00, 0x56, 0x36, 0x00, 0x00, // ;
61 0x00, 0x08, 0x14, 0x22, 0x41, // <
62 0x14, 0x14, 0x14, 0x14, 0x14, // =
63 0x41, 0x22, 0x14, 0x08, 0x00, // >
64 0x02, 0x01, 0x51, 0x09, 0x06, // ?
65 0x32, 0x49, 0x79, 0x41, 0x3E, // @
66 0x7E, 0x11, 0x11, 0x11, 0x7E, // A
67 0x7F, 0x49, 0x49, 0x49, 0x36, // B
68 0x3E, 0x41, 0x41, 0x41, 0x22, // C
69 0x7F, 0x41, 0x41, 0x22, 0x1C, // D
70 0x7F, 0x49, 0x49, 0x49, 0x41, // E
71 0x7F, 0x09, 0x09, 0x01, 0x01, // F
72 0x3E, 0x41, 0x41, 0x51, 0x32, // G
73 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
74 0x00, 0x41, 0x7F, 0x41, 0x00, // I
75 0x20, 0x40, 0x41, 0x3F, 0x01, // J
76 0x7F, 0x08, 0x14, 0x22, 0x41, // K
77 0x7F, 0x40, 0x40, 0x40, 0x40, // L
78 0x7F, 0x02, 0x04, 0x02, 0x7F, // M
79 0x7F, 0x04, 0x08, 0x10, 0x7F, // N
80 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
81 0x7F, 0x09, 0x09, 0x09, 0x06, // P
82 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
83 0x7F, 0x09, 0x19, 0x29, 0x46, // R
84 0x46, 0x49, 0x49, 0x49, 0x31, // S
85 0x01, 0x01, 0x7F, 0x01, 0x01, // T
86 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
87 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
88 0x7F, 0x20, 0x18, 0x20, 0x7F, // W
89 0x63, 0x14, 0x08, 0x14, 0x63, // X
90 0x03, 0x04, 0x78, 0x04, 0x03, // Y
91 0x61, 0x51, 0x49, 0x45, 0x43, // Z
92 0x00, 0x00, 0x7F, 0x41, 0x41, // [
93 0x02, 0x04, 0x08, 0x10, 0x20, // /
94 0x41, 0x41, 0x7F, 0x00, 0x00, // ]
95 0x04, 0x02, 0x01, 0x02, 0x04, // ^
96 0x40, 0x40, 0x40, 0x40, 0x40, // _
97 0x00, 0x01, 0x02, 0x04, 0x00, // `
98 0x20, 0x54, 0x54, 0x54, 0x78, // a
99 0x7F, 0x48, 0x44, 0x44, 0x38, // b
100 0x38, 0x44, 0x44, 0x44, 0x20, // c
101 0x38, 0x44, 0x44, 0x48, 0x7F, // d
102 0x38, 0x54, 0x54, 0x54, 0x18, // e
103 0x08, 0x7E, 0x09, 0x01, 0x02, // f
104 0x08, 0x14, 0x54, 0x54, 0x3C, // g
105 0x7F, 0x08, 0x04, 0x04, 0x78, // h
106 0x00, 0x44, 0x7D, 0x40, 0x00, // i
107 0x20, 0x40, 0x44, 0x3D, 0x00, // j
108 0x00, 0x7F, 0x10, 0x28, 0x44, // k
109 0x00, 0x41, 0x7F, 0x40, 0x00, // l
110 0x7C, 0x04, 0x18, 0x04, 0x78, // m
111 0x7C, 0x08, 0x04, 0x04, 0x78, // n
112 0x38, 0x44, 0x44, 0x44, 0x38, // o
113 0x7C, 0x14, 0x14, 0x14, 0x08, // p
114 0x08, 0x14, 0x14, 0x18, 0x7C, // q
115 0x7C, 0x08, 0x04, 0x04, 0x08, // r
116 0x48, 0x54, 0x54, 0x54, 0x20, // s
117 0x04, 0x3F, 0x44, 0x40, 0x20, // t
118 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
119 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
120 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
121 0x44, 0x28, 0x10, 0x28, 0x44, // x
122 0x0C, 0x50, 0x50, 0x50, 0x3C, // y
123 0x44, 0x64, 0x54, 0x4C, 0x44, // z
124 0x00, 0x08, 0x36, 0x41, 0x00, // {
125 0x00, 0x00, 0x7F, 0x00, 0x00, // |
126 0x00, 0x41, 0x36, 0x08, 0x00, // }
127 0x08, 0x08, 0x2A, 0x1C, 0x08, // ->
128 0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
132 FATFS fatfs[_VOLUMES];
140 void disp_clear(const uint8_t r, const uint8_t g, const uint8_t b)
143 get_mpf(MPF_DISPLAY, &vp);
144 ((display_msg_t*)vp)->cmd = DISPLAY_CMD_CLEAR;
145 display_clear_t *param =
146 (display_clear_t *)&(((display_msg_t*)vp)->param);
150 snd_mbx(MBX_DISPLAY, vp);
163 get_mpf(MPF_DISPLAY, &vp);
164 ((display_msg_t*)vp)->cmd = DISPLAY_CMD_LINE;
165 display_line_t *param =
166 (display_line_t *)&(((display_msg_t*)vp)->param);
174 snd_mbx(MBX_DISPLAY, vp);
187 get_mpf(MPF_DISPLAY, &vp);
188 ((display_msg_t*)vp)->cmd = DISPLAY_CMD_BOX;
189 display_box_t *param =
190 (display_box_t *)&(((display_msg_t*)vp)->param);
198 snd_mbx(MBX_DISPLAY, vp);
214 get_mpf(MPF_DISPLAY, &vp);
215 ((display_msg_t*)vp)->cmd = DISPLAY_CMD_FILLBOX;
216 display_fillbox_t *param =
217 (display_fillbox_t *)&(((display_msg_t*)vp)->param);
228 snd_mbx(MBX_DISPLAY, vp);
242 get_mpf(MPF_DISPLAY, &vp);
243 ((display_msg_t*)vp)->cmd = DISPLAY_CMD_TEXT;
244 display_text_t *param =
245 (display_text_t *)&(((display_msg_t*)vp)->param);
254 param->text[i] = *strp;
258 param->text[i] = '\0';
259 snd_mbx(MBX_DISPLAY, vp);
262 void disp_bmpfile(const char *filename)
267 get_mpf(MPF_DISPLAY, &vp);
268 ((display_msg_t*)vp)->cmd = DISPLAY_CMD_BMPFILE;
269 display_bmpfile_t *param =
270 (display_bmpfile_t *)&(((display_msg_t*)vp)->param);
271 strp = (char *)filename;
274 param->filename[i++] = *strp;
277 param->filename[i++] = '\0';
278 snd_mbx(MBX_DISPLAY, vp);
281 void disp_audio_levelmeter(const int left, const int right)
284 get_mpf(MPF_DISPLAY, &vp);
285 ((display_msg_t*)vp)->cmd = DISPLAY_CMD_AUDIO_LEVELMETER;
286 display_audio_levelmeter_t *param =
287 (display_audio_levelmeter_t *)&(((display_msg_t*)vp)->param);
289 param->right = right;
290 snd_mbx(MBX_DISPLAY, vp);
293 void cmd_clear(display_clear_t *p)
300 oled_fill_box(0, 0, OLED_X - 1, OLED_Y - 1, c, c);
303 void cmd_line(display_line_t *p)
310 oled_draw_line(p->x1, p->y1, p->x2, p->y2, c);
313 void cmd_box(display_box_t *p)
320 oled_draw_line(p->x1, p->y1, p->x2, p->y1, c);
321 oled_draw_line(p->x2, p->y1, p->x2, p->y2, c);
322 oled_draw_line(p->x2, p->y2, p->x1, p->y2, c);
323 oled_draw_line(p->x1, p->y2, p->x1, p->y1, c);
326 void cmd_fillbox(display_fillbox_t *p)
336 oled_fill_box(p->x1, p->y1, p->x2, p->y2, c1, c2);
339 void draw_char(uint8_t x, uint8_t y, char c, Color *col) {
341 if ((FONT_MIN_CODE <= c) &&(c <= FONT_MAX_CODE)) {
342 int aofs = (c - FONT_MIN_CODE) * FONT_X;
343 for (i = 0; i < FONT_X; i++) {
344 uint8_t pat = font5x7_data[aofs + i];
345 for (j = 0; j < FONT_Y; j++) {
346 if (pat & (1 << j)) {
347 oled_draw_pixel(x + i, y + j, *col);
352 for (i = 0; i < FONT_X; i++) {
353 uint8_t pat = (i % 2) ? 0x55 : 0xAA;
354 for (j = 0; j < FONT_Y; j++) {
355 if (pat & (1 << j)) {
356 oled_draw_pixel(x + i, y + j, *col);
363 void cmd_text(display_text_t *p)
370 char *strp = p->text;
373 draw_char(p->x + (FONT_X * cnt), p->y, *strp, &col);
383 FRESULT fr = f_read(&work.fil, &c, 1, &n);
384 return ((fr == FR_OK) ? c : -1);
387 void dispfunc(int x, int y, int r, int g, int b)
390 if ((0 <= x) && (0 <= y) && (x < OLED_X) && (y < OLED_Y)) {
394 oled_draw_pixel(x, y, c);
398 void cmd_bmpfile(display_bmpfile_t *p)
402 bmp_rgbquad_t bmprgbquad;
404 int a = f_mount(0, &work.fatfs[0]);
405 int b = f_opendir(&work.dir, "");
406 if ((a == 0) && (b == 0)) {
407 FRESULT res = f_open(
408 &work.fil, p->filename, FA_OPEN_EXISTING|FA_READ);
410 bmplowio_header_read(ff_getc, &bmpfile, &bmpinfo);
411 if (have_palette(&bmpinfo)) {
412 bmplowio_palette_read(
415 (1 << bmpinfo.biBitCount));
423 syslog(LOG_NOTICE, "file open failed.(%d)", res);
426 syslog(LOG_NOTICE, "mount failed.");
430 void cmd_audio_levelmeter(display_audio_levelmeter_t *p)
440 static const int LVW = OLED_X;
441 static const int LVH = 2;
442 static const int LVOFSX = 0;
443 static const int LVOFSY = 10;
445 unsigned int PL = ((((uint32_t)p->left ) ^ 0x80000000) >> 24) - 128;
446 unsigned int PR = ((((uint32_t)p->right) ^ 0x80000000) >> 24) - 128;
449 if (PL < 0) { PL = 0; }
450 if (PR < 0) { PR = 0; }
451 if (LVW <= PL) { PL = LVW - 1; }
452 if (LVW <= PR) { PR = LVW - 1; }
458 LVOFSX + 0, LVOFSY + 0,
459 LVOFSX + PL - 1, LVOFSY + LVH - 1,
462 LVOFSX + PL, LVOFSY + 0,
463 LVOFSX + OLED_X - 1, LVOFSY + LVH - 1,
470 LVOFSX + 0, LVOFSY + LVH,
471 LVOFSX + PR - 1, LVOFSY + LVH + LVH - 1,
474 LVOFSX + PR, LVOFSY + LVH,
475 LVOFSX + OLED_X - 1, LVOFSY + LVH + LVH - 1,
479 void task_display(intptr_t exinf)
487 oled_clear(0, 0, OLED_X - 1, OLED_Y - 1);
495 if (rcv_mbx(MBX_DISPLAY, (T_MSG**)&p) == E_OK) {
497 * コマンドによってパラメータの型が決まる。
500 uint8_t cmd = ((display_msg_t*)p)->cmd;
501 void* param = ((display_msg_t*)p)->param;
503 case DISPLAY_CMD_CLEAR:
504 cmd_clear((display_clear_t *)param);
506 case DISPLAY_CMD_LINE:
507 cmd_line((display_line_t *)param);
509 case DISPLAY_CMD_BOX:
510 cmd_box((display_box_t *)param);
512 case DISPLAY_CMD_FILLBOX:
513 cmd_fillbox((display_fillbox_t *)param);
515 case DISPLAY_CMD_TEXT:
516 cmd_text((display_text_t *)param);
518 case DISPLAY_CMD_BMPFILE:
519 cmd_bmpfile((display_bmpfile_t *)param);
521 case DISPLAY_CMD_AUDIO_LEVELMETER:
522 cmd_audio_levelmeter((display_audio_levelmeter_t *)param);
525 syslog(LOG_NOTICE, "Unknown command number %d.", cmd);
528 rel_mpf(MPF_DISPLAY, (VP)p);