mirror of
https://github.com/espressif/openthread.git
synced 2026-08-08 03:37:46 +00:00
[diag] add gpio mode commands (#8391)
This commit adds diag commands for setting the GPIO mode to resolve the conflict https://github.com/openthread/openthread/issues/8362.
This commit is contained in:
@@ -35,8 +35,11 @@
|
||||
|
||||
#include <openthread/config.h>
|
||||
#include <openthread/platform/alarm-milli.h>
|
||||
#include <openthread/platform/diag.h>
|
||||
#include <openthread/platform/radio.h>
|
||||
|
||||
#include "utils/code_utils.h"
|
||||
|
||||
#if OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
|
||||
/**
|
||||
@@ -45,6 +48,14 @@
|
||||
*/
|
||||
static bool sDiagMode = false;
|
||||
|
||||
enum
|
||||
{
|
||||
SIM_GPIO = 0,
|
||||
};
|
||||
|
||||
static otGpioMode sGpioMode = OT_GPIO_MODE_INPUT;
|
||||
static bool sGpioValue = false;
|
||||
|
||||
void otPlatDiagModeSet(bool aMode)
|
||||
{
|
||||
sDiagMode = aMode;
|
||||
@@ -77,4 +88,47 @@ void otPlatDiagAlarmCallback(otInstance *aInstance)
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
}
|
||||
|
||||
otError otPlatDiagGpioSet(uint32_t aGpio, bool aValue)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
otEXPECT_ACTION(aGpio == SIM_GPIO, error = OT_ERROR_INVALID_ARGS);
|
||||
sGpioValue = aValue;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otPlatDiagGpioGet(uint32_t aGpio, bool *aValue)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
otEXPECT_ACTION((aGpio == SIM_GPIO) && (aValue != NULL), error = OT_ERROR_INVALID_ARGS);
|
||||
*aValue = sGpioValue;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otPlatDiagGpioSetMode(uint32_t aGpio, otGpioMode aMode)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
otEXPECT_ACTION(aGpio == SIM_GPIO, error = OT_ERROR_INVALID_ARGS);
|
||||
sGpioMode = aMode;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otPlatDiagGpioGetMode(uint32_t aGpio, otGpioMode *aMode)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
otEXPECT_ACTION((aGpio == SIM_GPIO) && (aMode != NULL), error = OT_ERROR_INVALID_ARGS);
|
||||
*aMode = sGpioMode;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
|
||||
@@ -166,13 +166,6 @@ static otMacKeyMaterial sCurrKey;
|
||||
static otMacKeyMaterial sNextKey;
|
||||
static otRadioKeyType sKeyType;
|
||||
|
||||
enum
|
||||
{
|
||||
SIM_GPIO = 0,
|
||||
};
|
||||
|
||||
static bool sGpioValue = false;
|
||||
|
||||
static int8_t GetRssi(uint16_t aChannel);
|
||||
|
||||
#if OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
|
||||
@@ -1406,25 +1399,3 @@ void parseFromEnvAsUint16(const char *aEnvName, uint16_t *aValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
otError otPlatDiagGpioSet(uint32_t aGpio, bool aValue)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
otEXPECT_ACTION(aGpio == SIM_GPIO, error = OT_ERROR_INVALID_ARGS);
|
||||
sGpioValue = aValue;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otPlatDiagGpioGet(uint32_t aGpio, bool *aValue)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
otEXPECT_ACTION((aGpio == SIM_GPIO) && (aValue != NULL), error = OT_ERROR_INVALID_ARGS);
|
||||
*aValue = sGpioValue;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (261)
|
||||
#define OPENTHREAD_API_VERSION (262)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -56,6 +56,16 @@ extern "C" {
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This enumeration defines the gpio modes.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
OT_GPIO_MODE_INPUT = 0, ///< Input mode without pull resistor.
|
||||
OT_GPIO_MODE_OUTPUT = 1, ///< Output mode.
|
||||
} otGpioMode;
|
||||
|
||||
/**
|
||||
* This function processes a factory diagnostics command line.
|
||||
*
|
||||
@@ -155,6 +165,34 @@ otError otPlatDiagGpioSet(uint32_t aGpio, bool aValue);
|
||||
*/
|
||||
otError otPlatDiagGpioGet(uint32_t aGpio, bool *aValue);
|
||||
|
||||
/**
|
||||
* This function sets the gpio mode.
|
||||
*
|
||||
* @param[in] aGpio The gpio number.
|
||||
* @param[out] aMode The gpio mode.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the gpio mode.
|
||||
* @retval OT_ERROR_INVALID_ARGS @p aGpio is not supported.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on the platform.
|
||||
*
|
||||
*/
|
||||
otError otPlatDiagGpioSetMode(uint32_t aGpio, otGpioMode aMode);
|
||||
|
||||
/**
|
||||
* This function gets the gpio mode.
|
||||
*
|
||||
* @param[in] aGpio The gpio number.
|
||||
* @param[out] aValue A pointer where to put gpio value.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully got the gpio value.
|
||||
* @retval OT_ERROR_FAILED The gpio is neither in input nor output mode. For example, if the gpio is in
|
||||
* analog mode.
|
||||
* @retval OT_ERROR_INVALID_ARGS @p aGpio is not supported or @p aMode is NULL.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on the platform.
|
||||
*
|
||||
*/
|
||||
otError otPlatDiagGpioGetMode(uint32_t aGpio, otGpioMode *aMode);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -179,6 +179,34 @@ The parameter `value` has to be `0` or `1`.
|
||||
Done
|
||||
```
|
||||
|
||||
### diag gpio mode \<gpio\>
|
||||
|
||||
Get the gpio mode.
|
||||
|
||||
```bash
|
||||
> diag gpio mode 1
|
||||
in
|
||||
Done
|
||||
```
|
||||
|
||||
### diag gpio mode \<gpio\> in
|
||||
|
||||
Sets the given gpio to the input mode without pull resistor.
|
||||
|
||||
```bash
|
||||
> diag gpio mode 1 in
|
||||
Done
|
||||
```
|
||||
|
||||
### diag gpio mode \<gpio\> out
|
||||
|
||||
Sets the given gpio to the output mode.
|
||||
|
||||
```bash
|
||||
> diag gpio mode 1 out
|
||||
Done
|
||||
```
|
||||
|
||||
### diag stop
|
||||
|
||||
Stop diagnostics mode and print statistics.
|
||||
|
||||
@@ -545,10 +545,11 @@ exit:
|
||||
|
||||
Error Diags::ProcessGpio(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
long value;
|
||||
uint32_t gpio;
|
||||
bool level;
|
||||
Error error = kErrorInvalidArgs;
|
||||
long value;
|
||||
uint32_t gpio;
|
||||
bool level;
|
||||
otGpioMode mode;
|
||||
|
||||
if ((aArgsLength == 2) && (strcmp(aArgs[0], "get") == 0))
|
||||
{
|
||||
@@ -564,9 +565,31 @@ Error Diags::ProcessGpio(uint8_t aArgsLength, char *aArgs[], char *aOutput, size
|
||||
SuccessOrExit(error = ParseBool(aArgs[2], level));
|
||||
SuccessOrExit(error = otPlatDiagGpioSet(gpio, level));
|
||||
}
|
||||
else
|
||||
else if ((aArgsLength >= 2) && (strcmp(aArgs[0], "mode") == 0))
|
||||
{
|
||||
error = kErrorInvalidArgs;
|
||||
SuccessOrExit(error = ParseLong(aArgs[1], value));
|
||||
gpio = static_cast<uint32_t>(value);
|
||||
|
||||
if (aArgsLength == 2)
|
||||
{
|
||||
SuccessOrExit(error = otPlatDiagGpioGetMode(gpio, &mode));
|
||||
if (mode == OT_GPIO_MODE_INPUT)
|
||||
{
|
||||
snprintf(aOutput, aOutputMaxLen, "in\r\n");
|
||||
}
|
||||
else if (mode == OT_GPIO_MODE_OUTPUT)
|
||||
{
|
||||
snprintf(aOutput, aOutputMaxLen, "out\r\n");
|
||||
}
|
||||
}
|
||||
else if ((aArgsLength == 3) && (strcmp(aArgs[2], "in") == 0))
|
||||
{
|
||||
SuccessOrExit(error = otPlatDiagGpioSetMode(gpio, OT_GPIO_MODE_INPUT));
|
||||
}
|
||||
else if ((aArgsLength == 3) && (strcmp(aArgs[2], "out") == 0))
|
||||
{
|
||||
SuccessOrExit(error = otPlatDiagGpioSetMode(gpio, OT_GPIO_MODE_OUTPUT));
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -725,4 +748,20 @@ OT_TOOL_WEAK otError otPlatDiagGpioGet(uint32_t aGpio, bool *aValue)
|
||||
return OT_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatDiagGpioSetMode(uint32_t aGpio, otGpioMode aMode)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aGpio);
|
||||
OT_UNUSED_VARIABLE(aMode);
|
||||
|
||||
return OT_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatDiagGpioGetMode(uint32_t aGpio, otGpioMode *aMode)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aGpio);
|
||||
OT_UNUSED_VARIABLE(aMode);
|
||||
|
||||
return OT_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
|
||||
@@ -575,6 +575,46 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otPlatDiagGpioSetMode(uint32_t aGpio, otGpioMode aMode)
|
||||
{
|
||||
otError error;
|
||||
char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE];
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "gpio mode %d %s", aGpio, aMode == OT_GPIO_MODE_INPUT ? "in" : "out");
|
||||
SuccessOrExit(error = sRadioSpinel.PlatDiagProcess(cmd, nullptr, 0));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otPlatDiagGpioGetMode(uint32_t aGpio, otGpioMode *aMode)
|
||||
{
|
||||
otError error;
|
||||
char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE];
|
||||
char output[OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE];
|
||||
char * str;
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "gpio mode %d", aGpio);
|
||||
SuccessOrExit(error = sRadioSpinel.PlatDiagProcess(cmd, output, sizeof(output)));
|
||||
VerifyOrExit((str = strtok(output, "\r")) != nullptr, error = OT_ERROR_FAILED);
|
||||
|
||||
if (strcmp(str, "in") == 0)
|
||||
{
|
||||
*aMode = OT_GPIO_MODE_INPUT;
|
||||
}
|
||||
else if (strcmp(str, "out") == 0)
|
||||
{
|
||||
*aMode = OT_GPIO_MODE_OUTPUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = OT_ERROR_FAILED;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
@@ -161,6 +161,20 @@ send "diag gpio get 0\n"
|
||||
expect "1"
|
||||
expect_line "Done"
|
||||
|
||||
send "diag gpio mode 0 in\n"
|
||||
expect_line "Done"
|
||||
|
||||
send "diag gpio mode 0\n"
|
||||
expect "in"
|
||||
expect_line "Done"
|
||||
|
||||
send "diag gpio mode 0 out\n"
|
||||
expect_line "Done"
|
||||
|
||||
send "diag gpio mode 0\n"
|
||||
expect "out"
|
||||
expect_line "Done"
|
||||
|
||||
send "diag invalid_commad\n"
|
||||
expect "Error 35: InvalidCommand"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user