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