From f32e68651133960f257f7505ac7fac7f46986252 Mon Sep 17 00:00:00 2001 From: Maciej Baczmanski Date: Wed, 10 Jan 2024 13:03:21 +0100 Subject: [PATCH] net: openthread: implement `otPlatResetToBootloader` This commit implements `otPlatResetToBootloader` in two ways: - trigger reset to bootloader using boot mode retention API - trigger reset to bootloader by triggering GPIO pin (applicable for nRF52840 Dongle) Signed-off-by: Maciej Baczmanski --- dts/bindings/options/openthread,config.yaml | 7 +++ modules/openthread/CMakeLists.txt | 1 + modules/openthread/Kconfig.features | 23 ++++++- modules/openthread/platform/misc.c | 66 +++++++++++++++++++++ 4 files changed, 95 insertions(+), 2 deletions(-) diff --git a/dts/bindings/options/openthread,config.yaml b/dts/bindings/options/openthread,config.yaml index 054107fab4..6366c289c8 100644 --- a/dts/bindings/options/openthread,config.yaml +++ b/dts/bindings/options/openthread,config.yaml @@ -10,6 +10,7 @@ description: | compatible = "openthread,config"; diag-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>, <&gpio1 0 GPIO_ACTIVE_LOW>; + bootloader-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; }; }; @@ -21,3 +22,9 @@ properties: description: | This enables access to diagnostic GPIO pins. Each field consists of GPIO pin's configuration: controller's phandle, pin number and configuration flags. + + bootloader-gpios: + type: phandle-array + description: | + This enables resetting to bootloader by triggering given GPIO pin. Property represents + chosen GPIO pin's configuration: controller's phandle, pin number and configuration flags. diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index c9ccf07464..5b64d3be2f 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -99,6 +99,7 @@ kconfig_to_ot_option(CONFIG_OPENTHREAD_NETDATA_PUBLISHER OT_NETDATA_PUBLISHER "E kconfig_to_ot_option(CONFIG_OPENTHREAD_OPERATIONAL_DATASET_AUTO_INIT OT_OPERATIONAL_DATASET_AUTO_INIT "Enable operational dataset auto init") kconfig_to_ot_option(CONFIG_OPENTHREAD_OTNS OT_OTNS "Enable OTNS support") kconfig_to_ot_option(CONFIG_OPENTHREAD_PING_SENDER OT_PING_SENDER "Enable ping sender support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE OT_PLATFORM_BOOTLOADER_MODE "Enable platform bootloader mode support") kconfig_to_ot_option(CONFIG_OPENTHREAD_PLATFORM_KEY_REF OT_PLATFORM_KEY_REF "Enable platform key reference support") kconfig_to_ot_option(CONFIG_OPENTHREAD_PLATFORM_NETIF OT_PLATFORM_NETIF "Enable platform netif support") kconfig_to_ot_option(CONFIG_OPENTHREAD_PLATFORM_UDP OT_PLATFORM_UDP "Enable platform UDP support") diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index 952a7853b4..ba3990a348 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -17,7 +17,7 @@ config OPENTHREAD_THREAD_VERSION_1_3 bool "Version 1.3" config OPENTHREAD_THREAD_VERSION_1_3_1 bool "Version 1.3.1" -endchoice +endchoice # OPENTHREAD_STACK_VERSION config OPENTHREAD_THREAD_VERSION string @@ -255,6 +255,25 @@ config OPENTHREAD_PLATFORM_KEY_REF Enable usage of cryptographic key references instead of literal keys. This requires a crypto backend library that supports key references. +choice OPENTHREAD_PLATFORM_BOOTLOADER_MODE_CHOICE + prompt "Platform bootloader mode configuration" + optional + +config OPENTHREAD_PLATFORM_BOOTLOADER_MODE_RETENTION + bool "Bootloader mode support with boot mode retention API" + depends on RETENTION_BOOT_MODE && REBOOT + select OPENTHREAD_PLATFORM_BOOTLOADER_MODE + +config OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO + bool "Bootloader mode support with GPIO pin trigger" + select OPENTHREAD_PLATFORM_BOOTLOADER_MODE +endchoice # OPENTHREAD_PLATFORM_BOOTLOADER_MODE + +config OPENTHREAD_PLATFORM_BOOTLOADER_MODE + bool + help + Platform bootloader mode support + config OPENTHREAD_PLATFORM_NETIF bool "Platform netif support" @@ -276,7 +295,7 @@ config OPENTHREAD_POWER_SUPPLY_EXTERNAL_STABLE config OPENTHREAD_POWER_SUPPLY_EXTERNAL_UNSTABLE bool "OT_POWER_SUPPLY_EXTERNAL_UNSTABLE" -endchoice +endchoice # OPENTHREAD_POWER_SUPPLY_CHOICE config OPENTHREAD_POWER_SUPPLY string diff --git a/modules/openthread/platform/misc.c b/modules/openthread/platform/misc.c index 7f57dddb9e..11fdc42ec3 100644 --- a/modules/openthread/platform/misc.c +++ b/modules/openthread/platform/misc.c @@ -9,6 +9,24 @@ #include #include +#if defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_RETENTION) + +#include + +#elif defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO) + +BUILD_ASSERT(DT_HAS_COMPAT_STATUS_OKAY(openthread_config), + "`openthread,config` compatible node not found"); +BUILD_ASSERT(DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(openthread_config), bootloader_gpios), + "`bootloader-gpios` property missing from `openthread,config` compatible node"); + +#include + +static const struct gpio_dt_spec bootloader_gpio = + GPIO_DT_SPEC_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(openthread_config), + bootloader_gpios); +#endif + #include "platform-zephyr.h" void otPlatReset(otInstance *aInstance) @@ -19,6 +37,54 @@ void otPlatReset(otInstance *aInstance) sys_reboot(SYS_REBOOT_WARM); } +#if defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE) +otError otPlatResetToBootloader(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + +#if defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_RETENTION) + if (bootmode_set(BOOT_MODE_TYPE_BOOTLOADER)) { + return OT_ERROR_NOT_CAPABLE; + } + sys_reboot(SYS_REBOOT_WARM); + +#elif defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO) + /* + * To enable resetting to bootloader by triggering gpio pin, + * select `CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO=y`, + * and in Devicetree create `openthread` node in `/options/` path with + * `compatible = "openthread,config"` property and `bootloader-gpios` property, + * which should represent GPIO pin's configuration, + * containing controller phandle, pin number and pin flags. e.g: + * + * options { + * openthread { + * compatible = "openthread,config"; + * bootloader-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + * }; + * }; + * + * Note: in below implementation, chosen GPIO pin is configured as output + * and initialized to active state (logical value ‘1’). + * Configuring pin flags in `bootloader-gpios` allows to choose + * if pin should be active in high or in low state. + */ + + if (!gpio_is_ready_dt(&bootloader_gpio)) { + return OT_ERROR_NOT_CAPABLE; + } + gpio_pin_configure_dt(&bootloader_gpio, GPIO_OUTPUT_ACTIVE); + +#endif + + /* + * Return OT_ERROR_NOT_CAPABLE if resetting has been unsuccessful (invalid configuration or + * triggering reset had no effect) + */ + return OT_ERROR_NOT_CAPABLE; +} +#endif /* defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE) */ + otPlatResetReason otPlatGetResetReason(otInstance *aInstance) { ARG_UNUSED(aInstance);