You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/06/27 12:51:57 UTC
[GitHub] rymanluk closed pull request #1219: Battery Shell
rymanluk closed pull request #1219: Battery Shell
URL: https://github.com/apache/mynewt-core/pull/1219
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/hw/battery/include/battery/battery_adc.h b/hw/battery/include/battery/battery_adc.h
new file mode 100644
index 0000000000..520fa3951f
--- /dev/null
+++ b/hw/battery/include/battery/battery_adc.h
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * resarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __BATTERY_ADC_H__
+#define __BATTERY_ADC_H__
+
+#include <os/mynewt.h>
+#include <battery/battery_drv.h>
+#include <battery/battery.h>
+
+#ifdef __cplusplus
+#extern "C" {
+#endif
+
+/*
+ * Structure passed to os_dev_create
+ */
+struct battery_adc_cfg
+{
+ struct os_dev *battery;
+ const char *adc_dev_name;
+ /* Platform dependent configuration, needed for os_dev_open() of adc device */
+ void *adc_open_arg;
+ /* Platform dependent channel configuration, needed for adc_chan_config() */
+ void *adc_channel_cfg;
+ /* channel */
+ uint8_t channel;
+ /* multiplier for ADC reading */
+ int mul;
+ /* divider for ADC reading */
+ int div;
+};
+
+/* battery_adc device */
+struct battery_adc
+{
+ /* Underlying OS device */
+ struct battery_driver dev;
+
+ /* Configuration values */
+ struct battery_adc_cfg cfg;
+
+ struct adc_dev *adc_dev;
+};
+
+/**
+ * Expects to be called back through os_dev_create().
+ *
+ * @param dec ptr to the device object associated with this ADC channel
+ * @param arg argument passed to OS device init
+ *
+ * @return 0 on success, non-zero on failure.
+ */
+int battery_adc_init(struct os_dev *dev, void *arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BATTERY_ADC_H__ */
diff --git a/hw/battery/src/battery.c b/hw/battery/src/battery.c
index 6e0c83e997..517fa5f5b6 100644
--- a/hw/battery/src/battery.c
+++ b/hw/battery/src/battery.c
@@ -734,12 +734,36 @@ battery_prop_poll_unsubscribe(struct battery_prop_listener *listener,
static int
battery_open(struct os_dev *dev, uint32_t timeout, void *arg)
{
- return 0;
+ struct battery *bat = (struct battery *)dev;
+ struct os_dev *drv_dev;
+ int rollback = -1;
+ int i;
+ int rc = 0;
+
+ for (i = 0; i < BATTERY_DRIVERS_MAX && bat->b_drivers[i]; ++i) {
+ drv_dev = os_dev_open(bat->b_drivers[i]->dev.od_name, 0, NULL);
+ assert(drv_dev == &bat->b_drivers[i]->dev);
+ if (drv_dev != &bat->b_drivers[i]->dev) {
+ rollback = i - 1;
+ rc = -1;
+ break;
+ }
+ }
+ for (i = rollback; i >= 0; --i) {
+ os_dev_close(&bat->b_drivers[i]->dev);
+ }
+ return rc;
}
static int
battery_close(struct os_dev *dev)
{
+ struct battery *bat = (struct battery *)dev;
+ int i;
+
+ for (i = 0; i < BATTERY_DRIVERS_MAX && bat->b_drivers[i]; ++i) {
+ os_dev_close(&bat->b_drivers[i]->dev);
+ }
return 0;
}
diff --git a/hw/battery/src/battery_adc.c b/hw/battery/src/battery_adc.c
new file mode 100644
index 0000000000..af9f74acba
--- /dev/null
+++ b/hw/battery/src/battery_adc.c
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "os/mynewt.h"
+#include <battery/battery.h>
+#include <battery/battery_prop.h>
+#include <battery/battery_drv.h>
+#include <battery/battery_adc.h>
+#include <adc/adc.h>
+
+/* Battery manager interface functions */
+
+static int
+battery_adc_property_get(struct battery_driver *driver,
+ struct battery_property *property, uint32_t timeout)
+{
+ int rc = 0;
+ struct battery_adc *bat_adc = (struct battery_adc *)driver->bd_driver_data;
+ int val;
+
+ /* Only one property is supported, voltate */
+ if (property->bp_type == BATTERY_PROP_VOLTAGE_NOW &&
+ property->bp_flags == 0) {
+ /* Blocking read of voltage */
+ rc = adc_read_channel(bat_adc->adc_dev, bat_adc->cfg.channel, &val);
+ if (rc == 0) {
+ property->bp_valid = 1;
+ /* Convert value to according to reference voltage and multiplier
+ * and divider if external resistor divider is used for measurement.
+ */
+ property->bp_value.bpv_voltage =
+ adc_result_mv(bat_adc->adc_dev, bat_adc->cfg.channel, val) *
+ bat_adc->cfg.mul / bat_adc->cfg.div;
+ }
+ } else {
+ rc = -1;
+ assert(0);
+ }
+
+ return rc;
+}
+
+static int
+battery_adc_property_set(struct battery_driver *driver,
+ struct battery_property *property)
+{
+ int rc = -1;
+
+ return rc;
+}
+
+static int
+battery_adc_enable(struct battery *battery)
+{
+ return 0;
+}
+
+static int
+battery_adc_disable(struct battery *battery)
+{
+ return 0;
+}
+
+static const struct battery_driver_functions battery_adc_drv_funcs = {
+ .bdf_property_get = battery_adc_property_get,
+ .bdf_property_set = battery_adc_property_set,
+
+ .bdf_enable = battery_adc_enable,
+ .bdf_disable = battery_adc_disable,
+};
+
+static const struct battery_driver_property battery_adc_properties[] = {
+ { BATTERY_PROP_VOLTAGE_NOW, 0, "VoltageADC" },
+ { BATTERY_PROP_NONE },
+};
+
+static int
+battery_adc_open(struct os_dev *dev, uint32_t timeout, void *arg)
+{
+ int rc = -1;
+ struct battery_adc *bat_adc = (struct battery_adc *)dev;
+ (void)arg;
+
+ /* Open ADC with parameters specified in BSP */
+ bat_adc->adc_dev = (struct adc_dev *)os_dev_open(
+ (char *)bat_adc->cfg.adc_dev_name, timeout, bat_adc->cfg.adc_open_arg);
+ if (bat_adc->adc_dev) {
+ /* Setup channel configuration to use for battery voltage */
+ adc_chan_config(bat_adc->adc_dev, bat_adc->cfg.channel,
+ bat_adc->cfg.adc_channel_cfg);
+ rc = 0;
+ }
+ return rc;
+}
+
+static int
+battery_adc_close(struct os_dev *dev)
+{
+ struct battery_adc *bat_adc = (struct battery_adc *)dev;
+ if (bat_adc->adc_dev) {
+ os_dev_close((struct os_dev *)&bat_adc->dev);
+ bat_adc->adc_dev = NULL;
+ }
+ return 0;
+}
+
+/* driver open implementation */
+int
+battery_adc_init(struct os_dev *dev, void *arg)
+{
+ struct battery_adc *bat_adc;
+ struct battery_adc_cfg *init_arg = (struct battery_adc_cfg *)arg;
+
+ if (!dev || !arg) {
+ return SYS_ENODEV;
+ }
+
+ OS_DEV_SETHANDLERS(dev, battery_adc_open, battery_adc_close);
+
+ bat_adc = (struct battery_adc *)dev;
+ bat_adc->cfg = *((struct battery_adc_cfg *)arg);
+ bat_adc->dev.bd_funcs = &battery_adc_drv_funcs;
+ bat_adc->dev.bd_driver_data = bat_adc;
+ bat_adc->dev.bd_driver_properties = battery_adc_properties;
+ /* Divider and multiplier are set to 1 by default just make sure they
+ * are not set to 0
+ */
+ assert(bat_adc->cfg.div != 0);
+ assert(bat_adc->cfg.mul != 0);
+ /* Add driver to battery, this will update battery properties */
+ battery_add_driver(init_arg->battery, &bat_adc->dev);
+
+ return 0;
+}
+
diff --git a/hw/battery/src/battery_shell.c b/hw/battery/src/battery_shell.c
new file mode 100644
index 0000000000..1de5097c5a
--- /dev/null
+++ b/hw/battery/src/battery_shell.c
@@ -0,0 +1,358 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <console/console.h>
+#include <shell/shell.h>
+#include <bsp/bsp.h>
+#include <parse/parse.h>
+#include <battery/battery.h>
+#include <battery/battery_prop.h>
+
+static int bat_compat_cmd(int argc, char **argv);
+
+struct os_dev *bat;
+
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+#define HELP(a) &(a)
+
+static const struct shell_param bat_read_params[] =
+{
+ { "all" },
+ { NULL }
+};
+
+static const struct shell_param bat_monitor_params[] =
+{
+ { NULL }
+};
+
+static const struct shell_cmd_help bat_read_help =
+{
+ .summary = "read battery properties",
+ .usage = "read <prop>",
+ .params = bat_read_params,
+};
+
+static const struct shell_cmd_help bat_list_help =
+{
+ .summary = "list battery properties",
+ .usage = "list",
+ .params = NULL,
+};
+
+static const struct shell_cmd_help bat_poll_rate_help =
+{
+ .summary = "set battery polling rate",
+ .usage = "pollrate <time_in_s>",
+ .params = NULL,
+};
+
+static const struct shell_cmd_help bat_monitor_help =
+{
+ .summary = "start battery property monitoring",
+ .usage = "monitor <prop> [off]",
+ .params = bat_monitor_params,
+};
+
+#else
+#define HELP(a) NULL
+#endif
+
+static const struct shell_cmd bat_cli_cmd =
+{
+ .sc_cmd = "bat",
+ .sc_cmd_func = bat_compat_cmd,
+};
+
+/**
+ * cmd bat help
+ *
+ * Help for the bat command.
+ *
+ */
+static void cmd_bat_help(void)
+{
+ console_printf("Usage: bat <cmd> [options]\n");
+ console_printf("Available bat commands:\n");
+ console_printf(" pollrate <time_in_s>\n");
+ console_printf(" monitor [<prop>] [off]\n");
+ console_printf(" list\n");
+ console_printf(" read [<prop>] | all\n");
+
+ console_printf("Examples:\n");
+ console_printf(" list\n");
+ console_printf(" monitor VoltageADC\n");
+ console_printf(" monitor off\n");
+ console_printf(" read Voltage\n");
+ console_printf(" read all\n");
+}
+
+static const char *bat_status[] = {
+ "???",
+ "charging",
+ "discharging",
+ "connected not charging",
+ "battery full",
+};
+
+static const char *bat_level[] = {
+ "???",
+ "battery level critical",
+ "battery level low",
+ "battery level normal",
+ "battery level high",
+ "battery level full",
+};
+
+static void print_property(const struct battery_property *prop)
+{
+ char name[20];
+
+ battery_prop_get_name(prop, name, 20);
+
+ switch (prop->bp_type) {
+ case BATTERY_PROP_VOLTAGE_NOW:
+ case BATTERY_PROP_VOLTAGE_AVG:
+ case BATTERY_PROP_VOLTAGE_MAX:
+ case BATTERY_PROP_VOLTAGE_MAX_DESIGN:
+ case BATTERY_PROP_VOLTAGE_MIN:
+ case BATTERY_PROP_VOLTAGE_MIN_DESIGN:
+ console_printf(" %s %ld mV\n", name, prop->bp_value.bpv_voltage);
+ break;
+ case BATTERY_PROP_TEMP_NOW:
+ case BATTERY_PROP_TEMP_AMBIENT:
+ console_printf(" %s %f deg C\n", name, prop->bp_value.bpv_temperature);
+ break;
+ case BATTERY_PROP_CURRENT_NOW:
+ case BATTERY_PROP_CURRENT_MAX:
+ case BATTERY_PROP_CURRENT_AVG:
+ console_printf(" %s %ld mA\n", name, prop->bp_value.bpv_current);
+ break;
+ case BATTERY_PROP_TIME_TO_EMPTY_NOW:
+ case BATTERY_PROP_TIME_TO_FULL_NOW:
+ console_printf(" %s %ld s\n", name, prop->bp_value.bpv_time_in_s);
+ break;
+ case BATTERY_PROP_SOC:
+ console_printf(" %s %d %%\n", name, prop->bp_value.bpv_soc);
+ break;
+ case BATTERY_PROP_STATUS:
+ console_printf(" %s %s\n", name,
+ bat_status[prop->bp_value.bpv_status]);
+ break;
+ case BATTERY_PROP_CAPACITY:
+ console_printf(" %s %lu mAh\n", name, prop->bp_value.bpv_capacity);
+ break;
+ case BATTERY_PROP_CAPACITY_LEVEL:
+ console_printf(" %s %s\n", name,
+ bat_level[prop->bp_value.bpv_capacity_level]);
+ break;
+ case BATTERY_PROP_CYCLE_COUNT:
+ console_printf(" %s %d\n", name, prop->bp_value.bpv_cycle_count);
+ break;
+ default:
+ break;
+ }
+}
+
+static int cmd_bat_read(int argc, char **argv)
+{
+ int rc = 0;
+ int maxp;
+ int i;
+ struct battery_property *prop;
+
+ if (argc < 2) {
+ console_printf("Invalid number of arguments, use read <prop>\n");
+ goto err;
+ }
+
+ if (argc == 2 && strcmp("all", argv[1]) == 0) {
+ maxp = battery_get_property_count(bat, NULL);
+ for (i = 0; i < maxp; ++i) {
+ prop = battery_enum_property(bat, NULL, i);
+ battery_prop_get_value(prop);
+ if (!prop->bp_valid) {
+ console_printf("Error reading property\n");
+ goto err;
+ }
+ print_property(prop);
+ }
+ } else {
+ for (i = 1; i < argc; ++i) {
+ prop = battery_find_property_by_name(bat, argv[i]);
+ if (prop == NULL) {
+ console_printf("Invalid property name %s\n", argv[i]);
+ goto err;
+ }
+ battery_prop_get_value(prop);
+ if (!prop->bp_valid) {
+ console_printf("Error reading property\n");
+ goto err;
+ }
+ print_property(prop);
+ }
+ }
+err:
+ return rc;
+}
+
+static int cmd_bat_list(int argc, char **argv)
+{
+ int i;
+ int max = battery_get_property_count(bat, NULL);
+ struct battery_property *prop;
+ char name[20];
+
+ for (i = 0; i < max; ++i) {
+ prop = battery_enum_property(bat, NULL, i);
+ if (prop) {
+ console_printf(" %s\n", battery_prop_get_name(prop, name, 20));
+ }
+ }
+ return 0;
+}
+
+static int cmd_bat_poll_rate(int argc, char **argv)
+{
+ int rc;
+ uint32_t rate_in_s;
+
+ if (argc == 2) {
+ rate_in_s = (uint32_t)parse_ull_bounds(argv[1], 1, 255, &rc);
+ if (rc) {
+ console_printf("Invalid poll rate, use 1..255\n");
+ } else {
+ battery_set_poll_rate_ms(bat, rate_in_s * 1000);
+ }
+ } else {
+ console_printf("Missing poll rate argument\n");
+ }
+ return 0;
+}
+
+static int bat_property(struct battery_prop_listener *listener,
+ const struct battery_property *prop)
+{
+ print_property(prop);
+ return 0;
+}
+
+static struct battery_prop_listener listener = {
+ .bpl_prop_changed = bat_property,
+ .bpl_prop_read = bat_property,
+};
+
+static int cmd_bat_monitor(int argc, char **argv)
+{
+ int rc = 0;
+ struct battery_property *prop;
+
+ if (argc < 2) {
+ console_printf("Invalid number of arguments, use monitor <prop_nam>\n");
+ goto err;
+ }
+
+ prop = battery_find_property_by_name(bat, argv[1]);
+ if (prop == NULL) {
+ if (strcmp(argv[1], "off") == 0) {
+ battery_prop_poll_unsubscribe(&listener, NULL);
+ goto err;
+ }
+ console_printf("Invalid property name\n");
+ goto err;
+ }
+
+ if (argc == 3) {
+ if (strcmp(argv[2], "off") == 0) {
+ battery_prop_poll_unsubscribe(&listener, prop);
+ goto err;
+ } else if (strcmp(argv[2], "on") != 0) {
+ console_printf("Invalid parameter %s\n", argv[2]);
+ goto err;
+ }
+ }
+ battery_prop_poll_subscribe(&listener, prop);
+
+err:
+ return rc;
+}
+
+static const struct shell_cmd bat_cli_commands[] =
+{
+ { "read", cmd_bat_read, HELP(bat_read_help) },
+ { "list", cmd_bat_list, HELP(bat_list_help) },
+ { "pollrate", cmd_bat_poll_rate, HELP(bat_poll_rate_help) },
+ { "monitor", cmd_bat_monitor, HELP(bat_monitor_help) },
+ { NULL, NULL, NULL }
+};
+
+/**
+ * bat cmd
+ *
+ * Main processing function for K4 cli bat command
+ *
+ * @param argc Number of arguments
+ * @param argv Argument list
+ *
+ * @return int 0: success, -1 error
+ */
+static int bat_compat_cmd(int argc, char **argv)
+{
+ int rc;
+ int i;
+
+ for (i = 0; bat_cli_commands[i].sc_cmd; ++i)
+ {
+ if (strcmp(bat_cli_commands[i].sc_cmd, argv[1]) == 0)
+ {
+ rc = bat_cli_commands[i].sc_cmd_func(argc - 1, argv + 1);
+ break;
+ }
+ }
+ /* No command found */
+ if (bat_cli_commands[i].sc_cmd == NULL)
+ {
+ console_printf("Invalid command.\n");
+ rc = -1;
+ }
+
+ /* Print help in case of error */
+ if (rc)
+ {
+ cmd_bat_help();
+ }
+
+ return rc;
+}
+
+void
+battery_shell_register(void)
+{
+ int rc;
+
+ rc = shell_register("bat", bat_cli_commands);
+ rc = shell_cmd_register(&bat_cli_cmd);
+ SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register battery shell");
+
+ bat = os_dev_open("battery_0", 0, NULL);
+ SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to open battery device");
+}
diff --git a/hw/battery/syscfg.yml b/hw/battery/syscfg.yml
index 1fe9a4dced..3945e02a77 100644
--- a/hw/battery/syscfg.yml
+++ b/hw/battery/syscfg.yml
@@ -19,9 +19,9 @@
# Package: hw/battery
syscfg.defs:
- BATTERY_CLI:
+ BATTERY_SHELL:
description: 'Whether or not to enable the battery shell support'
- value: 1
+ value: 0
BATTERY_MGR_EVQ:
description: >
diff --git a/hw/drivers/bq27z561/src/bq27z561.c b/hw/drivers/bq27z561/src/bq27z561.c
index e0a66461e2..f9318eec22 100644
--- a/hw/drivers/bq27z561/src/bq27z561.c
+++ b/hw/drivers/bq27z561/src/bq27z561.c
@@ -663,6 +663,11 @@ bq27z561_battery_property_get(struct battery_driver *driver,
rc = -1;
assert(0);
}
+ if (rc == 0) {
+ property->bp_valid = 1;
+ } else {
+ property->bp_valid = 0;
+ }
return rc;
}
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
With regards,
Apache Git Services