1 /*
2 * Copyright (c) 2024 Analog Devices, Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(app_device, LOG_LEVEL_DBG);
9
10 #include <zephyr/kernel.h>
11 #include <zephyr/drivers/sensor.h>
12 #include <zephyr/drivers/led.h>
13 #include <zephyr/random/random.h>
14
15 #include "device.h"
16
17 #define SENSOR_CHAN SENSOR_CHAN_AMBIENT_TEMP
18 #define SENSOR_UNIT "Celsius"
19
20 /* Devices */
21 static const struct device *sensor = DEVICE_DT_GET_OR_NULL(DT_ALIAS(ambient_temp0));
22 static const struct device *leds = DEVICE_DT_GET_OR_NULL(DT_INST(0, gpio_leds));
23
24 /* Command handlers */
led_on_handler(void)25 static void led_on_handler(void)
26 {
27 device_write_led(LED_USER, LED_ON);
28 }
29
led_off_handler(void)30 static void led_off_handler(void)
31 {
32 device_write_led(LED_USER, LED_OFF);
33 }
34
35 /* Supported device commands */
36 struct device_cmd device_commands[] = {
37 {"led_on", led_on_handler},
38 {"led_off", led_off_handler}
39 };
40
41 const size_t num_device_commands = ARRAY_SIZE(device_commands);
42
43 /* Command dispatcher */
device_command_handler(uint8_t * command)44 void device_command_handler(uint8_t *command)
45 {
46 for (int i = 0; i < num_device_commands; i++) {
47 if (strcmp(command, device_commands[i].command) == 0) {
48 LOG_INF("Executing device command: %s", device_commands[i].command);
49 return device_commands[i].handler();
50 }
51 }
52 LOG_ERR("Unknown command: %s", command);
53 }
54
device_read_sensor(struct sensor_sample * sample)55 int device_read_sensor(struct sensor_sample *sample)
56 {
57 int rc;
58 struct sensor_value sensor_val;
59
60 /* Read sample only if a real sensor device is present
61 * otherwise return a dummy value
62 */
63 if (sensor == NULL) {
64 sample->unit = SENSOR_UNIT;
65 sample->value = 20.0 + (double)sys_rand32_get() / UINT32_MAX * 5.0;
66 return 0;
67 }
68
69 rc = sensor_sample_fetch(sensor);
70 if (rc) {
71 LOG_ERR("Failed to fetch sensor sample [%d]", rc);
72 return rc;
73 }
74
75 rc = sensor_channel_get(sensor, SENSOR_CHAN, &sensor_val);
76 if (rc) {
77 LOG_ERR("Failed to get sensor channel [%d]", rc);
78 return rc;
79 }
80
81 sample->unit = SENSOR_UNIT;
82 sample->value = sensor_value_to_double(&sensor_val);
83 return rc;
84 }
85
device_write_led(enum led_id led_idx,enum led_state state)86 int device_write_led(enum led_id led_idx, enum led_state state)
87 {
88 int rc;
89
90 switch (state) {
91 case LED_OFF:
92 if (leds == NULL) {
93 LOG_INF("LED %d OFF", led_idx);
94 break;
95 }
96 led_off(leds, led_idx);
97 break;
98 case LED_ON:
99 if (leds == NULL) {
100 LOG_INF("LED %d ON", led_idx);
101 break;
102 }
103 led_on(leds, led_idx);
104 break;
105 default:
106 LOG_ERR("Invalid LED state setting");
107 rc = -EINVAL;
108 break;
109 }
110
111 return rc;
112 }
113
devices_ready(void)114 bool devices_ready(void)
115 {
116 bool rc = true;
117
118 /* Check readiness only if a real sensor device is present */
119 if (sensor != NULL) {
120 if (!device_is_ready(sensor)) {
121 LOG_ERR("Device %s is not ready", sensor->name);
122 rc = false;
123 } else {
124 LOG_INF("Device %s is ready", sensor->name);
125 }
126 }
127
128 if (leds != NULL) {
129 if (!device_is_ready(leds)) {
130 LOG_ERR("Device %s is not ready", leds->name);
131 rc = false;
132 } else {
133 LOG_INF("Device %s is ready", leds->name);
134 }
135 }
136
137 return rc;
138 }
139