1 /*
2 * Copyright (c) 2019 Alexander Wachter
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/sys/printk.h>
8 #include <zephyr/shell/shell.h>
9 #include <zephyr/drivers/hwinfo.h>
10 #include <zephyr/types.h>
11 #include <zephyr/logging/log.h>
12
cmd_get_device_id(const struct shell * sh,size_t argc,char ** argv)13 static int cmd_get_device_id(const struct shell *sh, size_t argc, char **argv)
14 {
15 uint8_t dev_id[16];
16 ssize_t length;
17 int i;
18
19 length = hwinfo_get_device_id(dev_id, sizeof(dev_id));
20
21 if (length == -ENOSYS) {
22 shell_error(sh, "Not supported by hardware");
23 return -ENOSYS;
24 } else if (length < 0) {
25 shell_error(sh, "Error: %zd", length);
26 return length;
27 }
28
29 shell_fprintf(sh, SHELL_NORMAL, "Length: %zd\n", length);
30 shell_fprintf(sh, SHELL_NORMAL, "ID: 0x");
31
32 for (i = 0 ; i < length ; i++) {
33 shell_fprintf(sh, SHELL_NORMAL, "%02x", dev_id[i]);
34 }
35
36 shell_fprintf(sh, SHELL_NORMAL, "\n");
37
38 return 0;
39 }
40
cmd_get_device_eui64(const struct shell * sh,size_t argc,char ** argv)41 static int cmd_get_device_eui64(const struct shell *sh, size_t argc, char **argv)
42 {
43 uint8_t dev_eui64[8];
44 int ret;
45 int i;
46
47 ret = hwinfo_get_device_eui64(dev_eui64);
48
49 if (ret == -ENOSYS) {
50 shell_error(sh, "Not supported by hardware");
51 return -ENOSYS;
52 } else if (ret < 0) {
53 shell_error(sh, "Error: %d", ret);
54 return ret;
55 }
56
57 shell_fprintf(sh, SHELL_NORMAL, "EUI64: 0x");
58
59 for (i = 0 ; i < 8 ; i++) {
60 shell_fprintf(sh, SHELL_NORMAL, "%02x", dev_eui64[i]);
61 }
62
63 shell_fprintf(sh, SHELL_NORMAL, "\n");
64
65 return 0;
66 }
67
cause_to_string(uint32_t cause)68 static inline const char *cause_to_string(uint32_t cause)
69 {
70 switch (cause) {
71 case RESET_PIN:
72 return "pin";
73
74 case RESET_SOFTWARE:
75 return "software";
76
77 case RESET_BROWNOUT:
78 return "brownout";
79
80 case RESET_POR:
81 return "power-on reset";
82
83 case RESET_WATCHDOG:
84 return "watchdog";
85
86 case RESET_DEBUG:
87 return "debug";
88
89 case RESET_SECURITY:
90 return "security";
91
92 case RESET_LOW_POWER_WAKE:
93 return "low power wake-up";
94
95 case RESET_CPU_LOCKUP:
96 return "CPU lockup";
97
98 case RESET_PARITY:
99 return "parity error";
100
101 case RESET_PLL:
102 return "PLL error";
103
104 case RESET_CLOCK:
105 return "clock";
106
107 case RESET_HARDWARE:
108 return "hardware";
109
110 case RESET_USER:
111 return "user";
112
113 case RESET_TEMPERATURE:
114 return "temperature";
115
116 default:
117 return "unknown";
118 }
119 }
120
print_all_reset_causes(const struct shell * sh,uint32_t cause)121 static void print_all_reset_causes(const struct shell *sh, uint32_t cause)
122 {
123 for (uint32_t cause_mask = 1; cause_mask; cause_mask <<= 1) {
124 if (cause & cause_mask) {
125 shell_print(sh, "- %s",
126 cause_to_string(cause & cause_mask));
127 }
128 }
129 }
130
cmd_show_reset_cause(const struct shell * sh,size_t argc,char ** argv)131 static int cmd_show_reset_cause(const struct shell *sh, size_t argc,
132 char **argv)
133 {
134 int res;
135 uint32_t cause;
136
137 ARG_UNUSED(argc);
138 ARG_UNUSED(argv);
139
140 res = hwinfo_get_reset_cause(&cause);
141 if (res == -ENOSYS) {
142 shell_error(sh, "Not supported by hardware");
143 return res;
144 } else if (res != 0) {
145 shell_error(sh, "Error reading the cause [%d]", res);
146 return res;
147 }
148
149 if (cause != 0) {
150 shell_print(sh, "reset caused by:");
151 print_all_reset_causes(sh, cause);
152 } else {
153 shell_print(sh, "No reset cause set");
154 }
155
156 return 0;
157 }
158
cmd_clear_reset_cause(const struct shell * sh,size_t argc,char ** argv)159 static int cmd_clear_reset_cause(const struct shell *sh, size_t argc,
160 char **argv)
161 {
162 int res;
163
164 ARG_UNUSED(argc);
165 ARG_UNUSED(argv);
166
167 res = hwinfo_clear_reset_cause();
168 if (res == -ENOSYS) {
169 shell_error(sh, "Not supported by hardware");
170 } else if (res != 0) {
171 shell_error(sh, "Error clearing the reset causes [%d]", res);
172 return res;
173 }
174
175 return 0;
176 }
177
cmd_supported_reset_cause(const struct shell * sh,size_t argc,char ** argv)178 static int cmd_supported_reset_cause(const struct shell *sh, size_t argc,
179 char **argv)
180 {
181 uint32_t cause;
182 int res;
183
184 ARG_UNUSED(argc);
185 ARG_UNUSED(argv);
186
187 res = hwinfo_get_supported_reset_cause(&cause);
188 if (res == -ENOSYS) {
189 shell_error(sh, "Not supported by hardware");
190 } else if (res != 0) {
191 shell_error(sh, "Could not get the supported reset causes [%d]", res);
192 return res;
193 }
194
195 if (cause != 0) {
196 shell_print(sh, "supported reset causes:");
197 print_all_reset_causes(sh, cause);
198 } else {
199 shell_print(sh, "No causes supported");
200 }
201
202 return 0;
203 }
204
205 SHELL_STATIC_SUBCMD_SET_CREATE(sub_reset_cause,
206 SHELL_CMD_ARG(show, NULL, "Show persistent reset causes",
207 cmd_show_reset_cause, 1, 0),
208 SHELL_CMD_ARG(clear, NULL, "Clear all persistent reset causes",
209 cmd_clear_reset_cause, 1, 0),
210 SHELL_CMD_ARG(supported, NULL,
211 "Get a list of all supported reset causes",
212 cmd_supported_reset_cause, 1, 0),
213 SHELL_SUBCMD_SET_END /* Array terminated. */
214 );
215
216 SHELL_STATIC_SUBCMD_SET_CREATE(sub_hwinfo,
217 SHELL_CMD_ARG(devid, NULL, "Show device id", cmd_get_device_id, 1, 0),
218 SHELL_CMD_ARG(deveui64, NULL, "Show device eui64", cmd_get_device_eui64, 1, 0),
219 SHELL_CMD_ARG(reset_cause, &sub_reset_cause, "Reset cause commands",
220 cmd_show_reset_cause, 1, 0),
221 SHELL_SUBCMD_SET_END /* Array terminated. */
222 );
223
224 SHELL_CMD_ARG_REGISTER(hwinfo, &sub_hwinfo, "HWINFO commands", NULL, 2, 0);
225