123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- /*
- * Copyright 2020 Google LLC
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <shell/shell.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <device.h>
- #include <drivers/sensor.h>
- /**
- * @brief Collect the values for several channels
- *
- * @param dev Sensor device to read from
- * @param ... any number of pairs of arguments:
- * first is the sensor channel to read (-1 to terminate the list)
- * second is a pointer to the struct sensor_value to put it in
- * @return 0 on success
- * @return negative error code from sensor API on failure
- */
- static int get_channels(const struct device *dev, ...)
- {
- va_list ptr;
- int i;
- va_start(ptr, dev);
- for (i = 0;; i++) {
- int chan;
- struct sensor_value *val;
- int err;
- chan = va_arg(ptr, int);
- if (chan == -1)
- break;
- val = va_arg(ptr, struct sensor_value *);
- err = sensor_channel_get(dev, chan, val);
- if (err < 0) {
- va_end(ptr);
- return err;
- }
- }
- va_end(ptr);
- return 0;
- }
- /* battery */
- static int cmd_battery(const struct shell *shell, size_t argc, char **argv)
- {
- struct sensor_value temp, volt, current, i_desired, charge_remain;
- struct sensor_value charge, v_desired, v_design, cap, nom_cap;
- struct sensor_value full, empty;
- const struct device *dev;
- bool allowed;
- int err;
- dev = device_get_binding(DT_LABEL(DT_ALIAS(battery)));
- if (!dev) {
- shell_error(shell, "Device unknown (%s)", argv[1]);
- return -ENODEV;
- }
- err = sensor_sample_fetch(dev);
- if (err < 0) {
- shell_error(shell, "Failed to read sensor: %d", err);
- }
- err = get_channels(dev,
- SENSOR_CHAN_GAUGE_TEMP, &temp,
- SENSOR_CHAN_GAUGE_VOLTAGE, &volt,
- SENSOR_CHAN_GAUGE_AVG_CURRENT, ¤t,
- SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE, &v_desired,
- SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT,
- &i_desired,
- SENSOR_CHAN_GAUGE_STATE_OF_CHARGE, &charge,
- SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE, &v_design,
- SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY,
- &charge_remain,
- SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY, &cap,
- SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY, &nom_cap,
- SENSOR_CHAN_GAUGE_TIME_TO_FULL, &full,
- SENSOR_CHAN_GAUGE_TIME_TO_EMPTY, &empty,
- -1);
- if (err < 0) {
- return err;
- }
- shell_fprintf(shell, SHELL_NORMAL, "Temp: %.1d.%02d C\n", temp.val1,
- temp.val2 / 10000);
- shell_fprintf(shell, SHELL_NORMAL, "V: %5d.%02d V\n", volt.val1,
- volt.val2 / 10000);
- shell_fprintf(shell, SHELL_NORMAL, "V-desired: %d.%02d V\n",
- v_desired.val1, v_desired.val2 / 10000);
- shell_fprintf(shell, SHELL_NORMAL, "I: %d mA", current.val1);
- if (current.val1 > 0) {
- shell_fprintf(shell, SHELL_NORMAL, " (CHG)");
- } else if (current.val1 < 0) {
- shell_fprintf(shell, SHELL_NORMAL, " (DISCHG)");
- }
- shell_fprintf(shell, SHELL_NORMAL, "\n");
- shell_fprintf(shell, SHELL_NORMAL, "I-desired: %5d mA\n",
- i_desired.val1);
- allowed = i_desired.val1 && v_desired.val2 && charge.val1 < 100;
- shell_fprintf(shell, SHELL_NORMAL, "Charging: %sAllowed\n",
- allowed ? "" : "Not ");
- shell_fprintf(shell, SHELL_NORMAL, "Charge: %d %%\n", charge.val1);
- shell_fprintf(shell, SHELL_NORMAL, "V-design: %d.%02d V\n",
- v_design.val1, v_design.val2 / 10000);
- shell_fprintf(shell, SHELL_NORMAL, "Remaining: %d mA\n",
- charge_remain.val1);
- shell_fprintf(shell, SHELL_NORMAL, "Cap-full: %d mA\n", cap.val1);
- shell_fprintf(shell, SHELL_NORMAL, "Design: %d mA\n", nom_cap.val1);
- shell_fprintf(shell, SHELL_NORMAL, "Time full: %dh:%02d\n",
- full.val1 / 60, full.val1 % 60);
- shell_fprintf(shell, SHELL_NORMAL, "Time empty: %dh:%02d\n",
- empty.val1 / 60, empty.val1 % 60);
- return 0;
- }
- SHELL_CMD_REGISTER(battery, NULL, "Battery status", cmd_battery);
|