Merge 4990e079da
into b74cd39ab5
This commit is contained in:
commit
ea12ee438b
12 changed files with 312 additions and 13 deletions
app
include
module
drivers/sensor/battery
dts/bindings/sensor
src
docs/docs/config
21
app/include/drivers/sensor/battery/battery_charging.h
Normal file
21
app/include/drivers/sensor/battery/battery_charging.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_BATTERY_BATTERY_CHARGING_H_
|
||||
#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_BATTERY_BATTERY_CHARGING_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
|
||||
enum sensor_channel_bvd {
|
||||
/** Charging state, bool **/
|
||||
SENSOR_CHAN_CHARGING = SENSOR_CHAN_PRIV_START,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -7,3 +7,4 @@
|
|||
#pragma once
|
||||
|
||||
uint8_t zmk_battery_state_of_charge(void);
|
||||
bool zmk_battery_charging(void);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
struct zmk_battery_state_changed {
|
||||
// TODO: Other battery channels
|
||||
uint8_t state_of_charge;
|
||||
bool charging;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(zmk_battery_state_changed);
|
||||
|
@ -19,6 +20,7 @@ ZMK_EVENT_DECLARE(zmk_battery_state_changed);
|
|||
struct zmk_peripheral_battery_state_changed {
|
||||
uint8_t source;
|
||||
// TODO: Other battery channels
|
||||
// Charging state not broadcast over BAS so no need to have it in peripheral event
|
||||
uint8_t state_of_charge;
|
||||
};
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
|
||||
zephyr_include_directories(.)
|
||||
zephyr_include_directories(${CMAKE_SOURCE_DIR}/include)
|
||||
|
||||
zephyr_library()
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <errno.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
|
||||
#include <drivers/sensor/battery/battery_charging.h>
|
||||
|
||||
#include "battery_common.h"
|
||||
|
||||
int battery_channel_get(const struct battery_value *value, enum sensor_channel chan,
|
||||
|
@ -22,6 +24,11 @@ int battery_channel_get(const struct battery_value *value, enum sensor_channel c
|
|||
val_out->val2 = 0;
|
||||
break;
|
||||
|
||||
case SENSOR_CHAN_CHARGING:
|
||||
val_out->val1 = value->charging;
|
||||
val_out->val2 = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ struct battery_value {
|
|||
uint16_t adc_raw;
|
||||
uint16_t millivolts;
|
||||
uint8_t state_of_charge;
|
||||
bool charging;
|
||||
};
|
||||
|
||||
int battery_channel_get(const struct battery_value *value, enum sensor_channel chan,
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/adc.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include <drivers/sensor/battery/battery_charging.h>
|
||||
#include "battery_common.h"
|
||||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
@ -23,16 +25,59 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
|
||||
static const struct device *adc = DEVICE_DT_GET(DT_NODELABEL(adc));
|
||||
|
||||
struct vddh_config {
|
||||
struct gpio_dt_spec chg;
|
||||
};
|
||||
|
||||
struct vddh_data {
|
||||
struct adc_channel_cfg acc;
|
||||
struct adc_sequence as;
|
||||
struct battery_value value;
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
const struct device *dev;
|
||||
const struct sensor_trigger *data_ready_trigger;
|
||||
struct gpio_callback gpio_cb;
|
||||
sensor_trigger_handler_t data_ready_handler;
|
||||
struct k_work work;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
static void set_int(const struct device *dev, const bool en) {
|
||||
const struct vddh_config *drv_cfg = dev->config;
|
||||
int ret =
|
||||
gpio_pin_interrupt_configure_dt(&drv_cfg->chg, en ? GPIO_INT_EDGE_BOTH : GPIO_INT_DISABLE);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("can't set interrupt");
|
||||
}
|
||||
}
|
||||
|
||||
static int vddh_trigger_set(const struct device *dev, const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler) {
|
||||
struct vddh_data *drv_data = dev->data;
|
||||
|
||||
set_int(dev, false);
|
||||
if (trig->type != SENSOR_TRIG_DATA_READY) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
drv_data->data_ready_trigger = trig;
|
||||
drv_data->data_ready_handler = handler;
|
||||
set_int(dev, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vddh_int_cb(const struct device *dev) {
|
||||
struct vddh_data *drv_data = dev->data;
|
||||
drv_data->data_ready_handler(dev, drv_data->data_ready_trigger);
|
||||
LOG_DBG("Setting int on %d", 0);
|
||||
set_int(dev, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int vddh_sample_fetch(const struct device *dev, enum sensor_channel chan) {
|
||||
// Make sure selected channel is supported
|
||||
if (chan != SENSOR_CHAN_GAUGE_VOLTAGE && chan != SENSOR_CHAN_GAUGE_STATE_OF_CHARGE &&
|
||||
chan != SENSOR_CHAN_ALL) {
|
||||
(enum sensor_channel_bvd)chan != SENSOR_CHAN_CHARGING && chan != SENSOR_CHAN_ALL) {
|
||||
LOG_DBG("Selected channel is not supported: %d.", chan);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
@ -61,6 +106,19 @@ static int vddh_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
|||
LOG_DBG("ADC raw %d ~ %d mV => %d%%", drv_data->value.adc_raw, drv_data->value.millivolts,
|
||||
drv_data->value.state_of_charge);
|
||||
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
const struct vddh_config *drv_cfg = dev->config;
|
||||
int raw = gpio_pin_get_dt(&drv_cfg->chg);
|
||||
if (raw == -EIO || raw == -EWOULDBLOCK) {
|
||||
LOG_DBG("Failed to read chg status: %d", raw);
|
||||
return raw;
|
||||
} else {
|
||||
bool charging = raw;
|
||||
LOG_DBG("Charging state: %d", raw);
|
||||
drv_data->value.charging = charging;
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -70,7 +128,22 @@ static int vddh_channel_get(const struct device *dev, enum sensor_channel chan,
|
|||
return battery_channel_get(&drv_data->value, chan, val);
|
||||
}
|
||||
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
static void vddh_work_cb(struct k_work *work) {
|
||||
struct vddh_data *drv_data = CONTAINER_OF(work, struct vddh_data, work);
|
||||
vddh_int_cb(drv_data->dev);
|
||||
}
|
||||
static void vddh_gpio_cb(const struct device *port, struct gpio_callback *cb, uint32_t pins) {
|
||||
struct vddh_data *drv_data = CONTAINER_OF(cb, struct vddh_data, gpio_cb);
|
||||
set_int(drv_data->dev, false);
|
||||
k_work_submit(&drv_data->work);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct sensor_driver_api vddh_api = {
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
.trigger_set = vddh_trigger_set,
|
||||
#endif
|
||||
.sample_fetch = vddh_sample_fetch,
|
||||
.channel_get = vddh_channel_get,
|
||||
};
|
||||
|
@ -104,13 +177,41 @@ static int vddh_init(const struct device *dev) {
|
|||
#error Unsupported ADC
|
||||
#endif
|
||||
|
||||
const int rc = adc_channel_setup(adc, &drv_data->acc);
|
||||
int rc = adc_channel_setup(adc, &drv_data->acc);
|
||||
LOG_DBG("VDDHDIV5 setup returned %d", rc);
|
||||
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
const struct vddh_config *drv_cfg = dev->config;
|
||||
if (!device_is_ready(drv_cfg->chg.port)) {
|
||||
LOG_ERR("GPIO port for chg reading is not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
rc = gpio_pin_configure_dt(&drv_cfg->chg, GPIO_INPUT);
|
||||
if (rc != 0) {
|
||||
LOG_ERR("Failed to set chg feed %u: %d", drv_cfg->chg.pin, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
drv_data->dev = dev;
|
||||
gpio_init_callback(&drv_data->gpio_cb, vddh_gpio_cb, BIT(drv_cfg->chg.pin));
|
||||
int ret = gpio_add_callback(drv_cfg->chg.port, &drv_data->gpio_cb);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to set chg callback: %d", ret);
|
||||
return -EIO;
|
||||
}
|
||||
k_work_init(&drv_data->work, vddh_work_cb);
|
||||
#endif // DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct vddh_data vddh_data;
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0, &vddh_init, NULL, &vddh_data, NULL, POST_KERNEL,
|
||||
static const struct vddh_config vddh_cfg = {
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
.chg = GPIO_DT_SPEC_INST_GET(0, chg_gpios),
|
||||
#endif
|
||||
};
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0, &vddh_init, NULL, &vddh_data, &vddh_cfg, POST_KERNEL,
|
||||
CONFIG_SENSOR_INIT_PRIORITY, &vddh_api);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include "battery_common.h"
|
||||
#include <drivers/sensor/battery/battery_charging.h>
|
||||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
|
@ -24,6 +25,7 @@ struct io_channel_config {
|
|||
struct bvd_config {
|
||||
struct io_channel_config io_channel;
|
||||
struct gpio_dt_spec power;
|
||||
struct gpio_dt_spec chg;
|
||||
uint32_t output_ohm;
|
||||
uint32_t full_ohm;
|
||||
};
|
||||
|
@ -33,8 +35,47 @@ struct bvd_data {
|
|||
struct adc_channel_cfg acc;
|
||||
struct adc_sequence as;
|
||||
struct battery_value value;
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
const struct device *dev;
|
||||
const struct sensor_trigger *data_ready_trigger;
|
||||
struct gpio_callback gpio_cb;
|
||||
sensor_trigger_handler_t data_ready_handler;
|
||||
struct k_work work;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
static void set_int(const struct device *dev, const bool en) {
|
||||
const struct bvd_config *drv_cfg = dev->config;
|
||||
int ret =
|
||||
gpio_pin_interrupt_configure_dt(&drv_cfg->chg, en ? GPIO_INT_EDGE_BOTH : GPIO_INT_DISABLE);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("can't set interrupt");
|
||||
}
|
||||
}
|
||||
|
||||
static int bvd_trigger_set(const struct device *dev, const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler) {
|
||||
struct bvd_data *drv_data = dev->data;
|
||||
|
||||
set_int(dev, false);
|
||||
if (trig->type != SENSOR_TRIG_DATA_READY) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
drv_data->data_ready_trigger = trig;
|
||||
drv_data->data_ready_handler = handler;
|
||||
set_int(dev, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bvd_int_cb(const struct device *dev) {
|
||||
struct bvd_data *drv_data = dev->data;
|
||||
drv_data->data_ready_handler(dev, drv_data->data_ready_trigger);
|
||||
LOG_DBG("Setting int on %d", 0);
|
||||
set_int(dev, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int bvd_sample_fetch(const struct device *dev, enum sensor_channel chan) {
|
||||
struct bvd_data *drv_data = dev->data;
|
||||
const struct bvd_config *drv_cfg = dev->config;
|
||||
|
@ -42,7 +83,7 @@ static int bvd_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
|||
|
||||
// Make sure selected channel is supported
|
||||
if (chan != SENSOR_CHAN_GAUGE_VOLTAGE && chan != SENSOR_CHAN_GAUGE_STATE_OF_CHARGE &&
|
||||
chan != SENSOR_CHAN_ALL) {
|
||||
(enum sensor_channel_bvd)chan != SENSOR_CHAN_CHARGING && chan != SENSOR_CHAN_ALL) {
|
||||
LOG_DBG("Selected channel is not supported: %d.", chan);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
@ -93,6 +134,18 @@ static int bvd_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
|||
}
|
||||
#endif // DT_INST_NODE_HAS_PROP(0, power_gpios)
|
||||
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
int raw = gpio_pin_get_dt(&drv_cfg->chg);
|
||||
if (raw == -EIO || raw == -EWOULDBLOCK) {
|
||||
LOG_DBG("Failed to read chg status: %d", raw);
|
||||
return raw;
|
||||
} else {
|
||||
bool charging = raw;
|
||||
LOG_DBG("Charging state: %d", raw);
|
||||
drv_data->value.charging = charging;
|
||||
}
|
||||
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -102,7 +155,22 @@ static int bvd_channel_get(const struct device *dev, enum sensor_channel chan,
|
|||
return battery_channel_get(&drv_data->value, chan, val);
|
||||
}
|
||||
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
static void bvd_work_cb(struct k_work *work) {
|
||||
struct bvd_data *drv_data = CONTAINER_OF(work, struct bvd_data, work);
|
||||
bvd_int_cb(drv_data->dev);
|
||||
}
|
||||
static void bvd_gpio_cb(const struct device *port, struct gpio_callback *cb, uint32_t pins) {
|
||||
struct bvd_data *drv_data = CONTAINER_OF(cb, struct bvd_data, gpio_cb);
|
||||
set_int(drv_data->dev, false);
|
||||
k_work_submit(&drv_data->work);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct sensor_driver_api bvd_api = {
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
.trigger_set = bvd_trigger_set,
|
||||
#endif
|
||||
.sample_fetch = bvd_sample_fetch,
|
||||
.channel_get = bvd_channel_get,
|
||||
};
|
||||
|
@ -130,6 +198,27 @@ static int bvd_init(const struct device *dev) {
|
|||
}
|
||||
#endif // DT_INST_NODE_HAS_PROP(0, power_gpios)
|
||||
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
if (!device_is_ready(drv_cfg->chg.port)) {
|
||||
LOG_ERR("GPIO port for chg reading is not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
rc = gpio_pin_configure_dt(&drv_cfg->chg, GPIO_INPUT);
|
||||
if (rc != 0) {
|
||||
LOG_ERR("Failed to set chg feed %u: %d", drv_cfg->chg.pin, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
drv_data->dev = dev;
|
||||
gpio_init_callback(&drv_data->gpio_cb, bvd_gpio_cb, BIT(drv_cfg->chg.pin));
|
||||
int ret = gpio_add_callback(drv_cfg->chg.port, &drv_data->gpio_cb);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to set chg callback: %d", ret);
|
||||
return -EIO;
|
||||
}
|
||||
k_work_init(&drv_data->work, bvd_work_cb);
|
||||
#endif // DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
|
||||
drv_data->as = (struct adc_sequence){
|
||||
.channels = BIT(0),
|
||||
.buffer = &drv_data->value.adc_raw,
|
||||
|
@ -166,6 +255,9 @@ static const struct bvd_config bvd_cfg = {
|
|||
},
|
||||
#if DT_INST_NODE_HAS_PROP(0, power_gpios)
|
||||
.power = GPIO_DT_SPEC_INST_GET(0, power_gpios),
|
||||
#endif
|
||||
#if DT_INST_NODE_HAS_PROP(0, chg_gpios)
|
||||
.chg = GPIO_DT_SPEC_INST_GET(0, chg_gpios),
|
||||
#endif
|
||||
.output_ohm = DT_INST_PROP(0, output_ohms),
|
||||
.full_ohm = DT_INST_PROP(0, full_ohms),
|
||||
|
|
|
@ -4,3 +4,9 @@
|
|||
description: Battery SoC monitoring using nRF VDDH
|
||||
|
||||
compatible: "zmk,battery-nrf-vddh"
|
||||
|
||||
properties:
|
||||
chg-gpios:
|
||||
required: false
|
||||
type: phandle-array
|
||||
description: "A GPIO pin to report charging state to"
|
||||
|
|
|
@ -6,3 +6,9 @@ description: Battery SoC monitoring using voltage divider
|
|||
compatible: "zmk,battery-voltage-divider"
|
||||
|
||||
include: voltage-divider.yaml
|
||||
|
||||
properties:
|
||||
chg-gpios:
|
||||
required: false
|
||||
type: phandle-array
|
||||
description: "A GPIO pin to report charging state to"
|
||||
|
|
|
@ -22,9 +22,13 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
#include <zmk/activity.h>
|
||||
#include <zmk/workqueue.h>
|
||||
|
||||
#include <drivers/sensor/battery/battery_charging.h>
|
||||
|
||||
static uint8_t last_state_of_charge = 0;
|
||||
static bool charging = 0;
|
||||
|
||||
uint8_t zmk_battery_state_of_charge(void) { return last_state_of_charge; }
|
||||
bool zmk_battery_charging(void) { return charging; }
|
||||
|
||||
#if DT_HAS_CHOSEN(zmk_battery)
|
||||
static const struct device *const battery = DEVICE_DT_GET(DT_CHOSEN(zmk_battery));
|
||||
|
@ -91,8 +95,31 @@ static int zmk_battery_update(const struct device *battery) {
|
|||
#error "Not a supported reporting fetch mode"
|
||||
#endif
|
||||
|
||||
if (last_state_of_charge != state_of_charge.val1) {
|
||||
#if DT_NODE_HAS_PROP(DT_CHOSEN(zmk_battery), chg_gpios)
|
||||
|
||||
rc = sensor_sample_fetch_chan(battery, SENSOR_CHAN_CHARGING);
|
||||
|
||||
if (rc != 0) {
|
||||
LOG_DBG("Failed to fetch charging value: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
struct sensor_value charging_state;
|
||||
rc = sensor_channel_get(battery, SENSOR_CHAN_CHARGING, &charging_state);
|
||||
if (rc != 0) {
|
||||
LOG_DBG("Failed to get battery charging status: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (last_state_of_charge != state_of_charge.val1
|
||||
#if DT_NODE_HAS_PROP(DT_CHOSEN(zmk_battery), chg_gpios)
|
||||
|| charging != charging_state.val1
|
||||
#endif
|
||||
) {
|
||||
last_state_of_charge = state_of_charge.val1;
|
||||
#if DT_NODE_HAS_PROP(DT_CHOSEN(zmk_battery), chg_gpios)
|
||||
charging = charging_state.val1;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_BT_BAS)
|
||||
LOG_DBG("Setting BAS GATT battery level to %d.", last_state_of_charge);
|
||||
|
||||
|
@ -103,8 +130,8 @@ static int zmk_battery_update(const struct device *battery) {
|
|||
return rc;
|
||||
}
|
||||
#endif
|
||||
rc = raise_zmk_battery_state_changed(
|
||||
(struct zmk_battery_state_changed){.state_of_charge = last_state_of_charge});
|
||||
rc = raise_zmk_battery_state_changed((struct zmk_battery_state_changed){
|
||||
.state_of_charge = last_state_of_charge, .charging = charging});
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
@ -131,7 +158,11 @@ static void zmk_battery_start_reporting() {
|
|||
k_timer_start(&battery_timer, K_NO_WAIT, K_SECONDS(CONFIG_ZMK_BATTERY_REPORT_INTERVAL));
|
||||
}
|
||||
}
|
||||
|
||||
#if DT_NODE_HAS_PROP(DT_CHOSEN(zmk_battery), chg_gpios)
|
||||
static void handle_chg_trig(const struct device *dev, const struct sensor_trigger *trig) {
|
||||
zmk_battery_update(dev);
|
||||
}
|
||||
#endif
|
||||
static int zmk_battery_init(void) {
|
||||
#if !DT_HAS_CHOSEN(zmk_battery)
|
||||
battery = device_get_binding("BATTERY");
|
||||
|
@ -148,6 +179,16 @@ static int zmk_battery_init(void) {
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
#if DT_NODE_HAS_PROP(DT_CHOSEN(zmk_battery), chg_gpios)
|
||||
struct sensor_trigger trigger = {
|
||||
.type = SENSOR_TRIG_DATA_READY,
|
||||
.chan = SENSOR_CHAN_ALL,
|
||||
};
|
||||
if (sensor_trigger_set(battery, &trigger, handle_chg_trig) < 0) {
|
||||
LOG_ERR("can't set batt chg trigger");
|
||||
};
|
||||
#endif
|
||||
|
||||
zmk_battery_start_reporting();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -49,22 +49,42 @@ Applies to: [`/chosen` node](https://docs.zephyrproject.org/3.5.0/build/dts/intr
|
|||
|
||||
## Battery Voltage Divider Sensor
|
||||
|
||||
Driver for reading the voltage of a battery using an ADC connected to a voltage divider.
|
||||
Driver for reading the voltage of a battery using an ADC connected to a voltage divider. This driver can also read a GPIO pin to detect whether the battery is charging or not. This requires supported hardware (a battery charging IC with an output to indicate charging status). This functionality is optional, if the hardware doesn't support it the `chg-gpios` devicetree configuration does not have to be set.
|
||||
|
||||
### Devicetree
|
||||
|
||||
Applies to: `compatible = "zmk,battery-voltage-divider"`
|
||||
|
||||
See [Zephyr's voltage divider documentation](https://docs.zephyrproject.org/3.5.0/build/dts/api/bindings/iio/afe/voltage-divider.html).
|
||||
Definition file: [zmk/app/module/dts/bindings/sensor/zmk,battery-voltage-divider.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/module/dts/bindings/sensor/zmk,battery-voltage-divider.yaml)
|
||||
|
||||
The ZMK battery voltage divider includes the [Zephyr voltage divider](https://docs.zephyrproject.org/latest/build/dts/api/bindings/adc/voltage-divider.html) and adds on additional functionality.
|
||||
|
||||
| Property | Type | Description | Default |
|
||||
| ----------- | ---------- | ------------------------------------------------ | ------- |
|
||||
| `chg-gpios` | GPIO array | GPIO connected to the charging IC's charging pin | |
|
||||
|
||||
:::note Charging indication
|
||||
|
||||
The battery charging status is not consumed by any built-in indicators currently and it cannot be conveyed to the host over BLE.
|
||||
|
||||
:::
|
||||
|
||||
## nRF VDDH Battery Sensor
|
||||
|
||||
Driver for reading the voltage of a battery using a Nordic nRF52's VDDH pin.
|
||||
Driver for reading the voltage of a battery using a Nordic nRF52's VDDH pin. This driver can also read a GPIO pin to detect whether the battery is charging or not. This requires supported hardware (a battery charging IC with an output to indicate charging status). This functionality is optional, if the hardware doesn't support it the `chg-gpios` devicetree configuration does not have to be set.
|
||||
|
||||
### Devicetree
|
||||
|
||||
Applies to: `compatible = "zmk,battery-nrf-vddh"`
|
||||
|
||||
Definition file: [zmk/app/module/dts/bindings/sensor/zmk,battery-nrf-vddh.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/module/dts/bindings/sensor/zmk%2Cbattery-nrf-vddh.yaml)
|
||||
Definition file: [zmk/app/module/dts/bindings/sensor/zmk,battery-nrf-vddh.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/module/dts/bindings/sensor/zmk,battery-nrf-vddh.yaml)
|
||||
|
||||
This driver has no configuration.
|
||||
| Property | Type | Description | Default |
|
||||
| ----------- | ---------- | ------------------------------------------------ | ------- |
|
||||
| `chg-gpios` | GPIO array | GPIO connected to the charging IC's charging pin | |
|
||||
|
||||
:::note Charging indication
|
||||
|
||||
The battery charging status is not consumed by any built-in indicators currently and it cannot be conveyed to the host over BLE.
|
||||
|
||||
:::
|
||||
|
|
Loading…
Add table
Reference in a new issue