1 /*
2 * Copyright (c) 2023 Google LLC
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdlib.h>
8 #include <string.h>
9
10 #include <zephyr/drivers/sensor.h>
11 #include <zephyr/kernel.h>
12
13 #include "sensor_shell.h"
14
15 /* Create a single common config for streaming */
16 static struct sensor_stream_trigger iodev_sensor_shell_trigger;
17 static struct sensor_read_config iodev_sensor_shell_stream_config = {
18 .sensor = NULL,
19 .is_streaming = true,
20 .triggers = &iodev_sensor_shell_trigger,
21 .count = 0,
22 .max = 1,
23 };
24 RTIO_IODEV_DEFINE(iodev_sensor_shell_stream, &__sensor_iodev_api,
25 &iodev_sensor_shell_stream_config);
26
sensor_shell_processing_entry_point(void * a,void * b,void * c)27 static void sensor_shell_processing_entry_point(void *a, void *b, void *c)
28 {
29 ARG_UNUSED(a);
30 ARG_UNUSED(b);
31 ARG_UNUSED(c);
32
33 while (true) {
34 sensor_processing_with_callback(&sensor_read_rtio,
35 sensor_shell_processing_callback);
36 }
37 }
38 K_THREAD_DEFINE(sensor_shell_processing_tid, CONFIG_SENSOR_SHELL_THREAD_STACK_SIZE,
39 sensor_shell_processing_entry_point, NULL, NULL, NULL, 0, 0, 0);
40
cmd_sensor_stream(const struct shell * shell_ptr,size_t argc,char * argv[])41 int cmd_sensor_stream(const struct shell *shell_ptr, size_t argc, char *argv[])
42 {
43 static struct rtio_sqe *current_streaming_handle;
44 static struct sensor_shell_processing_context ctx;
45 const struct device *dev = device_get_binding(argv[1]);
46
47 if (argc != 5 && argc != 3) {
48 shell_error(shell_ptr, "Wrong number of arguments (%zu)", argc);
49 return -EINVAL;
50 }
51
52 if (dev == NULL) {
53 shell_error(shell_ptr, "Device unknown (%s)", argv[1]);
54 return -ENODEV;
55 }
56
57 if (current_streaming_handle != NULL) {
58 shell_info(shell_ptr, "Disabling existing stream");
59 rtio_sqe_cancel(current_streaming_handle);
60 }
61
62 if (strcmp("off", argv[2]) == 0) {
63 return 0;
64 }
65
66 if (strcmp("on", argv[2]) != 0) {
67 shell_error(shell_ptr, "Unknown streaming operation (%s)", argv[2]);
68 return -EINVAL;
69 }
70
71 if (strcmp("double_tap", argv[3]) == 0) {
72 iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_DOUBLE_TAP;
73 } else if (strcmp("data_ready", argv[3]) == 0) {
74 iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_DATA_READY;
75 } else if (strcmp("delta", argv[3]) == 0) {
76 iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_DELTA;
77 } else if (strcmp("freefall", argv[3]) == 0) {
78 iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_FREEFALL;
79 } else if (strcmp("motion", argv[3]) == 0) {
80 iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_MOTION;
81 } else if (strcmp("near_far", argv[3]) == 0) {
82 iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_NEAR_FAR;
83 } else if (strcmp("stationary", argv[3]) == 0) {
84 iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_STATIONARY;
85 } else if (strcmp("threshold", argv[3]) == 0) {
86 iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_THRESHOLD;
87 } else if (strcmp("fifo_wm", argv[3]) == 0) {
88 iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_FIFO_WATERMARK;
89 } else if (strcmp("fifo_full", argv[3]) == 0) {
90 iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_FIFO_FULL;
91 } else if (strcmp("tap", argv[3]) == 0) {
92 iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_TAP;
93 } else {
94 shell_error(shell_ptr, "Invalid trigger (%s)", argv[3]);
95 return -EINVAL;
96 }
97
98 if (strcmp("incl", argv[4]) == 0) {
99 iodev_sensor_shell_trigger.opt = SENSOR_STREAM_DATA_INCLUDE;
100 } else if (strcmp("drop", argv[4]) == 0) {
101 iodev_sensor_shell_trigger.opt = SENSOR_STREAM_DATA_DROP;
102 } else if (strcmp("nop", argv[4]) == 0) {
103 iodev_sensor_shell_trigger.opt = SENSOR_STREAM_DATA_NOP;
104 } else {
105 shell_error(shell_ptr, "Unknown trigger op (%s)", argv[4]);
106 return -EINVAL;
107 }
108
109 shell_print(shell_ptr, "Enabling stream...");
110 iodev_sensor_shell_stream_config.sensor = dev;
111
112 iodev_sensor_shell_stream_config.count = 1;
113
114 ctx.dev = dev;
115 ctx.sh = shell_ptr;
116
117 int rc = sensor_stream(&iodev_sensor_shell_stream, &sensor_read_rtio, &ctx,
118 ¤t_streaming_handle);
119
120 if (rc != 0) {
121 shell_error(shell_ptr, "Failed to start stream");
122 }
123 return rc;
124 }
125