| /* |
| * Copyright (c) 2018 Diego Sueiro |
| * |
| * 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> |
| |
| #define SENSOR_GET_HELP \ |
| "Get sensor data. Channel names are optional. All channels are read " \ |
| "when no channels are provided. Syntax:\n" \ |
| "<device_name> <channel name 0> .. <channel name N>" |
| |
| extern struct device __device_start[]; |
| extern struct device __device_end[]; |
| |
| const char *sensor_channel_name[SENSOR_CHAN_ALL] = { |
| [SENSOR_CHAN_ACCEL_X] = "accel_x", |
| [SENSOR_CHAN_ACCEL_Y] = "accel_y", |
| [SENSOR_CHAN_ACCEL_Z] = "accel_z", |
| [SENSOR_CHAN_ACCEL_XYZ] = "accel_xyz", |
| [SENSOR_CHAN_GYRO_X] = "gyro_x", |
| [SENSOR_CHAN_GYRO_Y] = "gyro_y", |
| [SENSOR_CHAN_GYRO_Z] = "gyro_z", |
| [SENSOR_CHAN_GYRO_XYZ] = "gyro_xyz", |
| [SENSOR_CHAN_MAGN_X] = "magn_x", |
| [SENSOR_CHAN_MAGN_Y] = "magn_y", |
| [SENSOR_CHAN_MAGN_Z] = "magn_z", |
| [SENSOR_CHAN_MAGN_XYZ] = "magn_xyz", |
| [SENSOR_CHAN_DIE_TEMP] = "die_temp", |
| [SENSOR_CHAN_AMBIENT_TEMP] = "ambient_temp", |
| [SENSOR_CHAN_PRESS] = "press", |
| [SENSOR_CHAN_PROX] = "prox", |
| [SENSOR_CHAN_HUMIDITY] = "humidity", |
| [SENSOR_CHAN_LIGHT] = "light", |
| [SENSOR_CHAN_IR] = "ir", |
| [SENSOR_CHAN_RED] = "red", |
| [SENSOR_CHAN_GREEN] = "green", |
| [SENSOR_CHAN_BLUE] = "blue", |
| [SENSOR_CHAN_ALTITUDE] = "altitude", |
| [SENSOR_CHAN_PM_1_0] = "pm_1_0", |
| [SENSOR_CHAN_PM_2_5] = "pm_2_5", |
| [SENSOR_CHAN_PM_10] = "pm_10", |
| [SENSOR_CHAN_DISTANCE] = "distance", |
| [SENSOR_CHAN_CO2] = "co2", |
| [SENSOR_CHAN_VOC] = "voc", |
| [SENSOR_CHAN_VOLTAGE] = "voltage", |
| [SENSOR_CHAN_CURRENT] = "current", |
| [SENSOR_CHAN_ROTATION] = "rotation", |
| }; |
| |
| static int handle_channel_by_name(const struct shell *shell, struct device *dev, |
| const char *channel_name) |
| { |
| int i; |
| struct sensor_value value[3]; |
| int err; |
| |
| for (i = 0; i < ARRAY_SIZE(sensor_channel_name); i++) { |
| if (strcmp(channel_name, sensor_channel_name[i]) == 0) { |
| break; |
| } |
| } |
| |
| if (i == ARRAY_SIZE(sensor_channel_name)) { |
| shell_error(shell, "Channel not supported (%s)", channel_name); |
| return -ENOTSUP; |
| } |
| |
| err = sensor_channel_get(dev, i, value); |
| if (err < 0) { |
| return err; |
| } |
| |
| if (i != SENSOR_CHAN_ACCEL_XYZ && |
| i != SENSOR_CHAN_GYRO_XYZ && |
| i != SENSOR_CHAN_MAGN_XYZ) { |
| shell_print(shell, |
| "channel idx=%d %s = %10.6f", i, |
| sensor_channel_name[i], |
| sensor_value_to_double(&value[0])); |
| } else { |
| shell_print(shell, |
| "channel idx=%d %s x = %10.6f y = %10.6f z = %10.6f", |
| i, sensor_channel_name[i], |
| sensor_value_to_double(&value[0]), |
| sensor_value_to_double(&value[1]), |
| sensor_value_to_double(&value[2])); |
| } |
| |
| return 0; |
| } |
| static int cmd_get_sensor(const struct shell *shell, size_t argc, char *argv[]) |
| { |
| struct device *dev; |
| int err; |
| |
| dev = device_get_binding(argv[1]); |
| if (dev == NULL) { |
| 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"); |
| } |
| |
| if (argc == 2) { |
| /* read all channels */ |
| for (int i = 0; i < ARRAY_SIZE(sensor_channel_name); i++) { |
| if (sensor_channel_name[i]) { |
| handle_channel_by_name(shell, dev, |
| sensor_channel_name[i]); |
| } |
| } |
| } else { |
| for (int i = 2; i < argc; i++) { |
| err = handle_channel_by_name(shell, dev, argv[i]); |
| if (err < 0) { |
| shell_error(shell, |
| "Failed to read channel (%s)", argv[i]); |
| } |
| } |
| } |
| |
| return 0; |
| } |
| |
| static void channel_name_get(size_t idx, struct shell_static_entry *entry); |
| |
| SHELL_DYNAMIC_CMD_CREATE(dsub_channel_name, channel_name_get); |
| |
| static void channel_name_get(size_t idx, struct shell_static_entry *entry) |
| { |
| int cnt = 0; |
| |
| entry->syntax = NULL; |
| entry->handler = NULL; |
| entry->help = NULL; |
| entry->subcmd = &dsub_channel_name; |
| |
| for (int i = 0; i < SENSOR_CHAN_ALL; i++) { |
| if (sensor_channel_name[i] != NULL) { |
| if (cnt == idx) { |
| entry->syntax = sensor_channel_name[i]; |
| break; |
| } |
| cnt++; |
| } |
| } |
| } |
| |
| static void device_name_get(size_t idx, struct shell_static_entry *entry); |
| |
| SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get); |
| |
| static void device_name_get(size_t idx, struct shell_static_entry *entry) |
| { |
| int device_idx = 0; |
| struct device *dev; |
| |
| entry->syntax = NULL; |
| entry->handler = NULL; |
| entry->help = NULL; |
| entry->subcmd = &dsub_channel_name; |
| |
| for (dev = __device_start; dev != __device_end; dev++) { |
| if ((dev->driver_api != NULL) && |
| strcmp(dev->name, "") && (dev->name != NULL)) { |
| if (idx == device_idx) { |
| entry->syntax = dev->name; |
| break; |
| } |
| device_idx++; |
| } |
| } |
| } |
| |
| SHELL_STATIC_SUBCMD_SET_CREATE(sub_sensor, |
| SHELL_CMD_ARG(get, &dsub_device_name, SENSOR_GET_HELP, cmd_get_sensor, |
| 2, 255), |
| SHELL_SUBCMD_SET_END |
| ); |
| |
| SHELL_CMD_REGISTER(sensor, &sub_sensor, "Sensor commands", NULL); |