shell_battery.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * Copyright 2020 Google LLC
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <shell/shell.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <device.h>
  11. #include <drivers/sensor.h>
  12. /**
  13. * @brief Collect the values for several channels
  14. *
  15. * @param dev Sensor device to read from
  16. * @param ... any number of pairs of arguments:
  17. * first is the sensor channel to read (-1 to terminate the list)
  18. * second is a pointer to the struct sensor_value to put it in
  19. * @return 0 on success
  20. * @return negative error code from sensor API on failure
  21. */
  22. static int get_channels(const struct device *dev, ...)
  23. {
  24. va_list ptr;
  25. int i;
  26. va_start(ptr, dev);
  27. for (i = 0;; i++) {
  28. int chan;
  29. struct sensor_value *val;
  30. int err;
  31. chan = va_arg(ptr, int);
  32. if (chan == -1)
  33. break;
  34. val = va_arg(ptr, struct sensor_value *);
  35. err = sensor_channel_get(dev, chan, val);
  36. if (err < 0) {
  37. va_end(ptr);
  38. return err;
  39. }
  40. }
  41. va_end(ptr);
  42. return 0;
  43. }
  44. /* battery */
  45. static int cmd_battery(const struct shell *shell, size_t argc, char **argv)
  46. {
  47. struct sensor_value temp, volt, current, i_desired, charge_remain;
  48. struct sensor_value charge, v_desired, v_design, cap, nom_cap;
  49. struct sensor_value full, empty;
  50. const struct device *dev;
  51. bool allowed;
  52. int err;
  53. dev = device_get_binding(DT_LABEL(DT_ALIAS(battery)));
  54. if (!dev) {
  55. shell_error(shell, "Device unknown (%s)", argv[1]);
  56. return -ENODEV;
  57. }
  58. err = sensor_sample_fetch(dev);
  59. if (err < 0) {
  60. shell_error(shell, "Failed to read sensor: %d", err);
  61. }
  62. err = get_channels(dev,
  63. SENSOR_CHAN_GAUGE_TEMP, &temp,
  64. SENSOR_CHAN_GAUGE_VOLTAGE, &volt,
  65. SENSOR_CHAN_GAUGE_AVG_CURRENT, &current,
  66. SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE, &v_desired,
  67. SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT,
  68. &i_desired,
  69. SENSOR_CHAN_GAUGE_STATE_OF_CHARGE, &charge,
  70. SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE, &v_design,
  71. SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY,
  72. &charge_remain,
  73. SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY, &cap,
  74. SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY, &nom_cap,
  75. SENSOR_CHAN_GAUGE_TIME_TO_FULL, &full,
  76. SENSOR_CHAN_GAUGE_TIME_TO_EMPTY, &empty,
  77. -1);
  78. if (err < 0) {
  79. return err;
  80. }
  81. shell_fprintf(shell, SHELL_NORMAL, "Temp: %.1d.%02d C\n", temp.val1,
  82. temp.val2 / 10000);
  83. shell_fprintf(shell, SHELL_NORMAL, "V: %5d.%02d V\n", volt.val1,
  84. volt.val2 / 10000);
  85. shell_fprintf(shell, SHELL_NORMAL, "V-desired: %d.%02d V\n",
  86. v_desired.val1, v_desired.val2 / 10000);
  87. shell_fprintf(shell, SHELL_NORMAL, "I: %d mA", current.val1);
  88. if (current.val1 > 0) {
  89. shell_fprintf(shell, SHELL_NORMAL, " (CHG)");
  90. } else if (current.val1 < 0) {
  91. shell_fprintf(shell, SHELL_NORMAL, " (DISCHG)");
  92. }
  93. shell_fprintf(shell, SHELL_NORMAL, "\n");
  94. shell_fprintf(shell, SHELL_NORMAL, "I-desired: %5d mA\n",
  95. i_desired.val1);
  96. allowed = i_desired.val1 && v_desired.val2 && charge.val1 < 100;
  97. shell_fprintf(shell, SHELL_NORMAL, "Charging: %sAllowed\n",
  98. allowed ? "" : "Not ");
  99. shell_fprintf(shell, SHELL_NORMAL, "Charge: %d %%\n", charge.val1);
  100. shell_fprintf(shell, SHELL_NORMAL, "V-design: %d.%02d V\n",
  101. v_design.val1, v_design.val2 / 10000);
  102. shell_fprintf(shell, SHELL_NORMAL, "Remaining: %d mA\n",
  103. charge_remain.val1);
  104. shell_fprintf(shell, SHELL_NORMAL, "Cap-full: %d mA\n", cap.val1);
  105. shell_fprintf(shell, SHELL_NORMAL, "Design: %d mA\n", nom_cap.val1);
  106. shell_fprintf(shell, SHELL_NORMAL, "Time full: %dh:%02d\n",
  107. full.val1 / 60, full.val1 % 60);
  108. shell_fprintf(shell, SHELL_NORMAL, "Time empty: %dh:%02d\n",
  109. empty.val1 / 60, empty.val1 % 60);
  110. return 0;
  111. }
  112. SHELL_CMD_REGISTER(battery, NULL, "Battery status", cmd_battery);