#include #include "oswald.h" #include "oswald_main.h" #include "oswald_watch_faces.h" #include "oswald_graphics.h" #include "oswald_hal.h" #include "oswald_screens.h" #if defined(__GNUC__) && (__MSP430X__ > 0) __attribute__((__far__)) #endif #include "bitmaps/timesetup_icon.xbm" #if defined(__GNUC__) && (__MSP430X__ > 0) __attribute__((__far__)) #endif #include "bitmaps/stopwatch_icon.xbm" #if defined(__GNUC__) && (__MSP430X__ > 0) __attribute__((__far__)) #endif #include "bitmaps/alarm_icon.xbm" #if defined(__GNUC__) && (__MSP430X__ > 0) __attribute__((__far__)) #endif #include "bitmaps/startstopbutton_icon.xbm" #if defined(__GNUC__) && (__MSP430X__ > 0) __attribute__((__far__)) #endif #include "bitmaps/lapsebutton_icon.xbm" #if defined(__GNUC__) && (__MSP430X__ > 0) __attribute__((__far__)) #endif #include "bitmaps/upbutton_icon.xbm" #if defined(__GNUC__) && (__MSP430X__ > 0) __attribute__((__far__)) #endif #include "bitmaps/downbutton_icon.xbm" #if defined(__GNUC__) && (__MSP430X__ > 0) __attribute__((__far__)) #endif #include "bitmaps/Bluetooth_icon.xbm" typedef struct { void (*screendraw_func)(boolean show_seconds); boolean show_seconds; boolean analogue; } idle_data_t; static idle_data_t idle_screen = { DrawLcdDigitalClock, TRUE, FALSE, }; event_ret_t idle_handle_user_buttons(watch_button button) { switch (button) { case BUTTON_A: if (idle_screen.show_seconds) idle_screen.show_seconds = FALSE; else idle_screen.show_seconds = TRUE; break; case BUTTON_B: if (idle_screen.analogue == TRUE) { idle_screen.analogue = FALSE; idle_screen.screendraw_func = DrawLcdDigitalClock; } else { idle_screen.analogue = TRUE; idle_screen.screendraw_func = DrawLcdAnaClock; }; break; case BUTTON_C: return EVENT_RET_UNHANDLED; break; case BUTTON_F: OswaldState.screen_id = DATETIME_SETTING_SCREEN; OswaldState.screen = &OswaldScreens[OswaldState.screen_id]; OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL); return EVENT_RET_HANDLED; break; default: return EVENT_RET_UNHANDLED; break; }; idle_screen.screendraw_func(idle_screen.show_seconds); return EVENT_RET_HANDLED; } event_ret_t idle_handle_events(uint16_t event, void *data) { switch (event) { case EVENT_ONE_SEC_TIMER: case EVENT_SCREEN_VISIBLE: idle_screen.screendraw_func(idle_screen.show_seconds); return EVENT_RET_HANDLED; break; case EVENT_USER_BUTTONS: dbg_out("button event %d\n", *(int *)data); return idle_handle_user_buttons(*(watch_button *)data); break; default: return EVENT_RET_UNHANDLED; break; }; return EVENT_RET_UNHANDLED; } typedef struct { accel_data_t accdata; } accelscreen_data_t; static accelscreen_data_t accel_screen = { { 0, 0, 0}, }; void draw_accel_screen(accel_data_t *accel_data) { hal_lcd_clear_display(); oswald_write_string(0, 2, FONT_6x9, "X:"); oswald_write_number(20, 2, FONT_6x9, accel_data->x); oswald_write_string(0, 16, FONT_6x9, "Y:"); oswald_write_number(20, 16, FONT_6x9, accel_data->y); oswald_write_string(0, 32, FONT_6x9, "Z:"); oswald_write_number(20, 32, FONT_6x9, accel_data->z); oswald_write_string(0, 54, FONT_6x9, "Light:"); oswald_write_number(50, 54, FONT_6x9, accel_data->z); hal_lcd_update_display(); } event_ret_t accel_handle_events(uint16_t event, void *data) { switch (event) { case EVENT_SCREEN_VISIBLE: draw_accel_screen(&accel_screen.accdata); return EVENT_RET_HANDLED; break; case EVENT_ACCEL_UPDATE: { accel_data_t *accel_data = (accel_data_t *)data; accel_screen.accdata.x = accel_data->x; accel_screen.accdata.y = accel_data->y; accel_screen.accdata.z = accel_data->z; draw_accel_screen(&accel_screen.accdata); }; return EVENT_RET_HANDLED; break; case EVENT_USER_BUTTONS: dbg_out("button event %d\n", *(int *)data); break; default: return EVENT_RET_UNHANDLED; break; }; return EVENT_RET_UNHANDLED; } typedef struct { uint8_t pos; boolean set_mode; boolean on; } datetime_setup_data_t; static datetime_setup_data_t dt_setup_screen = { 0, FALSE, TRUE }; void draw_datetime_setup_screen(datetime_setup_data_t *sdata) { hal_lcd_clear_display(); oswald_draw_bitmap(36, 0, timesetup_icon_width, timesetup_icon_height, timesetup_icon_bits); oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits); oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits); if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) { oswald_write_character(2, 30, FONT_LCD13x21, (OswaldClk.hour / 10)); oswald_write_character(15, 30, FONT_LCD13x21, (OswaldClk.hour % 10)); } oswald_write_character(25, 30, FONT_LCD13x21, 10); if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) { oswald_write_character(34, 30, FONT_LCD13x21, (OswaldClk.minute / 10)); oswald_write_character(47, 30, FONT_LCD13x21, (OswaldClk.minute % 10)); } if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2) { oswald_write_character(61, 38, FONT_LCD8x13, (OswaldClk.second / 10)); oswald_write_character(69, 38, FONT_LCD8x13, (OswaldClk.second % 10)); } if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3) { oswald_write_number(2, 55, FONT_DROID8x12, OswaldClk.day); } oswald_write_character(15, 55, FONT_DROID8x12, '.'); if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4) { oswald_write_number(21, 55, FONT_DROID8x12, OswaldClk.month); } oswald_write_character(36, 55, FONT_DROID8x12, '.'); if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5) { oswald_write_number(43, 55, FONT_DROID8x12, OswaldClk.year); } if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) { if (OswaldClk.clk24hr) { oswald_write_character(2, 76, FONT_6x9, 'x'); } else { oswald_write_character(2, 76, FONT_6x9, '_'); } } oswald_write_string(15, 73, FONT_DROID8x12, "24hr"); if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) { if (OswaldClk.day_first) { oswald_write_character(2, 86, FONT_6x9, 'x'); } else { oswald_write_character(2, 86, FONT_6x9, '_'); } } oswald_write_string(15, 83, FONT_DROID8x12, "dd.mm. mm/dd"); hal_lcd_update_display(); } void datetime_handle_updown(uint8_t pos, int8_t incr) { switch (pos) { case 0: // hour if (OswaldClk.hour == 0 && incr == -1) { OswaldClk.hour = 23; break; }; OswaldClk.hour += incr; if (OswaldClk.hour > 23) OswaldClk.hour = 0; break; case 1: // minute if (OswaldClk.minute == 0 && incr == -1) { OswaldClk.minute = 59; break; }; OswaldClk.minute += incr; if (OswaldClk.minute > 59) OswaldClk.minute = 0; break; case 2: // second OswaldClk.second = 0; break; case 3: // day if (OswaldClk.day == 1 && incr == -1) { OswaldClk.day = 31; break; }; OswaldClk.day += incr; if (OswaldClk.day > 31) OswaldClk.day = 1; break; case 4: // month if (OswaldClk.month == 1 && incr == -1) { OswaldClk.month = 12; break; }; OswaldClk.month += incr; if (OswaldClk.month > 12) OswaldClk.month = 1; break; case 5: // year OswaldClk.year += incr; break; case 6: // 24hr / 12hr if (OswaldClk.clk24hr) OswaldClk.clk24hr = FALSE; else OswaldClk.clk24hr = TRUE; break; case 7: // dd.mm. / mm/dd if (OswaldClk.day_first) OswaldClk.day_first = FALSE; else OswaldClk.day_first = TRUE; break; default: break; }; if (pos == 2) hal_set_rtc(&OswaldClk, TRUE); else hal_set_rtc(&OswaldClk, FALSE); } event_ret_t handle_setup_datetime_buttons(watch_button button, datetime_setup_data_t *sdata) { switch (button) { case BUTTON_A: datetime_handle_updown(sdata->pos, 1); break; case BUTTON_B: datetime_handle_updown(sdata->pos, -1); break; case BUTTON_C: sdata->pos++; sdata->pos %= 8; break; case BUTTON_F: OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL); OswaldState.screen_id = IDLE_SCREEN; OswaldState.screen = &OswaldScreens[OswaldState.screen_id]; OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL); return EVENT_RET_HANDLED; break; default: return EVENT_RET_UNHANDLED; break; } draw_datetime_setup_screen(sdata); return EVENT_RET_HANDLED; } event_ret_t datetime_setup_events(uint16_t event, void *data) { switch (event) { case EVENT_SCREEN_VISIBLE: dt_setup_screen.pos = 0; draw_datetime_setup_screen(&dt_setup_screen); hal_enable_halfsecond_timer(); return EVENT_RET_HANDLED; break; case EVENT_SCREEN_DESTROY: hal_disable_halfsecond_timer(); return EVENT_RET_HANDLED; break; case EVENT_USER_BUTTONS: dbg_out("button event %d\n", *(int *)data); return handle_setup_datetime_buttons(*(watch_button *)data, &dt_setup_screen); break; case EVENT_HALF_SEC_TIMER: if (dt_setup_screen.on) dt_setup_screen.on = FALSE; else dt_setup_screen.on = TRUE; draw_datetime_setup_screen(&dt_setup_screen); return EVENT_RET_HANDLED; break; default: return EVENT_RET_UNHANDLED; break; }; return EVENT_RET_UNHANDLED; } /* * Alarm setup */ typedef struct { uint8_t pos; boolean set_mode; boolean on; } alarm_setup_data_t; static alarm_setup_data_t alarm_setup_screen = { 0, FALSE, TRUE }; void draw_alarm_setup_screen(alarm_setup_data_t *sdata) { hal_lcd_clear_display(); oswald_draw_bitmap(36, 0, alarm_icon_width, alarm_icon_height, alarm_icon_bits); oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits); oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits); if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) { oswald_write_character(18, 30, FONT_LCD13x21, (OswaldAlarm.hour / 10)); oswald_write_character(32, 30, FONT_LCD13x21, (OswaldAlarm.hour % 10)); } oswald_write_character(42, 30, FONT_LCD13x21, 10); if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) { oswald_write_character(53, 30, FONT_LCD13x21, (OswaldAlarm.minute / 10)); oswald_write_character(67, 30, FONT_LCD13x21, (OswaldAlarm.minute % 10)); } oswald_write_character(3, 55, FONT_6x9, 'S'); oswald_write_character(15, 55, FONT_6x9, 'M'); oswald_write_character(27, 55, FONT_6x9, 'T'); oswald_write_character(39, 55, FONT_6x9, 'W'); oswald_write_character(51, 55, FONT_6x9, 'T'); oswald_write_character(63, 55, FONT_6x9, 'F'); oswald_write_character(75, 55, FONT_6x9, 'S'); if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2) oswald_write_character(3, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_SUNDAY) ? 'x' : '_'); if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3) oswald_write_character(15, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_MONDAY) ? 'x' : '_'); if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4) oswald_write_character(27, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_TUESDAY) ? 'x' : '_'); if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5) oswald_write_character(39, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_WEDNESDAY) ? 'x' : '_'); if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) oswald_write_character(51, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_THURSDAY) ? 'x' : '_'); if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) oswald_write_character(63, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_FRIDAY) ? 'x' : '_'); if ((sdata->pos == 8 && sdata->on) || sdata->pos != 8) oswald_write_character(75, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_SATURDAY) ? 'x' : '_'); hal_lcd_update_display(); } void alarm_handle_updown(uint8_t pos, int8_t incr) { switch (pos) { case 0: // hour if (OswaldAlarm.hour == 0 && incr == -1) { OswaldAlarm.hour = 23; break; }; OswaldAlarm.hour += incr; if (OswaldAlarm.hour > 23) OswaldAlarm.hour = 0; break; case 1: // minute if (OswaldAlarm.minute == 0 && incr == -1) { OswaldAlarm.minute = 59; break; }; OswaldAlarm.minute += incr; if (OswaldAlarm.minute > 59) OswaldAlarm.minute = 0; break; case 2: // sunday OswaldAlarm.wday ^= WDAY_SUNDAY; break; case 3: // monday OswaldAlarm.wday ^= WDAY_MONDAY; break; case 4: // tuesday OswaldAlarm.wday ^= WDAY_TUESDAY; break; case 5: // wednesday OswaldAlarm.wday ^= WDAY_WEDNESDAY; break; case 6: // thursday OswaldAlarm.wday ^= WDAY_THURSDAY; break; case 7: // friday OswaldAlarm.wday ^= WDAY_FRIDAY; break; case 8: // saturday OswaldAlarm.wday ^= WDAY_SATURDAY; break; default: break; }; } event_ret_t handle_setup_alarm_buttons(watch_button button, alarm_setup_data_t *sdata) { if (alarm_setup_screen.set_mode) { switch (button) { case BUTTON_A: alarm_handle_updown(sdata->pos, 1); break; case BUTTON_B: alarm_handle_updown(sdata->pos, -1); break; case BUTTON_C: sdata->pos++; sdata->pos %= 9; break; case BUTTON_F: alarm_setup_screen.set_mode = FALSE; break; default: return EVENT_RET_UNHANDLED; break; } } else { switch (button) { case BUTTON_F: alarm_setup_screen.set_mode = TRUE; break; default: return EVENT_RET_UNHANDLED; break; } } draw_alarm_setup_screen(sdata); return EVENT_RET_HANDLED; } event_ret_t alarm_setup_events(uint16_t event, void *data) { switch (event) { case EVENT_SCREEN_VISIBLE: alarm_setup_screen.pos = 0; alarm_setup_screen.on = TRUE; alarm_setup_screen.set_mode = FALSE; draw_alarm_setup_screen(&alarm_setup_screen); hal_enable_halfsecond_timer(); return EVENT_RET_HANDLED; break; case EVENT_SCREEN_DESTROY: hal_disable_halfsecond_timer(); return EVENT_RET_HANDLED; break; case EVENT_USER_BUTTONS: dbg_out("button event %d\n", *(int *)data); return handle_setup_alarm_buttons(*(watch_button *)data, &alarm_setup_screen); break; case EVENT_HALF_SEC_TIMER: if (alarm_setup_screen.set_mode) { if (alarm_setup_screen.on) alarm_setup_screen.on = FALSE; else alarm_setup_screen.on = TRUE; } else alarm_setup_screen.on = TRUE; draw_alarm_setup_screen(&alarm_setup_screen); return EVENT_RET_HANDLED; break; default: return EVENT_RET_UNHANDLED; break; }; return EVENT_RET_UNHANDLED; } /* * Test menu */ typedef struct { uint8_t menu_pos; } test_menu_t; static test_menu_t test_menu = { 0 }; void draw_menu_test_screen(void) { hal_lcd_clear_display(); #if 0 SetFont(MetaWatch16); WriteLcdString(2, 2, "Menu"); SetFont(MetaWatch7); WriteLcdString(2, 20, "Item 1"); WriteLcdString(2, 29, "Item 2"); WriteLcdString(2, 38, "Item 3"); WriteLcdString(2, 47, "Item 4"); WriteLcdString(2, 56, "Item 5"); WriteLcdString(50, 20+(9*test_menu.menu_pos), "*"); #endif oswald_write_string(2, 2, FONT_DROID11x14b, "Menu"); oswald_write_string(2, 20, FONT_DROID8x12, "Item 1"); oswald_write_string(2, 29, FONT_DROID8x12, "Item 2"); oswald_write_string(2, 38, FONT_DROID8x12, "Item 3"); oswald_write_string(2, 47, FONT_DROID8x12, "Item 4"); oswald_write_string(2, 56, FONT_DROID8x12, "Item 5"); oswald_write_character(50, 18+(9*test_menu.menu_pos), FONT_6x9, 0x11); hal_lcd_update_display(); } event_ret_t handle_menu_user_buttons(watch_button button) { switch (button) { case BUTTON_A: test_menu.menu_pos--; test_menu.menu_pos %= 5; break; case BUTTON_B: test_menu.menu_pos++; test_menu.menu_pos %= 5; break; default: return EVENT_RET_UNHANDLED; break; } draw_menu_test_screen(); return EVENT_RET_HANDLED; } event_ret_t test_menu_handle_events(uint16_t event, void *data) { switch (event) { case EVENT_USER_BUTTONS: dbg_out("button event %d\n", *(int *)data); return handle_menu_user_buttons(*(watch_button *)data); break; case EVENT_SCREEN_VISIBLE: test_menu.menu_pos = 0; draw_menu_test_screen(); break; default: return EVENT_RET_UNHANDLED; break; }; return EVENT_RET_HANDLED; } /* * Stop Watch */ typedef struct { uint8_t hr; uint8_t min; uint8_t sec; uint8_t csec; uint8_t lapse_hr; uint8_t lapse_min; uint8_t lapse_sec; uint8_t lapse_csec; boolean running; } stopwatch_data_t; static stopwatch_data_t stopwatch_screen = { 0, 0, 0, 0, 0, 0, 0, 0, FALSE }; #if 0 static void update_stop_watch_screen(stopwatch_data_t *sdata) { //char tstr[16]; #if 0 SetFont(MetaWatchMonospaced10); snprintf(tstr, 16, "%02d:%02d:%02d.%1d", sdata->hr, sdata->min, sdata->sec, sdata->csec / 10); WriteLcdString(5, 40, tstr); snprintf(tstr, 16, "%02d:%02d:%02d.%02d", sdata->lapse_hr, sdata->lapse_min, sdata->lapse_sec, sdata->lapse_csec); WriteLcdString(5, 60, tstr); #endif #if 0 snprintf(tstr, 16, "%02d:%02d:%02d.%1d", sdata->hr, sdata->min, sdata->sec, sdata->csec / 10); oswald_write_string(5, 40, FONT_6x9, tstr); snprintf(tstr, 16, "%02d:%02d:%02d.%02d", sdata->lapse_hr, sdata->lapse_min, sdata->lapse_sec, sdata->lapse_csec); oswald_write_string(5, 60, FONT_6x9, tstr); #endif hal_lcd_update_display(); } #endif static void draw_stop_watch_screen(stopwatch_data_t *sdata) { int gRow = 1; int gColumn = 35; hal_lcd_clear_display(); oswald_draw_bitmap(36, 0, stopwatch_icon_width, stopwatch_icon_height, stopwatch_icon_bits); oswald_draw_bitmap(81, 6, startstopbutton_icon_width, startstopbutton_icon_height, startstopbutton_icon_bits); oswald_draw_bitmap(81, 38, lapsebutton_icon_width, lapsebutton_icon_height, lapsebutton_icon_bits); #if 0 update_stop_watch_screen(sdata); #else gRow += 3 + oswald_write_character(gRow, gColumn, FONT_LCD13x21, (sdata->hr % 10)); gRow += oswald_write_character(gRow, gColumn, FONT_LCD13x21, (sdata->min / 10)); gRow += 3 + oswald_write_character(gRow, gColumn, FONT_LCD13x21, (sdata->min % 10)); gRow += oswald_write_character(gRow, gColumn, FONT_LCD13x21, (sdata->sec / 10)); gRow += 3 + oswald_write_character(gRow, gColumn, FONT_LCD13x21, (sdata->sec % 10)); gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, (sdata->csec / 10)); gRow = 6; gColumn = 62; gRow += 13 + oswald_write_character(gRow, gColumn, FONT_LCD8x13, (sdata->lapse_hr % 10)); gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, (sdata->lapse_min / 10)); gRow += 13 + oswald_write_character(gRow, gColumn, FONT_LCD8x13, (sdata->lapse_min % 10)); gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, (sdata->lapse_sec / 10)); gRow += 3 + oswald_write_character(gRow, gColumn, FONT_LCD8x13, (sdata->lapse_sec % 10)); gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, (sdata->lapse_csec / 10)); gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, (sdata->lapse_csec % 10)); hal_lcd_update_display(); #endif } event_ret_t handle_stop_watch_buttons(watch_button button) { switch (button) { case BUTTON_A: // start/stop if (stopwatch_screen.running) { hal_disable_centisecond_timer(); stopwatch_screen.running = FALSE; } else { hal_enable_centisecond_timer(); stopwatch_screen.running = TRUE; } return EVENT_RET_HANDLED; break; case BUTTON_B: // lapse stopwatch_screen.lapse_hr = stopwatch_screen.hr; stopwatch_screen.lapse_min = stopwatch_screen.min; stopwatch_screen.lapse_sec = stopwatch_screen.sec; stopwatch_screen.lapse_csec = stopwatch_screen.csec; return EVENT_RET_HANDLED; break; case BUTTON_F: // reset stopwatch_screen.hr = 0; stopwatch_screen.min = 0; stopwatch_screen.sec = 0; stopwatch_screen.csec = 0; stopwatch_screen.lapse_hr = 0; stopwatch_screen.lapse_min = 0; stopwatch_screen.lapse_sec = 0; stopwatch_screen.lapse_csec = 0; return EVENT_RET_HANDLED; break; default: return EVENT_RET_UNHANDLED; break; } return EVENT_RET_UNHANDLED; } event_ret_t stop_watch_handle_events(uint16_t event, void *data) { switch (event) { case EVENT_USER_BUTTONS: dbg_out("button event %d\n", *(int *)data); return handle_stop_watch_buttons(*(watch_button *)data); //update_stop_watch_screen(&stopwatch_screen); draw_stop_watch_screen(&stopwatch_screen); break; case EVENT_SCREEN_VISIBLE: hal_lcd_clear_display(); draw_stop_watch_screen(&stopwatch_screen); return EVENT_RET_HANDLED; break; case EVENT_SCREEN_DESTROY: hal_disable_centisecond_timer(); stopwatch_screen.running = FALSE; return EVENT_RET_HANDLED; break; case EVENT_CS_TIMER: stopwatch_screen.csec++; if (stopwatch_screen.csec > 99) { stopwatch_screen.csec = 0; stopwatch_screen.sec++; }; if (stopwatch_screen.sec > 59) { stopwatch_screen.sec = 0; stopwatch_screen.min++; }; if (stopwatch_screen.min > 59) { stopwatch_screen.min = 0; stopwatch_screen.hr++; }; if (stopwatch_screen.hr > 59) { stopwatch_screen.hr = 0; }; if (stopwatch_screen.csec % 10 == 0) draw_stop_watch_screen(&stopwatch_screen); //update_stop_watch_screen(&stopwatch_screen); return EVENT_RET_HANDLED; break; default: return EVENT_RET_UNHANDLED; break; }; return EVENT_RET_HANDLED; } /* * when alarm is fired */ void draw_alarm_screen(void) { hal_lcd_clear_display(); oswald_draw_bitmap(36, 20, alarm_icon_width, alarm_icon_height, alarm_icon_bits); hal_lcd_update_display(); } event_ret_t alarm_handle_events(uint16_t event, void *data) { switch (event) { case EVENT_SCREEN_VISIBLE: draw_alarm_screen(); hal_enable_halfsecond_timer(); hal_vibration_set_state(TRUE); return EVENT_RET_HANDLED; break; case EVENT_SCREEN_DESTROY: hal_disable_halfsecond_timer(); hal_lcd_set_backlight(FALSE); hal_vibration_set_state(FALSE); return EVENT_RET_HANDLED; break; case EVENT_USER_BUTTONS: dbg_out("button event %d\n", *(int *)data); // hal_lcd_set_backlight(FALSE); return EVENT_RET_HANDLED; break; case EVENT_HALF_SEC_TIMER: hal_lcd_set_backlight(!hal_lcd_get_backlight()); hal_vibration_set_state(!hal_vibration_get_state()); dbg_out("timer\n"); return EVENT_RET_HANDLED; break; default: return EVENT_RET_UNHANDLED; break; }; return EVENT_RET_HANDLED; } /* * Bluetooth screen */ typedef struct { uint8_t pos; boolean bt_en; boolean set_mode; boolean on; } bluetooth_data_t; static bluetooth_data_t bluetooth_screen = { 0, FALSE, FALSE, TRUE }; void draw_bluetooth_screen(bluetooth_data_t *sdata) { char bstr[20]; uint8_t *bd_addr; hal_lcd_clear_display(); oswald_draw_bitmap(36, 0, Bluetooth_icon_width, Bluetooth_icon_height, Bluetooth_icon_bits); oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits); oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits); oswald_write_string(1, 30, FONT_DROID8x12, "Enable:"); if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) { oswald_write_character(53, 30, FONT_DROID8x12, bluetooth_screen.bt_en ? 'x' : '_'); } oswald_write_string(1, 40, FONT_DROID8x12, "State:"); switch (hal_bluetooth_get_state()) { case BLUETOOTH_OFF: oswald_write_string(53, 40, FONT_DROID8x12, "off"); break; case BLUETOOTH_ON: oswald_write_string(53, 40, FONT_DROID8x12, "on"); break; case BLUETOOTH_CONNECTED: oswald_write_string(53, 40, FONT_DROID8x12, "conn."); break; default: break; }; oswald_write_string(1, 50, FONT_DROID8x12, "Visible:"); if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) { oswald_write_character(53, 50, FONT_DROID8x12, hal_bluetooth_get_visible() ? 'x' : '_'); } if (hal_bluetooth_get_state() >= BLUETOOTH_ON) { bd_addr = hal_bluetooth_get_local_bdaddr(); 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]); oswald_write_string(2, 85, FONT_5x7, bstr); } else { } hal_lcd_update_display(); } void bluetooth_handle_updown(uint8_t pos, int8_t incr) { switch (pos) { case 0: if (hal_bluetooth_get_state() >= BLUETOOTH_ON) { hal_bluetooth_set_state(BLUETOOTH_OFF); bluetooth_screen.bt_en = FALSE; } else { hal_bluetooth_set_state(BLUETOOTH_ON); bluetooth_screen.bt_en = TRUE; } break; case 1: if (hal_bluetooth_get_state() >= BLUETOOTH_ON && !hal_bluetooth_get_visible()) { hal_bluetooth_set_visible(TRUE); } else { hal_bluetooth_set_visible(FALSE); } break; case 2: break; case 3: break; case 4: break; case 5: break; case 6: break; case 7: break; case 8: break; default: break; }; } event_ret_t handle_bluetooth_buttons(watch_button button, bluetooth_data_t *sdata) { if (bluetooth_screen.set_mode) { switch (button) { case BUTTON_A: bluetooth_handle_updown(sdata->pos, 1); break; case BUTTON_B: bluetooth_handle_updown(sdata->pos, -1); break; case BUTTON_C: sdata->pos++; sdata->pos %= 2; break; case BUTTON_F: bluetooth_screen.set_mode = FALSE; break; default: return EVENT_RET_UNHANDLED; break; } } else { switch (button) { case BUTTON_F: bluetooth_screen.set_mode = TRUE; break; default: return EVENT_RET_UNHANDLED; break; } } draw_bluetooth_screen(sdata); return EVENT_RET_HANDLED; } event_ret_t bluetooth_screen_events(uint16_t event, void *data) { switch (event) { case EVENT_SCREEN_VISIBLE: bluetooth_screen.pos = 0; bluetooth_screen.bt_en = (hal_bluetooth_get_state() > 0); draw_bluetooth_screen(&bluetooth_screen); hal_enable_halfsecond_timer(); break; case EVENT_SCREEN_DESTROY: hal_disable_halfsecond_timer(); break; case EVENT_USER_BUTTONS: dbg_out("button event %d\n", *(int *)data); return handle_bluetooth_buttons(*(watch_button *)data, &bluetooth_screen); break; case EVENT_HALF_SEC_TIMER: if (bluetooth_screen.set_mode) { if (bluetooth_screen.on) bluetooth_screen.on = FALSE; else bluetooth_screen.on = TRUE; } else bluetooth_screen.on = TRUE; draw_bluetooth_screen(&bluetooth_screen); break; default: return EVENT_RET_UNHANDLED; break; }; return EVENT_RET_HANDLED; }