From 844f2c76749cbc5ff611d8e69819af82b698089a Mon Sep 17 00:00:00 2001 From: Nick Date: Sat, 19 Sep 2020 19:14:59 -0500 Subject: [PATCH 01/10] Voltage divider driver initial implementation --- app/boards/arm/nice_nano/nice_nano.dts | 10 ++ app/boards/arm/nice_nano/nice_nano_defconfig | 4 + app/drivers/zephyr/CMakeLists.txt | 1 + app/drivers/zephyr/battery_voltage_divider.c | 115 ++++++++++++++++++ .../bindings/zmk,battery-voltage-divider.yaml | 9 ++ 5 files changed, 139 insertions(+) create mode 100644 app/drivers/zephyr/battery_voltage_divider.c create mode 100644 app/drivers/zephyr/dts/bindings/zmk,battery-voltage-divider.yaml diff --git a/app/boards/arm/nice_nano/nice_nano.dts b/app/boards/arm/nice_nano/nice_nano.dts index 2e9556b8..18312ecc 100644 --- a/app/boards/arm/nice_nano/nice_nano.dts +++ b/app/boards/arm/nice_nano/nice_nano.dts @@ -29,6 +29,16 @@ }; }; + vbatt { + compatible = "zmk,battery-voltage-divider"; + io-channels = <&adc 2>; + output-ohms = <2000000>; + full-ohms = <(2000000 + 806000)>; + }; +}; + +&adc { + status = "okay"; }; &gpio0 { diff --git a/app/boards/arm/nice_nano/nice_nano_defconfig b/app/boards/arm/nice_nano/nice_nano_defconfig index 393d61fe..b727fe0b 100644 --- a/app/boards/arm/nice_nano/nice_nano_defconfig +++ b/app/boards/arm/nice_nano/nice_nano_defconfig @@ -10,6 +10,10 @@ CONFIG_ARM_MPU=y # enable GPIO CONFIG_GPIO=y +CONFIG_ADC=y + +CONFIG_NEWLIB_LIBC=y + CONFIG_USE_DT_CODE_PARTITION=y CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/app/drivers/zephyr/CMakeLists.txt b/app/drivers/zephyr/CMakeLists.txt index 8778ded3..0b1d18fb 100644 --- a/app/drivers/zephyr/CMakeLists.txt +++ b/app/drivers/zephyr/CMakeLists.txt @@ -5,6 +5,7 @@ if(CONFIG_ZMK_KSCAN_GPIO_DRIVER) zephyr_library_sources( kscan_gpio_matrix.c kscan_gpio_direct.c + battery_voltage_divider.c ) zephyr_library_sources_ifdef(CONFIG_EC11 ec11.c) diff --git a/app/drivers/zephyr/battery_voltage_divider.c b/app/drivers/zephyr/battery_voltage_divider.c new file mode 100644 index 00000000..35fc799c --- /dev/null +++ b/app/drivers/zephyr/battery_voltage_divider.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_battery_voltage_divider + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) + +#define VBATT DT_PATH(vbatt) + +struct battery_config { + struct device *adc; + struct adc_channel_cfg acc; + struct adc_sequence as; + int16_t adc_raw; +}; + +static struct battery_config battery_config; + +static int lithium_ion_mv_to_pct(int16_t bat_mv) { + // Magic function that maps mV to this discharge graph from adafruit: https://learn.adafruit.com/li-ion-and-lipoly-batteries/voltages + return round(106.818 + (-0.032685 - 106.818) / pow(1 + pow(bat_mv/3679.35, 58.979), 0.347386)); +} + +static void battery_read(struct k_work *workd) { + struct battery_config *cfg = &battery_config; + struct adc_sequence *as = &cfg->as; + + int rc = adc_read(cfg->adc, as); + as->calibrate = false; + if (rc == 0) { + int32_t val = cfg->adc_raw; + + adc_raw_to_millivolts(adc_ref_internal(cfg->adc), cfg->acc.gain, as->resolution, &val); + + rc = val * (uint64_t)DT_PROP(VBATT, full_ohms) / DT_PROP(VBATT, output_ohms); + LOG_DBG("ADC raw %d ~ %d mV => %d mV\n", cfg->adc_raw, val, rc); + int percent = lithium_ion_mv_to_pct(rc); + LOG_DBG("Percent: %d", percent); + } else { + LOG_DBG("Failed to read ADC: %d", rc); + } +} + +K_WORK_DEFINE(battery_work, battery_read); + +static void battery_handler(struct k_timer *timer) +{ + k_work_submit(&battery_work); +} + +K_TIMER_DEFINE(battery_tick, battery_handler, NULL); + +static int battery_setup(struct device *_arg) { + struct battery_config *cfg = &battery_config; + struct adc_sequence *as = &cfg->as; + struct adc_channel_cfg *acc = &cfg->acc; + + cfg->adc = device_get_binding(DT_IO_CHANNELS_LABEL(VBATT)); + + if (cfg->adc == NULL) { + LOG_ERR("ADC %s failed to retrieve", DT_IO_CHANNELS_LABEL(VBATT)); + return -ENOENT; + } + + *as = (struct adc_sequence){ + .channels = BIT(0), + .buffer = &cfg->adc_raw, + .buffer_size = sizeof(cfg->adc_raw), + .oversampling = 4, + .calibrate = true, + }; + +#ifdef CONFIG_ADC_NRFX_SAADC + *acc = (struct adc_channel_cfg){ + .gain = ADC_GAIN_1_5, + .reference = ADC_REF_INTERNAL, + .acquisition_time = ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 40), + .input_positive = SAADC_CH_PSELP_PSELP_AnalogInput0 + DT_IO_CHANNELS_INPUT(VBATT), + }; + + as->resolution = 12; +#else +#error Unsupported ADC +#endif + + int adc_rc = adc_channel_setup(cfg->adc, acc); + LOG_DBG("AIN%u setup returned %d", DT_IO_CHANNELS_INPUT(VBATT), adc_rc); + + if (adc_rc != 0) { + return adc_rc; + } + + k_timer_start(&battery_tick, K_NO_WAIT, K_SECONDS(5)); + + return 0; +} + +SYS_INIT(battery_setup, + APPLICATION, + CONFIG_APPLICATION_INIT_PRIORITY); + +#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ \ No newline at end of file diff --git a/app/drivers/zephyr/dts/bindings/zmk,battery-voltage-divider.yaml b/app/drivers/zephyr/dts/bindings/zmk,battery-voltage-divider.yaml new file mode 100644 index 00000000..f6e06427 --- /dev/null +++ b/app/drivers/zephyr/dts/bindings/zmk,battery-voltage-divider.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2020 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: Battery SoC monitoring using voltage divider + +compatible: "zmk,battery-voltage-divider" + +include: voltage-divider.yaml + \ No newline at end of file From f5909f9c265ec1d88ee4fc13d45745873a2ad081 Mon Sep 17 00:00:00 2001 From: Nick Date: Sat, 19 Sep 2020 19:18:03 -0500 Subject: [PATCH 02/10] fix(clang-format) --- app/drivers/zephyr/battery_voltage_divider.c | 109 +++++++++---------- 1 file changed, 53 insertions(+), 56 deletions(-) diff --git a/app/drivers/zephyr/battery_voltage_divider.c b/app/drivers/zephyr/battery_voltage_divider.c index 35fc799c..34de6cf1 100644 --- a/app/drivers/zephyr/battery_voltage_divider.c +++ b/app/drivers/zephyr/battery_voltage_divider.c @@ -21,95 +21,92 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #define VBATT DT_PATH(vbatt) struct battery_config { - struct device *adc; - struct adc_channel_cfg acc; - struct adc_sequence as; - int16_t adc_raw; + struct device *adc; + struct adc_channel_cfg acc; + struct adc_sequence as; + int16_t adc_raw; }; static struct battery_config battery_config; static int lithium_ion_mv_to_pct(int16_t bat_mv) { - // Magic function that maps mV to this discharge graph from adafruit: https://learn.adafruit.com/li-ion-and-lipoly-batteries/voltages - return round(106.818 + (-0.032685 - 106.818) / pow(1 + pow(bat_mv/3679.35, 58.979), 0.347386)); + // Magic function that maps mV to this discharge graph from adafruit: + // https://learn.adafruit.com/li-ion-and-lipoly-batteries/voltages + return round(106.818 + + (-0.032685 - 106.818) / pow(1 + pow(bat_mv / 3679.35, 58.979), 0.347386)); } static void battery_read(struct k_work *workd) { - struct battery_config *cfg = &battery_config; - struct adc_sequence *as = &cfg->as; + struct battery_config *cfg = &battery_config; + struct adc_sequence *as = &cfg->as; - int rc = adc_read(cfg->adc, as); - as->calibrate = false; - if (rc == 0) { - int32_t val = cfg->adc_raw; + int rc = adc_read(cfg->adc, as); + as->calibrate = false; + if (rc == 0) { + int32_t val = cfg->adc_raw; - adc_raw_to_millivolts(adc_ref_internal(cfg->adc), cfg->acc.gain, as->resolution, &val); + adc_raw_to_millivolts(adc_ref_internal(cfg->adc), cfg->acc.gain, as->resolution, &val); - rc = val * (uint64_t)DT_PROP(VBATT, full_ohms) / DT_PROP(VBATT, output_ohms); - LOG_DBG("ADC raw %d ~ %d mV => %d mV\n", cfg->adc_raw, val, rc); - int percent = lithium_ion_mv_to_pct(rc); - LOG_DBG("Percent: %d", percent); - } else { - LOG_DBG("Failed to read ADC: %d", rc); - } + rc = val * (uint64_t)DT_PROP(VBATT, full_ohms) / DT_PROP(VBATT, output_ohms); + LOG_DBG("ADC raw %d ~ %d mV => %d mV\n", cfg->adc_raw, val, rc); + int percent = lithium_ion_mv_to_pct(rc); + LOG_DBG("Percent: %d", percent); + } else { + LOG_DBG("Failed to read ADC: %d", rc); + } } K_WORK_DEFINE(battery_work, battery_read); -static void battery_handler(struct k_timer *timer) -{ - k_work_submit(&battery_work); -} +static void battery_handler(struct k_timer *timer) { k_work_submit(&battery_work); } K_TIMER_DEFINE(battery_tick, battery_handler, NULL); static int battery_setup(struct device *_arg) { - struct battery_config *cfg = &battery_config; - struct adc_sequence *as = &cfg->as; - struct adc_channel_cfg *acc = &cfg->acc; + struct battery_config *cfg = &battery_config; + struct adc_sequence *as = &cfg->as; + struct adc_channel_cfg *acc = &cfg->acc; - cfg->adc = device_get_binding(DT_IO_CHANNELS_LABEL(VBATT)); + cfg->adc = device_get_binding(DT_IO_CHANNELS_LABEL(VBATT)); - if (cfg->adc == NULL) { - LOG_ERR("ADC %s failed to retrieve", DT_IO_CHANNELS_LABEL(VBATT)); - return -ENOENT; - } + if (cfg->adc == NULL) { + LOG_ERR("ADC %s failed to retrieve", DT_IO_CHANNELS_LABEL(VBATT)); + return -ENOENT; + } - *as = (struct adc_sequence){ - .channels = BIT(0), - .buffer = &cfg->adc_raw, - .buffer_size = sizeof(cfg->adc_raw), - .oversampling = 4, - .calibrate = true, - }; + *as = (struct adc_sequence){ + .channels = BIT(0), + .buffer = &cfg->adc_raw, + .buffer_size = sizeof(cfg->adc_raw), + .oversampling = 4, + .calibrate = true, + }; #ifdef CONFIG_ADC_NRFX_SAADC - *acc = (struct adc_channel_cfg){ - .gain = ADC_GAIN_1_5, - .reference = ADC_REF_INTERNAL, - .acquisition_time = ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 40), - .input_positive = SAADC_CH_PSELP_PSELP_AnalogInput0 + DT_IO_CHANNELS_INPUT(VBATT), - }; + *acc = (struct adc_channel_cfg){ + .gain = ADC_GAIN_1_5, + .reference = ADC_REF_INTERNAL, + .acquisition_time = ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 40), + .input_positive = SAADC_CH_PSELP_PSELP_AnalogInput0 + DT_IO_CHANNELS_INPUT(VBATT), + }; - as->resolution = 12; + as->resolution = 12; #else #error Unsupported ADC #endif - int adc_rc = adc_channel_setup(cfg->adc, acc); - LOG_DBG("AIN%u setup returned %d", DT_IO_CHANNELS_INPUT(VBATT), adc_rc); + int adc_rc = adc_channel_setup(cfg->adc, acc); + LOG_DBG("AIN%u setup returned %d", DT_IO_CHANNELS_INPUT(VBATT), adc_rc); - if (adc_rc != 0) { - return adc_rc; - } + if (adc_rc != 0) { + return adc_rc; + } - k_timer_start(&battery_tick, K_NO_WAIT, K_SECONDS(5)); + k_timer_start(&battery_tick, K_NO_WAIT, K_SECONDS(5)); - return 0; + return 0; } -SYS_INIT(battery_setup, - APPLICATION, - CONFIG_APPLICATION_INIT_PRIORITY); +SYS_INIT(battery_setup, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); #endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ \ No newline at end of file From 3082455aecc98532807aba3226321a94d2ed4b0c Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 23 Oct 2020 00:45:59 -0500 Subject: [PATCH 03/10] Refactor driver to use Sensor API --- .../arm/bluemicro840/bluemicro840_v1.dts | 8 + app/boards/arm/nice_nano/nice_nano.dts | 1 + app/boards/arm/nrfmicro/nrfmicro_13.dts | 8 + app/drivers/zephyr/battery_voltage_divider.c | 187 +++++++++++++----- .../bindings/zmk,battery-voltage-divider.yaml | 5 + 5 files changed, 162 insertions(+), 47 deletions(-) diff --git a/app/boards/arm/bluemicro840/bluemicro840_v1.dts b/app/boards/arm/bluemicro840/bluemicro840_v1.dts index c693662a..ac8ba56e 100644 --- a/app/boards/arm/bluemicro840/bluemicro840_v1.dts +++ b/app/boards/arm/bluemicro840/bluemicro840_v1.dts @@ -29,6 +29,14 @@ }; }; + vbatt { + compatible = "zmk,battery-voltage-divider"; + label = "VOLTAGE_DIVIDER"; + io-channels = <&adc 7>; + output-ohms = <2000000>; + full-ohms = <(2000000 + 806000)>; + }; + }; &gpio0 { diff --git a/app/boards/arm/nice_nano/nice_nano.dts b/app/boards/arm/nice_nano/nice_nano.dts index 18312ecc..72804e3c 100644 --- a/app/boards/arm/nice_nano/nice_nano.dts +++ b/app/boards/arm/nice_nano/nice_nano.dts @@ -31,6 +31,7 @@ vbatt { compatible = "zmk,battery-voltage-divider"; + label = "VOLTAGE_DIVIDER"; io-channels = <&adc 2>; output-ohms = <2000000>; full-ohms = <(2000000 + 806000)>; diff --git a/app/boards/arm/nrfmicro/nrfmicro_13.dts b/app/boards/arm/nrfmicro/nrfmicro_13.dts index 95bd8adc..840014ad 100644 --- a/app/boards/arm/nrfmicro/nrfmicro_13.dts +++ b/app/boards/arm/nrfmicro/nrfmicro_13.dts @@ -26,6 +26,14 @@ }; }; + vbatt { + compatible = "zmk,battery-voltage-divider"; + label = "VOLTAGE_DIVIDER"; + io-channels = <&adc 2>; + output-ohms = <2000000>; + full-ohms = <(2000000 + 820000)>; + }; + }; &gpio0 { diff --git a/app/drivers/zephyr/battery_voltage_divider.c b/app/drivers/zephyr/battery_voltage_divider.c index 34de6cf1..abe7cb5f 100644 --- a/app/drivers/zephyr/battery_voltage_divider.c +++ b/app/drivers/zephyr/battery_voltage_divider.c @@ -16,97 +16,190 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); -#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) - -#define VBATT DT_PATH(vbatt) - -struct battery_config { - struct device *adc; - struct adc_channel_cfg acc; - struct adc_sequence as; - int16_t adc_raw; +struct io_channel_config { + const char *label; + uint8_t channel; }; -static struct battery_config battery_config; +struct gpio_channel_config { + const char *label; + uint8_t pin; + uint8_t flags; +}; -static int lithium_ion_mv_to_pct(int16_t bat_mv) { +struct bvd_config { + struct io_channel_config io_channel; + struct gpio_channel_config power_gpios; + uint32_t output_ohm; + uint32_t full_ohm; +}; + +struct bvd_data { + struct device *adc; + struct device *gpio; + struct adc_channel_cfg acc; + struct adc_sequence as; + uint16_t adc_raw; + uint16_t voltage; + uint8_t state_of_charge; +}; + +static uint8_t lithium_ion_mv_to_pct(int16_t bat_mv) { // Magic function that maps mV to this discharge graph from adafruit: // https://learn.adafruit.com/li-ion-and-lipoly-batteries/voltages return round(106.818 + (-0.032685 - 106.818) / pow(1 + pow(bat_mv / 3679.35, 58.979), 0.347386)); } -static void battery_read(struct k_work *workd) { - struct battery_config *cfg = &battery_config; - struct adc_sequence *as = &cfg->as; +static int bvd_sample_fetch(struct device *dev, enum sensor_channel chan) { + struct bvd_data *drv_data = dev->driver_data; + const struct bvd_config *drv_cfg = dev->config_info; + struct adc_sequence *as = &drv_data->as; - int rc = adc_read(cfg->adc, as); + int rc = 0; + + // Enable power GPIO if present + if (drv_data->gpio) { + rc = gpio_pin_set(drv_data->gpio, drv_cfg->power_gpios.pin, 1); + + if (rc != 0) { + LOG_DBG("Failed to enable ADC power GPIO: %d", rc); + return rc; + } + } + + // Read ADC + rc = adc_read(drv_data->adc, as); as->calibrate = false; + if (rc == 0) { - int32_t val = cfg->adc_raw; + int32_t val = drv_data->adc_raw; - adc_raw_to_millivolts(adc_ref_internal(cfg->adc), cfg->acc.gain, as->resolution, &val); + adc_raw_to_millivolts(adc_ref_internal(drv_data->adc), drv_data->acc.gain, as->resolution, &val); - rc = val * (uint64_t)DT_PROP(VBATT, full_ohms) / DT_PROP(VBATT, output_ohms); - LOG_DBG("ADC raw %d ~ %d mV => %d mV\n", cfg->adc_raw, val, rc); - int percent = lithium_ion_mv_to_pct(rc); + uint16_t millivolts = val * (uint64_t)drv_cfg->full_ohm / drv_cfg->output_ohm; + LOG_DBG("ADC raw %d ~ %d mV => %d mV\n", drv_data->adc_raw, val, millivolts); + uint8_t percent = lithium_ion_mv_to_pct(millivolts); LOG_DBG("Percent: %d", percent); + + drv_data->voltage = millivolts; + drv_data->state_of_charge = percent; } else { LOG_DBG("Failed to read ADC: %d", rc); } + + // Disable power GPIO if present + if (drv_data->gpio) { + rc = gpio_pin_set(drv_data->gpio, drv_cfg->power_gpios.pin, 0); + + if (rc != 0) { + LOG_DBG("Failed to disable ADC power GPIO: %d", rc); + } + } + + return rc; } -K_WORK_DEFINE(battery_work, battery_read); +static int bvd_channel_get(struct device *dev, enum sensor_channel chan, + struct sensor_value *val) { + struct bvd_data *drv_data = dev->driver_data; -static void battery_handler(struct k_timer *timer) { k_work_submit(&battery_work); } + switch(chan) { + case SENSOR_CHAN_GAUGE_VOLTAGE: + val->val1 = drv_data->voltage / 1000; + val->val2 = (drv_data->voltage % 1000) * 1000U; + break; -K_TIMER_DEFINE(battery_tick, battery_handler, NULL); + case SENSOR_CHAN_GAUGE_STATE_OF_CHARGE: + val->val1 = drv_data->state_of_charge; + val->val2 = 0; + break; -static int battery_setup(struct device *_arg) { - struct battery_config *cfg = &battery_config; - struct adc_sequence *as = &cfg->as; - struct adc_channel_cfg *acc = &cfg->acc; + default: + return -ENOTSUP; + } - cfg->adc = device_get_binding(DT_IO_CHANNELS_LABEL(VBATT)); + return 0; +} - if (cfg->adc == NULL) { - LOG_ERR("ADC %s failed to retrieve", DT_IO_CHANNELS_LABEL(VBATT)); +static const struct sensor_driver_api bvd_api = { + .sample_fetch = bvd_sample_fetch, + .channel_get = bvd_channel_get, +}; + + +static int bvd_init(struct device *dev) { + struct bvd_data *drv_data = dev->driver_data; + const struct bvd_config *drv_cfg = dev->config_info; + + drv_data->adc = device_get_binding(drv_cfg->io_channel.label); + + if (drv_data->adc == NULL) { + LOG_ERR("ADC %s failed to retrieve", drv_cfg->io_channel.label); return -ENOENT; } - *as = (struct adc_sequence){ + int rc = 0; + + if (drv_cfg->power_gpios.label) { + drv_data->gpio = device_get_binding(drv_cfg->power_gpios.label); + if (drv_data->gpio == NULL) { + LOG_ERR("Failed to get GPIO %s", drv_cfg->power_gpios.label); + return -ENOENT; + } + rc = gpio_pin_configure(drv_data->gpio, drv_cfg->power_gpios.pin, + GPIO_OUTPUT_INACTIVE | drv_cfg->power_gpios.flags); + if (rc != 0) { + LOG_ERR("Failed to control feed %s.%u: %d", + drv_cfg->power_gpios.label, drv_cfg->power_gpios.pin, rc); + return rc; + } + } + + drv_data->as = (struct adc_sequence){ .channels = BIT(0), - .buffer = &cfg->adc_raw, - .buffer_size = sizeof(cfg->adc_raw), + .buffer = &drv_data->adc_raw, + .buffer_size = sizeof(drv_data->adc_raw), .oversampling = 4, .calibrate = true, }; #ifdef CONFIG_ADC_NRFX_SAADC - *acc = (struct adc_channel_cfg){ + drv_data->acc = (struct adc_channel_cfg){ .gain = ADC_GAIN_1_5, .reference = ADC_REF_INTERNAL, .acquisition_time = ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 40), - .input_positive = SAADC_CH_PSELP_PSELP_AnalogInput0 + DT_IO_CHANNELS_INPUT(VBATT), + .input_positive = SAADC_CH_PSELP_PSELP_AnalogInput0 + drv_cfg->io_channel.channel, }; - as->resolution = 12; + drv_data->as.resolution = 12; #else #error Unsupported ADC #endif - int adc_rc = adc_channel_setup(cfg->adc, acc); - LOG_DBG("AIN%u setup returned %d", DT_IO_CHANNELS_INPUT(VBATT), adc_rc); + rc = adc_channel_setup(drv_data->adc, &drv_data->acc); + LOG_DBG("AIN%u setup returned %d", drv_cfg->io_channel.channel, rc); - if (adc_rc != 0) { - return adc_rc; - } - - k_timer_start(&battery_tick, K_NO_WAIT, K_SECONDS(5)); - - return 0; + return rc; } -SYS_INIT(battery_setup, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); +static struct bvd_data bvd_data; +static const struct bvd_config bvd_cfg = { + .io_channel = { + DT_INST_IO_CHANNELS_LABEL(0), + DT_INST_IO_CHANNELS_INPUT(0), + }, +#if DT_INST_NODE_HAS_PROP(0, power_gpios) + .power_gpios = { + DT_INST_GPIO_LABEL(0, power_gpios), + DT_INST_PIN(0, power_gpios), + DT_INST_FLAGS(0, power_gpios), + }, +#endif + .output_ohm = DT_INST_PROP(0, output_ohms), + .full_ohm = DT_INST_PROP(0, full_ohms), +}; -#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ \ No newline at end of file +DEVICE_AND_API_INIT(bvd_dev, DT_INST_LABEL(0), &bvd_init, + &bvd_data, &bvd_cfg, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, + &bvd_api); diff --git a/app/drivers/zephyr/dts/bindings/zmk,battery-voltage-divider.yaml b/app/drivers/zephyr/dts/bindings/zmk,battery-voltage-divider.yaml index f6e06427..3f391d78 100644 --- a/app/drivers/zephyr/dts/bindings/zmk,battery-voltage-divider.yaml +++ b/app/drivers/zephyr/dts/bindings/zmk,battery-voltage-divider.yaml @@ -6,4 +6,9 @@ description: Battery SoC monitoring using voltage divider compatible: "zmk,battery-voltage-divider" include: voltage-divider.yaml + +properties: + label: + required: true + type: string \ No newline at end of file From 162c6b77db27c158b05ed65effa8d8ded68ba9b7 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 23 Oct 2020 00:50:39 -0500 Subject: [PATCH 04/10] clang-format and add missing defconfig values --- .../bluemicro840/bluemicro840_v1_defconfig | 4 + app/boards/arm/nrfmicro/nrfmicro_13_defconfig | 4 + app/drivers/zephyr/battery_voltage_divider.c | 86 +++++++++---------- 3 files changed, 51 insertions(+), 43 deletions(-) diff --git a/app/boards/arm/bluemicro840/bluemicro840_v1_defconfig b/app/boards/arm/bluemicro840/bluemicro840_v1_defconfig index 96f03ca4..2a799811 100644 --- a/app/boards/arm/bluemicro840/bluemicro840_v1_defconfig +++ b/app/boards/arm/bluemicro840/bluemicro840_v1_defconfig @@ -10,6 +10,10 @@ CONFIG_ARM_MPU=y # enable GPIO CONFIG_GPIO=y +CONFIG_ADC=y + +CONFIG_NEWLIB_LIBC=y + CONFIG_USE_DT_CODE_PARTITION=y CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/app/boards/arm/nrfmicro/nrfmicro_13_defconfig b/app/boards/arm/nrfmicro/nrfmicro_13_defconfig index cac11642..0421653d 100644 --- a/app/boards/arm/nrfmicro/nrfmicro_13_defconfig +++ b/app/boards/arm/nrfmicro/nrfmicro_13_defconfig @@ -10,6 +10,10 @@ CONFIG_ARM_MPU=y # enable GPIO CONFIG_GPIO=y +CONFIG_ADC=y + +CONFIG_NEWLIB_LIBC=y + CONFIG_USE_DT_CODE_PARTITION=y CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/app/drivers/zephyr/battery_voltage_divider.c b/app/drivers/zephyr/battery_voltage_divider.c index abe7cb5f..7dba86a3 100644 --- a/app/drivers/zephyr/battery_voltage_divider.c +++ b/app/drivers/zephyr/battery_voltage_divider.c @@ -17,21 +17,21 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); struct io_channel_config { - const char *label; - uint8_t channel; + const char *label; + uint8_t channel; }; struct gpio_channel_config { - const char *label; - uint8_t pin; - uint8_t flags; + const char *label; + uint8_t pin; + uint8_t flags; }; struct bvd_config { - struct io_channel_config io_channel; - struct gpio_channel_config power_gpios; - uint32_t output_ohm; - uint32_t full_ohm; + struct io_channel_config io_channel; + struct gpio_channel_config power_gpios; + uint32_t output_ohm; + uint32_t full_ohm; }; struct bvd_data { @@ -75,7 +75,8 @@ static int bvd_sample_fetch(struct device *dev, enum sensor_channel chan) { if (rc == 0) { int32_t val = drv_data->adc_raw; - adc_raw_to_millivolts(adc_ref_internal(drv_data->adc), drv_data->acc.gain, as->resolution, &val); + adc_raw_to_millivolts(adc_ref_internal(drv_data->adc), drv_data->acc.gain, as->resolution, + &val); uint16_t millivolts = val * (uint64_t)drv_cfg->full_ohm / drv_cfg->output_ohm; LOG_DBG("ADC raw %d ~ %d mV => %d mV\n", drv_data->adc_raw, val, millivolts); @@ -94,17 +95,16 @@ static int bvd_sample_fetch(struct device *dev, enum sensor_channel chan) { if (rc != 0) { LOG_DBG("Failed to disable ADC power GPIO: %d", rc); - } + } } return rc; } -static int bvd_channel_get(struct device *dev, enum sensor_channel chan, - struct sensor_value *val) { +static int bvd_channel_get(struct device *dev, enum sensor_channel chan, struct sensor_value *val) { struct bvd_data *drv_data = dev->driver_data; - switch(chan) { + switch (chan) { case SENSOR_CHAN_GAUGE_VOLTAGE: val->val1 = drv_data->voltage / 1000; val->val2 = (drv_data->voltage % 1000) * 1000U; @@ -119,7 +119,7 @@ static int bvd_channel_get(struct device *dev, enum sensor_channel chan, return -ENOTSUP; } - return 0; + return 0; } static const struct sensor_driver_api bvd_api = { @@ -127,7 +127,6 @@ static const struct sensor_driver_api bvd_api = { .channel_get = bvd_channel_get, }; - static int bvd_init(struct device *dev) { struct bvd_data *drv_data = dev->driver_data; const struct bvd_config *drv_cfg = dev->config_info; @@ -142,19 +141,19 @@ static int bvd_init(struct device *dev) { int rc = 0; if (drv_cfg->power_gpios.label) { - drv_data->gpio = device_get_binding(drv_cfg->power_gpios.label); - if (drv_data->gpio == NULL) { - LOG_ERR("Failed to get GPIO %s", drv_cfg->power_gpios.label); - return -ENOENT; - } - rc = gpio_pin_configure(drv_data->gpio, drv_cfg->power_gpios.pin, - GPIO_OUTPUT_INACTIVE | drv_cfg->power_gpios.flags); - if (rc != 0) { - LOG_ERR("Failed to control feed %s.%u: %d", - drv_cfg->power_gpios.label, drv_cfg->power_gpios.pin, rc); - return rc; - } - } + drv_data->gpio = device_get_binding(drv_cfg->power_gpios.label); + if (drv_data->gpio == NULL) { + LOG_ERR("Failed to get GPIO %s", drv_cfg->power_gpios.label); + return -ENOENT; + } + rc = gpio_pin_configure(drv_data->gpio, drv_cfg->power_gpios.pin, + GPIO_OUTPUT_INACTIVE | drv_cfg->power_gpios.flags); + if (rc != 0) { + LOG_ERR("Failed to control feed %s.%u: %d", drv_cfg->power_gpios.label, + drv_cfg->power_gpios.pin, rc); + return rc; + } + } drv_data->as = (struct adc_sequence){ .channels = BIT(0), @@ -185,21 +184,22 @@ static int bvd_init(struct device *dev) { static struct bvd_data bvd_data; static const struct bvd_config bvd_cfg = { - .io_channel = { - DT_INST_IO_CHANNELS_LABEL(0), - DT_INST_IO_CHANNELS_INPUT(0), - }, + .io_channel = + { + DT_INST_IO_CHANNELS_LABEL(0), + DT_INST_IO_CHANNELS_INPUT(0), + }, #if DT_INST_NODE_HAS_PROP(0, power_gpios) - .power_gpios = { - DT_INST_GPIO_LABEL(0, power_gpios), - DT_INST_PIN(0, power_gpios), - DT_INST_FLAGS(0, power_gpios), - }, + .power_gpios = + { + DT_INST_GPIO_LABEL(0, power_gpios), + DT_INST_PIN(0, power_gpios), + DT_INST_FLAGS(0, power_gpios), + }, #endif - .output_ohm = DT_INST_PROP(0, output_ohms), - .full_ohm = DT_INST_PROP(0, full_ohms), + .output_ohm = DT_INST_PROP(0, output_ohms), + .full_ohm = DT_INST_PROP(0, full_ohms), }; -DEVICE_AND_API_INIT(bvd_dev, DT_INST_LABEL(0), &bvd_init, - &bvd_data, &bvd_cfg, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, - &bvd_api); +DEVICE_AND_API_INIT(bvd_dev, DT_INST_LABEL(0), &bvd_init, &bvd_data, &bvd_cfg, POST_KERNEL, + CONFIG_SENSOR_INIT_PRIORITY, &bvd_api); From 8efcd80f3ae594a489339ac23de8890399f22f59 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 23 Oct 2020 00:57:32 -0500 Subject: [PATCH 05/10] Add missing ADC and fix formatting --- app/boards/arm/bluemicro840/bluemicro840_v1.dts | 4 ++++ app/boards/arm/nice_nano/nice_nano.dts | 4 ++-- app/boards/arm/nrfmicro/nrfmicro_13.dts | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/boards/arm/bluemicro840/bluemicro840_v1.dts b/app/boards/arm/bluemicro840/bluemicro840_v1.dts index ac8ba56e..32aa2e6f 100644 --- a/app/boards/arm/bluemicro840/bluemicro840_v1.dts +++ b/app/boards/arm/bluemicro840/bluemicro840_v1.dts @@ -39,6 +39,10 @@ }; +&adc { + status = "okay"; +}; + &gpio0 { status = "okay"; }; diff --git a/app/boards/arm/nice_nano/nice_nano.dts b/app/boards/arm/nice_nano/nice_nano.dts index 997d195a..18195412 100644 --- a/app/boards/arm/nice_nano/nice_nano.dts +++ b/app/boards/arm/nice_nano/nice_nano.dts @@ -28,8 +28,8 @@ label = "Blue LED"; }; }; - - ext-power { + + ext-power { compatible = "zmk,ext-power-generic"; label = "EXT_POWER"; control-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; diff --git a/app/boards/arm/nrfmicro/nrfmicro_13.dts b/app/boards/arm/nrfmicro/nrfmicro_13.dts index ae6c1af8..5ae11ba0 100644 --- a/app/boards/arm/nrfmicro/nrfmicro_13.dts +++ b/app/boards/arm/nrfmicro/nrfmicro_13.dts @@ -25,8 +25,8 @@ label = "Blue LED"; }; }; - - ext-power { + + ext-power { compatible = "zmk,ext-power-generic"; label = "EXT_POWER"; control-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; From 6047415b1c26ec06198edecf656d6d9edcd01446 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 23 Oct 2020 01:19:47 -0500 Subject: [PATCH 06/10] Fix build for boards without voltage divider --- app/drivers/zephyr/battery_voltage_divider.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/drivers/zephyr/battery_voltage_divider.c b/app/drivers/zephyr/battery_voltage_divider.c index 7dba86a3..980f1b40 100644 --- a/app/drivers/zephyr/battery_voltage_divider.c +++ b/app/drivers/zephyr/battery_voltage_divider.c @@ -16,6 +16,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) + struct io_channel_config { const char *label; uint8_t channel; @@ -203,3 +205,5 @@ static const struct bvd_config bvd_cfg = { DEVICE_AND_API_INIT(bvd_dev, DT_INST_LABEL(0), &bvd_init, &bvd_data, &bvd_cfg, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &bvd_api); + +#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */ From a67a8cd3b87e67176fb88c1d04d95004f7ff905d Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 23 Oct 2020 22:37:44 -0500 Subject: [PATCH 07/10] Check if fetch channel is supported --- app/drivers/zephyr/battery_voltage_divider.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/drivers/zephyr/battery_voltage_divider.c b/app/drivers/zephyr/battery_voltage_divider.c index 980f1b40..6139d46f 100644 --- a/app/drivers/zephyr/battery_voltage_divider.c +++ b/app/drivers/zephyr/battery_voltage_divider.c @@ -58,6 +58,11 @@ static int bvd_sample_fetch(struct device *dev, enum sensor_channel chan) { const struct bvd_config *drv_cfg = dev->config_info; struct adc_sequence *as = &drv_data->as; + // Make sure selected channel is supported + if (chan != SENSOR_CHAN_GAUGE_VOLTAGE && chan != SENSOR_CHAN_GAUGE_STATE_OF_CHARGE) { + return -ENOTSUP; + } + int rc = 0; // Enable power GPIO if present From adb07926b1d6760e63e19134b338f8b1ba460483 Mon Sep 17 00:00:00 2001 From: Nick Date: Sat, 24 Oct 2020 18:52:34 -0500 Subject: [PATCH 08/10] Remove newlib dep --- .../arm/bluemicro840/bluemicro840_v1_defconfig | 2 -- app/boards/arm/nice_nano/nice_nano_defconfig | 2 -- app/boards/arm/nrfmicro/nrfmicro_13_defconfig | 2 -- app/drivers/zephyr/battery_voltage_divider.c | 18 +++++++++++------- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/app/boards/arm/bluemicro840/bluemicro840_v1_defconfig b/app/boards/arm/bluemicro840/bluemicro840_v1_defconfig index 2a799811..00d56612 100644 --- a/app/boards/arm/bluemicro840/bluemicro840_v1_defconfig +++ b/app/boards/arm/bluemicro840/bluemicro840_v1_defconfig @@ -12,8 +12,6 @@ CONFIG_GPIO=y CONFIG_ADC=y -CONFIG_NEWLIB_LIBC=y - CONFIG_USE_DT_CODE_PARTITION=y CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/app/boards/arm/nice_nano/nice_nano_defconfig b/app/boards/arm/nice_nano/nice_nano_defconfig index b727fe0b..a888cb3f 100644 --- a/app/boards/arm/nice_nano/nice_nano_defconfig +++ b/app/boards/arm/nice_nano/nice_nano_defconfig @@ -12,8 +12,6 @@ CONFIG_GPIO=y CONFIG_ADC=y -CONFIG_NEWLIB_LIBC=y - CONFIG_USE_DT_CODE_PARTITION=y CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/app/boards/arm/nrfmicro/nrfmicro_13_defconfig b/app/boards/arm/nrfmicro/nrfmicro_13_defconfig index 0421653d..4e44ea36 100644 --- a/app/boards/arm/nrfmicro/nrfmicro_13_defconfig +++ b/app/boards/arm/nrfmicro/nrfmicro_13_defconfig @@ -12,8 +12,6 @@ CONFIG_GPIO=y CONFIG_ADC=y -CONFIG_NEWLIB_LIBC=y - CONFIG_USE_DT_CODE_PARTITION=y CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/app/drivers/zephyr/battery_voltage_divider.c b/app/drivers/zephyr/battery_voltage_divider.c index 6139d46f..5bac5447 100644 --- a/app/drivers/zephyr/battery_voltage_divider.c +++ b/app/drivers/zephyr/battery_voltage_divider.c @@ -7,12 +7,10 @@ #define DT_DRV_COMPAT zmk_battery_voltage_divider #include -#include #include #include #include #include -#include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -47,10 +45,16 @@ struct bvd_data { }; static uint8_t lithium_ion_mv_to_pct(int16_t bat_mv) { - // Magic function that maps mV to this discharge graph from adafruit: + // Simple linear approximation of a battery based off adafruit's discharge graph: // https://learn.adafruit.com/li-ion-and-lipoly-batteries/voltages - return round(106.818 + - (-0.032685 - 106.818) / pow(1 + pow(bat_mv / 3679.35, 58.979), 0.347386)); + + if (bat_mv >= 4200) { + return 100; + } else if (bat_mv <= 3450) { + return 0; + } + + return bat_mv * 2 / 15 - 459; } static int bvd_sample_fetch(struct device *dev, enum sensor_channel chan) { @@ -142,7 +146,7 @@ static int bvd_init(struct device *dev) { if (drv_data->adc == NULL) { LOG_ERR("ADC %s failed to retrieve", drv_cfg->io_channel.label); - return -ENOENT; + return -ENODEV; } int rc = 0; @@ -151,7 +155,7 @@ static int bvd_init(struct device *dev) { drv_data->gpio = device_get_binding(drv_cfg->power_gpios.label); if (drv_data->gpio == NULL) { LOG_ERR("Failed to get GPIO %s", drv_cfg->power_gpios.label); - return -ENOENT; + return -ENODEV; } rc = gpio_pin_configure(drv_data->gpio, drv_cfg->power_gpios.pin, GPIO_OUTPUT_INACTIVE | drv_cfg->power_gpios.flags); From 63007fb6c136b8475894a6315f12eabeea952ca4 Mon Sep 17 00:00:00 2001 From: Nick Date: Sat, 24 Oct 2020 18:54:56 -0500 Subject: [PATCH 09/10] fix: clang-format --- app/drivers/zephyr/battery_voltage_divider.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/drivers/zephyr/battery_voltage_divider.c b/app/drivers/zephyr/battery_voltage_divider.c index 5bac5447..09a353a7 100644 --- a/app/drivers/zephyr/battery_voltage_divider.c +++ b/app/drivers/zephyr/battery_voltage_divider.c @@ -47,7 +47,7 @@ struct bvd_data { static uint8_t lithium_ion_mv_to_pct(int16_t bat_mv) { // Simple linear approximation of a battery based off adafruit's discharge graph: // https://learn.adafruit.com/li-ion-and-lipoly-batteries/voltages - + if (bat_mv >= 4200) { return 100; } else if (bat_mv <= 3450) { From a0087311038e9b21c2a45499e669d1300af16f83 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 26 Oct 2020 16:01:57 -0500 Subject: [PATCH 10/10] Implement Kconfig and enhance error checks --- app/boards/arm/bluemicro840/Kconfig.defconfig | 3 +++ app/boards/arm/bluemicro840/bluemicro840_v1_defconfig | 2 -- app/boards/arm/nice_nano/Kconfig.defconfig | 3 +++ app/boards/arm/nice_nano/nice_nano_defconfig | 2 -- app/boards/arm/nrfmicro/Kconfig.defconfig | 3 +++ app/boards/arm/nrfmicro/nrfmicro_13_defconfig | 2 -- app/drivers/zephyr/CMakeLists.txt | 2 +- app/drivers/zephyr/Kconfig | 6 ++++++ app/drivers/zephyr/battery_voltage_divider.c | 11 ++++------- 9 files changed, 20 insertions(+), 14 deletions(-) diff --git a/app/boards/arm/bluemicro840/Kconfig.defconfig b/app/boards/arm/bluemicro840/Kconfig.defconfig index 566b5a42..2b55e17c 100644 --- a/app/boards/arm/bluemicro840/Kconfig.defconfig +++ b/app/boards/arm/bluemicro840/Kconfig.defconfig @@ -27,4 +27,7 @@ config ZMK_BLE config ZMK_USB default y +config ZMK_BATTERY_VOLTAGE_DIVIDER + default y + endif # BOARD_BLUEMICRO840_V1 diff --git a/app/boards/arm/bluemicro840/bluemicro840_v1_defconfig b/app/boards/arm/bluemicro840/bluemicro840_v1_defconfig index 00d56612..96f03ca4 100644 --- a/app/boards/arm/bluemicro840/bluemicro840_v1_defconfig +++ b/app/boards/arm/bluemicro840/bluemicro840_v1_defconfig @@ -10,8 +10,6 @@ CONFIG_ARM_MPU=y # enable GPIO CONFIG_GPIO=y -CONFIG_ADC=y - CONFIG_USE_DT_CODE_PARTITION=y CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/app/boards/arm/nice_nano/Kconfig.defconfig b/app/boards/arm/nice_nano/Kconfig.defconfig index 0961ddd1..205050af 100644 --- a/app/boards/arm/nice_nano/Kconfig.defconfig +++ b/app/boards/arm/nice_nano/Kconfig.defconfig @@ -25,4 +25,7 @@ config ZMK_BLE config ZMK_USB default y +config ZMK_BATTERY_VOLTAGE_DIVIDER + default y + endif # BOARD_NICE_NANO diff --git a/app/boards/arm/nice_nano/nice_nano_defconfig b/app/boards/arm/nice_nano/nice_nano_defconfig index a888cb3f..393d61fe 100644 --- a/app/boards/arm/nice_nano/nice_nano_defconfig +++ b/app/boards/arm/nice_nano/nice_nano_defconfig @@ -10,8 +10,6 @@ CONFIG_ARM_MPU=y # enable GPIO CONFIG_GPIO=y -CONFIG_ADC=y - CONFIG_USE_DT_CODE_PARTITION=y CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/app/boards/arm/nrfmicro/Kconfig.defconfig b/app/boards/arm/nrfmicro/Kconfig.defconfig index 7957b4a5..a3c02c22 100644 --- a/app/boards/arm/nrfmicro/Kconfig.defconfig +++ b/app/boards/arm/nrfmicro/Kconfig.defconfig @@ -35,6 +35,9 @@ if BOARD_NRFMICRO_13 config BOARD_NRFMICRO_CHARGER default y +config ZMK_BATTERY_VOLTAGE_DIVIDER + default y + endif # BOARD_NRFMICRO_13 endif # BOARD_NRFMICRO_11 || BOARD_NRFMICRO_11_FLIPPED || BOARD_NRFMICRO_13 diff --git a/app/boards/arm/nrfmicro/nrfmicro_13_defconfig b/app/boards/arm/nrfmicro/nrfmicro_13_defconfig index 4e44ea36..cac11642 100644 --- a/app/boards/arm/nrfmicro/nrfmicro_13_defconfig +++ b/app/boards/arm/nrfmicro/nrfmicro_13_defconfig @@ -10,8 +10,6 @@ CONFIG_ARM_MPU=y # enable GPIO CONFIG_GPIO=y -CONFIG_ADC=y - CONFIG_USE_DT_CODE_PARTITION=y CONFIG_MPU_ALLOW_FLASH_WRITE=y diff --git a/app/drivers/zephyr/CMakeLists.txt b/app/drivers/zephyr/CMakeLists.txt index 0b1d18fb..fc43fb8c 100644 --- a/app/drivers/zephyr/CMakeLists.txt +++ b/app/drivers/zephyr/CMakeLists.txt @@ -5,9 +5,9 @@ if(CONFIG_ZMK_KSCAN_GPIO_DRIVER) zephyr_library_sources( kscan_gpio_matrix.c kscan_gpio_direct.c - battery_voltage_divider.c ) zephyr_library_sources_ifdef(CONFIG_EC11 ec11.c) zephyr_library_sources_ifdef(CONFIG_EC11_TRIGGER ec11_trigger.c) + zephyr_library_sources_ifdef(CONFIG_ZMK_BATTERY_VOLTAGE_DIVIDER battery_voltage_divider.c) endif() diff --git a/app/drivers/zephyr/Kconfig b/app/drivers/zephyr/Kconfig index 0534cab2..6b177fb1 100644 --- a/app/drivers/zephyr/Kconfig +++ b/app/drivers/zephyr/Kconfig @@ -21,6 +21,12 @@ config ZMK_KSCAN_INIT_PRIORITY help Keyboard scan device driver initialization priority. +config ZMK_BATTERY_VOLTAGE_DIVIDER + bool "ZMK battery voltage divider" + select ADC + help + Enable ZMK battery voltage divider driver for battery monitoring. + menuconfig EC11 bool "EC11 Incremental Encoder Sensor" depends on GPIO diff --git a/app/drivers/zephyr/battery_voltage_divider.c b/app/drivers/zephyr/battery_voltage_divider.c index 09a353a7..37ac024b 100644 --- a/app/drivers/zephyr/battery_voltage_divider.c +++ b/app/drivers/zephyr/battery_voltage_divider.c @@ -14,8 +14,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); -#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) - struct io_channel_config { const char *label; uint8_t channel; @@ -102,10 +100,11 @@ static int bvd_sample_fetch(struct device *dev, enum sensor_channel chan) { // Disable power GPIO if present if (drv_data->gpio) { - rc = gpio_pin_set(drv_data->gpio, drv_cfg->power_gpios.pin, 0); + int rc2 = gpio_pin_set(drv_data->gpio, drv_cfg->power_gpios.pin, 0); - if (rc != 0) { - LOG_DBG("Failed to disable ADC power GPIO: %d", rc); + if (rc2 != 0) { + LOG_DBG("Failed to disable ADC power GPIO: %d", rc2); + return rc2; } } @@ -214,5 +213,3 @@ static const struct bvd_config bvd_cfg = { DEVICE_AND_API_INIT(bvd_dev, DT_INST_LABEL(0), &bvd_init, &bvd_data, &bvd_cfg, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &bvd_api); - -#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */