From 469b5c14e4f3a3df80d928b8f6175749691785e7 Mon Sep 17 00:00:00 2001 From: Tan Yan Quan Date: Wed, 25 Dec 2024 21:05:08 +0800 Subject: [PATCH 1/5] fix(openthread): turn off rx for SSED running CSL during idle --- .../ieee802154/driver/esp_ieee802154_dev.c | 75 ++++++++++-------- .../ieee802154/driver/esp_ieee802154_timer.c | 71 ++++++++++++++++- .../ieee802154/driver/esp_ieee802154_util.c | 2 +- components/ieee802154/esp_ieee802154.c | 25 ++---- .../ieee802154/include/esp_ieee802154.h | 16 ++-- components/ieee802154/linker.lf | 77 ++++++++++--------- .../private_include/esp_ieee802154_dev.h | 9 +-- .../private_include/esp_ieee802154_timer.h | 40 +++++++++- components/openthread/Kconfig | 8 +- .../openthread-core-esp32x-ftd-config.h | 14 +++- .../openthread-core-esp32x-mtd-config.h | 49 ++++++++++++ .../src/port/esp_openthread_radio.c | 18 ++++- 12 files changed, 300 insertions(+), 104 deletions(-) diff --git a/components/ieee802154/driver/esp_ieee802154_dev.c b/components/ieee802154/driver/esp_ieee802154_dev.c index b252457ca7..79fbaa8013 100644 --- a/components/ieee802154/driver/esp_ieee802154_dev.c +++ b/components/ieee802154/driver/esp_ieee802154_dev.c @@ -131,12 +131,24 @@ static IRAM_ATTR void event_end_process(void) ieee802154_etm_channel_clear(IEEE802154_ETM_CHANNEL1); ieee802154_ll_set_transmit_security(false); ieee802154_timer0_stop(); + ieee802154_timer1_stop(); } #if !CONFIG_IEEE802154_TEST +IEEE802154_NOINLINE static void ieee802154_rx_ack_timeout_callback(void* s_tx_frame) +{ + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK); + + ieee802154_inner_transmit_failed((uint8_t*)s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK); + NEEDS_NEXT_OPT(true); +} + static IRAM_ATTR void receive_ack_timeout_timer_start(uint32_t duration) { ieee802154_ll_enable_events(IEEE802154_EVENT_TIMER0_OVERFLOW); + + uint32_t current_time = (uint32_t)esp_timer_get_time(); + ieee802154_timer0_fire_at_with_callback(current_time + duration, ieee802154_rx_ack_timeout_callback, (void*)s_tx_frame); ieee802154_timer0_set_threshold(duration); ieee802154_timer0_start(); } @@ -396,22 +408,16 @@ static IRAM_ATTR void next_operation(void) static void isr_handle_timer0_done(void) { -#if !CONFIG_IEEE802154_TEST - if (s_ieee802154_state == IEEE802154_STATE_RX_ACK) { - ieee802154_inner_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK); - NEEDS_NEXT_OPT(true); - } -#else + ieee802154_timer0_execute_callback(); +#if CONFIG_IEEE802154_TEST + extern void esp_ieee802154_timer0_done(void); esp_ieee802154_timer0_done(); #endif } static void isr_handle_timer1_done(void) { - // timer 1 is now unused. -#if CONFIG_IEEE802154_TEST - esp_ieee802154_timer1_done(); -#endif + ieee802154_timer1_execute_callback(); } static IRAM_ATTR void isr_handle_tx_done(void) @@ -501,7 +507,8 @@ static IRAM_ATTR void isr_handle_rx_phase_rx_abort(ieee802154_ll_rx_abort_reason case IEEE802154_RX_ABORT_BY_TX_ACK_STOP: case IEEE802154_RX_ABORT_BY_ED_STOP: // do nothing - break; + NEEDS_NEXT_OPT(false); + return; case IEEE802154_RX_ABORT_BY_SFD_TIMEOUT: case IEEE802154_RX_ABORT_BY_CRC_ERROR: case IEEE802154_RX_ABORT_BY_INVALID_LEN: @@ -540,6 +547,8 @@ static IRAM_ATTR void isr_handle_tx_ack_phase_rx_abort(ieee802154_ll_rx_abort_re case IEEE802154_RX_ABORT_BY_RX_STOP: case IEEE802154_RX_ABORT_BY_TX_ACK_STOP: case IEEE802154_RX_ABORT_BY_ED_STOP: + NEEDS_NEXT_OPT(false); + return; case IEEE802154_RX_ABORT_BY_SFD_TIMEOUT: case IEEE802154_RX_ABORT_BY_CRC_ERROR: case IEEE802154_RX_ABORT_BY_INVALID_LEN: @@ -789,7 +798,7 @@ esp_err_t ieee802154_mac_init(void) ieee802154_ll_enable_events(IEEE802154_EVENT_MASK); #if !CONFIG_IEEE802154_TEST - ieee802154_ll_disable_events((IEEE802154_EVENT_TIMER0_OVERFLOW) | (IEEE802154_EVENT_TIMER1_OVERFLOW)); + ieee802154_ll_disable_events(IEEE802154_EVENT_TIMER0_OVERFLOW); #endif ieee802154_ll_enable_tx_abort_events(BIT(IEEE802154_TX_ABORT_BY_RX_ACK_TIMEOUT - 1) | BIT(IEEE802154_TX_ABORT_BY_TX_COEX_BREAK - 1) | BIT(IEEE802154_TX_ABORT_BY_TX_SECURITY_ERROR - 1) | BIT(IEEE802154_TX_ABORT_BY_CCA_FAILED - 1) | BIT(IEEE802154_TX_ABORT_BY_CCA_BUSY - 1)); ieee802154_ll_enable_rx_abort_events(BIT(IEEE802154_RX_ABORT_BY_TX_ACK_TIMEOUT - 1) | BIT(IEEE802154_RX_ABORT_BY_TX_ACK_COEX_BREAK - 1)); @@ -908,16 +917,10 @@ esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca) return ieee802154_transmit_internal(frame, cca); } -IEEE802154_NOINLINE static bool is_target_time_expired(uint32_t target, uint32_t now) -{ - return (((now - target) & (1 << 31)) == 0); -} - esp_err_t ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time) { ESP_RETURN_ON_FALSE(frame[0] <= 127, ESP_ERR_INVALID_ARG, IEEE802154_TAG, "Invalid frame length."); uint32_t tx_target_time; - uint32_t current_time; IEEE802154_RF_ENABLE(); tx_init(frame); IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_TX_AT); @@ -927,9 +930,7 @@ esp_err_t ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time) ieee802154_set_state(IEEE802154_STATE_TX_CCA); ieee802154_enter_critical(); ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL0, ETM_EVENT_TIMER0_OVERFLOW, ETM_TASK_ED_TRIG_TX); - current_time = (uint32_t)esp_timer_get_time(); - ieee802154_timer0_set_threshold((is_target_time_expired(tx_target_time, current_time) ? 0 : (tx_target_time - current_time))); //uint: 1us - ieee802154_timer0_start(); + ieee802154_timer0_fire_at(tx_target_time); ieee802154_exit_critical(); } else { tx_target_time = time - IEEE802154_TX_RAMPUP_TIME_US; @@ -940,9 +941,7 @@ esp_err_t ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time) } ieee802154_enter_critical(); ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL0, ETM_EVENT_TIMER0_OVERFLOW, ETM_TASK_TX_START); - current_time = (uint32_t)esp_timer_get_time(); - ieee802154_timer0_set_threshold((is_target_time_expired(tx_target_time, current_time) ? 0 : (tx_target_time - current_time))); //uint: 1us - ieee802154_timer0_start(); + ieee802154_timer0_fire_at(tx_target_time); ieee802154_exit_critical(); } @@ -970,20 +969,34 @@ esp_err_t ieee802154_receive(void) return ESP_OK; } -esp_err_t ieee802154_receive_at(uint32_t time) +IEEE802154_NOINLINE static void ieee802154_finish_receive_at(void* ctx) { - uint32_t rx_target_time = time - IEEE802154_RX_RAMPUP_TIME_US; - uint32_t current_time; + (void)ctx; + stop_current_operation(); + esp_ieee802154_receive_at_done(); +} + +IEEE802154_NOINLINE static void ieee802154_start_receive_at(void* ctx) +{ + uint32_t rx_stop_time = (uint32_t)ctx; + ieee802154_timer1_fire_at_with_callback(rx_stop_time, ieee802154_finish_receive_at, NULL); +} + +esp_err_t ieee802154_receive_at(uint32_t time, uint32_t duration) +{ + // TODO: Light sleep current optimization, TZ-1613. IEEE802154_RF_ENABLE(); ieee802154_enter_critical(); rx_init(); IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_RX_AT); set_next_rx_buffer(); ieee802154_set_state(IEEE802154_STATE_RX); - ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL1, ETM_EVENT_TIMER0_OVERFLOW, ETM_TASK_RX_START); - current_time = (uint32_t)esp_timer_get_time(); - ieee802154_timer0_set_threshold((is_target_time_expired(rx_target_time, current_time) ? 0 : (rx_target_time - current_time))); //uint: 1us - ieee802154_timer0_start(); + ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL1, ETM_EVENT_TIMER1_OVERFLOW, ETM_TASK_RX_START); + if (duration) { + ieee802154_timer1_fire_at_with_callback(time - IEEE802154_RX_RAMPUP_TIME_US, ieee802154_start_receive_at, (void*)(time + duration)); + } else { + ieee802154_timer1_fire_at(time - IEEE802154_RX_RAMPUP_TIME_US); + } ieee802154_exit_critical(); return ESP_OK; } diff --git a/components/ieee802154/driver/esp_ieee802154_timer.c b/components/ieee802154/driver/esp_ieee802154_timer.c index e2bff1a59b..0bf928e71b 100644 --- a/components/ieee802154/driver/esp_ieee802154_timer.c +++ b/components/ieee802154/driver/esp_ieee802154_timer.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,12 @@ #include "esp_check.h" #include "esp_ieee802154_timer.h" #include "esp_ieee802154_util.h" +#include + +static timer_callback_t s_timer0_callback = NULL; +static timer_callback_t s_timer1_callback = NULL; +static void* s_timer0_ctx = NULL; +static void* s_timer1_ctx = NULL; void ieee802154_timer0_start(void) { @@ -17,6 +23,8 @@ void ieee802154_timer0_start(void) void ieee802154_timer0_stop(void) { + s_timer0_callback = NULL; + s_timer0_ctx = NULL; ieee802154_ll_set_cmd(IEEE802154_CMD_TIMER0_STOP); } @@ -41,6 +49,8 @@ void ieee802154_timer1_start(void) void ieee802154_timer1_stop(void) { + s_timer1_callback = NULL; + s_timer1_ctx = NULL; ieee802154_ll_set_cmd(IEEE802154_CMD_TIMER1_STOP); } @@ -57,3 +67,62 @@ uint32_t ieee802154_timer1_get_value(void) { return ieee802154_ll_timer1_get_value(); } + +FORCE_INLINE_ATTR bool is_target_time_expired(uint32_t target, uint32_t now) +{ + return (((now - target) & (1 << 31)) == 0); +} + +void ieee802154_timer0_fire_at(uint32_t fire_time) +{ + uint32_t current_time = (uint32_t)esp_timer_get_time(); + ieee802154_timer0_set_threshold((is_target_time_expired(fire_time, current_time) ? 0 : (fire_time - current_time))); //uint: 1us + ieee802154_timer0_start(); +} + +void ieee802154_timer1_fire_at(uint32_t fire_time) +{ + uint32_t current_time = (uint32_t)esp_timer_get_time(); + ieee802154_timer1_set_threshold((is_target_time_expired(fire_time, current_time) ? 0 : (fire_time - current_time))); //uint: 1us + ieee802154_timer1_start(); +} + +void ieee802154_timer0_fire_at_with_callback(uint32_t fire_time, timer_callback_t timer0_cb, void *timer0_ctx) +{ + s_timer0_callback = timer0_cb; + s_timer0_ctx = timer0_ctx; + ieee802154_timer0_fire_at(fire_time); +} + +void ieee802154_timer1_fire_at_with_callback(uint32_t fire_time, timer_callback_t timer1_cb, void *timer1_ctx) +{ + s_timer1_callback = timer1_cb; + s_timer1_ctx = timer1_ctx; + ieee802154_timer1_fire_at(fire_time); +} + +void ieee802154_timer0_execute_callback(void) +{ + timer_callback_t callback_tmp = s_timer0_callback; // tmp function used to allow new callback function to set a new callback without overwriting it + void* ctx_tmp = s_timer0_ctx; + + s_timer0_callback = NULL; + s_timer0_ctx = NULL; + + if (callback_tmp) { + callback_tmp(ctx_tmp); + } +} + +void ieee802154_timer1_execute_callback(void) +{ + timer_callback_t callback_tmp = s_timer1_callback; // tmp function used to allow new callback function to set a new callback without overwriting it + void* ctx_tmp = s_timer1_ctx; + + s_timer1_callback = NULL; + s_timer1_ctx = NULL; + + if (callback_tmp) { + callback_tmp(ctx_tmp); + } +} diff --git a/components/ieee802154/driver/esp_ieee802154_util.c b/components/ieee802154/driver/esp_ieee802154_util.c index a8b8131645..73f31d2b52 100644 --- a/components/ieee802154/driver/esp_ieee802154_util.c +++ b/components/ieee802154/driver/esp_ieee802154_util.c @@ -66,7 +66,7 @@ void ieee802154_set_txrx_pti(ieee802154_txrx_scene_t txrx_scene) // TZ-97: implement these two functions using ETM common interface void ieee802154_etm_channel_clear(uint32_t channel) { - if (!(REG_READ(ETM_CHEN_AD0_REG) & (1 << channel))) { + if ((REG_READ(ETM_CHEN_AD0_REG) & (1 << channel))) { REG_WRITE(ETM_CHENCLR_AD0_REG, (REG_READ(ETM_CHENCLR_AD0_REG)) | 1 << channel); } } diff --git a/components/ieee802154/esp_ieee802154.c b/components/ieee802154/esp_ieee802154.c index 4cc1805441..1af2b475ba 100644 --- a/components/ieee802154/esp_ieee802154.c +++ b/components/ieee802154/esp_ieee802154.c @@ -211,8 +211,7 @@ esp_err_t esp_ieee802154_set_multipan_enable(uint8_t mask) ieee802154_ll_set_multipan_enable_mask(mask); return ESP_OK; } - -#else +#endif // CONFIG_IEEE802154_MULTI_PAN_ENABLE esp_err_t esp_ieee802154_set_ack_timeout(uint32_t timeout) { @@ -264,8 +263,6 @@ esp_err_t esp_ieee802154_set_extended_address(const uint8_t *ext_addr) return ESP_OK; } -#endif // CONFIG_IEEE802154_MULTI_PAN_ENABLE - esp_ieee802154_pending_mode_t esp_ieee802154_get_pending_mode(void) { return ieee802154_pib_get_pending_mode(); @@ -308,9 +305,9 @@ esp_err_t esp_ieee802154_receive(void) return ieee802154_receive(); } -esp_err_t esp_ieee802154_receive_at(uint32_t time) +esp_err_t esp_ieee802154_receive_at(uint32_t time, uint32_t duration) { - return ieee802154_receive_at(time); + return ieee802154_receive_at(time, duration); } esp_err_t esp_ieee802154_energy_detect(uint32_t duration) @@ -337,6 +334,7 @@ esp_ieee802154_state_t esp_ieee802154_get_state(void) case IEEE802154_STATE_RX: case IEEE802154_STATE_TX_ACK: + case IEEE802154_STATE_TX_ENH_ACK: case IEEE802154_STATE_ED: return ESP_IEEE802154_RADIO_RECEIVE; @@ -344,7 +342,6 @@ esp_ieee802154_state_t esp_ieee802154_get_state(void) case IEEE802154_STATE_CCA: case IEEE802154_STATE_TX: case IEEE802154_STATE_RX_ACK: - case IEEE802154_STATE_TX_ENH_ACK: return ESP_IEEE802154_RADIO_TRANSMIT; default: @@ -433,6 +430,10 @@ __attribute__((weak)) void esp_ieee802154_energy_detect_done(int8_t power) __attribute__((weak)) void esp_ieee802154_ed_failed(uint16_t error) { +} +__attribute__((weak)) void esp_ieee802154_receive_at_done(void) +{ + } __attribute__((weak)) esp_err_t esp_ieee802154_enh_ack_generator(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info, uint8_t* enhack_frame) @@ -441,16 +442,6 @@ __attribute__((weak)) esp_err_t esp_ieee802154_enh_ack_generator(uint8_t *frame, return ESP_FAIL; } -__attribute__((weak)) void esp_ieee802154_timer0_done(void) -{ - -} - -__attribute__((weak)) void esp_ieee802154_timer1_done(void) -{ - -} - #if CONFIG_IEEE802154_TXRX_STATISTIC void esp_ieee802154_txrx_statistic_clear(void) { diff --git a/components/ieee802154/include/esp_ieee802154.h b/components/ieee802154/include/esp_ieee802154.h index 881206803c..60a38d4096 100644 --- a/components/ieee802154/include/esp_ieee802154.h +++ b/components/ieee802154/include/esp_ieee802154.h @@ -588,18 +588,24 @@ extern void esp_ieee802154_transmit_sfd_done(uint8_t *frame); extern void esp_ieee802154_energy_detect_done(int8_t power); /** - * @brief Set the IEEE 802.15.4 Radio to receive state at a specific time. + * @brief The receive window for receive_at has finished. * - * @note Radio will start receiving after the timestamp, and continue receiving until it receives a valid frame. - * Refer to `esp_ieee802154_receive_done()`. + */ +extern void esp_ieee802154_receive_at_done(void); + +/** + * @brief Set the IEEE 802.15.4 Radio to receive state at a specific time, for a specific duration. * - * @param[in] time A specific timestamp for starting receiving. + * @note Radio will start receiving after the timestamp, and continue receiving for the specific duration. + * + * @param[in] time A specific timestamp for starting receiving. + * @param[in] duration A specific duration after which to stop receiving. Set duration = 0 to rx indefinitely. * @return * - ESP_OK on success * - ESP_FAIL on failure due to invalid state. * */ -esp_err_t esp_ieee802154_receive_at(uint32_t time); +esp_err_t esp_ieee802154_receive_at(uint32_t time, uint32_t duration); /** * @brief Transmit the given frame at a specific time. diff --git a/components/ieee802154/linker.lf b/components/ieee802154/linker.lf index f84200a51f..1928229b66 100644 --- a/components/ieee802154/linker.lf +++ b/components/ieee802154/linker.lf @@ -4,30 +4,30 @@ entries: if IEEE802154_ENABLED = y: # When adding static functions here, add IEEE802154_NOINLINE attribute to them esp_ieee802154_ack: ieee802154_ack_config_pending_bit (noflash) - esp_ieee802154_dev: ieee802154_rx_frame_info_update (noflash) esp_ieee802154_dev: ieee802154_isr (noflash) + esp_ieee802154_dev: ieee802154_rx_frame_info_update (noflash) + esp_ieee802154_event: ieee802154_inner_energy_detect_done (noflash) + esp_ieee802154_event: ieee802154_inner_enh_ack_generator (noflash) esp_ieee802154_event: ieee802154_inner_receive_done (noflash) esp_ieee802154_event: ieee802154_inner_receive_sfd_done (noflash) esp_ieee802154_event: ieee802154_inner_transmit_done (noflash) esp_ieee802154_event: ieee802154_inner_transmit_failed (noflash) esp_ieee802154_event: ieee802154_inner_transmit_sfd_done (noflash) - esp_ieee802154_event: ieee802154_inner_energy_detect_done (noflash) - esp_ieee802154_event: ieee802154_inner_enh_ack_generator (noflash) + esp_ieee802154_frame: ieee802154_frame_get_security_field_len (noflash) + esp_ieee802154_frame: ieee802154_frame_get_security_payload_offset (noflash) + esp_ieee802154_frame: ieee802154_frame_get_src_addr (noflash) + esp_ieee802154_frame: ieee802154_frame_security_header_offset (noflash) esp_ieee802154_frame: is_dst_panid_present (noflash) esp_ieee802154_frame: is_src_panid_present (noflash) - esp_ieee802154_frame: ieee802154_frame_security_header_offset (noflash) - esp_ieee802154_frame: ieee802154_frame_get_security_field_len (noflash) - esp_ieee802154_frame: ieee802154_frame_get_src_addr (noflash) - esp_ieee802154_frame: ieee802154_frame_get_security_payload_offset (noflash) esp_ieee802154_pib: ieee802154_pib_get_pending_mode (noflash) esp_ieee802154_pib: ieee802154_pib_get_rx_when_idle (noflash) - esp_ieee802154_sec: ieee802154_transmit_security_config (noflash) esp_ieee802154_sec: ieee802154_sec_update (noflash) + esp_ieee802154_sec: ieee802154_transmit_security_config (noflash) esp_ieee802154_timer: ieee802154_timer0_set_threshold (noflash) - esp_ieee802154_timer: ieee802154_timer1_set_threshold (noflash) esp_ieee802154_timer: ieee802154_timer0_start (noflash) - esp_ieee802154_timer: ieee802154_timer1_start (noflash) esp_ieee802154_timer: ieee802154_timer0_stop (noflash) + esp_ieee802154_timer: ieee802154_timer1_set_threshold (noflash) + esp_ieee802154_timer: ieee802154_timer1_start (noflash) esp_ieee802154_timer: ieee802154_timer1_stop (noflash) esp_ieee802154_util: ieee802154_etm_channel_clear (noflash) @@ -35,35 +35,38 @@ entries: esp_ieee802154_debug (noflash) if IEEE802154_TIMING_OPTIMIZATION = y: - esp_ieee802154_dev: set_next_rx_buffer (noflash) - esp_ieee802154_dev: stop_rx (noflash) - esp_ieee802154_dev: stop_tx_ack (noflash) - esp_ieee802154_dev: stop_tx (noflash) - esp_ieee802154_dev: stop_cca (noflash) - esp_ieee802154_dev: stop_tx_cca (noflash) - esp_ieee802154_dev: stop_rx_ack (noflash) - esp_ieee802154_dev: stop_ed (noflash) - esp_ieee802154_dev: stop_current_operation (noflash) - esp_ieee802154_dev: is_target_time_expired (noflash) - esp_ieee802154_dev: ieee802154_transmit_at (noflash) - esp_ieee802154_dev: ieee802154_receive_at (noflash) - esp_ieee802154_dev: ieee802154_transmit (noflash) - esp_ieee802154_dev: ieee802154_receive (noflash) - esp_ieee802154_pib: ieee802154_pib_update (noflash) - esp_ieee802154_pib: ieee802154_txpower_convert (noflash) - esp_ieee802154_util: ieee802154_channel_to_freq (noflash) - esp_ieee802154: esp_ieee802154_transmit_at (noflash) - esp_ieee802154: esp_ieee802154_receive_at (noflash) - esp_ieee802154: esp_ieee802154_transmit (noflash) - esp_ieee802154: esp_ieee802154_receive (noflash) - - if OPENTHREAD_CSL_ENABLE = y || OPENTHREAD_LINK_METRICS = y: esp_ieee802154: esp_ieee802154_enh_ack_generator (noflash) esp_ieee802154: esp_ieee802154_get_extended_address (noflash) - esp_ieee802154: esp_ieee802154_set_transmit_security (noflash) - - if OPENTHREAD_LINK_METRICS = y: esp_ieee802154: esp_ieee802154_get_recent_lqi (noflash) esp_ieee802154: esp_ieee802154_get_recent_rssi (noflash) - esp_ieee802154_dev: ieee802154_get_recent_rssi (noflash) + esp_ieee802154: esp_ieee802154_receive (noflash) + esp_ieee802154: esp_ieee802154_receive_at (noflash) + esp_ieee802154: esp_ieee802154_set_transmit_security (noflash) + esp_ieee802154: esp_ieee802154_transmit (noflash) + esp_ieee802154: esp_ieee802154_transmit_at (noflash) + esp_ieee802154_dev: ieee802154_finish_receive_at (noflash) esp_ieee802154_dev: ieee802154_get_recent_lqi (noflash) + esp_ieee802154_dev: ieee802154_get_recent_rssi (noflash) + esp_ieee802154_dev: ieee802154_receive (noflash) + esp_ieee802154_dev: ieee802154_receive_at (noflash) + esp_ieee802154_dev: ieee802154_start_receive_at (noflash) + esp_ieee802154_dev: ieee802154_transmit (noflash) + esp_ieee802154_dev: ieee802154_transmit_at (noflash) + esp_ieee802154_dev: set_next_rx_buffer (noflash) + esp_ieee802154_dev: stop_cca (noflash) + esp_ieee802154_dev: stop_current_operation (noflash) + esp_ieee802154_dev: stop_ed (noflash) + esp_ieee802154_dev: stop_rx (noflash) + esp_ieee802154_dev: stop_rx_ack (noflash) + esp_ieee802154_dev: stop_tx (noflash) + esp_ieee802154_dev: stop_tx_ack (noflash) + esp_ieee802154_dev: stop_tx_cca (noflash) + esp_ieee802154_pib: ieee802154_pib_update (noflash) + esp_ieee802154_pib: ieee802154_txpower_convert (noflash) + esp_ieee802154_timer: ieee802154_timer0_execute_callback (noflash) + esp_ieee802154_timer: ieee802154_timer0_fire_at (noflash) + esp_ieee802154_timer: ieee802154_timer0_fire_at_with_callback (noflash) + esp_ieee802154_timer: ieee802154_timer1_execute_callback (noflash) + esp_ieee802154_timer: ieee802154_timer1_fire_at (noflash) + esp_ieee802154_timer: ieee802154_timer1_fire_at_with_callback (noflash) + esp_ieee802154_util: ieee802154_channel_to_freq (noflash) diff --git a/components/ieee802154/private_include/esp_ieee802154_dev.h b/components/ieee802154/private_include/esp_ieee802154_dev.h index a88ff663df..221c2c32be 100644 --- a/components/ieee802154/private_include/esp_ieee802154_dev.h +++ b/components/ieee802154/private_include/esp_ieee802154_dev.h @@ -141,10 +141,11 @@ esp_err_t ieee802154_receive_handle_done(const uint8_t* frame); esp_err_t ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time); /** - * @brief Set the IEEE 802.15.4 Radio to receive state at a specific time. + * @brief Set the IEEE 802.15.4 Radio to receive state at a specific time, for a specific duration. * * - * @param[in] time A specific timestamp for starting receiving. + * @param[in] time A specific timestamp for starting receiving. + * @param[in] duration A specific duration after which to stop receiving. Set duration = 0 to rx indefinitely. * @return * - ESP_OK on success * - ESP_FAIL on failure due to invalid state. @@ -153,7 +154,7 @@ esp_err_t ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time); * Ref to esp_ieee802154_receive_done(). * */ -esp_err_t ieee802154_receive_at(uint32_t time); +esp_err_t ieee802154_receive_at(uint32_t time, uint32_t duration); /** * @brief Set the IEEE 802.15.4 Radio to sleep state. @@ -263,8 +264,6 @@ bool ieee802154_mac_is_inited(void); #if CONFIG_IEEE802154_TEST #define IEEE802154_STATIC #define IEEE802154_INLINE -extern void esp_ieee802154_timer0_done(void); -extern void esp_ieee802154_timer1_done(void); #else #define IEEE802154_STATIC static #define IEEE802154_INLINE inline diff --git a/components/ieee802154/private_include/esp_ieee802154_timer.h b/components/ieee802154/private_include/esp_ieee802154_timer.h index aee1230720..d07c9b4ea2 100644 --- a/components/ieee802154/private_include/esp_ieee802154_timer.h +++ b/components/ieee802154/private_include/esp_ieee802154_timer.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -79,6 +79,44 @@ esp_err_t ieee802154_timer1_set_threshold(uint32_t value); */ uint32_t ieee802154_timer1_get_value(void); +/** + * @brief Set timer0 to fire at specific time. + * + */ +void ieee802154_timer0_fire_at(uint32_t fire_time); + +/** + * @brief Set timer1 to fire at specific time. + * + */ +void ieee802154_timer1_fire_at(uint32_t fire_time); + +typedef void (*timer_callback_t)(void* ctx); + +/** + * @brief Set timer0 to fire at specific time with callback. + * + */ +void ieee802154_timer0_fire_at_with_callback(uint32_t fire_time, timer_callback_t timer0_callback, void *timer0_ctx); + +/** + * @brief Set timer1 to fire at specific time with callback. + * + */ +void ieee802154_timer1_fire_at_with_callback(uint32_t fire_time, timer_callback_t timer1_callback, void *timer1_ctx); + +/** + * @brief Execute timer0 callback. + * + */ +void ieee802154_timer0_execute_callback(void); + +/** + * @brief Execute timer1 callback. + * + */ +void ieee802154_timer1_execute_callback(void); + #ifdef __cplusplus } #endif diff --git a/components/openthread/Kconfig b/components/openthread/Kconfig index fdd5445456..1a72bce3c6 100644 --- a/components/openthread/Kconfig +++ b/components/openthread/Kconfig @@ -259,6 +259,7 @@ menu "OpenThread" config OPENTHREAD_LINK_METRICS bool "Enable link metrics feature" default n + select IEEE802154_TIMING_OPTIMIZATION if IEEE802154_ENABLED help Select this option to enable link metrics feature @@ -271,6 +272,7 @@ menu "OpenThread" config OPENTHREAD_CSL_ENABLE bool "Enable CSL feature" default n + select IEEE802154_TIMING_OPTIMIZATION if IEEE802154_ENABLED help Select this option to enable CSL feature menu "CSL Configurations" @@ -278,13 +280,13 @@ menu "OpenThread" config OPENTHREAD_CSL_ACCURACY int "The current CSL rx/tx scheduling drift, in units of ± ppm" - default 1 + default 20 help The current accuracy of the clock used for scheduling CSL operations config OPENTHREAD_CSL_UNCERTAIN int "The CSL Uncertainty in units of 10 us." - default 1 + default 0 help The fixed uncertainty of the Device for scheduling CSL Transmissions in units of 10 microseconds. @@ -374,7 +376,7 @@ menu "OpenThread" config OPENTHREAD_XTAL_ACCURACY int "The accuracy of the XTAL" - default 130 + default 10 help The device's XTAL accuracy, in ppm. diff --git a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h index 4f3b1f7fd6..99b859ce17 100644 --- a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h @@ -726,11 +726,21 @@ /** * @def OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US * - * Define as 1 to set the ahead time for CSL transmit timing. + * Define how many microseconds ahead should MAC deliver CSL frame to SubMac. * */ #ifndef OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US -#define OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US 20000 +#define OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US (2 * 1000000 / CONFIG_FREERTOS_HZ) +#endif + +/** + * @def OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD + * + * Reception scheduling and ramp up time needed for the CSL receiver to be ready, in units of microseconds. + * + */ +#ifndef OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD +#define OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD (OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US + 320) #endif /** diff --git a/components/openthread/private_include/openthread-core-esp32x-mtd-config.h b/components/openthread/private_include/openthread-core-esp32x-mtd-config.h index 2bad19b27e..d4e3b0c3af 100644 --- a/components/openthread/private_include/openthread-core-esp32x-mtd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-mtd-config.h @@ -400,3 +400,52 @@ #ifndef OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_MARK_ECN_INTERVAL #define OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_MARK_ECN_INTERVAL 1000 #endif + +#ifdef OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +#error `OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE` is redefined. +#endif +#if CONFIG_OPENTHREAD_CSL_ENABLE + +/** + * @def OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + * + * Define as 1 to support Thread 1.2 CSL feature. + * + */ +#define OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1 + +/** + * @def OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE + * + * Define as 1 to enable support Thread 1.2 CSL debug. + * + */ +#ifdef OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE +#error `OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE` is redefined. +#endif +#define OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE CONFIG_OPENTHREAD_CSL_DEBUG_ENABLE + +#else + +#define OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 0 +#endif // CONFIG_OPENTHREAD_CSL_ENABLE + +/** + * @def OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US + * + * Define how many microseconds ahead should MAC deliver CSL frame to SubMac. + * + */ +#ifndef OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US +#define OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US (2 * 1000000 / CONFIG_FREERTOS_HZ) +#endif + +/** + * @def OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD + * + * Reception scheduling and ramp up time needed for the CSL receiver to be ready, in units of microseconds. + * + */ +#ifndef OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD +#define OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD (OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US + 320) +#endif diff --git a/components/openthread/src/port/esp_openthread_radio.c b/components/openthread/src/port/esp_openthread_radio.c index e1ea8fc839..9dfbd63de8 100644 --- a/components/openthread/src/port/esp_openthread_radio.c +++ b/components/openthread/src/port/esp_openthread_radio.c @@ -47,6 +47,7 @@ #define EVENT_TX_FAILED (1 << 1) #define EVENT_RX_DONE (1 << 2) #define EVENT_ENERGY_DETECT_DONE (1 << 3) +#define EVENT_SLEEP (1 << 4) typedef struct { uint8_t length; @@ -241,6 +242,11 @@ esp_err_t esp_openthread_radio_process(otInstance *aInstance, const esp_openthre } } + if (get_event(EVENT_SLEEP)) { + clr_event(EVENT_SLEEP); + esp_ieee802154_sleep(); + } + return ESP_OK; } @@ -312,7 +318,11 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame) aFrame->mPsdu[-1] = aFrame->mLength; // length locates one byte before the psdu (esp_openthread_radio_tx_psdu); if (otMacFrameIsSecurityEnabled(aFrame) && !aFrame->mInfo.mTxInfo.mIsSecurityProcessed) { +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + if (!s_transmit_frame.mInfo.mTxInfo.mIsARetx || s_csl_period > 0) { +#else if (!s_transmit_frame.mInfo.mTxInfo.mIsARetx) { +#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE otMacFrameSetFrameCounter(aFrame, s_mac_frame_counter++); } if (otMacFrameIsKeyIdMode1(aFrame)) { @@ -362,7 +372,8 @@ otRadioCaps otPlatRadioGetCaps(otInstance *aInstance) otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, uint32_t aStart, uint32_t aDuration) { - esp_ieee802154_receive_at((aStart + aDuration)); + esp_ieee802154_set_channel(aChannel); + esp_ieee802154_receive_at(aStart, aDuration); return OT_ERROR_NONE; } @@ -826,3 +837,8 @@ uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance) OT_UNUSED_VARIABLE(aInstance); return CONFIG_OPENTHREAD_SUPPORTED_CHANNEL_MASK; } + +void esp_ieee802154_receive_at_done(void) +{ + set_event(EVENT_SLEEP); +} From 47cd629459feb12a838b541fac1ddfa73b23b798 Mon Sep 17 00:00:00 2001 From: Tan Yan Quan Date: Wed, 12 Mar 2025 16:16:18 +0800 Subject: [PATCH 2/5] fix(openthread): modify ETM task numbers for esp32c5 --- components/soc/esp32c5/register/soc/ieee802154_reg.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/soc/esp32c5/register/soc/ieee802154_reg.h b/components/soc/esp32c5/register/soc/ieee802154_reg.h index e1a9db3190..0c7884fc2e 100644 --- a/components/soc/esp32c5/register/soc/ieee802154_reg.h +++ b/components/soc/esp32c5/register/soc/ieee802154_reg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -514,9 +514,9 @@ extern "C" { #define ETM_EVENT_TIMER1_OVERFLOW 58 #define ETM_EVENT_TIMER0_OVERFLOW 59 -#define ETM_TASK_ED_TRIG_TX 64 -#define ETM_TASK_RX_START 65 -#define ETM_TASK_TX_START 68 +#define ETM_TASK_ED_TRIG_TX 65 +#define ETM_TASK_RX_START 66 +#define ETM_TASK_TX_START 69 #ifdef __cplusplus } From b0149016199d1fed47ff520a55cebf2294ab4725 Mon Sep 17 00:00:00 2001 From: Tan Yan Quan Date: Thu, 13 Mar 2025 14:21:09 +0800 Subject: [PATCH 3/5] fix(openthread): calibrate CSL tx parameters --- components/ieee802154/Kconfig | 2 +- components/openthread/Kconfig | 1 - components/openthread/src/port/esp_openthread_radio.c | 10 ++-------- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/components/ieee802154/Kconfig b/components/ieee802154/Kconfig index 2f8c7034b5..1f1500a59a 100644 --- a/components/ieee802154/Kconfig +++ b/components/ieee802154/Kconfig @@ -75,7 +75,7 @@ menu "IEEE 802.15.4" config IEEE802154_TIMING_OPTIMIZATION bool "Enable throughput optimization" depends on IEEE802154_ENABLED - default n + default y help Enabling this option increases throughput by ~5% at the expense of ~2.1k IRAM code size increase. diff --git a/components/openthread/Kconfig b/components/openthread/Kconfig index 1a72bce3c6..428f180c47 100644 --- a/components/openthread/Kconfig +++ b/components/openthread/Kconfig @@ -276,7 +276,6 @@ menu "OpenThread" help Select this option to enable CSL feature menu "CSL Configurations" - depends on OPENTHREAD_CSL_ENABLE config OPENTHREAD_CSL_ACCURACY int "The current CSL rx/tx scheduling drift, in units of ± ppm" diff --git a/components/openthread/src/port/esp_openthread_radio.c b/components/openthread/src/port/esp_openthread_radio.c index 9dfbd63de8..6808dc0548 100644 --- a/components/openthread/src/port/esp_openthread_radio.c +++ b/components/openthread/src/port/esp_openthread_radio.c @@ -38,10 +38,8 @@ #define ESP_RECEIVE_SENSITIVITY -120 #define ESP_OPENTHREAD_XTAL_ACCURACY CONFIG_OPENTHREAD_XTAL_ACCURACY -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #define ESP_OPENTHREAD_CSL_ACCURACY CONFIG_OPENTHREAD_CSL_ACCURACY #define ESP_OPENTHREAD_CSL_UNCERTAIN CONFIG_OPENTHREAD_CSL_UNCERTAIN -#endif #define EVENT_TX_DONE (1 << 0) #define EVENT_TX_FAILED (1 << 1) @@ -581,6 +579,8 @@ otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, otShort return OT_ERROR_NONE; } +#endif + uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance) { return ESP_OPENTHREAD_CSL_ACCURACY; @@ -591,8 +591,6 @@ uint8_t otPlatRadioGetCslUncertainty(otInstance *aInstance) return ESP_OPENTHREAD_CSL_UNCERTAIN; } -#endif - // events void IRAM_ATTR esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_ieee802154_frame_info_t *ack_frame_info) @@ -620,11 +618,7 @@ static void IRAM_ATTR convert_to_ot_frame(uint8_t *data, esp_ieee802154_frame_in radio_frame->mInfo.mRxInfo.mRssi = frame_info->rssi; radio_frame->mInfo.mRxInfo.mLqi = frame_info->lqi; radio_frame->mInfo.mRxInfo.mAckedWithFramePending = frame_info->pending; - radio_frame->mInfo.mRxInfo.mTimestamp = otPlatTimeGet(); - -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE radio_frame->mInfo.mRxInfo.mTimestamp = frame_info->timestamp; -#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE } static esp_err_t IRAM_ATTR enh_ack_set_security_addr_and_key(otRadioFrame *ack_frame) From fceb55dd25eb5c26acec93eae9c496351be68c57 Mon Sep 17 00:00:00 2001 From: Tan Yan Quan Date: Fri, 21 Mar 2025 16:47:35 +0800 Subject: [PATCH 4/5] refactor(openthread): move isr_handle_timerX to esp_ieee802154_timer --- .../ieee802154/driver/esp_ieee802154_dev.c | 19 --------- .../ieee802154/driver/esp_ieee802154_timer.c | 40 ++++++++++++------- components/ieee802154/linker.lf | 6 ++- .../private_include/esp_ieee802154_timer.h | 20 ++++++++-- 4 files changed, 45 insertions(+), 40 deletions(-) diff --git a/components/ieee802154/driver/esp_ieee802154_dev.c b/components/ieee802154/driver/esp_ieee802154_dev.c index 79fbaa8013..0c3f7d4ddc 100644 --- a/components/ieee802154/driver/esp_ieee802154_dev.c +++ b/components/ieee802154/driver/esp_ieee802154_dev.c @@ -149,8 +149,6 @@ static IRAM_ATTR void receive_ack_timeout_timer_start(uint32_t duration) uint32_t current_time = (uint32_t)esp_timer_get_time(); ieee802154_timer0_fire_at_with_callback(current_time + duration, ieee802154_rx_ack_timeout_callback, (void*)s_tx_frame); - ieee802154_timer0_set_threshold(duration); - ieee802154_timer0_start(); } #endif @@ -406,20 +404,6 @@ static IRAM_ATTR void next_operation(void) } } -static void isr_handle_timer0_done(void) -{ - ieee802154_timer0_execute_callback(); -#if CONFIG_IEEE802154_TEST - extern void esp_ieee802154_timer0_done(void); - esp_ieee802154_timer0_done(); -#endif -} - -static void isr_handle_timer1_done(void) -{ - ieee802154_timer1_execute_callback(); -} - static IRAM_ATTR void isr_handle_tx_done(void) { event_end_process(); @@ -507,7 +491,6 @@ static IRAM_ATTR void isr_handle_rx_phase_rx_abort(ieee802154_ll_rx_abort_reason case IEEE802154_RX_ABORT_BY_TX_ACK_STOP: case IEEE802154_RX_ABORT_BY_ED_STOP: // do nothing - NEEDS_NEXT_OPT(false); return; case IEEE802154_RX_ABORT_BY_SFD_TIMEOUT: case IEEE802154_RX_ABORT_BY_CRC_ERROR: @@ -547,8 +530,6 @@ static IRAM_ATTR void isr_handle_tx_ack_phase_rx_abort(ieee802154_ll_rx_abort_re case IEEE802154_RX_ABORT_BY_RX_STOP: case IEEE802154_RX_ABORT_BY_TX_ACK_STOP: case IEEE802154_RX_ABORT_BY_ED_STOP: - NEEDS_NEXT_OPT(false); - return; case IEEE802154_RX_ABORT_BY_SFD_TIMEOUT: case IEEE802154_RX_ABORT_BY_CRC_ERROR: case IEEE802154_RX_ABORT_BY_INVALID_LEN: diff --git a/components/ieee802154/driver/esp_ieee802154_timer.c b/components/ieee802154/driver/esp_ieee802154_timer.c index 0bf928e71b..d44249e529 100644 --- a/components/ieee802154/driver/esp_ieee802154_timer.c +++ b/components/ieee802154/driver/esp_ieee802154_timer.c @@ -87,42 +87,52 @@ void ieee802154_timer1_fire_at(uint32_t fire_time) ieee802154_timer1_start(); } -void ieee802154_timer0_fire_at_with_callback(uint32_t fire_time, timer_callback_t timer0_cb, void *timer0_ctx) +void ieee802154_timer0_set_callback(timer_callback_t timer0_cb, void *timer0_ctx) { s_timer0_callback = timer0_cb; s_timer0_ctx = timer0_ctx; +} + +void ieee802154_timer1_set_callback(timer_callback_t timer1_cb, void *timer1_ctx) +{ + s_timer1_callback = timer1_cb; + s_timer1_ctx = timer1_ctx; +} + +void ieee802154_timer0_fire_at_with_callback(uint32_t fire_time, timer_callback_t timer0_cb, void *timer0_ctx) +{ + ieee802154_timer0_set_callback(timer0_cb, timer0_ctx); ieee802154_timer0_fire_at(fire_time); } void ieee802154_timer1_fire_at_with_callback(uint32_t fire_time, timer_callback_t timer1_cb, void *timer1_ctx) { - s_timer1_callback = timer1_cb; - s_timer1_ctx = timer1_ctx; + ieee802154_timer1_set_callback(timer1_cb, timer1_ctx); ieee802154_timer1_fire_at(fire_time); } -void ieee802154_timer0_execute_callback(void) +void isr_handle_timer0_done(void) { - timer_callback_t callback_tmp = s_timer0_callback; // tmp function used to allow new callback function to set a new callback without overwriting it - void* ctx_tmp = s_timer0_ctx; + if (s_timer0_callback) { + timer_callback_t callback_tmp = s_timer0_callback; // tmp function used to allow new callback function to set a new callback without overwriting it + void* ctx_tmp = s_timer0_ctx; - s_timer0_callback = NULL; - s_timer0_ctx = NULL; + s_timer0_callback = NULL; + s_timer0_ctx = NULL; - if (callback_tmp) { callback_tmp(ctx_tmp); } } -void ieee802154_timer1_execute_callback(void) +void isr_handle_timer1_done(void) { - timer_callback_t callback_tmp = s_timer1_callback; // tmp function used to allow new callback function to set a new callback without overwriting it - void* ctx_tmp = s_timer1_ctx; + if (s_timer1_callback) { + timer_callback_t callback_tmp = s_timer1_callback; // tmp function used to allow new callback function to set a new callback without overwriting it + void* ctx_tmp = s_timer1_ctx; - s_timer1_callback = NULL; - s_timer1_ctx = NULL; + s_timer1_callback = NULL; + s_timer1_ctx = NULL; - if (callback_tmp) { callback_tmp(ctx_tmp); } } diff --git a/components/ieee802154/linker.lf b/components/ieee802154/linker.lf index 1928229b66..ad766e556f 100644 --- a/components/ieee802154/linker.lf +++ b/components/ieee802154/linker.lf @@ -63,10 +63,12 @@ entries: esp_ieee802154_dev: stop_tx_cca (noflash) esp_ieee802154_pib: ieee802154_pib_update (noflash) esp_ieee802154_pib: ieee802154_txpower_convert (noflash) - esp_ieee802154_timer: ieee802154_timer0_execute_callback (noflash) esp_ieee802154_timer: ieee802154_timer0_fire_at (noflash) esp_ieee802154_timer: ieee802154_timer0_fire_at_with_callback (noflash) - esp_ieee802154_timer: ieee802154_timer1_execute_callback (noflash) + esp_ieee802154_timer: ieee802154_timer0_set_callback (noflash) esp_ieee802154_timer: ieee802154_timer1_fire_at (noflash) esp_ieee802154_timer: ieee802154_timer1_fire_at_with_callback (noflash) + esp_ieee802154_timer: ieee802154_timer1_set_callback (noflash) + esp_ieee802154_timer: isr_handle_timer0_done (noflash) + esp_ieee802154_timer: isr_handle_timer1_done (noflash) esp_ieee802154_util: ieee802154_channel_to_freq (noflash) diff --git a/components/ieee802154/private_include/esp_ieee802154_timer.h b/components/ieee802154/private_include/esp_ieee802154_timer.h index d07c9b4ea2..f445a281ec 100644 --- a/components/ieee802154/private_include/esp_ieee802154_timer.h +++ b/components/ieee802154/private_include/esp_ieee802154_timer.h @@ -93,6 +93,18 @@ void ieee802154_timer1_fire_at(uint32_t fire_time); typedef void (*timer_callback_t)(void* ctx); +/** + * @brief Set timer0 callback. + * + */ +void ieee802154_timer0_set_callback(timer_callback_t timer0_cb, void *timer0_ctx); + +/** + * @brief Set timer1 callback. + * + */ +void ieee802154_timer1_set_callback(timer_callback_t timer1_cb, void *timer1_ctx); + /** * @brief Set timer0 to fire at specific time with callback. * @@ -106,16 +118,16 @@ void ieee802154_timer0_fire_at_with_callback(uint32_t fire_time, timer_callback_ void ieee802154_timer1_fire_at_with_callback(uint32_t fire_time, timer_callback_t timer1_callback, void *timer1_ctx); /** - * @brief Execute timer0 callback. + * @brief ISR handle for timer0. * */ -void ieee802154_timer0_execute_callback(void); +void isr_handle_timer0_done(void); /** - * @brief Execute timer1 callback. + * @brief ISR handle for timer1. * */ -void ieee802154_timer1_execute_callback(void); +void isr_handle_timer1_done(void); #ifdef __cplusplus } From d3bc511c36181eec973ec9621f69e035bd6ea443 Mon Sep 17 00:00:00 2001 From: Tan Yan Quan Date: Mon, 24 Mar 2025 14:53:20 +0800 Subject: [PATCH 5/5] fix(openthread): add some bugfixes to pass CI pipeline --- components/ieee802154/private_include/esp_ieee802154_dev.h | 2 +- components/openthread/src/port/esp_openthread_radio.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/ieee802154/private_include/esp_ieee802154_dev.h b/components/ieee802154/private_include/esp_ieee802154_dev.h index 221c2c32be..1d53af66f0 100644 --- a/components/ieee802154/private_include/esp_ieee802154_dev.h +++ b/components/ieee802154/private_include/esp_ieee802154_dev.h @@ -268,7 +268,7 @@ bool ieee802154_mac_is_inited(void); #define IEEE802154_STATIC static #define IEEE802154_INLINE inline #endif // CONFIG_IEEE802154_TEST -#define IEEE802154_NOINLINE __attribute__((noinline)) +#define IEEE802154_NOINLINE __attribute__((noinline, used)) #ifdef __cplusplus } diff --git a/components/openthread/src/port/esp_openthread_radio.c b/components/openthread/src/port/esp_openthread_radio.c index 6808dc0548..812329cca9 100644 --- a/components/openthread/src/port/esp_openthread_radio.c +++ b/components/openthread/src/port/esp_openthread_radio.c @@ -658,7 +658,7 @@ esp_err_t IRAM_ATTR esp_ieee802154_enh_ack_generator(uint8_t *frame, esp_ieee802 { otRadioFrame ack_frame; otRadioFrame ot_frame; - uint8_t ack_ie_data[OT_ACK_IE_MAX_SIZE]; + uint8_t ack_ie_data[OT_ACK_IE_MAX_SIZE] = {0}; uint8_t offset = 0; #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE uint8_t link_metrics_data_len = 0;