/* * Copyright (c) 2020 The ZMK Contributors * * SPDX-License-Identifier: MIT */ #include #include #include #include #include #include #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include #include static uint8_t last_state_of_charge = 0; uint8_t zmk_battery_state_of_charge() { return last_state_of_charge; } #if DT_HAS_CHOSEN(zmk_battery) static const struct device *const battery = DEVICE_DT_GET(DT_CHOSEN(zmk_battery)); #else #warning \ "Using a node labeled BATTERY for the battery sensor is deprecated. Set a zmk,battery chosen node instead. (Ignore this if you don't have a battery sensor.)" static const struct device *battery; #endif static int zmk_battery_update(const struct device *battery) { struct sensor_value state_of_charge; int rc = sensor_sample_fetch_chan(battery, SENSOR_CHAN_GAUGE_STATE_OF_CHARGE); if (rc != 0) { LOG_DBG("Failed to fetch battery values: %d", rc); return rc; } rc = sensor_channel_get(battery, SENSOR_CHAN_GAUGE_STATE_OF_CHARGE, &state_of_charge); if (rc != 0) { LOG_DBG("Failed to get battery state of charge: %d", rc); return rc; } if (last_state_of_charge != state_of_charge.val1) { last_state_of_charge = state_of_charge.val1; LOG_DBG("Setting BAS GATT battery level to %d.", last_state_of_charge); rc = bt_bas_set_battery_level(last_state_of_charge); if (rc != 0) { LOG_WRN("Failed to set BAS GATT battery level (err %d)", rc); return rc; } rc = ZMK_EVENT_RAISE(new_zmk_battery_state_changed( (struct zmk_battery_state_changed){.state_of_charge = last_state_of_charge})); } return rc; } static void zmk_battery_work(struct k_work *work) { int rc = zmk_battery_update(battery); if (rc != 0) { LOG_DBG("Failed to update battery value: %d.", rc); } } K_WORK_DEFINE(battery_work, zmk_battery_work); static void zmk_battery_timer(struct k_timer *timer) { k_work_submit(&battery_work); } K_TIMER_DEFINE(battery_timer, zmk_battery_timer, NULL); static int zmk_battery_init(const struct device *_arg) { #if !DT_HAS_CHOSEN(zmk_battery) battery = device_get_binding("BATTERY"); if (battery == NULL) { return -ENODEV; } LOG_WRN("Finding battery device labeled BATTERY is deprecated. Use zmk,battery chosen node."); #endif if (!device_is_ready(battery)) { LOG_ERR("Battery device \"%s\" is not ready", battery->name); return -ENODEV; } int rc = zmk_battery_update(battery); if (rc != 0) { LOG_DBG("Failed to update battery value: %d.", rc); return rc; } k_timer_start(&battery_timer, K_MINUTES(1), K_SECONDS(CONFIG_ZMK_BATTERY_REPORT_INTERVAL)); return 0; } SYS_INIT(zmk_battery_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);