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