samples: shields: npm6001_ek: add utility to test regulators
Add a utility sub-shell to test all regulators embedded in the nPM6001 PMIC. Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
parent
5f8d59d69f
commit
460f2d04fa
2 changed files with 317 additions and 0 deletions
|
@ -10,6 +10,7 @@ This sample is provided as an example to test the :ref:`npm6001_ek`. The sample
|
||||||
provides a shell interface that allows to test multiple functionalities offered
|
provides a shell interface that allows to test multiple functionalities offered
|
||||||
by the nPM6001 PMIC, including:
|
by the nPM6001 PMIC, including:
|
||||||
|
|
||||||
|
- Regulators (BUCK0/1/2/3 and LDO0/1)
|
||||||
- GPIO
|
- GPIO
|
||||||
- Watchdog
|
- Watchdog
|
||||||
|
|
||||||
|
@ -41,6 +42,68 @@ Note that this sample automatically sets ``SHIELD`` to ``npm6001_ek``. Once
|
||||||
flashed, you should boot into the shell interface. The ``npm6001`` command is
|
flashed, you should boot into the shell interface. The ``npm6001`` command is
|
||||||
provided to test the PMIC. Below you can find details for each subcommand.
|
provided to test the PMIC. Below you can find details for each subcommand.
|
||||||
|
|
||||||
|
Regulators
|
||||||
|
==========
|
||||||
|
|
||||||
|
The ``npm6001`` shell interface provides the ``regulator`` subcommand to test
|
||||||
|
the regulators embedded in the PMIC (BUCK0/1/2/3 and LDO0/1). Below you can
|
||||||
|
find some command examples.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# list all the available regulators
|
||||||
|
npm6001 regulator list
|
||||||
|
BUCK0
|
||||||
|
BUCK1
|
||||||
|
BUCK2
|
||||||
|
BUCK3
|
||||||
|
LDO0
|
||||||
|
LDO1
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# list all the supported voltages by BUCK2
|
||||||
|
npm6001 regulator voltages BUCK2
|
||||||
|
1200 mV
|
||||||
|
1250 mV
|
||||||
|
1300 mV
|
||||||
|
1350 mV
|
||||||
|
1400 mV
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# enable BUCK3
|
||||||
|
npm6001 regulator enable BUCK3
|
||||||
|
# disable BUCK3
|
||||||
|
npm6001 regulator disable BUCK3
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# set BUCK3 voltage to exactly 3000 mV
|
||||||
|
npm6001 regulator set BUCK3 3000
|
||||||
|
# obtain the actual BUCK3 configured voltage
|
||||||
|
npm6001 regulator get BUCK3
|
||||||
|
3000 mV
|
||||||
|
# set BUCK0 voltage to a value between 2350 mV and 2450 mV
|
||||||
|
npm6001 regulator set BUCK0 2350 2450
|
||||||
|
# obtain the actual BUCK0 configured voltage
|
||||||
|
npm6001 regulator get BUCK3
|
||||||
|
2400 mV
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# set BUCK0 to hysteretic mode
|
||||||
|
npm6001 regulator modeset BUCK0 hys
|
||||||
|
# set BUCK0 to PWM mode
|
||||||
|
npm6001 regulator modeset BUCK0 pwm
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# get active errors on BUCK0
|
||||||
|
npm6001 regulator errors BUCK0
|
||||||
|
Overcurrent: [ ]
|
||||||
|
Overtemp.: [ ]
|
||||||
|
|
||||||
GPIO
|
GPIO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
|
|
@ -7,16 +7,42 @@
|
||||||
|
|
||||||
#include <zephyr/device.h>
|
#include <zephyr/device.h>
|
||||||
#include <zephyr/drivers/gpio.h>
|
#include <zephyr/drivers/gpio.h>
|
||||||
|
#include <zephyr/drivers/regulator.h>
|
||||||
#include <zephyr/drivers/watchdog.h>
|
#include <zephyr/drivers/watchdog.h>
|
||||||
#include <zephyr/dt-bindings/gpio/nordic-npm6001-gpio.h>
|
#include <zephyr/dt-bindings/gpio/nordic-npm6001-gpio.h>
|
||||||
|
#include <zephyr/dt-bindings/regulator/npm6001.h>
|
||||||
#include <zephyr/posix/unistd.h>
|
#include <zephyr/posix/unistd.h>
|
||||||
#include <zephyr/shell/shell.h>
|
#include <zephyr/shell/shell.h>
|
||||||
#include <zephyr/sys/printk.h>
|
#include <zephyr/sys/printk.h>
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
|
||||||
|
struct regulators_map {
|
||||||
|
const char *name;
|
||||||
|
const struct device *dev;
|
||||||
|
};
|
||||||
|
|
||||||
static const struct device *const gpio = DEVICE_DT_GET_ONE(nordic_npm6001_gpio);
|
static const struct device *const gpio = DEVICE_DT_GET_ONE(nordic_npm6001_gpio);
|
||||||
static const struct device *const wdt = DEVICE_DT_GET_ONE(nordic_npm6001_wdt);
|
static const struct device *const wdt = DEVICE_DT_GET_ONE(nordic_npm6001_wdt);
|
||||||
|
static const struct regulators_map regulators[] = {
|
||||||
|
{ "BUCK0", DEVICE_DT_GET_OR_NULL(DT_NODELABEL(npm6001_ek_buck0)) },
|
||||||
|
{ "BUCK1", DEVICE_DT_GET_OR_NULL(DT_NODELABEL(npm6001_ek_buck1)) },
|
||||||
|
{ "BUCK2", DEVICE_DT_GET_OR_NULL(DT_NODELABEL(npm6001_ek_buck2)) },
|
||||||
|
{ "BUCK3", DEVICE_DT_GET_OR_NULL(DT_NODELABEL(npm6001_ek_buck3)) },
|
||||||
|
{ "LDO0", DEVICE_DT_GET_OR_NULL(DT_NODELABEL(npm6001_ek_ldo0)) },
|
||||||
|
{ "LDO1", DEVICE_DT_GET_OR_NULL(DT_NODELABEL(npm6001_ek_ldo1)) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct device *name2reg(const char *name)
|
||||||
|
{
|
||||||
|
for (size_t i = 0U; i < ARRAY_SIZE(regulators); i++) {
|
||||||
|
if (strcmp(name, regulators[i].name) == 0) {
|
||||||
|
return regulators[i].dev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
|
@ -29,6 +55,213 @@ void main(void)
|
||||||
printk("nPM6001 Watchdog device not ready\n");
|
printk("nPM6001 Watchdog device not ready\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0U; i < ARRAY_SIZE(regulators); i++) {
|
||||||
|
if ((regulators[i].dev != NULL) &&
|
||||||
|
!device_is_ready(regulators[i].dev)) {
|
||||||
|
printk("nPM6001 %s regulator device not ready\n",
|
||||||
|
regulators[i].name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_regulator_list(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(argc);
|
||||||
|
ARG_UNUSED(argv);
|
||||||
|
|
||||||
|
for (size_t i = 0U; i < ARRAY_SIZE(regulators); i++) {
|
||||||
|
if (regulators[i].dev != NULL) {
|
||||||
|
shell_print(sh, "%s", regulators[i].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_regulator_voltages(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
unsigned int volt_cnt;
|
||||||
|
|
||||||
|
ARG_UNUSED(argc);
|
||||||
|
|
||||||
|
dev = name2reg(argv[1]);
|
||||||
|
if (dev == NULL) {
|
||||||
|
shell_error(sh, "Invalid regulator: %s", argv[1]);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
volt_cnt = regulator_count_voltages(dev);
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < volt_cnt; i++) {
|
||||||
|
int32_t volt_uv;
|
||||||
|
|
||||||
|
(void)regulator_list_voltage(dev, i, &volt_uv);
|
||||||
|
shell_print(sh, "%d mV", volt_uv / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_regulator_enable(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ARG_UNUSED(argc);
|
||||||
|
|
||||||
|
dev = name2reg(argv[1]);
|
||||||
|
if (dev == NULL) {
|
||||||
|
shell_error(sh, "Invalid regulator: %s", argv[1]);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regulator_enable(dev);
|
||||||
|
if (ret < 0) {
|
||||||
|
shell_error(sh, "Could not enable regulator (%d)", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_regulator_disable(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ARG_UNUSED(argc);
|
||||||
|
|
||||||
|
dev = name2reg(argv[1]);
|
||||||
|
if (dev == NULL) {
|
||||||
|
shell_error(sh, "Invalid regulator: %s", argv[1]);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regulator_disable(dev);
|
||||||
|
if (ret < 0) {
|
||||||
|
shell_error(sh, "Could not disable regulator (%d)", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_regulator_set(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
int32_t min_uv, max_uv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
dev = name2reg(argv[1]);
|
||||||
|
if (dev == NULL) {
|
||||||
|
shell_error(sh, "Invalid regulator: %s", argv[1]);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
min_uv = (int32_t)strtoul(argv[2], NULL, 10) * 1000;
|
||||||
|
if (argc == 4) {
|
||||||
|
max_uv = (int32_t)strtoul(argv[3], NULL, 10) * 1000;
|
||||||
|
} else {
|
||||||
|
max_uv = min_uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regulator_set_voltage(dev, min_uv, max_uv);
|
||||||
|
if (ret < 0) {
|
||||||
|
shell_error(sh, "Could not set voltage (%d)", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_regulator_get(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
int32_t volt_uv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ARG_UNUSED(argc);
|
||||||
|
|
||||||
|
dev = name2reg(argv[1]);
|
||||||
|
if (dev == NULL) {
|
||||||
|
shell_error(sh, "Invalid regulator: %s", argv[1]);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
volt_uv = (int32_t)strtoul(argv[1], NULL, 10) * 1000;
|
||||||
|
|
||||||
|
ret = regulator_get_voltage(dev, &volt_uv);
|
||||||
|
if (ret < 0) {
|
||||||
|
shell_error(sh, "Could not get voltage (%d)", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
shell_print(sh, "%d mV", volt_uv / 1000);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_regulator_modeset(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
regulator_mode_t mode;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ARG_UNUSED(argc);
|
||||||
|
|
||||||
|
dev = name2reg(argv[1]);
|
||||||
|
if (dev == NULL) {
|
||||||
|
shell_error(sh, "Invalid regulator: %s", argv[1]);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[2], "pwm") == 0) {
|
||||||
|
mode = NPM6001_MODE_PWM;
|
||||||
|
} else if (strcmp(argv[2], "hys") == 0) {
|
||||||
|
mode = NPM6001_MODE_HYS;
|
||||||
|
} else {
|
||||||
|
shell_error(sh, "Invalid mode: %s", argv[1]);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regulator_set_mode(dev, mode);
|
||||||
|
if (ret < 0) {
|
||||||
|
shell_error(sh, "Could not set mode (%d)", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_regulator_errors(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
regulator_error_flags_t errors;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ARG_UNUSED(argc);
|
||||||
|
|
||||||
|
dev = name2reg(argv[1]);
|
||||||
|
if (dev == NULL) {
|
||||||
|
shell_error(sh, "Invalid regulator: %s", argv[1]);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regulator_get_error_flags(dev, &errors);
|
||||||
|
if (ret < 0) {
|
||||||
|
shell_error(sh, "Could not get error flags (%d)", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
shell_print(sh, "Overcurrent:\t[%s]",
|
||||||
|
((errors & REGULATOR_ERROR_OVER_CURRENT) != 0U) ? "X" : " ");
|
||||||
|
shell_print(sh, "Overtemp.:\t[%s]",
|
||||||
|
((errors & REGULATOR_ERROR_OVER_TEMP) != 0U) ? "X" : " ");
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_gpio_configure(const struct shell *sh, size_t argc, char **argv)
|
static int cmd_gpio_configure(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
@ -190,6 +423,25 @@ static int cmd_wdt_kick(const struct shell *sh, size_t argc, char **argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHELL_STATIC_SUBCMD_SET_CREATE(sub_npm6001_regulator_cmds,
|
||||||
|
SHELL_CMD(list, NULL, "List regulator names",
|
||||||
|
cmd_regulator_list),
|
||||||
|
SHELL_CMD_ARG(voltages, NULL, "List voltages",
|
||||||
|
cmd_regulator_voltages, 2, 0),
|
||||||
|
SHELL_CMD_ARG(enable, NULL, "Enable regulator",
|
||||||
|
cmd_regulator_enable, 2, 0),
|
||||||
|
SHELL_CMD_ARG(disable, NULL, "Disable regulator",
|
||||||
|
cmd_regulator_disable, 2, 0),
|
||||||
|
SHELL_CMD_ARG(set, NULL, "Set voltage",
|
||||||
|
cmd_regulator_set, 3, 1),
|
||||||
|
SHELL_CMD_ARG(get, NULL, "Get voltage",
|
||||||
|
cmd_regulator_get, 2, 0),
|
||||||
|
SHELL_CMD_ARG(modeset, NULL, "Set mode PWM/HYS",
|
||||||
|
cmd_regulator_modeset, 3, 0),
|
||||||
|
SHELL_CMD_ARG(errors, NULL, "Get active errors",
|
||||||
|
cmd_regulator_errors, 2, 0),
|
||||||
|
SHELL_SUBCMD_SET_END);
|
||||||
|
|
||||||
SHELL_STATIC_SUBCMD_SET_CREATE(sub_npm6001_gpio_cmds,
|
SHELL_STATIC_SUBCMD_SET_CREATE(sub_npm6001_gpio_cmds,
|
||||||
SHELL_CMD_ARG(configure, NULL, "Configure GPIO",
|
SHELL_CMD_ARG(configure, NULL, "Configure GPIO",
|
||||||
cmd_gpio_configure, 5, 3),
|
cmd_gpio_configure, 5, 3),
|
||||||
|
@ -211,6 +463,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_npm6001_wdt_cmds,
|
||||||
SHELL_SUBCMD_SET_END);
|
SHELL_SUBCMD_SET_END);
|
||||||
|
|
||||||
SHELL_STATIC_SUBCMD_SET_CREATE(sub_npm6001_cmds,
|
SHELL_STATIC_SUBCMD_SET_CREATE(sub_npm6001_cmds,
|
||||||
|
SHELL_CMD(regulator, &sub_npm6001_regulator_cmds,
|
||||||
|
"Regulators", NULL),
|
||||||
SHELL_CMD(gpio, &sub_npm6001_gpio_cmds, "GPIO",
|
SHELL_CMD(gpio, &sub_npm6001_gpio_cmds, "GPIO",
|
||||||
NULL),
|
NULL),
|
||||||
SHELL_CMD(wdt, &sub_npm6001_wdt_cmds, "Watchdog",
|
SHELL_CMD(wdt, &sub_npm6001_wdt_cmds, "Watchdog",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue