feat(15.4): support setting 15.4 txrx pti when coex is enabled

This commit is contained in:
Xu Si Yu 2024-12-12 20:29:34 +08:00
parent 88d42e8b6a
commit bd2480ba07
17 changed files with 258 additions and 12 deletions

View File

@ -1,12 +1,11 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __COEXIST_I154_H__
#define __COEXIST_I154_H__
#ifdef CONFIG_SOC_IEEE802154_SUPPORTED
typedef enum {
IEEE802154_HIGH = 1,
IEEE802154_MIDDLE,
@ -15,11 +14,16 @@ typedef enum {
IEEE802154_EVENT_MAX,
} ieee802154_coex_event_t;
typedef struct {
ieee802154_coex_event_t idle;
ieee802154_coex_event_t txrx;
ieee802154_coex_event_t txrx_at;
} esp_ieee802154_coex_config_t;
void esp_coex_ieee802154_txrx_pti_set(ieee802154_coex_event_t event);
void esp_coex_ieee802154_ack_pti_set(ieee802154_coex_event_t event);
void esp_coex_ieee802154_coex_break_notify(void);
void esp_coex_ieee802154_extcoex_tx_stage(void);
void esp_coex_ieee802154_extcoex_rx_stage(void);
#endif
#endif

@ -1 +1 @@
Subproject commit ad30777643ca4c97fbce790f01aebd474ae4946f
Subproject commit 7b588f2dbb12ddcd46c075dcd041f4d03a59154f

View File

@ -35,5 +35,6 @@ idf_component_register(
INCLUDE_DIRS "${include}"
PRIV_INCLUDE_DIRS "${private_include}"
LDFRAGMENTS linker.lf
PRIV_REQUIRES esp_phy esp_timer esp_coex soc hal esp_pm
REQUIRES esp_coex
PRIV_REQUIRES esp_phy esp_timer soc hal esp_pm
)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,20 +22,39 @@ uint8_t ieee802154_channel_to_freq(uint8_t channel)
}
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
esp_ieee802154_coex_config_t s_coex_config = {
.idle = IEEE802154_IDLE,
.txrx = IEEE802154_LOW,
.txrx_at = IEEE802154_MIDDLE,
};
void ieee802154_set_coex_config(esp_ieee802154_coex_config_t config)
{
s_coex_config.idle = config.idle;
s_coex_config.txrx = config.txrx;
s_coex_config.txrx_at = config.txrx_at;
}
esp_ieee802154_coex_config_t ieee802154_get_coex_config(void)
{
return s_coex_config;
}
void ieee802154_set_txrx_pti(ieee802154_txrx_scene_t txrx_scene)
{
switch (txrx_scene) {
case IEEE802154_SCENE_IDLE:
esp_coex_ieee802154_txrx_pti_set(IEEE802154_IDLE);
esp_coex_ieee802154_txrx_pti_set(s_coex_config.idle);
break;
case IEEE802154_SCENE_TX:
case IEEE802154_SCENE_RX:
esp_coex_ieee802154_txrx_pti_set(IEEE802154_LOW);
esp_coex_ieee802154_txrx_pti_set(s_coex_config.txrx);
break;
case IEEE802154_SCENE_TX_AT:
case IEEE802154_SCENE_RX_AT:
esp_coex_ieee802154_txrx_pti_set(IEEE802154_MIDDLE);
esp_coex_ieee802154_txrx_pti_set(s_coex_config.txrx_at);
break;
default:
assert(false);

View File

@ -471,3 +471,15 @@ void esp_ieee802154_record_print(void)
ieee802154_record_print();
}
#endif // CONFIG_IEEE802154_RECORD
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
void esp_ieee802154_set_coex_config(esp_ieee802154_coex_config_t config)
{
ieee802154_set_coex_config(config);
}
esp_ieee802154_coex_config_t esp_ieee802154_get_coex_config(void)
{
return ieee802154_get_coex_config();
}
#endif

View File

@ -12,6 +12,10 @@
#include "esp_err.h"
#include "esp_ieee802154_types.h"
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
#include "esp_coex_i154.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -699,6 +703,27 @@ void esp_ieee802154_rx_buffer_statistic_print(void);
*/
void esp_ieee802154_record_print(void);
#endif // CONFIG_IEEE802154_RECORD
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
/**
* @brief Set the IEEE802.15.4 coexist config.
*
* @param[in] config The config of IEEE802.15.4 coexist.
*
*/
void esp_ieee802154_set_coex_config(esp_ieee802154_coex_config_t config);
/**
* @brief Get the IEEE802.15.4 coexist config.
*
* @return
* - The config of IEEE802.15.4 coexist.
*
*/
esp_ieee802154_coex_config_t esp_ieee802154_get_coex_config(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -368,6 +368,26 @@ void ieee802154_etm_set_event_task(uint32_t channel, uint32_t event, uint32_t ta
*/
void ieee802154_etm_channel_clear(uint32_t channel);
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
/**
* @brief Set the IEEE802.15.4 coexist config.
*
* @param[in] config The config of IEEE802.15.4 coexist.
*
*/
void ieee802154_set_coex_config(esp_ieee802154_coex_config_t config);
/**
* @brief Get the IEEE802.15.4 coexist config.
*
* @return
* - The config of IEEE802.15.4 coexist.
*
*/
esp_ieee802154_coex_config_t ieee802154_get_coex_config(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -274,7 +274,7 @@ idf_component_register(SRC_DIRS "${src_dirs}"
PRIV_INCLUDE_DIRS "${private_include_dirs}"
REQUIRES esp_netif lwip esp_driver_uart driver
LDFRAGMENTS linker.lf
PRIV_REQUIRES console esp_event esp_partition esp_timer
PRIV_REQUIRES console esp_coex esp_event esp_partition esp_timer
ieee802154 mbedtls nvs_flash)
if(CONFIG_OPENTHREAD_RADIO_TREL)

View File

@ -12,4 +12,6 @@
#define SPINEL_PROP_VENDOR_ESP_SET_PENDINGMODE (SPINEL_PROP_VENDOR_ESP__BEGIN + 2)
#define SPINEL_PROP_VENDOR_ESP_COEX_EVENT (SPINEL_PROP_VENDOR_ESP__BEGIN + 3)
#endif

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -12,6 +12,10 @@
#include "esp_openthread_types.h"
#include "openthread/instance.h"
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
#include "esp_coex_i154.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -53,6 +57,27 @@ void esp_openthread_radio_update(esp_openthread_mainloop_context_t *mainloop);
*/
esp_err_t esp_openthread_radio_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop);
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
/**
* @brief Set the coexist config.
*
* @param[in] config The config of coexist.
*
*/
void esp_openthread_set_coex_config(esp_ieee802154_coex_config_t config);
/**
* @brief Get the coexist config.
*
* @return
* - The config of coexist.
*
*/
esp_ieee802154_coex_config_t esp_openthread_get_coex_config(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -493,6 +493,17 @@
#ifndef OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL
#define OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL (60 * 1000 * 1000)
#endif
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
/**
* @def OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
*
* Enables compilation of vendor specific code for Spinel
*/
#ifndef OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
#define OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE 1
#endif
#endif
#endif // !CONFIG_OPENTHREAD_RADIO_NATIVE
#if CONFIG_OPENTHREAD_LINK_METRICS

View File

@ -50,11 +50,15 @@
#define OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT 3
#endif
/**
* @def OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
*
* Enables compilation of vendor specific code for Spinel
*/
#ifndef OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
#define OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE 1
#endif
/**
* @def OPENTHREAD_SPINEL_CONFIG_COMPATIBILITY_ERROR_CALLBACK_ENABLE
*

View File

@ -9,6 +9,10 @@
#include "esp_openthread_ncp.h"
#include "ncp_base.hpp"
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
#include "esp_coex_i154.h"
#endif
#if CONFIG_OPENTHREAD_RCP_UART
#include "utils/uart.h"
#endif
@ -65,6 +69,16 @@ otError NcpBase::VendorGetPropertyHandler(spinel_prop_key_t aPropKey)
switch (aPropKey)
{
case SPINEL_PROP_VENDOR_ESP_COEX_EVENT: {
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
esp_ieee802154_coex_config_t config = esp_ieee802154_get_coex_config();
const uint8_t *args = reinterpret_cast<const uint8_t *>(&config);
error = mEncoder.WriteDataWithLen(args, sizeof(esp_ieee802154_coex_config_t));
#else
error = OT_ERROR_NOT_IMPLEMENTED;
#endif
break;
}
default:
error = OT_ERROR_NOT_FOUND;
@ -95,6 +109,23 @@ otError NcpBase::VendorSetPropertyHandler(spinel_prop_key_t aPropKey)
esp_ieee802154_set_pending_mode(static_cast<esp_ieee802154_pending_mode_t>(pending_mode));
break;
}
case SPINEL_PROP_VENDOR_ESP_COEX_EVENT: {
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
const uint8_t *args = nullptr;
uint16_t len = 0;
mDecoder.ReadDataWithLen(args, len);
if (len == sizeof(esp_ieee802154_coex_config_t)) {
esp_ieee802154_coex_config_t config;
memcpy(&config, args, len);
esp_ieee802154_set_coex_config(config);
} else {
error = OT_ERROR_INVALID_ARGS;
}
#else
error = OT_ERROR_NOT_IMPLEMENTED;
#endif
break;
}
default:
error = OT_ERROR_NOT_FOUND;

View File

@ -32,6 +32,10 @@
#include "utils/link_metrics.h"
#include "utils/mac_frame.h"
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
#include "esp_coex_i154.h"
#endif
#define ESP_RECEIVE_SENSITIVITY -120
#define ESP_OPENTHREAD_XTAL_ACCURACY CONFIG_OPENTHREAD_XTAL_ACCURACY
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
@ -810,3 +814,15 @@ uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance)
OT_UNUSED_VARIABLE(aInstance);
return CONFIG_OPENTHREAD_SUPPORTED_CHANNEL_MASK;
}
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
void esp_openthread_set_coex_config(esp_ieee802154_coex_config_t config)
{
esp_ieee802154_set_coex_config(config);
}
esp_ieee802154_coex_config_t esp_openthread_get_coex_config(void)
{
return esp_ieee802154_get_coex_config();
}
#endif

View File

@ -56,6 +56,35 @@ static const esp_openthread_radio_config_t *s_esp_openthread_radio_config = NULL
static esp_openthread_compatibility_error_callback s_compatibility_error_callback = NULL;
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
#define SPINEL_PROP_VENDOR_ESP_COEX_EVENT (SPINEL_PROP_VENDOR_ESP__BEGIN + 3)
static esp_ieee802154_coex_config_t s_coex_config = {
.idle = IEEE802154_IDLE,
.txrx = IEEE802154_LOW,
.txrx_at = IEEE802154_MIDDLE,
};
static void esp_openthread_restore_coex_config(void *context)
{
esp_openthread_set_coex_config(s_coex_config);
}
static esp_err_t esp_openthread_radio_spinel_coex_config_init(void)
{
s_radio.SetVendorRestorePropertiesCallback(esp_openthread_restore_coex_config, esp_openthread_get_instance());
esp_ieee802154_coex_config_t coex_config;
uint16_t coex_config_len = 0;
ESP_RETURN_ON_ERROR(s_radio.Get(SPINEL_PROP_VENDOR_ESP_COEX_EVENT, SPINEL_DATATYPE_DATA_WLEN_S, &coex_config, &coex_config_len),
OT_PLAT_LOG_TAG, "Fail to get coex config");
ESP_RETURN_ON_FALSE(coex_config_len == sizeof(esp_ieee802154_coex_config_t), ESP_FAIL, OT_PLAT_LOG_TAG,
"Fail to get coex config");
s_coex_config = coex_config;
return ESP_OK;
}
#endif
static void esp_openthread_radio_config_set(const esp_openthread_radio_config_t *config)
{
s_esp_openthread_radio_config = config;
@ -109,6 +138,9 @@ esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *conf
s_spinel_driver.Init(s_spinel_interface.GetSpinelInterface(), true, iidList, ot::Spinel::kSpinelHeaderMaxNumIid);
s_radio.SetCompatibilityErrorCallback(ot_spinel_compatibility_error_callback, esp_openthread_get_instance());
s_radio.Init(/*skip_rcp_compatibility_check=*/false, /*reset_radio=*/true, &s_spinel_driver, s_radio_caps, /*RCP_time_sync=*/true);
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
ESP_RETURN_ON_ERROR(esp_openthread_radio_spinel_coex_config_init(), OT_PLAT_LOG_TAG, "Coex config init failed");
#endif
#if CONFIG_OPENTHREAD_RADIO_SPINEL_SPI // CONFIG_OPENTHREAD_RADIO_SPINEL_SPI
ESP_RETURN_ON_ERROR(s_spinel_interface.GetSpinelInterface().AfterRadioInit(), OT_PLAT_LOG_TAG, "Spinel interface init failed");
#endif
@ -483,3 +515,39 @@ uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance)
// Refer to `GetRadioChannelMask(bool aPreferred)`: FALSE to get supported channel mask
return s_radio.GetRadioChannelMask(false);
}
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
void esp_openthread_set_coex_config(esp_ieee802154_coex_config_t config)
{
otError err = s_radio.Set(SPINEL_PROP_VENDOR_ESP_COEX_EVENT, SPINEL_DATATYPE_DATA_WLEN_S, &s_coex_config, sizeof(esp_ieee802154_coex_config_t));
ESP_RETURN_ON_FALSE(err == OT_ERROR_NONE, , OT_PLAT_LOG_TAG, "Fail to set coex config");
s_coex_config = config;
}
esp_ieee802154_coex_config_t esp_openthread_get_coex_config(void)
{
return s_coex_config;
}
namespace ot {
namespace Spinel {
otError RadioSpinel::VendorHandleValueIs(spinel_prop_key_t aPropKey)
{
otError error = OT_ERROR_NONE;
switch (aPropKey)
{
default:
ESP_LOGW(OT_PLAT_LOG_TAG, "Not Implemented!");
error = OT_ERROR_NOT_FOUND;
break;
}
return error;
}
} // namespace Spinel
} // namespace ot
#endif

View File

@ -12,6 +12,7 @@
#include <esp_log.h>
#include <esp_openthread_dns64.h>
#include <esp_openthread_netif_glue_priv.h>
#include <esp_openthread_radio.h>
#include <esp_openthread_state.h>
#include <openthread/thread.h>
@ -62,6 +63,12 @@ static void handle_ot_netdata_change(void)
static void handle_ot_role_change(otInstance* instance)
{
#if !CONFIG_IEEE802154_TEST && (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE)
otLinkModeConfig linkmode = otThreadGetLinkMode(instance);
esp_ieee802154_coex_config_t config = esp_openthread_get_coex_config();
config.txrx = (linkmode.mRxOnWhenIdle) ? IEEE802154_LOW : IEEE802154_MIDDLE;
esp_openthread_set_coex_config(config);
#endif
static otDeviceRole s_previous_role = OT_DEVICE_ROLE_DISABLED;
otDeviceRole role = otThreadGetDeviceRole(instance);
esp_err_t ret = ESP_OK;

View File

@ -0,0 +1 @@
CONFIG_EXTERNAL_COEX_ENABLE=y