net: openthread: add gpio diag command implementation
implemented ot diag gpio get, set and mode commands Signed-off-by: Maciej Baczmanski <maciej.baczmanski@nordicsemi.no>
This commit is contained in:
parent
5ec1b4d1b2
commit
bf10d0dd16
23
dts/bindings/options/openthread,config.yaml
Normal file
23
dts/bindings/options/openthread,config.yaml
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
OpenThread configuration node.
|
||||
|
||||
Example usage:
|
||||
options {
|
||||
openthread {
|
||||
compatible = "openthread,config";
|
||||
diag-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>,
|
||||
<&gpio1 0 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
compatible: "openthread,config"
|
||||
|
||||
properties:
|
||||
diag-gpios:
|
||||
type: phandle-array
|
||||
description: |
|
||||
This enables access to diagnostic GPIO pins. Each field consists of
|
||||
GPIO pin's configuration: controller's phandle, pin number and configuration flags.
|
|
@ -5,9 +5,12 @@
|
|||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
|
||||
#include <openthread/platform/diag.h>
|
||||
|
||||
#include "platform-zephyr.h"
|
||||
#include "utils/code_utils.h"
|
||||
|
||||
/**
|
||||
* Diagnostics mode variables.
|
||||
|
@ -68,3 +71,157 @@ void otPlatDiagAlarmCallback(otInstance *aInstance)
|
|||
{
|
||||
ARG_UNUSED(aInstance);
|
||||
}
|
||||
|
||||
/*
|
||||
* To enable gpio diag commands, in Devicetree create `openthread` node in `/options/` path
|
||||
* with `compatible = "openthread,config"` property and `diag-gpios` property,
|
||||
* which should contain array of GPIO pin's configuration properties containing controller phandles,
|
||||
* pin numbers and pin flags. e.g:
|
||||
*
|
||||
* options {
|
||||
* openthread {
|
||||
* compatible = "openthread,config";
|
||||
* diag-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>,
|
||||
* <&gpio1 0 GPIO_ACTIVE_LOW>;
|
||||
* };
|
||||
* };
|
||||
*
|
||||
* To enable reading current gpio pin mode, define
|
||||
* `CONFIG_GPIO_GET_DIRECTION` in prj.conf.
|
||||
*
|
||||
* Note: `<gpio>` in `diag gpio` commands is an index of diag-gpios array. For example shown above,
|
||||
* `ot diag gpio mode 0` will return current mode of pin nmb 0 controlled by `gpio0` controller.
|
||||
*/
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(openthread_config) && \
|
||||
DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(openthread_config), diag_gpios)
|
||||
|
||||
static const struct gpio_dt_spec gpio_spec[] = {
|
||||
DT_FOREACH_PROP_ELEM_SEP(DT_COMPAT_GET_ANY_STATUS_OKAY(openthread_config),
|
||||
diag_gpios, GPIO_DT_SPEC_GET_BY_IDX, (,))};
|
||||
|
||||
static otError gpio_get_spec(uint32_t gpio_idx, const struct gpio_dt_spec **spec)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
otEXPECT_ACTION(gpio_idx < otARRAY_LENGTH(gpio_spec), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
*spec = &gpio_spec[gpio_idx];
|
||||
|
||||
otEXPECT_ACTION(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
|
||||
otEXPECT_ACTION(gpio_is_ready_dt(*spec), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
const struct gpio_driver_config *const cfg =
|
||||
(const struct gpio_driver_config *)((*spec)->port->config);
|
||||
|
||||
otEXPECT_ACTION((cfg->port_pin_mask & (gpio_port_pins_t)BIT((*spec)->pin)) != 0U,
|
||||
error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otPlatDiagGpioSet(uint32_t aGpio, bool aValue)
|
||||
{
|
||||
const struct gpio_dt_spec *spec;
|
||||
otError error;
|
||||
int rv;
|
||||
|
||||
error = gpio_get_spec(aGpio, &spec);
|
||||
|
||||
otEXPECT(error == OT_ERROR_NONE);
|
||||
|
||||
#if defined(CONFIG_GPIO_GET_DIRECTION)
|
||||
rv = gpio_pin_is_output_dt(spec);
|
||||
otEXPECT_ACTION(rv == 1, error = OT_ERROR_INVALID_STATE);
|
||||
#endif
|
||||
|
||||
rv = gpio_pin_set_dt(spec, (int)aValue);
|
||||
otEXPECT_ACTION(rv == 0, error = OT_ERROR_FAILED);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otPlatDiagGpioGet(uint32_t aGpio, bool *aValue)
|
||||
{
|
||||
const struct gpio_dt_spec *spec;
|
||||
otError error;
|
||||
int rv;
|
||||
|
||||
error = gpio_get_spec(aGpio, &spec);
|
||||
|
||||
otEXPECT(error == OT_ERROR_NONE);
|
||||
otEXPECT_ACTION(aValue != NULL, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
#if defined(CONFIG_GPIO_GET_DIRECTION)
|
||||
rv = gpio_pin_is_input_dt(spec);
|
||||
otEXPECT_ACTION(rv == 1, error = OT_ERROR_INVALID_STATE);
|
||||
#endif
|
||||
|
||||
rv = gpio_pin_get_dt(spec);
|
||||
otEXPECT_ACTION(rv >= 0, error = OT_ERROR_FAILED);
|
||||
*aValue = (bool)rv;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otPlatDiagGpioSetMode(uint32_t aGpio, otGpioMode aMode)
|
||||
{
|
||||
const struct gpio_dt_spec *spec;
|
||||
otError error;
|
||||
int rv = 0;
|
||||
|
||||
error = gpio_get_spec(aGpio, &spec);
|
||||
|
||||
otEXPECT(error == OT_ERROR_NONE);
|
||||
|
||||
switch (aMode) {
|
||||
case OT_GPIO_MODE_INPUT:
|
||||
rv = gpio_pin_configure_dt(spec, GPIO_INPUT);
|
||||
break;
|
||||
|
||||
case OT_GPIO_MODE_OUTPUT:
|
||||
rv = gpio_pin_configure_dt(spec, GPIO_OUTPUT);
|
||||
break;
|
||||
|
||||
default:
|
||||
error = OT_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
otEXPECT_ACTION(rv == 0, error = OT_ERROR_FAILED);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_GPIO_GET_DIRECTION)
|
||||
otError otPlatDiagGpioGetMode(uint32_t aGpio, otGpioMode *aMode)
|
||||
{
|
||||
const struct gpio_dt_spec *spec;
|
||||
otError error;
|
||||
gpio_port_pins_t pins_in, pins_out;
|
||||
int rv;
|
||||
|
||||
error = gpio_get_spec(aGpio, &spec);
|
||||
|
||||
otEXPECT(error == OT_ERROR_NONE);
|
||||
otEXPECT_ACTION(aMode != NULL, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
rv = gpio_port_get_direction(spec->port, BIT(spec->pin), &pins_in, &pins_out);
|
||||
otEXPECT_ACTION(rv >= 0, error = OT_ERROR_FAILED);
|
||||
|
||||
if (((gpio_port_pins_t)BIT(spec->pin) & pins_in) != 0U) {
|
||||
*aMode = OT_GPIO_MODE_INPUT;
|
||||
} else if (((gpio_port_pins_t)BIT(spec->pin) & pins_out) != 0U) {
|
||||
*aMode = OT_GPIO_MODE_OUTPUT;
|
||||
} else {
|
||||
error = OT_ERROR_FAILED;
|
||||
}
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#endif /* CONFIG_GPIO_GET_DIRECTION */
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(openthread_config) && \
|
||||
* DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(openthread_config), diag_gpios)
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue