/* * Adaptation to Oswald */ #include #include #include #include #include "mw_main.h" #include "mw_lcd.h" #include "mw_adc.h" #include "mw_bt.h" #include "bt_hci.h" #include "bt_l2cap.h" #include "bluetooth_init_cc256x.h" #include "mw_acc.h" #include "oswald.h" #include "oswald_hal.h" #include "calendar.h" const char *hal_get_version_string(void) { return MW_MAIN_VERSION; } const char *hal_get_buildno_string(void) { return BUILDNO; } const char *hal_get_radio_version_string(void) { return cc256x_version; } void hal_lcd_set_pixel(uint8_t x, uint8_t y, uint8_t color) { if (x > 95) x = 95; if (y > 95) y = 95; mw_lcd_draw_pixel(x, y, color ? LCD_BLACK : LCD_WHITE); } void hal_lcd_clear_display(void) { mw_lcd_clear_fb(); } void hal_lcd_update_display(void) { mw_lcd_update_screen(); } void hal_lcd_set_backlight(boolean state) { if (state) { ENABLE_LCD_LED(); } else { DISABLE_LCD_LED(); } } boolean hal_lcd_get_backlight(void) { return (LCD_LED_POUT & LCD_LED_PIN) ? TRUE : FALSE; } void hal_enable_centisecond_timer(void) { start_timer(TIMER_100MS_CYCLES); } void hal_disable_centisecond_timer(void) { stop_timer(); } void hal_enable_halfsecond_timer(void) { start_timer(TIMER_500MS_CYCLES); } void hal_disable_halfsecond_timer(void) { stop_timer(); } void hal_get_rtc(clock_state *rtc) { /* Update clock state from RTC */ rtc->hour = RTCHOUR; rtc->minute = RTCMIN; rtc->second = RTCSEC; rtc->day = RTCDAY; rtc->month = RTCMON; rtc->year = RTCYEAR; rtc->wday = RTCDOW; } void hal_set_rtc(clock_state *rtc, boolean set_sec) { /* Update clock state from RTC */ RTCHOUR = rtc->hour; RTCMIN = rtc->minute; if (set_sec) RTCSEC = rtc->second; RTCDAY = rtc->day; RTCMON = rtc->month; RTCYEAR = rtc->year; rtc->wday = getWochentag(rtc->day, rtc->month, rtc->year); RTCDOW = rtc->wday; } void hal_get_power_state(power_state *pwr) { unsigned int val; pwr->source = (BAT_CHARGE_IN & BAT_CHARGE_PWR_BIT) ? POWER_SOURCE_BATTERY : POWER_SOURCE_EXTERNAL; /* unless the charger is enabled we do not get a reasonable state */ if (!(BAT_CHARGE_IN & BAT_CHARGE_ENABLE_PIN)) { switch (BAT_CHARGE_IN & (BAT_CHARGE_STAT1 | BAT_CHARGE_STAT2)) { case BAT_CHARGE_STAT1: pwr->charge_state = POWER_CHARGER_DONE; break; case BAT_CHARGE_STAT2: pwr->charge_state = POWER_CHARGER_CHARGING; break; case (BAT_CHARGE_STAT1 | BAT_CHARGE_STAT2): pwr->charge_state = POWER_CHARGER_UNK; break; default: pwr->charge_state = POWER_CHARGER_PRECHARGE; break; } } else { pwr->charge_state = POWER_CHARGER_UNK; } if ((pwr->source == POWER_SOURCE_BATTERY) && (RTCSEC != 0)) { /* the ADC and activating the measuring shunts is * power expensive so only do this every minute */ return; }; /* get new values and so some averaging to avoid jumps */ val = mw_get_battery_adc_val(); pwr->percent = mw_get_battery_percentage_from_val(val); pwr->level = val; } void hal_vibration_set_state(boolean state) { #ifdef MW_DIGITAL_V2 if (state) { TA1CTL |= TASSEL__ACLK | MC__UPDOWN | ID_0; P7SEL |= BIT3; } else { TA1CTL = 0; P7SEL &= ~BIT3; } #endif } boolean hal_vibration_get_state(void) { #ifdef MW_DIGITAL_V2 return (P7SEL & BIT3) ? TRUE : FALSE; #else return FALSE; #endif } #define BLUETOOTH_DEVICE_NAME "Oswald on MetaWatch" static boolean bt_is_visible = FALSE; bluetooth_state hal_bluetooth_set_state(bluetooth_state state) { uint8_t buf[32]; if (state == BLUETOOTH_OFF && mw_bt_is_enabled() == 1) { mw_disable_bt(); bt_is_visible = FALSE; return BLUETOOTH_OFF; } else if (state == BLUETOOTH_ON && mw_bt_is_enabled() == 0) { mw_enable_bt(); // set our name memset(buf, 0, 32); strncpy((char *)buf, BLUETOOTH_DEVICE_NAME, strlen(BLUETOOTH_DEVICE_NAME)); bt_hci_cmd(HCI_HC_BB_OGF, HCI_W_LOCAL_NAME_OCF, strlen(BLUETOOTH_DEVICE_NAME)+1, buf); // read our local address bt_hci_cmd(HCI_INFO_PARAM_OGF, HCI_R_BD_ADDR_OCF, 0, NULL); // enable page scan buf[0] = HCI_BB_SCAN_PAGE; bt_hci_cmd(HCI_HC_BB_OGF, HCI_W_SCAN_EN_OCF, 1, buf); bt_is_visible = FALSE; return BLUETOOTH_ON; } else return BLUETOOTH_ILL; } bluetooth_state hal_bluetooth_get_state(void) { if (mw_bt_is_enabled() == 1) { if (bt_l2cap_get_connected(0x40)) return BLUETOOTH_CONNECTED; else return BLUETOOTH_ON; } else return BLUETOOTH_OFF; } uint8_t *hal_bluetooth_get_local_bdaddr(void) { return bt_hci_get_local_bdaddr(); } void hal_bluetooth_set_visible(boolean visible) { uint8_t buf[2]; if (mw_bt_is_enabled() == 0) { bt_is_visible = FALSE; return; } if (visible) { // enable page and inquiry scan buf[0] = HCI_BB_SCAN_INQUIRY | HCI_BB_SCAN_PAGE; bt_hci_cmd(HCI_HC_BB_OGF, HCI_W_SCAN_EN_OCF, 1, buf); bt_is_visible = TRUE; } else { // enable page scan only buf[0] = HCI_BB_SCAN_PAGE; bt_hci_cmd(HCI_HC_BB_OGF, HCI_W_SCAN_EN_OCF, 1, buf); bt_is_visible = FALSE; } } boolean hal_bluetooth_get_visible(void) { return bt_is_visible; } void hal_bluetooth_send_data(const void *mdat, uint16_t mlen) { bt_l2cap_send_channel(0x40, mdat, mlen); } /* * Control the accelerometer */ void hal_accelerometer_enable(void) { mw_acc_enable(); } void hal_accelerometer_disable(void) { mw_acc_disable(); } uint16_t hal_amblight_get_val(void) { return mw_get_amblight_adc_val(); }