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