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"
12 #include "timesetup_icon.xbm"
13 #include "stopwatch_icon.xbm"
14 #include "alarm_icon.xbm"
15 #include "startstopbutton_icon.xbm"
16 #include "lapsebutton_icon.xbm"
17 #include "upbutton_icon.xbm"
18 #include "downbutton_icon.xbm"
19 #include "Bluetooth_icon.xbm"
23 void (*screendraw_func)(boolean show_seconds);
27 static idle_data_t idle_screen = {
33 void idle_handle_user_buttons(watch_button button)
37 if (idle_screen.show_seconds)
38 idle_screen.show_seconds = FALSE;
40 idle_screen.show_seconds = TRUE;
43 if (idle_screen.analogue == TRUE) {
44 idle_screen.analogue = FALSE;
45 idle_screen.screendraw_func = DrawLcdDigitalClock;
47 idle_screen.analogue = TRUE;
48 idle_screen.screendraw_func = DrawLcdAnaClock;
52 OswaldState.screen_id = DATETIME_SETTING_SCREEN;
53 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
54 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
60 idle_screen.screendraw_func(idle_screen.show_seconds);
63 void idle_handle_events(u16t event, void *data)
66 case EVENT_ONE_SEC_TIMER:
67 case EVENT_SCREEN_VISIBLE:
68 idle_screen.screendraw_func(idle_screen.show_seconds);
70 case EVENT_USER_BUTTONS:
71 dbg_out("button event %d\n", *(int *)data);
72 idle_handle_user_buttons(*(watch_button *)data);
83 static accelscreen_data_t accel_screen = {
87 void draw_accel_screen(accel_data_t *accel_data)
89 hal_lcd_clear_display();
91 WriteLcdString(2, 2, "X:");
92 WriteLcdNumber(20, 2, accel_data->x);
93 WriteLcdString(2, 18, "Y:");
94 WriteLcdNumber(20, 18, accel_data->y);
95 WriteLcdString(2, 34, "Z:");
96 WriteLcdNumber(20, 34, accel_data->z);
98 WriteLcdString(2, 54, "Light:");
99 WriteLcdNumber(40, 54, accel_data->z);
101 hal_lcd_update_display();
104 void accel_handle_events(u16t event, void *data)
107 case EVENT_SCREEN_VISIBLE:
108 draw_accel_screen(&accel_screen.accdata);
110 case EVENT_ACCEL_UPDATE: {
111 accel_data_t *accel_data = (accel_data_t *)data;
112 accel_screen.accdata.x = accel_data->x;
113 accel_screen.accdata.y = accel_data->y;
114 accel_screen.accdata.z = accel_data->z;
115 draw_accel_screen(&accel_screen.accdata);
118 case EVENT_USER_BUTTONS:
119 dbg_out("button event %d\n", *(int *)data);
130 } datetime_setup_data_t;
131 static datetime_setup_data_t dt_setup_screen = {
136 void draw_datetime_setup_screen(datetime_setup_data_t *sdata)
138 hal_lcd_clear_display();
139 // SetFont(MetaWatch16);
140 // WriteLcdString(2, 2, "Set");
141 oswald_draw_bitmap(36, 0, timesetup_icon_width, timesetup_icon_height, timesetup_icon_bits);
143 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
144 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
146 SetFont(MetaWatchTime);
147 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
148 WriteLcdCharacter(2, 30, (OswaldClk.hour / 10));
149 WriteLcdCharacter(14, 30, (OswaldClk.hour % 10));
151 WriteLcdCharacter(26, 30, TIME_CHARACTER_COLON_INDEX);
153 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
154 WriteLcdCharacter(31, 30, (OswaldClk.minute / 10));
155 WriteLcdCharacter(43, 30, (OswaldClk.minute % 10));
158 WriteLcdCharacter(55, 20, TIME_CHARACTER_COLON_INDEX);
160 if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2) {
161 WriteLcdCharacter(60, 20, (OswaldClk.second / 10));
162 WriteLcdCharacter(72, 20, (OswaldClk.second % 10));
165 SetFont(MetaWatch16);
166 if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2) {
167 WriteLcdCharacter(59, 36, 0x30 + (OswaldClk.second / 10));
168 WriteLcdCharacter(66, 36, 0x30 + (OswaldClk.second % 10));
172 if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3) {
173 WriteLcdNumber(2, 55, OswaldClk.day);
175 WriteLcdString(18, 55, ".");
176 if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4) {
177 WriteLcdNumber(22, 55, OswaldClk.month);
179 WriteLcdString(38, 55, ".");
180 if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5) {
181 WriteLcdNumber(42, 55, OswaldClk.year);
185 if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) {
186 if (OswaldClk.clk24hr)
187 WriteLcdString(2, 76, "x");
189 WriteLcdString(2, 76, "_");
191 WriteLcdString(15, 76, "24hr");
193 if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) {
194 if (OswaldClk.day_first)
195 WriteLcdString(2, 89, "x");
197 WriteLcdString(2, 89, "_");
199 WriteLcdString(15, 89, "dd.mm. mm/dd");
201 hal_lcd_update_display();
204 void datetime_handle_updown(u8t pos, s8t incr)
208 if (OswaldClk.hour == 0 && incr == -1) {
212 OswaldClk.hour += incr;
213 if (OswaldClk.hour > 23)
217 if (OswaldClk.minute == 0 && incr == -1) {
218 OswaldClk.minute = 59;
221 OswaldClk.minute += incr;
222 if (OswaldClk.minute > 59)
223 OswaldClk.minute = 0;
226 OswaldClk.second = 0;
229 if (OswaldClk.day == 1 && incr == -1) {
233 OswaldClk.day += incr;
234 if (OswaldClk.day > 31)
238 if (OswaldClk.month == 1 && incr == -1) {
239 OswaldClk.month = 12;
242 OswaldClk.month += incr;
243 if (OswaldClk.month > 12)
247 OswaldClk.year += incr;
249 case 6: // 24hr / 12hr
250 if (OswaldClk.clk24hr)
251 OswaldClk.clk24hr = FALSE;
253 OswaldClk.clk24hr = TRUE;
255 case 7: // dd.mm. / mm/dd
256 if (OswaldClk.day_first)
257 OswaldClk.day_first = FALSE;
259 OswaldClk.day_first = TRUE;
265 hal_set_rtc(&OswaldClk, TRUE);
267 hal_set_rtc(&OswaldClk, FALSE);
270 void handle_setup_datetime_buttons(watch_button button, datetime_setup_data_t *sdata)
274 datetime_handle_updown(sdata->pos, 1);
277 datetime_handle_updown(sdata->pos, -1);
286 draw_datetime_setup_screen(sdata);
289 void datetime_setup_events(u16t event, void *data)
292 case EVENT_SCREEN_VISIBLE:
293 dt_setup_screen.pos = 0;
294 draw_datetime_setup_screen(&dt_setup_screen);
295 hal_enable_halfsecond_timer();
297 case EVENT_SCREEN_DESTROY:
298 hal_disable_halfsecond_timer();
300 case EVENT_USER_BUTTONS:
301 dbg_out("button event %d\n", *(int *)data);
302 handle_setup_datetime_buttons(*(watch_button *)data, &dt_setup_screen);
304 case EVENT_HALF_SEC_TIMER:
305 if (dt_setup_screen.on)
306 dt_setup_screen.on = FALSE;
308 dt_setup_screen.on = TRUE;
309 draw_datetime_setup_screen(&dt_setup_screen);
324 } alarm_setup_data_t;
325 static alarm_setup_data_t alarm_setup_screen = {
330 void draw_alarm_setup_screen(alarm_setup_data_t *sdata)
332 hal_lcd_clear_display();
334 oswald_draw_bitmap(36, 0, alarm_icon_width, alarm_icon_height, alarm_icon_bits);
336 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
337 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
339 SetFont(MetaWatchTime);
340 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
341 WriteLcdCharacter(22, 30, (OswaldAlarm.hour / 10));
342 WriteLcdCharacter(34, 30, (OswaldAlarm.hour % 10));
344 WriteLcdCharacter(46, 30, TIME_CHARACTER_COLON_INDEX);
346 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
347 WriteLcdCharacter(51, 30, (OswaldAlarm.minute / 10));
348 WriteLcdCharacter(63, 30, (OswaldAlarm.minute % 10));
351 SetFont(MetaWatchMonospaced10);
352 WriteLcdCharacter(3, 55, 'S');
353 WriteLcdCharacter(15, 55, 'M');
354 WriteLcdCharacter(27, 55, 'T');
355 WriteLcdCharacter(39, 55, 'W');
356 WriteLcdCharacter(51, 55, 'T');
357 WriteLcdCharacter(63, 55, 'F');
358 WriteLcdCharacter(75, 55, 'S');
360 if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2)
361 WriteLcdCharacter(3, 65, (OswaldAlarm.wday & WDAY_SUNDAY) ? 'x' : '_');
362 if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3)
363 WriteLcdCharacter(15, 65, (OswaldAlarm.wday & WDAY_MONDAY) ? 'x' : '_');
364 if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4)
365 WriteLcdCharacter(27, 65, (OswaldAlarm.wday & WDAY_TUESDAY) ? 'x' : '_');
366 if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5)
367 WriteLcdCharacter(39, 65, (OswaldAlarm.wday & WDAY_WEDNESDAY) ? 'x' : '_');
368 if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6)
369 WriteLcdCharacter(51, 65, (OswaldAlarm.wday & WDAY_THURSDAY) ? 'x' : '_');
370 if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7)
371 WriteLcdCharacter(63, 65, (OswaldAlarm.wday & WDAY_FRIDAY) ? 'x' : '_');
372 if ((sdata->pos == 8 && sdata->on) || sdata->pos != 8)
373 WriteLcdCharacter(75, 65, (OswaldAlarm.wday & WDAY_SATURDAY) ? 'x' : '_');
375 hal_lcd_update_display();
378 void alarm_handle_updown(u8t pos, s8t incr)
382 if (OswaldAlarm.hour == 0 && incr == -1) {
383 OswaldAlarm.hour = 23;
386 OswaldAlarm.hour += incr;
387 if (OswaldAlarm.hour > 23)
388 OswaldAlarm.hour = 0;
391 if (OswaldAlarm.minute == 0 && incr == -1) {
392 OswaldAlarm.minute = 59;
395 OswaldAlarm.minute += incr;
396 if (OswaldAlarm.minute > 59)
397 OswaldAlarm.minute = 0;
400 OswaldAlarm.wday ^= WDAY_SUNDAY;
403 OswaldAlarm.wday ^= WDAY_MONDAY;
406 OswaldAlarm.wday ^= WDAY_TUESDAY;
409 OswaldAlarm.wday ^= WDAY_WEDNESDAY;
412 OswaldAlarm.wday ^= WDAY_THURSDAY;
415 OswaldAlarm.wday ^= WDAY_FRIDAY;
418 OswaldAlarm.wday ^= WDAY_SATURDAY;
425 void handle_setup_alarm_buttons(watch_button button, alarm_setup_data_t *sdata)
429 alarm_handle_updown(sdata->pos, 1);
432 alarm_handle_updown(sdata->pos, -1);
441 draw_alarm_setup_screen(sdata);
444 void alarm_setup_events(u16t event, void *data)
447 case EVENT_SCREEN_VISIBLE:
448 alarm_setup_screen.pos = 0;
449 draw_alarm_setup_screen(&alarm_setup_screen);
450 hal_enable_halfsecond_timer();
452 case EVENT_SCREEN_DESTROY:
453 hal_disable_halfsecond_timer();
455 case EVENT_USER_BUTTONS:
456 dbg_out("button event %d\n", *(int *)data);
457 handle_setup_alarm_buttons(*(watch_button *)data, &alarm_setup_screen);
459 case EVENT_HALF_SEC_TIMER:
460 if (alarm_setup_screen.on)
461 alarm_setup_screen.on = FALSE;
463 alarm_setup_screen.on = TRUE;
464 draw_alarm_setup_screen(&alarm_setup_screen);
479 static test_menu_t test_menu = { 0 };
481 void draw_menu_test_screen(void)
483 hal_lcd_clear_display();
484 SetFont(MetaWatch16);
485 WriteLcdString(2, 2, "Menu");
487 WriteLcdString(2, 20, "Item 1");
488 WriteLcdString(2, 29, "Item 2");
489 WriteLcdString(2, 38, "Item 3");
490 WriteLcdString(2, 47, "Item 4");
491 WriteLcdString(2, 56, "Item 5");
493 WriteLcdString(50, 20+(9*test_menu.menu_pos), "*");
494 hal_lcd_update_display();
497 static void handle_menu_user_buttons(watch_button button)
501 test_menu.menu_pos--;
502 test_menu.menu_pos%=5;
505 test_menu.menu_pos++;
506 test_menu.menu_pos%=5;
511 draw_menu_test_screen();
514 void test_menu_handle_events(u16t event, void *data)
517 case EVENT_USER_BUTTONS:
518 dbg_out("button event %d\n", *(int *)data);
519 handle_menu_user_buttons(*(watch_button *)data);
521 case EVENT_SCREEN_VISIBLE:
522 test_menu.menu_pos = 0;
523 draw_menu_test_screen();
546 static stopwatch_data_t stopwatch_screen = { 0, 0, 0, 0, 0, 0, 0, 0, FALSE };
549 static void update_stop_watch_screen(stopwatch_data_t *sdata)
552 SetFont(MetaWatchMonospaced10);
554 snprintf(tstr, 16, "%02d:%02d:%02d.%1d", sdata->hr, sdata->min, sdata->sec, sdata->csec / 10);
555 WriteLcdString(5, 40, tstr);
556 snprintf(tstr, 16, "%02d:%02d:%02d.%02d", sdata->lapse_hr, sdata->lapse_min, sdata->lapse_sec, sdata->lapse_csec);
557 WriteLcdString(5, 60, tstr);
559 hal_lcd_update_display();
562 static void draw_stop_watch_screen(stopwatch_data_t *sdata)
564 oswald_draw_bitmap(36, 0, stopwatch_icon_width, stopwatch_icon_height, stopwatch_icon_bits);
565 oswald_draw_bitmap(81, 6, startstopbutton_icon_width, startstopbutton_icon_height, startstopbutton_icon_bits);
566 oswald_draw_bitmap(81, 38, lapsebutton_icon_width, lapsebutton_icon_height, lapsebutton_icon_bits);
568 update_stop_watch_screen(sdata);
571 static void handle_stop_watch_buttons(watch_button button)
574 case BUTTON_A: // start/stop
575 if (stopwatch_screen.running) {
576 hal_disable_centisecond_timer();
577 stopwatch_screen.running = FALSE;
579 hal_enable_centisecond_timer();
580 stopwatch_screen.running = TRUE;
583 case BUTTON_B: // lapse
584 stopwatch_screen.lapse_hr = stopwatch_screen.hr;
585 stopwatch_screen.lapse_min = stopwatch_screen.min;
586 stopwatch_screen.lapse_sec = stopwatch_screen.sec;
587 stopwatch_screen.lapse_csec = stopwatch_screen.csec;
589 case BUTTON_F: // reset
590 stopwatch_screen.hr = 0;
591 stopwatch_screen.min = 0;
592 stopwatch_screen.sec = 0;
593 stopwatch_screen.csec = 0;
594 stopwatch_screen.lapse_hr = 0;
595 stopwatch_screen.lapse_min = 0;
596 stopwatch_screen.lapse_sec = 0;
597 stopwatch_screen.lapse_csec = 0;
604 void stop_watch_handle_events(u16t event, void *data)
607 case EVENT_USER_BUTTONS:
608 dbg_out("button event %d\n", *(int *)data);
609 handle_stop_watch_buttons(*(watch_button *)data);
610 update_stop_watch_screen(&stopwatch_screen);
612 case EVENT_SCREEN_VISIBLE:
613 hal_lcd_clear_display();
614 draw_stop_watch_screen(&stopwatch_screen);
616 case EVENT_SCREEN_DESTROY:
617 hal_disable_centisecond_timer();
618 stopwatch_screen.running = FALSE;
621 stopwatch_screen.csec++;
622 if (stopwatch_screen.csec > 99) {
623 stopwatch_screen.csec = 0;
624 stopwatch_screen.sec++;
626 if (stopwatch_screen.sec > 59) {
627 stopwatch_screen.sec = 0;
628 stopwatch_screen.min++;
630 if (stopwatch_screen.min > 59) {
631 stopwatch_screen.min = 0;
632 stopwatch_screen.hr++;
634 if (stopwatch_screen.hr > 59) {
635 stopwatch_screen.hr = 0;
637 if (stopwatch_screen.csec % 10 == 0)
638 update_stop_watch_screen(&stopwatch_screen);
647 * when alarm is fired
649 void draw_alarm_screen(void)
651 hal_lcd_clear_display();
653 // SetFont(MetaWatch16);
654 // WriteLcdString(2, 2, "ALARM !");
655 oswald_draw_bitmap(36, 20, alarm_icon_width, alarm_icon_height, alarm_icon_bits);
658 hal_lcd_update_display();
661 void alarm_handle_events(u16t event, void *data)
664 case EVENT_SCREEN_VISIBLE:
666 hal_enable_halfsecond_timer();
667 hal_vibration_set_state(TRUE);
669 case EVENT_SCREEN_DESTROY:
670 hal_disable_halfsecond_timer();
671 hal_lcd_set_backlight(FALSE);
672 hal_vibration_set_state(FALSE);
674 case EVENT_USER_BUTTONS:
675 dbg_out("button event %d\n", *(int *)data);
676 // hal_lcd_set_backlight(FALSE);
678 case EVENT_HALF_SEC_TIMER:
679 hal_lcd_set_backlight(!hal_lcd_get_backlight());
680 hal_vibration_set_state(!hal_vibration_get_state());
697 static bluetooth_data_t bluetooth_screen = {
703 void draw_bluetooth_screen(bluetooth_data_t *sdata)
708 hal_lcd_clear_display();
710 oswald_draw_bitmap(36, 0, Bluetooth_icon_width, Bluetooth_icon_height, Bluetooth_icon_bits);
712 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
713 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
716 WriteLcdString(2, 30, "Enable:");
717 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
718 WriteLcdCharacter(45, 30, bluetooth_screen.bt_en ? 'x' : '_');
720 WriteLcdString(2, 39, "State:");
721 switch (hal_bluetooth_get_state()) {
723 WriteLcdString(45, 39, "off");
726 WriteLcdString(45, 39, "on");
728 case BLUETOOTH_CONNECTED:
729 WriteLcdString(45, 39, "conn.");
734 if (hal_bluetooth_get_state() >= BLUETOOTH_ON) {
735 bd_addr = hal_bluetooth_get_local_bdaddr();
736 snprintf(bstr, 20, "%02x:%02x:%02x:%02x:%02x:%02x", bd_addr[5], bd_addr[4], bd_addr[3], bd_addr[2], bd_addr[1], bd_addr[0]);
737 WriteLcdString(2, 48, bstr);
740 WriteLcdString(2, 57, "Visible:");
741 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
742 WriteLcdCharacter(45, 57, hal_bluetooth_get_visible() ? 'x' : '_');
745 hal_lcd_update_display();
748 void bluetooth_handle_updown(u8t pos, s8t incr)
752 if (hal_bluetooth_get_state() >= BLUETOOTH_ON) {
753 hal_bluetooth_set_state(BLUETOOTH_OFF);
754 bluetooth_screen.bt_en = FALSE;
756 hal_bluetooth_set_state(BLUETOOTH_ON);
757 bluetooth_screen.bt_en = TRUE;
761 if (hal_bluetooth_get_state() >= BLUETOOTH_ON && !hal_bluetooth_get_visible()) {
762 hal_bluetooth_set_visible(TRUE);
764 hal_bluetooth_set_visible(FALSE);
786 void handle_bluetooth_buttons(watch_button button, bluetooth_data_t *sdata)
790 bluetooth_handle_updown(sdata->pos, 1);
793 bluetooth_handle_updown(sdata->pos, -1);
802 draw_bluetooth_screen(sdata);
805 void bluetooth_screen_events(u16t event, void *data)
808 case EVENT_SCREEN_VISIBLE:
809 bluetooth_screen.pos = 0;
810 bluetooth_screen.bt_en = (hal_bluetooth_get_state() > 0);
811 draw_bluetooth_screen(&bluetooth_screen);
812 hal_enable_halfsecond_timer();
814 case EVENT_SCREEN_DESTROY:
815 hal_disable_halfsecond_timer();
817 case EVENT_USER_BUTTONS:
818 dbg_out("button event %d\n", *(int *)data);
819 handle_bluetooth_buttons(*(watch_button *)data, &bluetooth_screen);
821 case EVENT_HALF_SEC_TIMER:
822 if (bluetooth_screen.on)
823 bluetooth_screen.on = FALSE;
825 bluetooth_screen.on = TRUE;
826 draw_bluetooth_screen(&bluetooth_screen);