[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:
Zhanglong Xia
2022-11-12 04:51:24 +01:00
committed by GitHub
parent caec27dcf1
commit 3e138d3f5d
8 changed files with 220 additions and 36 deletions
+54
View File
@@ -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
-29
View File
@@ -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;
}
+1 -1
View File
@@ -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
+38
View File
@@ -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);
/**
* @}
*
+28
View File
@@ -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.
+45 -6
View File
@@ -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
+40
View File
@@ -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);
+14
View File
@@ -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"