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
|
||||
by the nPM6001 PMIC, including:
|
||||
|
||||
- Regulators (BUCK0/1/2/3 and LDO0/1)
|
||||
- GPIO
|
||||
- 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
|
||||
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
|
||||
====
|
||||
|
||||
|
|
|
@ -7,16 +7,42 @@
|
|||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/regulator.h>
|
||||
#include <zephyr/drivers/watchdog.h>
|
||||
#include <zephyr/dt-bindings/gpio/nordic-npm6001-gpio.h>
|
||||
#include <zephyr/dt-bindings/regulator/npm6001.h>
|
||||
#include <zephyr/posix/unistd.h>
|
||||
#include <zephyr/shell/shell.h>
|
||||
#include <zephyr/sys/printk.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 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)
|
||||
{
|
||||
|
@ -29,6 +55,213 @@ void main(void)
|
|||
printk("nPM6001 Watchdog device not ready\n");
|
||||
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)
|
||||
|
@ -190,6 +423,25 @@ static int cmd_wdt_kick(const struct shell *sh, size_t argc, char **argv)
|
|||
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_CMD_ARG(configure, NULL, "Configure GPIO",
|
||||
cmd_gpio_configure, 5, 3),
|
||||
|
@ -211,6 +463,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_npm6001_wdt_cmds,
|
|||
SHELL_SUBCMD_SET_END);
|
||||
|
||||
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",
|
||||
NULL),
|
||||
SHELL_CMD(wdt, &sub_npm6001_wdt_cmds, "Watchdog",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue