]> git.karo-electronics.de Git - oswald.git/blobdiff - ui/oswald_main.c
Shorten charger plug "tail"
[oswald.git] / ui / oswald_main.c
index 82b856712f9ebe3a1ec42c3c64dcac273b2a3a4c..f26603b9e4a085c9947d659cfef4a5f2d21be5e8 100644 (file)
@@ -1,6 +1,7 @@
 #include "oswald.h"
 #include "oswald_watch_faces.h"
 #include "oswald_screens.h"
+#include "oswald_hal.h"
 
 #include "embedvm.h"
 
  * through function calls thus saving stack space
  */
 clock_state OswaldClk;
+alarm_clk OswaldAlarm;
 watch_state OswaldState;
-watch_screen OswaldScreens[LAST_SCREEN];
+watch_screen OswaldScreens[SCREENS_END];
+power_state OswaldPowerState;
+uint8_t backlight_safety_off = 0;
+char MainMessage[148];
 
 
 void oswald_change_to_screen(screen_number screen_id)
@@ -27,43 +32,69 @@ void oswald_change_to_screen(screen_number screen_id)
        }
 }
 
-void oswald_set_time(u8t hour, u8t minute, u8t second)
+void oswald_set_time(uint8_t hour, uint8_t minute, uint8_t second, boolean clk24hr)
 {
        OswaldClk.hour = hour;
        OswaldClk.minute = minute;
        OswaldClk.second = second;
+       OswaldClk.clk24hr = clk24hr;
+}
+
+void oswald_set_date(uint8_t day, uint8_t month, uint16_t year, boolean day_first)
+{
+       OswaldClk.day = day;
+       OswaldClk.month = month;
+       OswaldClk.year = year;
+       OswaldClk.day_first = day_first;
 }
 
 static void update_clock_state (void)
 {
-       OswaldClk.second += 1;
-       if (OswaldClk.second > 59) {
-               OswaldClk.second = 0;
-               OswaldClk.minute += 1;
-       } else
-               return;
-       if (OswaldClk.minute > 59) {
-               OswaldClk.minute = 0;
-               OswaldClk.hour += 1;
-       } else
-               return;
-       if (OswaldClk.hour > 23) {
-               OswaldClk.hour = 0;
-               // day++
-       } else
-               return;
+       hal_get_rtc(&OswaldClk);
+
+       /* check for pending alarm once per minute */
+       if (OswaldClk.second == 0) {
+               if (OswaldClk.hour == OswaldAlarm.hour &&
+                       OswaldClk.minute == OswaldAlarm.minute &&
+                       ((1 << OswaldClk.wday) & OswaldAlarm.wday)) {
+                       OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL);
+                       OswaldState.screen_id = ALARM_SCREEN;
+                       OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
+                       OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
+               }
+       }
 }
 
 void oswald_one_second_tick(void)
 {
-       /* update our 'RTC' */
+       /* update clock - should use RTC if available */
        update_clock_state();
 
+       hal_get_power_state(&OswaldPowerState);
+       if (backlight_safety_off) {
+               backlight_safety_off--;
+               if (!backlight_safety_off)
+                       hal_lcd_set_backlight(FALSE);
+       }
+
        /* wake-up screen if interested in the one-second-event */
        if (OswaldState.screen->event_func != NULL &&
            (OswaldState.screen->event_mask & EVENT_ONE_SEC_TIMER))
                OswaldState.screen->event_func(EVENT_ONE_SEC_TIMER, NULL);
-       // oswald_update_screen();
+}
+
+void oswald_centisecond_tick(void)
+{
+       if (OswaldState.screen->event_func != NULL &&
+           (OswaldState.screen->event_mask & EVENT_CS_TIMER))
+               OswaldState.screen->event_func(EVENT_CS_TIMER, NULL);
+}
+
+void oswald_halfsecond_tick(void)
+{
+       if (OswaldState.screen->event_func != NULL &&
+           (OswaldState.screen->event_mask & EVENT_HALF_SEC_TIMER))
+               OswaldState.screen->event_func(EVENT_HALF_SEC_TIMER, NULL);
 }
 
 void oswald_handle_button_press(watch_button button)
@@ -71,24 +102,37 @@ void oswald_handle_button_press(watch_button button)
        switch (button) {
                case BUTTON_A:
                case BUTTON_B:
-               case BUTTON_D:
                case BUTTON_E:
+               case BUTTON_F:
                        if (OswaldState.screen->event_func != NULL &&
-                           (OswaldState.screen->event_mask & EVENT_USER_BUTTONS))
-                               OswaldState.screen->event_func(EVENT_USER_BUTTONS, &button);
+                           (OswaldState.screen->event_mask & EVENT_USER_BUTTONS)) {
+                               OswaldState.screen->event_func(EVENT_USER_BUTTONS, &button);
+                       }
                        break;
                case BUTTON_C:
+                       if (OswaldState.screen->event_func != NULL &&
+                           (OswaldState.screen->event_mask & EVENT_USER_BUTTONS)) {
+                               if (OswaldState.screen->event_func(EVENT_USER_BUTTONS, &button) == EVENT_RET_HANDLED)
+                                       break;
+                       }
+                       OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL);
                        // next screen
                        OswaldState.screen_id++;
                        if (OswaldState.screen_id >= LAST_SCREEN) {
                                OswaldState.screen_id = IDLE_SCREEN;
                        };
                        OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
-                       //oswald_update_screen();
                        OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
                        break;
-               case BUTTON_F:
+               case BUTTON_D:
                        // backlight on/off
+                       if (hal_lcd_get_backlight()) {
+                               hal_lcd_set_backlight(FALSE);
+                               backlight_safety_off = 0;
+                       } else {
+                               hal_lcd_set_backlight(TRUE);
+                               backlight_safety_off = 2;
+                       }
                        break;
                default:
                        // should never get here
@@ -96,25 +140,90 @@ void oswald_handle_button_press(watch_button button)
        };
 }
 
+void oswald_handle_accel_event(uint8_t x, uint8_t y, uint8_t z)
+{
+       accel_data_t accel_data;
+
+       accel_data.x = x;
+       accel_data.y = y;
+       accel_data.z = z;
+
+       if (OswaldState.screen->event_func != NULL &&
+           (OswaldState.screen->event_mask & EVENT_ACCEL_UPDATE))
+               OswaldState.screen->event_func(EVENT_ACCEL_UPDATE, &accel_data);
+}
+
+void oswald_handle_ambientlight_event(uint8_t light_level)
+{
+       if (OswaldState.screen->event_func != NULL &&
+           (OswaldState.screen->event_mask & EVENT_AMBIENTLIGHT_UPDATE))
+               OswaldState.screen->event_func(EVENT_AMBIENTLIGHT_UPDATE, &light_level);
+}
+
+void oswald_handle_comm_input(uint16_t mlen, const void *mdat)
+{
+       char *icmd = (char *) mdat;
+
+       if (icmd[0] == '$') {
+               if (strncmp(icmd, "$GRT", 4) == 0) { // get current RTC
+                       char rtime[16];
+                       snprintf(rtime, 16, "#RTC%02d%02d%02d\n", OswaldClk.hour, OswaldClk.minute, OswaldClk.second);
+                       hal_bluetooth_send_data(rtime, strlen(rtime));
+               } else if (strncmp(icmd, "$SRT", 4) == 0) { // set current RTC
+               } else if (strncmp(icmd, "$MSG", 4) == 0) { // message on main screen
+                       char *msg = (icmd+4);
+                       mlen -= 4;
+                       memset(MainMessage, 0, 148);
+                       strncpy(MainMessage, msg, (mlen > 147) ? 147 : mlen);
+               } else if (strncmp(icmd, "$MCL", 4) == 0) { // clear message
+                       memset(MainMessage, 0, 148);
+               } else if (strncmp(icmd, "$BAT", 4) == 0) { // clear message
+                       char rtime[16];
+                       snprintf(rtime, 16, "#BAT%d,%d\n", OswaldPowerState.charge_state, OswaldPowerState.percent);
+                       hal_bluetooth_send_data(rtime, strlen(rtime));
+               }
+       }
+}
+
 void oswald_init(void)
 {
        OswaldScreens[IDLE_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_ONE_SEC_TIMER;
        OswaldScreens[IDLE_SCREEN].event_func = idle_handle_events;
 
-       OswaldScreens[ACCEL_DISPLAY_SCREEN].event_mask = EVENT_USER_BUTTONS;
+       OswaldScreens[ACCEL_DISPLAY_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_ACCEL_UPDATE;
        OswaldScreens[ACCEL_DISPLAY_SCREEN].event_func = accel_handle_events;
-       
 
-       OswaldScreens[DATETIME_SETTING_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_ONE_SEC_TIMER;
+       OswaldScreens[DATETIME_SETTING_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_HALF_SEC_TIMER;
        OswaldScreens[DATETIME_SETTING_SCREEN].event_func = datetime_setup_events;
 
+       OswaldScreens[ALARM_SETUP_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_HALF_SEC_TIMER;
+       OswaldScreens[ALARM_SETUP_SCREEN].event_func = alarm_setup_events;
+
        OswaldScreens[MENU_TEST_SCREEN].event_mask = EVENT_USER_BUTTONS;
        OswaldScreens[MENU_TEST_SCREEN].event_func = test_menu_handle_events;
 
+       OswaldScreens[STOP_WATCH_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_CS_TIMER;
+       OswaldScreens[STOP_WATCH_SCREEN].event_func = stop_watch_handle_events;
+
+       OswaldScreens[BLUETOOTH_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_HALF_SEC_TIMER;
+       OswaldScreens[BLUETOOTH_SCREEN].event_func = bluetooth_screen_events;
+
+       OswaldScreens[ALARM_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_HALF_SEC_TIMER;
+       OswaldScreens[ALARM_SCREEN].event_func = alarm_handle_events;
+
+       OswaldScreens[INFO_SCREEN].event_mask = 0x00; // this one does not consume any events
+       OswaldScreens[INFO_SCREEN].event_func = info_screen_handle_events;
+
        OswaldState.screen_id = IDLE_SCREEN;
        OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
 
        if (OswaldState.screen->event_func != NULL)
                OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
+
+       OswaldAlarm.hour = 12;
+       OswaldAlarm.minute = 0;
+       OswaldAlarm.wday = 0x00;
+
+       // strcpy(MainMessage, "So koennte dann eine Nachricht aussehen. Samt Text mit Unterlaengen. Und dies ist dann die letzte Zeile und mehr Text als paßt.");
 }