4 #include "oswald_main.h"
5 #include "oswald_watch_faces.h"
7 #include "LcdDisplay.h"
8 #include "oswald_hal.h"
10 #include "oswald_screens.h"
14 void (*screendraw_func)(boolean show_seconds);
18 static idle_data_t idle_screen = {
24 void idle_handle_user_buttons(watch_button button)
28 if (idle_screen.show_seconds)
29 idle_screen.show_seconds = FALSE;
31 idle_screen.show_seconds = TRUE;
34 if (idle_screen.analogue == TRUE) {
35 idle_screen.analogue = FALSE;
36 idle_screen.screendraw_func = DrawLcdDigitalClock;
38 idle_screen.analogue = TRUE;
39 idle_screen.screendraw_func = DrawLcdAnaClock;
43 OswaldState.screen_id = DATETIME_SETTING_SCREEN;
44 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
45 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
51 idle_screen.screendraw_func(idle_screen.show_seconds);
54 void idle_handle_events(u16t event, void *data)
57 case EVENT_ONE_SEC_TIMER:
58 case EVENT_SCREEN_VISIBLE:
59 idle_screen.screendraw_func(idle_screen.show_seconds);
61 case EVENT_USER_BUTTONS:
62 dbg_out("button event %d\n", *(int *)data);
63 idle_handle_user_buttons(*(watch_button *)data);
74 static accelscreen_data_t accel_screen = {
78 void draw_accel_screen(accel_data_t *accel_data)
80 hal_lcd_clear_display();
82 WriteLcdString(2, 2, "X:");
83 WriteLcdNumber(20, 2, accel_data->x);
84 WriteLcdString(2, 18, "Y:");
85 WriteLcdNumber(20, 18, accel_data->y);
86 WriteLcdString(2, 34, "Z:");
87 WriteLcdNumber(20, 34, accel_data->z);
88 hal_lcd_update_display();
91 void accel_handle_events(u16t event, void *data)
94 case EVENT_SCREEN_VISIBLE:
95 draw_accel_screen(&accel_screen.accdata);
97 case EVENT_ACCEL_UPDATE: {
98 accel_data_t *accel_data = (accel_data_t *)data;
99 accel_screen.accdata.x = accel_data->x;
100 accel_screen.accdata.y = accel_data->y;
101 accel_screen.accdata.z = accel_data->z;
102 draw_accel_screen(&accel_screen.accdata);
105 case EVENT_USER_BUTTONS:
106 dbg_out("button event %d\n", *(int *)data);
117 } datetime_setup_data_t;
118 static datetime_setup_data_t dt_setup_screen = {
123 void draw_datetime_setup_screen(datetime_setup_data_t *sdata)
125 hal_lcd_clear_display();
126 SetFont(MetaWatch16);
127 WriteLcdString(2, 2, "Set");
129 SetFont(MetaWatchTime);
130 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
131 WriteLcdCharacter(2, 20, (OswaldClk.hour / 10));
132 WriteLcdCharacter(14, 20, (OswaldClk.hour % 10));
134 WriteLcdCharacter(26, 20, TIME_CHARACTER_COLON_INDEX);
136 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
137 WriteLcdCharacter(31, 20, (OswaldClk.minute / 10));
138 WriteLcdCharacter(43, 20, (OswaldClk.minute % 10));
141 WriteLcdCharacter(55, 20, TIME_CHARACTER_COLON_INDEX);
143 if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2) {
144 WriteLcdCharacter(60, 20, (OswaldClk.second / 10));
145 WriteLcdCharacter(72, 20, (OswaldClk.second % 10));
148 SetFont(MetaWatch16);
149 if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3) {
150 WriteLcdNumber(2, 45, OswaldClk.day);
152 WriteLcdString(18, 45, ".");
153 if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4) {
154 WriteLcdNumber(22, 45, OswaldClk.month);
156 WriteLcdString(38, 45, ".");
157 if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5) {
158 WriteLcdNumber(42, 45, OswaldClk.year);
162 if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) {
163 if (OswaldClk.clk24hr)
164 WriteLcdString(2, 66, "x");
166 WriteLcdString(2, 66, "_");
168 WriteLcdString(15, 66, "24hr");
170 if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) {
171 if (OswaldClk.day_first)
172 WriteLcdString(2, 79, "x");
174 WriteLcdString(2, 79, "_");
176 WriteLcdString(15, 79, "dd.mm. mm/dd");
178 hal_lcd_update_display();
181 void datetime_handle_updown(u8t pos, s8t incr)
185 if (OswaldClk.hour == 0 && incr == -1) {
189 OswaldClk.hour += incr;
190 if (OswaldClk.hour > 23)
194 if (OswaldClk.minute == 0 && incr == -1) {
195 OswaldClk.minute = 59;
198 OswaldClk.minute += incr;
199 if (OswaldClk.minute > 59)
200 OswaldClk.minute = 0;
203 OswaldClk.second = 0;
206 if (OswaldClk.day == 1 && incr == -1) {
210 OswaldClk.day += incr;
211 if (OswaldClk.day > 31)
215 if (OswaldClk.month == 1 && incr == -1) {
216 OswaldClk.month = 12;
219 OswaldClk.month += incr;
220 if (OswaldClk.month > 12)
224 OswaldClk.year += incr;
226 case 6: // 24hr / 12hr
227 if (OswaldClk.clk24hr)
228 OswaldClk.clk24hr = FALSE;
230 OswaldClk.clk24hr = TRUE;
232 case 7: // dd.mm. / mm/dd
233 if (OswaldClk.day_first)
234 OswaldClk.day_first = FALSE;
236 OswaldClk.day_first = TRUE;
242 hal_set_rtc(&OswaldClk, TRUE);
244 hal_set_rtc(&OswaldClk, FALSE);
247 void handle_setup_datetime_buttons(watch_button button, datetime_setup_data_t *sdata)
251 datetime_handle_updown(sdata->pos, 1);
254 datetime_handle_updown(sdata->pos, -1);
263 draw_datetime_setup_screen(sdata);
266 void datetime_setup_events(u16t event, void *data)
269 case EVENT_SCREEN_VISIBLE:
270 dt_setup_screen.pos = 0;
271 draw_datetime_setup_screen(&dt_setup_screen);
272 hal_enable_halfsecond_timer();
274 case EVENT_SCREEN_DESTROY:
275 hal_disable_halfsecond_timer();
277 case EVENT_USER_BUTTONS:
278 dbg_out("button event %d\n", *(int *)data);
279 handle_setup_datetime_buttons(*(watch_button *)data, &dt_setup_screen);
281 case EVENT_HALF_SEC_TIMER:
282 if (dt_setup_screen.on)
283 dt_setup_screen.on = FALSE;
285 dt_setup_screen.on = TRUE;
286 draw_datetime_setup_screen(&dt_setup_screen);
296 } alarm_setup_data_t;
297 static alarm_setup_data_t alarm_setup_screen = {
302 void draw_alarm_setup_screen(alarm_setup_data_t *sdata)
304 hal_lcd_clear_display();
306 SetFont(MetaWatch16);
307 WriteLcdString(2, 2, "Alarm");
309 SetFont(MetaWatchTime);
310 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
311 WriteLcdCharacter(2, 20, (OswaldAlarm.hour / 10));
312 WriteLcdCharacter(14, 20, (OswaldAlarm.hour % 10));
314 WriteLcdCharacter(26, 20, TIME_CHARACTER_COLON_INDEX);
316 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
317 WriteLcdCharacter(31, 20, (OswaldAlarm.minute / 10));
318 WriteLcdCharacter(43, 20, (OswaldAlarm.minute % 10));
321 SetFont(MetaWatchMonospaced10);
322 WriteLcdCharacter(3, 45, 'S');
323 WriteLcdCharacter(15, 45, 'M');
324 WriteLcdCharacter(27, 45, 'T');
325 WriteLcdCharacter(39, 45, 'W');
326 WriteLcdCharacter(51, 45, 'T');
327 WriteLcdCharacter(63, 45, 'F');
328 WriteLcdCharacter(75, 45, 'S');
330 if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2)
331 WriteLcdCharacter(3, 55, (OswaldAlarm.wday & WDAY_SUNDAY) ? 'x' : '_');
332 if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3)
333 WriteLcdCharacter(15, 55, (OswaldAlarm.wday & WDAY_MONDAY) ? 'x' : '_');
334 if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4)
335 WriteLcdCharacter(27, 55, (OswaldAlarm.wday & WDAY_TUESDAY) ? 'x' : '_');
336 if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5)
337 WriteLcdCharacter(39, 55, (OswaldAlarm.wday & WDAY_WEDNESDAY) ? 'x' : '_');
338 if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6)
339 WriteLcdCharacter(51, 55, (OswaldAlarm.wday & WDAY_THURSDAY) ? 'x' : '_');
340 if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7)
341 WriteLcdCharacter(63, 55, (OswaldAlarm.wday & WDAY_FRIDAY) ? 'x' : '_');
342 if ((sdata->pos == 8 && sdata->on) || sdata->pos != 8)
343 WriteLcdCharacter(75, 55, (OswaldAlarm.wday & WDAY_SATURDAY) ? 'x' : '_');
347 if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) {
348 if (OswaldClk.clk24hr)
349 WriteLcdString(2, 66, "x");
351 WriteLcdString(2, 66, "_");
353 WriteLcdString(15, 66, "24hr");
355 if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) {
356 if (OswaldClk.day_first)
357 WriteLcdString(2, 79, "x");
359 WriteLcdString(2, 79, "_");
361 WriteLcdString(15, 79, "dd.mm. mm/dd");
363 hal_lcd_update_display();
366 void alarm_handle_updown(u8t pos, s8t incr)
370 if (OswaldAlarm.hour == 0 && incr == -1) {
371 OswaldAlarm.hour = 23;
374 OswaldAlarm.hour += incr;
375 if (OswaldAlarm.hour > 23)
376 OswaldAlarm.hour = 0;
379 if (OswaldAlarm.minute == 0 && incr == -1) {
380 OswaldAlarm.minute = 59;
383 OswaldAlarm.minute += incr;
384 if (OswaldAlarm.minute > 59)
385 OswaldAlarm.minute = 0;
388 OswaldAlarm.wday ^= WDAY_SUNDAY;
391 OswaldAlarm.wday ^= WDAY_MONDAY;
394 OswaldAlarm.wday ^= WDAY_TUESDAY;
397 OswaldAlarm.wday ^= WDAY_WEDNESDAY;
400 OswaldAlarm.wday ^= WDAY_THURSDAY;
403 OswaldAlarm.wday ^= WDAY_FRIDAY;
406 OswaldAlarm.wday ^= WDAY_SATURDAY;
413 void handle_setup_alarm_buttons(watch_button button, alarm_setup_data_t *sdata)
417 alarm_handle_updown(sdata->pos, 1);
420 alarm_handle_updown(sdata->pos, -1);
429 draw_alarm_setup_screen(sdata);
432 void alarm_setup_events(u16t event, void *data)
435 case EVENT_SCREEN_VISIBLE:
436 alarm_setup_screen.pos = 0;
437 draw_alarm_setup_screen(&alarm_setup_screen);
438 hal_enable_halfsecond_timer();
440 case EVENT_SCREEN_DESTROY:
441 hal_disable_halfsecond_timer();
443 case EVENT_USER_BUTTONS:
444 dbg_out("button event %d\n", *(int *)data);
445 handle_setup_alarm_buttons(*(watch_button *)data, &alarm_setup_screen);
447 case EVENT_HALF_SEC_TIMER:
448 if (alarm_setup_screen.on)
449 alarm_setup_screen.on = FALSE;
451 alarm_setup_screen.on = TRUE;
452 draw_alarm_setup_screen(&alarm_setup_screen);
463 static test_menu_t test_menu = { 0 };
465 void draw_menu_test_screen(void)
467 hal_lcd_clear_display();
468 SetFont(MetaWatch16);
469 WriteLcdString(2, 2, "Menu");
471 WriteLcdString(2, 20, "Item 1");
472 WriteLcdString(2, 29, "Item 2");
473 WriteLcdString(2, 38, "Item 3");
474 WriteLcdString(2, 47, "Item 4");
475 WriteLcdString(2, 56, "Item 5");
477 WriteLcdString(50, 20+(9*test_menu.menu_pos), "*");
478 hal_lcd_update_display();
481 static void handle_menu_user_buttons(watch_button button)
485 test_menu.menu_pos--;
486 test_menu.menu_pos%=5;
489 test_menu.menu_pos++;
490 test_menu.menu_pos%=5;
495 draw_menu_test_screen();
498 void test_menu_handle_events(u16t event, void *data)
501 case EVENT_USER_BUTTONS:
502 dbg_out("button event %d\n", *(int *)data);
503 handle_menu_user_buttons(*(watch_button *)data);
505 case EVENT_SCREEN_VISIBLE:
506 test_menu.menu_pos = 0;
507 draw_menu_test_screen();
526 static stopwatch_data_t stopwatch_screen = { 0, 0, 0, 0, 0, 0, 0, 0, FALSE };
529 static void update_stop_watch_screen(stopwatch_data_t *sdata)
532 SetFont(MetaWatchMonospaced10);
535 WriteLcdNumber(0, 30, sdata->hr);
536 WriteLcdCharacter(14, 30, ':');
537 WriteLcdNumber(19, 30, sdata->min);
538 WriteLcdCharacter(33, 30, ':');
539 WriteLcdNumber(38, 30, sdata->sec);
540 WriteLcdCharacter(52, 30, '.');
541 WriteLcdNumber(57, 30, sdata->csec / 10);
543 WriteLcdNumber(0, 50, sdata->lapse_hr);
544 WriteLcdCharacter(14, 50, ':');
545 WriteLcdNumber(19, 50, sdata->lapse_min);
546 WriteLcdCharacter(33, 50, ':');
547 WriteLcdNumber(38, 50, sdata->lapse_sec);
548 WriteLcdCharacter(52, 50, '.');
549 WriteLcdNumber(57, 50, sdata->lapse_csec / 10);
551 snprintf(tstr, 16, "%02d:%02d:%02d.%1d", sdata->hr, sdata->min, sdata->sec, sdata->csec / 10);
552 WriteLcdString(0, 30, tstr);
553 snprintf(tstr, 16, "%02d:%02d:%02d.%02d", sdata->lapse_hr, sdata->lapse_min, sdata->lapse_sec, sdata->lapse_csec);
554 WriteLcdString(0, 50, tstr);
557 hal_lcd_update_display();
560 static void draw_stop_watch_screen(stopwatch_data_t *sdata)
562 SetFont(MetaWatch16);
563 WriteLcdString(2, 5, "StopWatch");
565 update_stop_watch_screen(sdata);
568 static void handle_stop_watch_buttons(watch_button button)
571 case BUTTON_A: // start/stop
572 if (stopwatch_screen.running) {
573 hal_disable_centisecond_timer();
574 stopwatch_screen.running = FALSE;
576 hal_enable_centisecond_timer();
577 stopwatch_screen.running = TRUE;
580 case BUTTON_B: // lapse
581 stopwatch_screen.lapse_hr = stopwatch_screen.hr;
582 stopwatch_screen.lapse_min = stopwatch_screen.min;
583 stopwatch_screen.lapse_sec = stopwatch_screen.sec;
584 stopwatch_screen.lapse_csec = stopwatch_screen.csec;
586 case BUTTON_F: // reset
587 stopwatch_screen.hr = 0;
588 stopwatch_screen.min = 0;
589 stopwatch_screen.sec = 0;
590 stopwatch_screen.csec = 0;
591 stopwatch_screen.lapse_hr = 0;
592 stopwatch_screen.lapse_min = 0;
593 stopwatch_screen.lapse_sec = 0;
594 stopwatch_screen.lapse_csec = 0;
601 void stop_watch_handle_events(u16t event, void *data)
604 case EVENT_USER_BUTTONS:
605 dbg_out("button event %d\n", *(int *)data);
606 handle_stop_watch_buttons(*(watch_button *)data);
607 update_stop_watch_screen(&stopwatch_screen);
609 case EVENT_SCREEN_VISIBLE:
610 hal_lcd_clear_display();
611 draw_stop_watch_screen(&stopwatch_screen);
613 case EVENT_SCREEN_DESTROY:
614 hal_disable_centisecond_timer();
615 stopwatch_screen.running = FALSE;
618 stopwatch_screen.csec++;
619 if (stopwatch_screen.csec > 99) {
620 stopwatch_screen.csec = 0;
621 stopwatch_screen.sec++;
623 if (stopwatch_screen.sec > 59) {
624 stopwatch_screen.sec = 0;
625 stopwatch_screen.min++;
627 if (stopwatch_screen.min > 59) {
628 stopwatch_screen.min = 0;
629 stopwatch_screen.hr++;
631 if (stopwatch_screen.hr > 59) {
632 stopwatch_screen.hr = 0;
634 if (stopwatch_screen.csec % 10 == 0)
635 update_stop_watch_screen(&stopwatch_screen);
643 void draw_alarm_screen(void)
645 hal_lcd_clear_display();
647 SetFont(MetaWatch16);
648 WriteLcdString(2, 2, "ALARM !");
650 hal_lcd_update_display();
653 void alarm_handle_events(u16t event, void *data)
656 case EVENT_SCREEN_VISIBLE:
658 hal_enable_halfsecond_timer();
659 hal_vibration_set_state(TRUE);
661 case EVENT_SCREEN_DESTROY:
662 hal_disable_halfsecond_timer();
663 hal_lcd_set_backlight(FALSE);
664 hal_vibration_set_state(FALSE);
666 case EVENT_USER_BUTTONS:
667 dbg_out("button event %d\n", *(int *)data);
668 // hal_lcd_set_backlight(FALSE);
670 case EVENT_HALF_SEC_TIMER:
671 hal_lcd_set_backlight(!hal_lcd_get_backlight());
672 hal_vibration_set_state(!hal_vibration_get_state());