You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
4.6 KiB
224 lines
4.6 KiB
/* |
|
* Copyright (c) 2019 Alexander Wachter |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#include <zephyr/sys/printk.h> |
|
#include <zephyr/shell/shell.h> |
|
#include <zephyr/drivers/hwinfo.h> |
|
#include <zephyr/types.h> |
|
#include <zephyr/logging/log.h> |
|
|
|
static int cmd_get_device_id(const struct shell *sh, size_t argc, char **argv) |
|
{ |
|
uint8_t dev_id[16]; |
|
ssize_t length; |
|
int i; |
|
|
|
length = hwinfo_get_device_id(dev_id, sizeof(dev_id)); |
|
|
|
if (length == -ENOSYS) { |
|
shell_error(sh, "Not supported by hardware"); |
|
return -ENOSYS; |
|
} else if (length < 0) { |
|
shell_error(sh, "Error: %zd", length); |
|
return length; |
|
} |
|
|
|
shell_fprintf(sh, SHELL_NORMAL, "Length: %zd\n", length); |
|
shell_fprintf(sh, SHELL_NORMAL, "ID: 0x"); |
|
|
|
for (i = 0 ; i < length ; i++) { |
|
shell_fprintf(sh, SHELL_NORMAL, "%02x", dev_id[i]); |
|
} |
|
|
|
shell_fprintf(sh, SHELL_NORMAL, "\n"); |
|
|
|
return 0; |
|
} |
|
|
|
static int cmd_get_device_eui64(const struct shell *sh, size_t argc, char **argv) |
|
{ |
|
uint8_t dev_eui64[8]; |
|
int ret; |
|
int i; |
|
|
|
ret = hwinfo_get_device_eui64(dev_eui64); |
|
|
|
if (ret == -ENOSYS) { |
|
shell_error(sh, "Not supported by hardware"); |
|
return -ENOSYS; |
|
} else if (ret < 0) { |
|
shell_error(sh, "Error: %d", ret); |
|
return ret; |
|
} |
|
|
|
shell_fprintf(sh, SHELL_NORMAL, "EUI64: 0x"); |
|
|
|
for (i = 0 ; i < 8 ; i++) { |
|
shell_fprintf(sh, SHELL_NORMAL, "%02x", dev_eui64[i]); |
|
} |
|
|
|
shell_fprintf(sh, SHELL_NORMAL, "\n"); |
|
|
|
return 0; |
|
} |
|
|
|
static inline const char *cause_to_string(uint32_t cause) |
|
{ |
|
switch (cause) { |
|
case RESET_PIN: |
|
return "pin"; |
|
|
|
case RESET_SOFTWARE: |
|
return "software"; |
|
|
|
case RESET_BROWNOUT: |
|
return "brownout"; |
|
|
|
case RESET_POR: |
|
return "power-on reset"; |
|
|
|
case RESET_WATCHDOG: |
|
return "watchdog"; |
|
|
|
case RESET_DEBUG: |
|
return "debug"; |
|
|
|
case RESET_SECURITY: |
|
return "security"; |
|
|
|
case RESET_LOW_POWER_WAKE: |
|
return "low power wake-up"; |
|
|
|
case RESET_CPU_LOCKUP: |
|
return "CPU lockup"; |
|
|
|
case RESET_PARITY: |
|
return "parity error"; |
|
|
|
case RESET_PLL: |
|
return "PLL error"; |
|
|
|
case RESET_CLOCK: |
|
return "clock"; |
|
|
|
case RESET_HARDWARE: |
|
return "hardware"; |
|
|
|
case RESET_USER: |
|
return "user"; |
|
|
|
case RESET_TEMPERATURE: |
|
return "temperature"; |
|
|
|
default: |
|
return "unknown"; |
|
} |
|
} |
|
|
|
static void print_all_reset_causes(const struct shell *sh, uint32_t cause) |
|
{ |
|
for (uint32_t cause_mask = 1; cause_mask; cause_mask <<= 1) { |
|
if (cause & cause_mask) { |
|
shell_print(sh, "- %s", |
|
cause_to_string(cause & cause_mask)); |
|
} |
|
} |
|
} |
|
|
|
static int cmd_show_reset_cause(const struct shell *sh, size_t argc, |
|
char **argv) |
|
{ |
|
int res; |
|
uint32_t cause; |
|
|
|
ARG_UNUSED(argc); |
|
ARG_UNUSED(argv); |
|
|
|
res = hwinfo_get_reset_cause(&cause); |
|
if (res == -ENOSYS) { |
|
shell_error(sh, "Not supported by hardware"); |
|
return res; |
|
} else if (res != 0) { |
|
shell_error(sh, "Error reading the cause [%d]", res); |
|
return res; |
|
} |
|
|
|
if (cause != 0) { |
|
shell_print(sh, "reset caused by:"); |
|
print_all_reset_causes(sh, cause); |
|
} else { |
|
shell_print(sh, "No reset cause set"); |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
static int cmd_clear_reset_cause(const struct shell *sh, size_t argc, |
|
char **argv) |
|
{ |
|
int res; |
|
|
|
ARG_UNUSED(argc); |
|
ARG_UNUSED(argv); |
|
|
|
res = hwinfo_clear_reset_cause(); |
|
if (res == -ENOSYS) { |
|
shell_error(sh, "Not supported by hardware"); |
|
} else if (res != 0) { |
|
shell_error(sh, "Error clearing the reset causes [%d]", res); |
|
return res; |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
static int cmd_supported_reset_cause(const struct shell *sh, size_t argc, |
|
char **argv) |
|
{ |
|
uint32_t cause; |
|
int res; |
|
|
|
ARG_UNUSED(argc); |
|
ARG_UNUSED(argv); |
|
|
|
res = hwinfo_get_supported_reset_cause(&cause); |
|
if (res == -ENOSYS) { |
|
shell_error(sh, "Not supported by hardware"); |
|
} else if (res != 0) { |
|
shell_error(sh, "Could not get the supported reset causes [%d]", res); |
|
return res; |
|
} |
|
|
|
if (cause != 0) { |
|
shell_print(sh, "supported reset causes:"); |
|
print_all_reset_causes(sh, cause); |
|
} else { |
|
shell_print(sh, "No causes supported"); |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
SHELL_STATIC_SUBCMD_SET_CREATE(sub_reset_cause, |
|
SHELL_CMD_ARG(show, NULL, "Show persistent reset causes", |
|
cmd_show_reset_cause, 1, 0), |
|
SHELL_CMD_ARG(clear, NULL, "Clear all persistent reset causes", |
|
cmd_clear_reset_cause, 1, 0), |
|
SHELL_CMD_ARG(supported, NULL, |
|
"Get a list of all supported reset causes", |
|
cmd_supported_reset_cause, 1, 0), |
|
SHELL_SUBCMD_SET_END /* Array terminated. */ |
|
); |
|
|
|
SHELL_STATIC_SUBCMD_SET_CREATE(sub_hwinfo, |
|
SHELL_CMD_ARG(devid, NULL, "Show device id", cmd_get_device_id, 1, 0), |
|
SHELL_CMD_ARG(deveui64, NULL, "Show device eui64", cmd_get_device_eui64, 1, 0), |
|
SHELL_CMD_ARG(reset_cause, &sub_reset_cause, "Reset cause commands", |
|
cmd_show_reset_cause, 1, 0), |
|
SHELL_SUBCMD_SET_END /* Array terminated. */ |
|
); |
|
|
|
SHELL_CMD_ARG_REGISTER(hwinfo, &sub_hwinfo, "HWINFO commands", NULL, 2, 0);
|
|
|