3 * @author Shinichiro Nakamura
4 * @brief メニュータスクの実装(task_menu)
6 * メニュータスクはユーザにシステムのサービスを提示し、
7 * ユーザからの要求をシステムに伝達する役目を果たす。
8 * ユーザからの入力はそれらを管理するタスクからの通知に依存する。
15 #include "kernel_cfg.h"
16 #include "task_menu.h"
18 #include "task_display.h"
19 #include "task_audio.h"
23 #define MSG_DEVICE(n) (((n) & 0xF000) >> 12)
24 #define MSG_VALUE(n) (((n) & 0x0FFF) >> 0)
48 void (*func)(ACTION act);
51 static PAGEID curr_page = PAGE_TOP;
57 menu_work_t menu_work;
59 #define DISP_MENUNAME(NAME) \
61 TSKAPI_DISPLAY_FILLBOX(0, 0, OLED_X - 1, 8, \
64 TSKAPI_DISPLAY_TEXT(0, 0, 0xFF, 0xFF, 0xFF, (NAME)); \
67 #define DISP_MENUTAG(A,B,C,D) \
69 TSKAPI_DISPLAY_FILLBOX(0, 52, OLED_X - 1, OLED_Y - 1, \
72 TSKAPI_DISPLAY_TEXT(2 + (24 * 0), 52, 0xFF, 0xFF, 0xFF, (A)); \
73 TSKAPI_DISPLAY_TEXT(2 + (24 * 1), 52, 0xFF, 0xFF, 0xFF, (B)); \
74 TSKAPI_DISPLAY_TEXT(2 + (24 * 2), 52, 0xFF, 0xFF, 0xFF, (C)); \
75 TSKAPI_DISPLAY_TEXT(2 + (24 * 3), 52, 0xFF, 0xFF, 0xFF, (D)); \
78 void page_splash(ACTION act)
85 void page_top(ACTION act)
88 TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
89 DISP_MENUNAME("[TOP]");
90 DISP_MENUTAG("M-1", "M-2", "M-3", "VER");
92 if (act == PAGE_TICK) {
94 for (i = 0; i < 4; i++) {
95 static const int MAXVAL = (1023/ 32);
96 static const int XOFS = 10;
97 static const int YOFS = 18;
98 int val = MAXVAL - (menu_work.val[i] / 32);
99 TSKAPI_DISPLAY_FILLBOX(
100 XOFS + i * 20, YOFS + 0,
101 XOFS + i * 20 + 10, YOFS + val,
104 TSKAPI_DISPLAY_FILLBOX(
105 XOFS + i * 20, YOFS + val,
106 XOFS + i * 20 + 10, YOFS + MAXVAL,
110 if (!TASK_AUDIO_ENABLED()) {
111 TSKAPI_DISPLAY_TEXT(10, 8, 0xFF, 0xFF, 0xFF, "AUDIO DISABLED");
114 if (act == PAGE_OUT) {
115 TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
119 void page_100(ACTION act)
121 if (act == PAGE_IN) {
122 TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
123 DISP_MENUNAME("[MENU-1]");
124 TSKAPI_DISPLAY_TEXT(20, 30, 0xFF, 0xFF, 0xFF, "-- MENU 1 --");
125 DISP_MENUTAG("", "", "", "RET");
127 if (act == PAGE_OUT) {
128 TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
132 void page_200(ACTION act)
134 if (act == PAGE_IN) {
135 TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
136 DISP_MENUNAME("[MENU-2]");
137 TSKAPI_DISPLAY_TEXT(20, 30, 0xFF, 0xFF, 0xFF, "-- MENU 2 --");
138 DISP_MENUTAG("", "", "", "RET");
140 if (act == PAGE_OUT) {
141 TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
145 void page_300(ACTION act)
147 if (act == PAGE_IN) {
148 TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
149 DISP_MENUNAME("[MENU-3]");
150 TSKAPI_DISPLAY_TEXT(20, 30, 0xFF, 0xFF, 0xFF, "-- MENU 3 --");
151 DISP_MENUTAG("", "", "", "RET");
153 if (act == PAGE_OUT) {
154 TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
158 void page_ver(ACTION act)
160 if (act == PAGE_IN) {
161 TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
162 DISP_MENUNAME("[Version]");
163 TSKAPI_DISPLAY_TEXT(20, 30, 0xFF, 0xFF, 0xFF, "Preliminary");
164 DISP_MENUTAG("", "", "", "RET");
166 if (act == PAGE_OUT) {
167 TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
171 static const menu_t menu[6] = {
172 {PAGE_TOP, {PAGE_100, PAGE_200, PAGE_300, PAGE_VER}, page_top},
173 {PAGE_100, {PAGE_100, PAGE_100, PAGE_100, PAGE_TOP}, page_100},
174 {PAGE_200, {PAGE_200, PAGE_200, PAGE_200, PAGE_TOP}, page_200},
175 {PAGE_300, {PAGE_300, PAGE_300, PAGE_300, PAGE_TOP}, page_300},
176 {PAGE_VER, {PAGE_VER, PAGE_VER, PAGE_VER, PAGE_TOP}, page_ver}
179 void execute_pagefunc(PAGEID page, ACTION act)
182 for (i = 0; i < sizeof(menu) / sizeof(menu[0]); i++) {
183 if (menu[i].curr_page == page) {
184 if (menu[i].func != NULL) {
192 PAGEID get_next_page(PAGEID page, int sw)
195 for (i = 0; i < sizeof(menu) / sizeof(menu[0]); i++) {
196 if (menu[i].curr_page == page) {
197 return menu[i].next_page[sw];
205 static const int XOFS = 5;
206 static const int YOFS = 10;
207 static const int YSTP = 12;
209 TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
210 TSKAPI_DISPLAY_BMPFILE("0:LOGO.BMP");
213 TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
214 TSKAPI_DISPLAY_TEXT(XOFS + 0, YOFS + YSTP * 0,
215 0xFF, 0xFF, 0xFF, "Special thanks to");
216 TSKAPI_DISPLAY_TEXT(XOFS + 22, YOFS + YSTP * 2,
217 0xFF, 0xFF, 0xFF, "Horie-san");
218 TSKAPI_DISPLAY_TEXT(XOFS + 20, YOFS + YSTP * 3,
219 0xFF, 0xFF, 0xFF, "Kaneko-san");
223 #define SCREEN_SAVE_COUNTER_INIT 100
225 void task_menu(intptr_t exinf)
227 volatile uint16_t msg;
228 volatile uint16_t screen_save = SCREEN_SAVE_COUNTER_INIT;
232 execute_pagefunc(curr_page, PAGE_IN);
236 * 有機ELディスプレイは焼き付けを起こしやすい。
237 * スクリーンを保護する意味で一定時間の操作がなければ
240 if (screen_save == 0) {
242 * スクリーン焼き付けを防止するための描画を実行する。
244 static uint32_t color = 0;
245 TSKAPI_DISPLAY_CLEAR(
246 (color >> 16) & 0xff,
248 (color >> 0) & 0xff);
253 * 各ページは自身が必要とする再描画を行うだろう。
255 execute_pagefunc(curr_page, PAGE_TICK);
257 * スクリーンセーバ起動カウンタをデクリメントする。
264 * ここではポーリングして、データがなければスルーする。
266 while (prcv_dtq(DTQ_USERINPUT, (intptr_t *)&msg) == E_OK) {
270 if ((DEVICE_SW0 <= MSG_DEVICE(msg))
271 && (MSG_DEVICE(msg) <= DEVICE_SW3)) {
273 * スイッチ入力がある時にはスクリーンセーバカウンタを
276 if (screen_save == 0) {
277 execute_pagefunc(curr_page, PAGE_IN);
279 screen_save = SCREEN_SAVE_COUNTER_INIT;
282 * スイッチがONエッジならばページの遷移処理を実行。
284 if (MSG_VALUE(msg)) {
285 PAGEID next_page = get_next_page(
286 curr_page, MSG_DEVICE(msg));
287 if (next_page != curr_page) {
288 execute_pagefunc(curr_page, PAGE_OUT);
289 curr_page = next_page;
290 execute_pagefunc(curr_page, PAGE_IN);
294 * 押されたスイッチのLEDを点灯させる。
296 switch (MSG_DEVICE(msg)) {
298 TSKAPI_LED_LEDMSG(SWLED0, MSG_VALUE(msg));
301 TSKAPI_LED_LEDMSG(SWLED1, MSG_VALUE(msg));
304 TSKAPI_LED_LEDMSG(SWLED2, MSG_VALUE(msg));
307 TSKAPI_LED_LEDMSG(SWLED3, MSG_VALUE(msg));
314 if ((DEVICE_VOL0 <= MSG_DEVICE(msg))
315 && (MSG_DEVICE(msg) <= DEVICE_VOL3)) {
317 * 作業用変数に与えられたレベルを格納しておく。
319 int ch = MSG_DEVICE(msg) - DEVICE_VOL0;
320 menu_work.val[ch] = MSG_VALUE(msg);
322 * オーディオパラメータをオーディオタスクに伝達する。
324 if (TASK_AUDIO_ENABLED()) {
325 switch (MSG_DEVICE(msg)) {
328 AUDIO_PARAM_VAR0, MSG_VALUE(msg));
332 AUDIO_PARAM_VAR1, MSG_VALUE(msg));
336 AUDIO_PARAM_VAR2, MSG_VALUE(msg));
340 AUDIO_PARAM_VAR3, MSG_VALUE(msg));