+ 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;
+}
+
+
+/*
+ * Alarm screen, shown 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);
+ return EVENT_RET_UNHANDLED;
+ 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 setup 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;
+}
+
+
+/*
+ * Info Screen
+ */
+void draw_info_screen(accel_data_t *accel_data)
+{
+ hal_lcd_clear_display();
+
+ oswald_draw_bitmap(36, 0, info_icon_width, info_icon_height, info_icon_bits);
+
+ oswald_write_string(2, 29, FONT_DROID8x12, "Oswald");
+ oswald_write_string(35, 29, FONT_DROID8x12, OSWALD_VERSION);
+ oswald_write_string(2, 41, FONT_DROID8x12, "HAL");
+ oswald_write_string(35, 41, FONT_DROID8x12, (char *)hal_get_version_string());
+ oswald_write_string(2, 53, FONT_DROID8x12, "Build");
+ oswald_write_string(35, 53, FONT_DROID8x12, (char *)hal_get_buildno_string());
+ oswald_write_string(2, 65, FONT_DROID8x12, "Radio");
+ oswald_write_string(35, 65, FONT_DROID8x12, (char *)hal_get_radio_version_string());
+
+ hal_lcd_update_display();
+}
+
+event_ret_t info_screen_handle_events(uint16_t event, void *data)
+{
+ switch (event) {
+ case EVENT_SCREEN_VISIBLE:
+ draw_info_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;