4 #include "oswald_main.h"
5 #include "oswald_watch_faces.h"
6 #include "oswald_graphics.h"
7 #include "oswald_hal.h"
9 #include "oswald_screens.h"
11 #include "LcdDisplay.h"
14 #if defined(__GNUC__) && (__MSP430X__ > 0)
15 __attribute__((__far__))
17 #include "bitmaps/timesetup_icon.xbm"
18 #if defined(__GNUC__) && (__MSP430X__ > 0)
19 __attribute__((__far__))
21 #include "bitmaps/stopwatch_icon.xbm"
22 #if defined(__GNUC__) && (__MSP430X__ > 0)
23 __attribute__((__far__))
25 #include "bitmaps/alarm_icon.xbm"
26 #if defined(__GNUC__) && (__MSP430X__ > 0)
27 __attribute__((__far__))
29 #include "bitmaps/startstopbutton_icon.xbm"
30 #if defined(__GNUC__) && (__MSP430X__ > 0)
31 __attribute__((__far__))
33 #include "bitmaps/lapsebutton_icon.xbm"
34 #if defined(__GNUC__) && (__MSP430X__ > 0)
35 __attribute__((__far__))
37 #include "bitmaps/upbutton_icon.xbm"
38 #if defined(__GNUC__) && (__MSP430X__ > 0)
39 __attribute__((__far__))
41 #include "bitmaps/downbutton_icon.xbm"
42 #if defined(__GNUC__) && (__MSP430X__ > 0)
43 __attribute__((__far__))
45 #include "bitmaps/Bluetooth_icon.xbm"
49 void (*screendraw_func)(boolean show_seconds);
53 static idle_data_t idle_screen = {
59 void idle_handle_user_buttons(watch_button button)
63 if (idle_screen.show_seconds)
64 idle_screen.show_seconds = FALSE;
66 idle_screen.show_seconds = TRUE;
69 if (idle_screen.analogue == TRUE) {
70 idle_screen.analogue = FALSE;
71 idle_screen.screendraw_func = DrawLcdDigitalClock;
73 idle_screen.analogue = TRUE;
74 idle_screen.screendraw_func = DrawLcdAnaClock;
78 OswaldState.screen_id = DATETIME_SETTING_SCREEN;
79 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
80 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
86 idle_screen.screendraw_func(idle_screen.show_seconds);
89 void idle_handle_events(u16t event, void *data)
92 case EVENT_ONE_SEC_TIMER:
93 case EVENT_SCREEN_VISIBLE:
94 idle_screen.screendraw_func(idle_screen.show_seconds);
96 case EVENT_USER_BUTTONS:
97 dbg_out("button event %d\n", *(int *)data);
98 idle_handle_user_buttons(*(watch_button *)data);
107 accel_data_t accdata;
108 } accelscreen_data_t;
109 static accelscreen_data_t accel_screen = {
113 void draw_accel_screen(accel_data_t *accel_data)
115 hal_lcd_clear_display();
117 oswald_write_string(0, 2, FONT_7x12b, "X:");
118 oswald_write_number(20, 2, FONT_7x12b, accel_data->x);
119 oswald_write_string(0, 18, FONT_7x12b, "Y:");
120 oswald_write_number(20, 18, FONT_7x12b, accel_data->y);
122 oswald_write_string(0, 34, FONT_8x12, "Z:");
123 oswald_write_number(20, 34, FONT_8x12, accel_data->z);
125 oswald_write_string(0, 54, FONT_12x16, "Light:");
126 oswald_write_number(50, 54, FONT_12x16, accel_data->z);
128 oswald_write_string(0, 70, FONT_12x20, "23:59");
130 hal_lcd_update_display();
133 void accel_handle_events(u16t event, void *data)
136 case EVENT_SCREEN_VISIBLE:
137 draw_accel_screen(&accel_screen.accdata);
139 case EVENT_ACCEL_UPDATE: {
140 accel_data_t *accel_data = (accel_data_t *)data;
141 accel_screen.accdata.x = accel_data->x;
142 accel_screen.accdata.y = accel_data->y;
143 accel_screen.accdata.z = accel_data->z;
144 draw_accel_screen(&accel_screen.accdata);
147 case EVENT_USER_BUTTONS:
148 dbg_out("button event %d\n", *(int *)data);
159 } datetime_setup_data_t;
160 static datetime_setup_data_t dt_setup_screen = {
165 void draw_datetime_setup_screen(datetime_setup_data_t *sdata)
167 hal_lcd_clear_display();
169 oswald_draw_bitmap(36, 0, timesetup_icon_width, timesetup_icon_height, timesetup_icon_bits);
171 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
172 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
174 SetFont(MetaWatchTime);
175 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
176 WriteLcdCharacter(2, 30, (OswaldClk.hour / 10));
177 WriteLcdCharacter(14, 30, (OswaldClk.hour % 10));
179 WriteLcdCharacter(26, 30, TIME_CHARACTER_COLON_INDEX);
181 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
182 WriteLcdCharacter(31, 30, (OswaldClk.minute / 10));
183 WriteLcdCharacter(43, 30, (OswaldClk.minute % 10));
186 SetFont(MetaWatch16);
187 if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2) {
188 WriteLcdCharacter(59, 36, 0x30 + (OswaldClk.second / 10));
189 WriteLcdCharacter(66, 36, 0x30 + (OswaldClk.second % 10));
193 if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3) {
194 WriteLcdNumber(2, 55, OswaldClk.day);
196 WriteLcdString(18, 55, ".");
197 if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4) {
198 WriteLcdNumber(22, 55, OswaldClk.month);
200 WriteLcdString(38, 55, ".");
201 if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5) {
202 WriteLcdNumber(42, 55, OswaldClk.year);
206 if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) {
207 if (OswaldClk.clk24hr)
208 WriteLcdString(2, 76, "x");
210 WriteLcdString(2, 76, "_");
212 WriteLcdString(15, 76, "24hr");
214 if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) {
215 if (OswaldClk.day_first)
216 WriteLcdString(2, 89, "x");
218 WriteLcdString(2, 89, "_");
220 WriteLcdString(15, 89, "dd.mm. mm/dd");
222 hal_lcd_update_display();
225 void datetime_handle_updown(u8t pos, s8t incr)
229 if (OswaldClk.hour == 0 && incr == -1) {
233 OswaldClk.hour += incr;
234 if (OswaldClk.hour > 23)
238 if (OswaldClk.minute == 0 && incr == -1) {
239 OswaldClk.minute = 59;
242 OswaldClk.minute += incr;
243 if (OswaldClk.minute > 59)
244 OswaldClk.minute = 0;
247 OswaldClk.second = 0;
250 if (OswaldClk.day == 1 && incr == -1) {
254 OswaldClk.day += incr;
255 if (OswaldClk.day > 31)
259 if (OswaldClk.month == 1 && incr == -1) {
260 OswaldClk.month = 12;
263 OswaldClk.month += incr;
264 if (OswaldClk.month > 12)
268 OswaldClk.year += incr;
270 case 6: // 24hr / 12hr
271 if (OswaldClk.clk24hr)
272 OswaldClk.clk24hr = FALSE;
274 OswaldClk.clk24hr = TRUE;
276 case 7: // dd.mm. / mm/dd
277 if (OswaldClk.day_first)
278 OswaldClk.day_first = FALSE;
280 OswaldClk.day_first = TRUE;
286 hal_set_rtc(&OswaldClk, TRUE);
288 hal_set_rtc(&OswaldClk, FALSE);
291 void handle_setup_datetime_buttons(watch_button button, datetime_setup_data_t *sdata)
295 datetime_handle_updown(sdata->pos, 1);
298 datetime_handle_updown(sdata->pos, -1);
307 draw_datetime_setup_screen(sdata);
310 void datetime_setup_events(u16t event, void *data)
313 case EVENT_SCREEN_VISIBLE:
314 dt_setup_screen.pos = 0;
315 draw_datetime_setup_screen(&dt_setup_screen);
316 hal_enable_halfsecond_timer();
318 case EVENT_SCREEN_DESTROY:
319 hal_disable_halfsecond_timer();
321 case EVENT_USER_BUTTONS:
322 dbg_out("button event %d\n", *(int *)data);
323 handle_setup_datetime_buttons(*(watch_button *)data, &dt_setup_screen);
325 case EVENT_HALF_SEC_TIMER:
326 if (dt_setup_screen.on)
327 dt_setup_screen.on = FALSE;
329 dt_setup_screen.on = TRUE;
330 draw_datetime_setup_screen(&dt_setup_screen);
345 } alarm_setup_data_t;
346 static alarm_setup_data_t alarm_setup_screen = {
351 void draw_alarm_setup_screen(alarm_setup_data_t *sdata)
353 hal_lcd_clear_display();
355 oswald_draw_bitmap(36, 0, alarm_icon_width, alarm_icon_height, alarm_icon_bits);
357 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
358 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
360 SetFont(MetaWatchTime);
361 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
362 WriteLcdCharacter(22, 30, (OswaldAlarm.hour / 10));
363 WriteLcdCharacter(34, 30, (OswaldAlarm.hour % 10));
365 WriteLcdCharacter(46, 30, TIME_CHARACTER_COLON_INDEX);
367 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
368 WriteLcdCharacter(51, 30, (OswaldAlarm.minute / 10));
369 WriteLcdCharacter(63, 30, (OswaldAlarm.minute % 10));
372 SetFont(MetaWatchMonospaced10);
373 WriteLcdCharacter(3, 55, 'S');
374 WriteLcdCharacter(15, 55, 'M');
375 WriteLcdCharacter(27, 55, 'T');
376 WriteLcdCharacter(39, 55, 'W');
377 WriteLcdCharacter(51, 55, 'T');
378 WriteLcdCharacter(63, 55, 'F');
379 WriteLcdCharacter(75, 55, 'S');
381 if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2)
382 WriteLcdCharacter(3, 65, (OswaldAlarm.wday & WDAY_SUNDAY) ? 'x' : '_');
383 if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3)
384 WriteLcdCharacter(15, 65, (OswaldAlarm.wday & WDAY_MONDAY) ? 'x' : '_');
385 if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4)
386 WriteLcdCharacter(27, 65, (OswaldAlarm.wday & WDAY_TUESDAY) ? 'x' : '_');
387 if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5)
388 WriteLcdCharacter(39, 65, (OswaldAlarm.wday & WDAY_WEDNESDAY) ? 'x' : '_');
389 if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6)
390 WriteLcdCharacter(51, 65, (OswaldAlarm.wday & WDAY_THURSDAY) ? 'x' : '_');
391 if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7)
392 WriteLcdCharacter(63, 65, (OswaldAlarm.wday & WDAY_FRIDAY) ? 'x' : '_');
393 if ((sdata->pos == 8 && sdata->on) || sdata->pos != 8)
394 WriteLcdCharacter(75, 65, (OswaldAlarm.wday & WDAY_SATURDAY) ? 'x' : '_');
396 hal_lcd_update_display();
399 void alarm_handle_updown(u8t pos, s8t incr)
403 if (OswaldAlarm.hour == 0 && incr == -1) {
404 OswaldAlarm.hour = 23;
407 OswaldAlarm.hour += incr;
408 if (OswaldAlarm.hour > 23)
409 OswaldAlarm.hour = 0;
412 if (OswaldAlarm.minute == 0 && incr == -1) {
413 OswaldAlarm.minute = 59;
416 OswaldAlarm.minute += incr;
417 if (OswaldAlarm.minute > 59)
418 OswaldAlarm.minute = 0;
421 OswaldAlarm.wday ^= WDAY_SUNDAY;
424 OswaldAlarm.wday ^= WDAY_MONDAY;
427 OswaldAlarm.wday ^= WDAY_TUESDAY;
430 OswaldAlarm.wday ^= WDAY_WEDNESDAY;
433 OswaldAlarm.wday ^= WDAY_THURSDAY;
436 OswaldAlarm.wday ^= WDAY_FRIDAY;
439 OswaldAlarm.wday ^= WDAY_SATURDAY;
446 void handle_setup_alarm_buttons(watch_button button, alarm_setup_data_t *sdata)
450 alarm_handle_updown(sdata->pos, 1);
453 alarm_handle_updown(sdata->pos, -1);
462 draw_alarm_setup_screen(sdata);
465 void alarm_setup_events(u16t event, void *data)
468 case EVENT_SCREEN_VISIBLE:
469 alarm_setup_screen.pos = 0;
470 draw_alarm_setup_screen(&alarm_setup_screen);
471 hal_enable_halfsecond_timer();
473 case EVENT_SCREEN_DESTROY:
474 hal_disable_halfsecond_timer();
476 case EVENT_USER_BUTTONS:
477 dbg_out("button event %d\n", *(int *)data);
478 handle_setup_alarm_buttons(*(watch_button *)data, &alarm_setup_screen);
480 case EVENT_HALF_SEC_TIMER:
481 if (alarm_setup_screen.on)
482 alarm_setup_screen.on = FALSE;
484 alarm_setup_screen.on = TRUE;
485 draw_alarm_setup_screen(&alarm_setup_screen);
500 static test_menu_t test_menu = { 0 };
502 void draw_menu_test_screen(void)
504 hal_lcd_clear_display();
505 SetFont(MetaWatch16);
506 WriteLcdString(2, 2, "Menu");
508 WriteLcdString(2, 20, "Item 1");
509 WriteLcdString(2, 29, "Item 2");
510 WriteLcdString(2, 38, "Item 3");
511 WriteLcdString(2, 47, "Item 4");
512 WriteLcdString(2, 56, "Item 5");
514 WriteLcdString(50, 20+(9*test_menu.menu_pos), "*");
515 hal_lcd_update_display();
518 static void handle_menu_user_buttons(watch_button button)
522 test_menu.menu_pos--;
523 test_menu.menu_pos%=5;
526 test_menu.menu_pos++;
527 test_menu.menu_pos%=5;
532 draw_menu_test_screen();
535 void test_menu_handle_events(u16t event, void *data)
538 case EVENT_USER_BUTTONS:
539 dbg_out("button event %d\n", *(int *)data);
540 handle_menu_user_buttons(*(watch_button *)data);
542 case EVENT_SCREEN_VISIBLE:
543 test_menu.menu_pos = 0;
544 draw_menu_test_screen();
567 static stopwatch_data_t stopwatch_screen = { 0, 0, 0, 0, 0, 0, 0, 0, FALSE };
570 static void update_stop_watch_screen(stopwatch_data_t *sdata)
573 SetFont(MetaWatchMonospaced10);
575 snprintf(tstr, 16, "%02d:%02d:%02d.%1d", sdata->hr, sdata->min, sdata->sec, sdata->csec / 10);
576 WriteLcdString(5, 40, tstr);
577 snprintf(tstr, 16, "%02d:%02d:%02d.%02d", sdata->lapse_hr, sdata->lapse_min, sdata->lapse_sec, sdata->lapse_csec);
578 WriteLcdString(5, 60, tstr);
580 hal_lcd_update_display();
583 static void draw_stop_watch_screen(stopwatch_data_t *sdata)
585 oswald_draw_bitmap(36, 0, stopwatch_icon_width, stopwatch_icon_height, stopwatch_icon_bits);
586 oswald_draw_bitmap(81, 6, startstopbutton_icon_width, startstopbutton_icon_height, startstopbutton_icon_bits);
587 oswald_draw_bitmap(81, 38, lapsebutton_icon_width, lapsebutton_icon_height, lapsebutton_icon_bits);
589 update_stop_watch_screen(sdata);
592 static void handle_stop_watch_buttons(watch_button button)
595 case BUTTON_A: // start/stop
596 if (stopwatch_screen.running) {
597 hal_disable_centisecond_timer();
598 stopwatch_screen.running = FALSE;
600 hal_enable_centisecond_timer();
601 stopwatch_screen.running = TRUE;
604 case BUTTON_B: // lapse
605 stopwatch_screen.lapse_hr = stopwatch_screen.hr;
606 stopwatch_screen.lapse_min = stopwatch_screen.min;
607 stopwatch_screen.lapse_sec = stopwatch_screen.sec;
608 stopwatch_screen.lapse_csec = stopwatch_screen.csec;
610 case BUTTON_F: // reset
611 stopwatch_screen.hr = 0;
612 stopwatch_screen.min = 0;
613 stopwatch_screen.sec = 0;
614 stopwatch_screen.csec = 0;
615 stopwatch_screen.lapse_hr = 0;
616 stopwatch_screen.lapse_min = 0;
617 stopwatch_screen.lapse_sec = 0;
618 stopwatch_screen.lapse_csec = 0;
625 void stop_watch_handle_events(u16t event, void *data)
628 case EVENT_USER_BUTTONS:
629 dbg_out("button event %d\n", *(int *)data);
630 handle_stop_watch_buttons(*(watch_button *)data);
631 update_stop_watch_screen(&stopwatch_screen);
633 case EVENT_SCREEN_VISIBLE:
634 hal_lcd_clear_display();
635 draw_stop_watch_screen(&stopwatch_screen);
637 case EVENT_SCREEN_DESTROY:
638 hal_disable_centisecond_timer();
639 stopwatch_screen.running = FALSE;
642 stopwatch_screen.csec++;
643 if (stopwatch_screen.csec > 99) {
644 stopwatch_screen.csec = 0;
645 stopwatch_screen.sec++;
647 if (stopwatch_screen.sec > 59) {
648 stopwatch_screen.sec = 0;
649 stopwatch_screen.min++;
651 if (stopwatch_screen.min > 59) {
652 stopwatch_screen.min = 0;
653 stopwatch_screen.hr++;
655 if (stopwatch_screen.hr > 59) {
656 stopwatch_screen.hr = 0;
658 if (stopwatch_screen.csec % 10 == 0)
659 update_stop_watch_screen(&stopwatch_screen);
668 * when alarm is fired
670 void draw_alarm_screen(void)
672 hal_lcd_clear_display();
674 // SetFont(MetaWatch16);
675 // WriteLcdString(2, 2, "ALARM !");
676 oswald_draw_bitmap(36, 20, alarm_icon_width, alarm_icon_height, alarm_icon_bits);
679 hal_lcd_update_display();
682 void alarm_handle_events(u16t event, void *data)
685 case EVENT_SCREEN_VISIBLE:
687 hal_enable_halfsecond_timer();
688 hal_vibration_set_state(TRUE);
690 case EVENT_SCREEN_DESTROY:
691 hal_disable_halfsecond_timer();
692 hal_lcd_set_backlight(FALSE);
693 hal_vibration_set_state(FALSE);
695 case EVENT_USER_BUTTONS:
696 dbg_out("button event %d\n", *(int *)data);
697 // hal_lcd_set_backlight(FALSE);
699 case EVENT_HALF_SEC_TIMER:
700 hal_lcd_set_backlight(!hal_lcd_get_backlight());
701 hal_vibration_set_state(!hal_vibration_get_state());
718 static bluetooth_data_t bluetooth_screen = {
724 void draw_bluetooth_screen(bluetooth_data_t *sdata)
729 hal_lcd_clear_display();
731 oswald_draw_bitmap(36, 0, Bluetooth_icon_width, Bluetooth_icon_height, Bluetooth_icon_bits);
733 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
734 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
737 WriteLcdString(2, 30, "Enable:");
738 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
739 WriteLcdCharacter(45, 30, bluetooth_screen.bt_en ? 'x' : '_');
741 WriteLcdString(2, 39, "State:");
742 switch (hal_bluetooth_get_state()) {
744 WriteLcdString(45, 39, "off");
747 WriteLcdString(45, 39, "on");
749 case BLUETOOTH_CONNECTED:
750 WriteLcdString(45, 39, "conn.");
755 if (hal_bluetooth_get_state() >= BLUETOOTH_ON) {
756 bd_addr = hal_bluetooth_get_local_bdaddr();
757 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]);
758 WriteLcdString(2, 48, bstr);
761 WriteLcdString(2, 57, "Visible:");
762 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
763 WriteLcdCharacter(45, 57, hal_bluetooth_get_visible() ? 'x' : '_');
766 hal_lcd_update_display();
769 void bluetooth_handle_updown(u8t pos, s8t incr)
773 if (hal_bluetooth_get_state() >= BLUETOOTH_ON) {
774 hal_bluetooth_set_state(BLUETOOTH_OFF);
775 bluetooth_screen.bt_en = FALSE;
777 hal_bluetooth_set_state(BLUETOOTH_ON);
778 bluetooth_screen.bt_en = TRUE;
782 if (hal_bluetooth_get_state() >= BLUETOOTH_ON && !hal_bluetooth_get_visible()) {
783 hal_bluetooth_set_visible(TRUE);
785 hal_bluetooth_set_visible(FALSE);
807 void handle_bluetooth_buttons(watch_button button, bluetooth_data_t *sdata)
811 bluetooth_handle_updown(sdata->pos, 1);
814 bluetooth_handle_updown(sdata->pos, -1);
823 draw_bluetooth_screen(sdata);
826 void bluetooth_screen_events(u16t event, void *data)
829 case EVENT_SCREEN_VISIBLE:
830 bluetooth_screen.pos = 0;
831 bluetooth_screen.bt_en = (hal_bluetooth_get_state() > 0);
832 draw_bluetooth_screen(&bluetooth_screen);
833 hal_enable_halfsecond_timer();
835 case EVENT_SCREEN_DESTROY:
836 hal_disable_halfsecond_timer();
838 case EVENT_USER_BUTTONS:
839 dbg_out("button event %d\n", *(int *)data);
840 handle_bluetooth_buttons(*(watch_button *)data, &bluetooth_screen);
842 case EVENT_HALF_SEC_TIMER:
843 if (bluetooth_screen.on)
844 bluetooth_screen.on = FALSE;
846 bluetooth_screen.on = TRUE;
847 draw_bluetooth_screen(&bluetooth_screen);