]> git.karo-electronics.de Git - oswald.git/blob - metawatch/oswald_hal.c
16b1cd1e4a58c659720f29454972a5215e3ab7a0
[oswald.git] / metawatch / oswald_hal.c
1 /*
2  * Adaptation to Oswald
3  */
4 #include <msp430.h>
5 #include <msp430xgeneric.h>
6 #include <stdint.h>
7 #include <string.h>
8
9 #include "mw_main.h"
10
11 #include "mw_lcd.h"
12 #include "mw_adc.h"
13 #include "mw_bt.h"
14 #include "bt_hci.h"
15 #include "bt_l2cap.h"
16 #include "bluetooth_init_cc256x.h"
17 #include "mw_acc.h"
18
19 #include "oswald.h"
20 #include "oswald_hal.h"
21
22 #include "calendar.h"
23
24
25 const char *hal_get_version_string(void)
26 {
27         return MW_MAIN_VERSION;
28 }
29
30 const char *hal_get_buildno_string(void)
31 {
32         return BUILDNO;
33 }
34
35 const char *hal_get_radio_version_string(void)
36 {
37         return cc256x_version;
38 }
39
40 void hal_lcd_set_pixel(uint8_t x, uint8_t y, uint8_t color)
41 {
42         x %= 96;
43         y %= 96;
44         mw_lcd_draw_pixel(x, y, color ? LCD_BLACK : LCD_WHITE);
45 }
46
47 void hal_lcd_clear_display(void)
48 {
49         mw_lcd_clear_fb();
50 }
51
52 void hal_lcd_update_display(void)
53 {
54         mw_lcd_update_screen();
55 }
56
57 void hal_lcd_set_backlight(boolean state)
58 {
59         if (state) {
60                 ENABLE_LCD_LED();
61         } else {
62                 DISABLE_LCD_LED();
63         }
64 }
65
66 boolean hal_lcd_get_backlight(void)
67 {
68         return (LCD_LED_POUT & LCD_LED_PIN) ? TRUE : FALSE;
69 }
70
71 void hal_enable_centisecond_timer(void)
72 {
73         start_timer(TIMER_100MS_CYCLES);
74 }
75
76 void hal_disable_centisecond_timer(void)
77 {
78         stop_timer();
79 }
80
81 void hal_enable_halfsecond_timer(void)
82 {
83         start_timer(TIMER_500MS_CYCLES);
84 }
85
86 void hal_disable_halfsecond_timer(void)
87 {
88         stop_timer();
89 }
90
91 void hal_get_rtc(clock_state *rtc)
92 {
93         /* Update clock state from RTC */
94         rtc->hour = RTCHOUR;
95         rtc->minute = RTCMIN;
96         rtc->second = RTCSEC;
97         rtc->day = RTCDAY;
98         rtc->month = RTCMON;
99         rtc->year = RTCYEAR;
100         rtc->wday = RTCDOW;
101 }
102
103 void hal_set_rtc(clock_state *rtc, boolean set_sec)
104 {
105         /* Update clock state from RTC */
106         RTCHOUR = rtc->hour;
107         RTCMIN = rtc->minute;
108         if (set_sec)
109                 RTCSEC = rtc->second;
110         RTCDAY = rtc->day;
111         RTCMON = rtc->month;
112         RTCYEAR = rtc->year;
113         rtc->wday = getWochentag(rtc->day, rtc->month, rtc->year);
114         RTCDOW = rtc->wday;
115 }
116
117 void hal_get_power_state(power_state *pwr)
118 {
119         unsigned int val;
120
121         pwr->source = (BAT_CHARGE_IN & BAT_CHARGE_PWR_BIT) ? POWER_SOURCE_BATTERY : POWER_SOURCE_EXTERNAL;
122
123         /* unless the charger is enabled we do not get a reasonable state */
124         if (!(BAT_CHARGE_IN & BAT_CHARGE_ENABLE_PIN)) {
125                 switch (BAT_CHARGE_IN & (BAT_CHARGE_STAT1 | BAT_CHARGE_STAT2)) {
126                         case BAT_CHARGE_STAT1:
127                                 pwr->charge_state = POWER_CHARGER_DONE;
128                                 break;
129                         case BAT_CHARGE_STAT2:
130                                 pwr->charge_state = POWER_CHARGER_CHARGING;
131                                 break;
132                         case (BAT_CHARGE_STAT1 | BAT_CHARGE_STAT2):
133                                 pwr->charge_state = POWER_CHARGER_UNK;
134                                 break;
135                         default:
136                                 pwr->charge_state = POWER_CHARGER_PRECHARGE;
137                                 break;
138                 }
139         } else {
140                 pwr->charge_state = POWER_CHARGER_UNK;
141         }
142
143         if ((pwr->source == POWER_SOURCE_BATTERY) && (RTCSEC != 0)) {
144                 /* the ADC and activating the measuring shunts is
145                  * power expensive so only do this every minute */
146                 return;
147         };
148
149         /* get new values and so some averaging to avoid jumps */
150         val = mw_get_battery_adc_val();
151         pwr->percent = mw_get_battery_percentage_from_val(val);
152         pwr->level = val;
153 }
154
155 void hal_vibration_set_state(boolean state)
156 {
157 #ifdef MW_DIGITAL_V2
158         if (state) {
159                 TA1CTL |= TASSEL__ACLK | MC__UPDOWN | ID_0;
160                 P7SEL |= BIT3;
161         } else {
162                 TA1CTL = 0;
163                 P7SEL &= ~BIT3;
164         }
165 #endif
166 }
167
168 boolean hal_vibration_get_state(void)
169 {
170 #ifdef MW_DIGITAL_V2
171         return (P7SEL & BIT3) ? TRUE : FALSE;
172 #else
173         return FALSE;
174 #endif
175 }
176
177 #define BLUETOOTH_DEVICE_NAME "Oswald on MetaWatch"
178 static boolean bt_is_visible = FALSE;
179
180
181 bluetooth_state hal_bluetooth_set_state(bluetooth_state state)
182 {
183         uint8_t buf[32];
184
185         if (state == BLUETOOTH_OFF && mw_bt_is_enabled() == 1) {
186                 mw_disable_bt();
187                 bt_is_visible = FALSE;
188                 return BLUETOOTH_OFF;
189         } else if (state == BLUETOOTH_ON && mw_bt_is_enabled() == 0) {
190                 mw_enable_bt();
191                 // set our name
192                 memset(buf, 0, 32);
193                 strncpy((char *)buf, BLUETOOTH_DEVICE_NAME, strlen(BLUETOOTH_DEVICE_NAME));
194                 bt_hci_cmd(HCI_HC_BB_OGF, HCI_W_LOCAL_NAME_OCF, strlen(BLUETOOTH_DEVICE_NAME)+1, buf);
195                 // read our local address
196                 bt_hci_cmd(HCI_INFO_PARAM_OGF, HCI_R_BD_ADDR_OCF, 0, NULL);
197                 // enable page scan
198                 buf[0] = HCI_BB_SCAN_PAGE;
199                 bt_hci_cmd(HCI_HC_BB_OGF, HCI_W_SCAN_EN_OCF, 1, buf);
200                 bt_is_visible = FALSE;
201                 return BLUETOOTH_ON;
202         } else
203                 return BLUETOOTH_ILL;
204 }
205
206 bluetooth_state hal_bluetooth_get_state(void)
207 {
208         if (mw_bt_is_enabled() == 1) {
209                 if (bt_l2cap_get_connected(0x40))
210                         return BLUETOOTH_CONNECTED;
211                 else
212                         return BLUETOOTH_ON;
213         } else
214                 return BLUETOOTH_OFF;
215 }
216
217 uint8_t *hal_bluetooth_get_local_bdaddr(void)
218 {
219         return bt_hci_get_local_bdaddr();
220 }
221
222 void hal_bluetooth_set_visible(boolean visible)
223 {
224         uint8_t buf[2];
225
226         if (mw_bt_is_enabled() == 0) {
227                 bt_is_visible = FALSE;
228                 return;
229         }
230
231         if (visible) {
232                 // enable page and inquiry scan
233                 buf[0] = HCI_BB_SCAN_INQUIRY | HCI_BB_SCAN_PAGE;
234                 bt_hci_cmd(HCI_HC_BB_OGF, HCI_W_SCAN_EN_OCF, 1, buf);
235                 bt_is_visible = TRUE;
236         } else {
237                 // enable page scan only
238                 buf[0] = HCI_BB_SCAN_PAGE;
239                 bt_hci_cmd(HCI_HC_BB_OGF, HCI_W_SCAN_EN_OCF, 1, buf);
240                 bt_is_visible = FALSE;
241         }
242 }
243
244 boolean hal_bluetooth_get_visible(void)
245 {
246         return bt_is_visible;
247 }
248
249 void hal_bluetooth_send_data(const void *mdat, uint16_t mlen)
250 {
251         bt_l2cap_send_channel(0x40, mdat, mlen);
252 }
253
254 /*
255  * Control the accelerometer
256  */
257 void hal_accelerometer_enable(void)
258 {
259         mw_acc_enable();
260 }
261
262 void hal_accelerometer_disable(void)
263 {
264         mw_acc_disable();
265 }
266
267 uint16_t hal_amblight_get_val(void)
268 {
269         return mw_get_amblight_adc_val();
270 }
271