]> git.karo-electronics.de Git - oswald.git/blob - ui/oswald_main.c
Oh boy... lots of changes, too many to describe
[oswald.git] / ui / oswald_main.c
1 #include "oswald.h"
2 #include "oswald_watch_faces.h"
3 #include "oswald_screens.h"
4 #include "oswald_hal.h"
5
6 #include "embedvm.h"
7
8 #include "oswald_main.h"
9
10 /*
11  * some variable defining our curent state
12  * these are globals in order to avoid having to pass pointers
13  * through function calls thus saving stack space
14  */
15 clock_state OswaldClk;
16 alarm_clk OswaldAlarm;
17 watch_state OswaldState;
18 watch_screen OswaldScreens[SCREENS_END];
19 power_state OswaldPowerState;
20 u8t backlight_safety_off = 0;
21
22 void oswald_change_to_screen(screen_number screen_id)
23 {
24         // we spare the update if no change happened
25         if (OswaldState.screen_id != screen_id) {
26                 OswaldState.screen_id = screen_id;
27                 if ((OswaldState.screen->event_func != NULL) &&
28                     (OswaldState.screen->event_mask & EVENT_SCREEN_VISIBLE))
29                                 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
30         }
31 }
32
33 void oswald_set_time(u8t hour, u8t minute, u8t second, boolean clk24hr)
34 {
35         OswaldClk.hour = hour;
36         OswaldClk.minute = minute;
37         OswaldClk.second = second;
38         OswaldClk.clk24hr = clk24hr;
39 }
40
41 void oswald_set_date(u8t day, u8t month, u16t year, boolean day_first)
42 {
43         OswaldClk.day = day;
44         OswaldClk.month = month;
45         OswaldClk.year = year;
46         OswaldClk.day_first = day_first;
47 }
48
49 static void update_clock_state (void)
50 {
51         hal_get_rtc(&OswaldClk);
52
53         /* check for pending alarm once per minute */
54         if (OswaldClk.second == 0) {
55                 if (OswaldClk.hour == OswaldAlarm.hour &&
56                         OswaldClk.minute == OswaldAlarm.minute &&
57                         ((1 << OswaldClk.wday) & OswaldAlarm.wday)) {
58                         OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL);
59                         OswaldState.screen_id = ALARM_SCREEN;
60                         OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
61                         OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
62                 }
63         }
64 }
65
66 void oswald_one_second_tick(void)
67 {
68         /* update clock - should use RTC if available */
69         update_clock_state();
70
71         hal_get_power_state(&OswaldPowerState);
72         if (backlight_safety_off) {
73                 backlight_safety_off--;
74                 if (!backlight_safety_off)
75                         hal_lcd_set_backlight(FALSE);
76         }
77
78         /* wake-up screen if interested in the one-second-event */
79         if (OswaldState.screen->event_func != NULL &&
80             (OswaldState.screen->event_mask & EVENT_ONE_SEC_TIMER))
81                 OswaldState.screen->event_func(EVENT_ONE_SEC_TIMER, NULL);
82 }
83
84 void oswald_centisecond_tick(void)
85 {
86         if (OswaldState.screen->event_func != NULL &&
87             (OswaldState.screen->event_mask & EVENT_CS_TIMER))
88                 OswaldState.screen->event_func(EVENT_CS_TIMER, NULL);
89 }
90
91 void oswald_halfsecond_tick(void)
92 {
93         if (OswaldState.screen->event_func != NULL &&
94             (OswaldState.screen->event_mask & EVENT_HALF_SEC_TIMER))
95                 OswaldState.screen->event_func(EVENT_HALF_SEC_TIMER, NULL);
96 }
97
98 void oswald_handle_button_press(watch_button button)
99 {
100         switch (button) {
101                 case BUTTON_D:
102                         // backlight on/off
103                         if (hal_lcd_get_backlight()) {
104                                 hal_lcd_set_backlight(FALSE);
105                                 backlight_safety_off = 0;
106                         } else {
107                                 hal_lcd_set_backlight(TRUE);
108                                 backlight_safety_off = 2;
109                         }
110                         break;
111                 case BUTTON_A:
112                 case BUTTON_B:
113                 case BUTTON_E:
114                 case BUTTON_F:
115                         if (OswaldState.screen->event_func != NULL &&
116                             (OswaldState.screen->event_mask & EVENT_USER_BUTTONS))
117                                 OswaldState.screen->event_func(EVENT_USER_BUTTONS, &button);
118                         break;
119                 case BUTTON_C:
120                         OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL);
121                         // next screen
122                         OswaldState.screen_id++;
123                         if (OswaldState.screen_id >= LAST_SCREEN) {
124                                 OswaldState.screen_id = IDLE_SCREEN;
125                         };
126                         OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
127                         OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
128                         break;
129                 default:
130                         // should never get here
131                         break;
132         };
133 }
134
135 void oswald_handle_accel_event(u8t x, u8t y, u8t z)
136 {
137         accel_data_t accel_data;
138
139         accel_data.x = x;
140         accel_data.y = y;
141         accel_data.z = z;
142
143         if (OswaldState.screen->event_func != NULL &&
144             (OswaldState.screen->event_mask & EVENT_ACCEL_UPDATE))
145                 OswaldState.screen->event_func(EVENT_ACCEL_UPDATE, &accel_data);
146 }
147
148 void oswald_handle_ambientlight_event(u8t light_level)
149 {
150         if (OswaldState.screen->event_func != NULL &&
151             (OswaldState.screen->event_mask & EVENT_AMBIENTLIGHT_UPDATE))
152                 OswaldState.screen->event_func(EVENT_AMBIENTLIGHT_UPDATE, &light_level);
153 }
154
155 void oswald_init(void)
156 {
157         OswaldScreens[IDLE_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_ONE_SEC_TIMER;
158         OswaldScreens[IDLE_SCREEN].event_func = idle_handle_events;
159
160         OswaldScreens[ACCEL_DISPLAY_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_ACCEL_UPDATE;
161         OswaldScreens[ACCEL_DISPLAY_SCREEN].event_func = accel_handle_events;
162
163         OswaldScreens[DATETIME_SETTING_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_HALF_SEC_TIMER;
164         OswaldScreens[DATETIME_SETTING_SCREEN].event_func = datetime_setup_events;
165
166         OswaldScreens[ALARM_SETUP_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_HALF_SEC_TIMER;
167         OswaldScreens[ALARM_SETUP_SCREEN].event_func = alarm_setup_events;
168
169         OswaldScreens[MENU_TEST_SCREEN].event_mask = EVENT_USER_BUTTONS;
170         OswaldScreens[MENU_TEST_SCREEN].event_func = test_menu_handle_events;
171
172         OswaldScreens[STOP_WATCH_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_CS_TIMER;
173         OswaldScreens[STOP_WATCH_SCREEN].event_func = stop_watch_handle_events;
174
175         OswaldScreens[ALARM_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_HALF_SEC_TIMER;
176         OswaldScreens[ALARM_SCREEN].event_func = alarm_handle_events;
177
178         OswaldState.screen_id = IDLE_SCREEN;
179         OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
180
181         if (OswaldState.screen->event_func != NULL)
182                 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
183
184         OswaldAlarm.hour = 12;
185         OswaldAlarm.minute = 0;
186         OswaldAlarm.wday = 0x00;
187 }
188