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 == -ENOTSUP) {
22 shell_error(sh, "Not supported by hardware");
23 return -ENOTSUP;
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
cause_to_string(uint32_t cause)41 static inline const char *cause_to_string(uint32_t cause)
42 {
43 switch (cause) {
44 case RESET_PIN:
45 return "pin";
46
47 case RESET_SOFTWARE:
48 return "software";
49
50 case RESET_BROWNOUT:
51 return "brownout";
52
53 case RESET_POR:
54 return "power-on reset";
55
56 case RESET_WATCHDOG:
57 return "watchdog";
58
59 case RESET_DEBUG:
60 return "debug";
61
62 case RESET_SECURITY:
63 return "security";
64
65 case RESET_LOW_POWER_WAKE:
66 return "low power wake-up";
67
68 case RESET_CPU_LOCKUP:
69 return "CPU lockup";
70
71 case RESET_PARITY:
72 return "parity error";
73
74 case RESET_PLL:
75 return "PLL error";
76
77 case RESET_CLOCK:
78 return "clock";
79
80 case RESET_HARDWARE:
81 return "hardware";
82
83 case RESET_USER:
84 return "user";
85
86 case RESET_TEMPERATURE:
87 return "temperature";
88
89 default:
90 return "unknown";
91 }
92 }
93
print_all_reset_causes(const struct shell * sh,uint32_t cause)94 static void print_all_reset_causes(const struct shell *sh, uint32_t cause)
95 {
96 for (uint32_t cause_mask = 1; cause_mask; cause_mask <<= 1) {
97 if (cause & cause_mask) {
98 shell_print(sh, "- %s",
99 cause_to_string(cause & cause_mask));
100 }
101 }
102 }
103
cmd_show_reset_cause(const struct shell * sh,size_t argc,char ** argv)104 static int cmd_show_reset_cause(const struct shell *sh, size_t argc,
105 char **argv)
106 {
107 int res;
108 uint32_t cause;
109
110 ARG_UNUSED(argc);
111 ARG_UNUSED(argv);
112
113 res = hwinfo_get_reset_cause(&cause);
114 if (res == -ENOTSUP) {
115 shell_error(sh, "Not supported by hardware");
116 return res;
117 } else if (res != 0) {
118 shell_error(sh, "Error reading the cause [%d]", res);
119 return res;
120 }
121
122 if (cause != 0) {
123 shell_print(sh, "reset caused by:");
124 print_all_reset_causes(sh, cause);
125 } else {
126 shell_print(sh, "No reset cause set");
127 }
128
129 return 0;
130 }
131
cmd_clear_reset_cause(const struct shell * sh,size_t argc,char ** argv)132 static int cmd_clear_reset_cause(const struct shell *sh, size_t argc,
133 char **argv)
134 {
135 int res;
136
137 ARG_UNUSED(argc);
138 ARG_UNUSED(argv);
139
140 res = hwinfo_clear_reset_cause();
141 if (res == -ENOTSUP) {
142 shell_error(sh, "Not supported by hardware");
143 } else if (res != 0) {
144 shell_error(sh, "Error clearing the reset causes [%d]", res);
145 return res;
146 }
147
148 return 0;
149 }
150
cmd_supported_reset_cause(const struct shell * sh,size_t argc,char ** argv)151 static int cmd_supported_reset_cause(const struct shell *sh, size_t argc,
152 char **argv)
153 {
154 uint32_t cause;
155 int res;
156
157 ARG_UNUSED(argc);
158 ARG_UNUSED(argv);
159
160 res = hwinfo_get_supported_reset_cause(&cause);
161 if (res == -ENOTSUP) {
162 shell_error(sh, "Not supported by hardware");
163 } else if (res != 0) {
164 shell_error(sh, "Could not get the supported reset causes [%d]", res);
165 return res;
166 }
167
168 if (cause != 0) {
169 shell_print(sh, "supported reset causes:");
170 print_all_reset_causes(sh, cause);
171 } else {
172 shell_print(sh, "No causes supported");
173 }
174
175 return 0;
176 }
177
178 SHELL_STATIC_SUBCMD_SET_CREATE(sub_reset_cause,
179 SHELL_CMD_ARG(show, NULL, "Show persistent reset causes",
180 cmd_show_reset_cause, 1, 0),
181 SHELL_CMD_ARG(clear, NULL, "Clear all persistent reset causes",
182 cmd_clear_reset_cause, 1, 0),
183 SHELL_CMD_ARG(supported, NULL,
184 "Get a list of all supported reset causes",
185 cmd_supported_reset_cause, 1, 0),
186 SHELL_SUBCMD_SET_END /* Array terminated. */
187 );
188
189 SHELL_STATIC_SUBCMD_SET_CREATE(sub_hwinfo,
190 SHELL_CMD_ARG(devid, NULL, "Show device id", cmd_get_device_id, 1, 0),
191 SHELL_CMD_ARG(reset_cause, &sub_reset_cause, "Reset cause commands",
192 cmd_show_reset_cause, 1, 0),
193 SHELL_SUBCMD_SET_END /* Array terminated. */
194 );
195
196 SHELL_CMD_ARG_REGISTER(hwinfo, &sub_hwinfo, "HWINFO commands", NULL, 2, 0);
197