Skip to content

Commit 4a83e6b

Browse files
committed
Merge branch 'feature/154_api_enhancement_for_mp_v5.1' into 'release/v5.1'
feat(802.15.4): support register isr callback (v5.1) See merge request espressif/esp-idf!36201
2 parents 8c1e948 + 6d28fb7 commit 4a83e6b

File tree

9 files changed

+326
-21
lines changed

9 files changed

+326
-21
lines changed

components/ieee802154/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ if(CONFIG_IEEE802154_ENABLED)
88
list(APPEND srcs "esp_ieee802154.c"
99
"driver/esp_ieee802154_ack.c"
1010
"driver/esp_ieee802154_dev.c"
11+
"driver/esp_ieee802154_event.c"
1112
"driver/esp_ieee802154_frame.c"
1213
"driver/esp_ieee802154_pib.c"
1314
"driver/esp_ieee802154_util.c"

components/ieee802154/driver/esp_ieee802154_dev.c

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -18,6 +18,7 @@
1818
#include "esp_timer.h"
1919
#include "esp_ieee802154_ack.h"
2020
#include "esp_ieee802154_dev.h"
21+
#include "esp_ieee802154_event.h"
2122
#include "esp_ieee802154_frame.h"
2223
#include "esp_ieee802154_pib.h"
2324
#include "esp_ieee802154_sec.h"
@@ -93,7 +94,7 @@ static void ieee802154_receive_done(uint8_t *data, esp_ieee802154_frame_info_t *
9394
// Ignore bit8 for the frame length, due to the max frame length is 127 based 802.15.4 spec.
9495
data[0] = data[0] & 0x7f;
9596
frame_info->process = true;
96-
esp_ieee802154_receive_done(data, frame_info);
97+
ieee802154_inner_receive_done(data, frame_info);
9798
}
9899
}
99100

@@ -102,13 +103,13 @@ static void ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, e
102103
if (ack && ack_frame_info) {
103104
IEEE802154_RX_BUFFER_STAT_IS_FREE(false);
104105
if (s_rx_index == CONFIG_IEEE802154_RX_BUFFER_SIZE) {
105-
esp_ieee802154_transmit_failed(frame, ESP_IEEE802154_TX_ERR_NO_ACK);
106+
ieee802154_inner_transmit_failed(frame, ESP_IEEE802154_TX_ERR_NO_ACK);
106107
} else {
107108
ack_frame_info->process = true;
108-
esp_ieee802154_transmit_done(frame, ack, ack_frame_info);
109+
ieee802154_inner_transmit_done(frame, ack, ack_frame_info);
109110
}
110111
} else {
111-
esp_ieee802154_transmit_done(frame, ack, ack_frame_info);
112+
ieee802154_inner_transmit_done(frame, ack, ack_frame_info);
112113
}
113114
}
114115

@@ -240,7 +241,7 @@ IEEE802154_NOINLINE static bool stop_tx(void)
240241
// if the tx is already done, and the frame is not ack request OR auto ack rx is disabled.
241242
ieee802154_transmit_done(s_tx_frame, NULL, NULL);
242243
} else {
243-
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_ABORT);
244+
ieee802154_inner_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_ABORT);
244245
}
245246

246247
ieee802154_ll_clear_events(IEEE802154_EVENT_TX_DONE | IEEE802154_EVENT_TX_ABORT | IEEE802154_EVENT_TX_SFD_DONE);
@@ -276,7 +277,7 @@ IEEE802154_NOINLINE static bool stop_rx_ack(void)
276277
if (events & IEEE802154_EVENT_ACK_RX_DONE) {
277278
ieee802154_transmit_done(s_tx_frame, (uint8_t *)&s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]);
278279
} else {
279-
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK);
280+
ieee802154_inner_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK);
280281
}
281282

282283
ieee802154_ll_clear_events(IEEE802154_EVENT_ACK_RX_DONE | IEEE802154_EVENT_RX_SFD_DONE | IEEE802154_EVENT_TX_ABORT);
@@ -397,7 +398,7 @@ static void isr_handle_timer0_done(void)
397398
{
398399
#if !CONFIG_IEEE802154_TEST
399400
if (s_ieee802154_state == IEEE802154_STATE_RX_ACK) {
400-
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK);
401+
ieee802154_inner_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK);
401402
NEEDS_NEXT_OPT(true);
402403
}
403404
#else
@@ -451,7 +452,7 @@ static IRAM_ATTR void isr_handle_rx_done(void)
451452
&& ieee802154_ll_get_tx_enhance_ack()) {
452453
s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index]);
453454
// For 2015 enh-ack, SW should generate an enh-ack then send it manually
454-
if (esp_ieee802154_enh_ack_generator(s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index], s_enh_ack_frame) == ESP_OK) {
455+
if (ieee802154_inner_enh_ack_generator(s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index], s_enh_ack_frame) == ESP_OK) {
455456
extcoex_tx_stage_start();
456457
#if !CONFIG_IEEE802154_TEST
457458
// Send the Enh-Ack frame if generator succeeds.
@@ -590,14 +591,14 @@ static IRAM_ATTR void isr_handle_tx_abort(ieee802154_ll_tx_abort_reason_t tx_abo
590591
case IEEE802154_TX_ABORT_BY_RX_ACK_TYPE_NOT_ACK:
591592
case IEEE802154_TX_ABORT_BY_RX_ACK_RESTART:
592593
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK);
593-
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_INVALID_ACK);
594+
ieee802154_inner_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_INVALID_ACK);
594595
NEEDS_NEXT_OPT(false);
595596
break;
596597
// The above events are only used in test mode.
597598
case IEEE802154_TX_ABORT_BY_RX_ACK_TIMEOUT:
598599
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK);
599600
ieee802154_ll_disable_events(IEEE802154_EVENT_TIMER0_OVERFLOW);
600-
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK);
601+
ieee802154_inner_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK);
601602
NEEDS_NEXT_OPT(true);
602603
break;
603604
case IEEE802154_TX_ABORT_BY_TX_COEX_BREAK:
@@ -606,22 +607,22 @@ static IRAM_ATTR void isr_handle_tx_abort(ieee802154_ll_tx_abort_reason_t tx_abo
606607
#endif
607608
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA);
608609
IEEE802154_TX_BREAK_COEX_NUMS_UPDATE();
609-
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_COEXIST);
610+
ieee802154_inner_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_COEXIST);
610611
NEEDS_NEXT_OPT(true);
611612
break;
612613
case IEEE802154_TX_ABORT_BY_TX_SECURITY_ERROR:
613614
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA);
614-
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_SECURITY);
615+
ieee802154_inner_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_SECURITY);
615616
NEEDS_NEXT_OPT(true);
616617
break;
617618
case IEEE802154_TX_ABORT_BY_CCA_FAILED:
618619
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_CCA);
619-
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_ABORT);
620+
ieee802154_inner_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_ABORT);
620621
NEEDS_NEXT_OPT(true);
621622
break;
622623
case IEEE802154_TX_ABORT_BY_CCA_BUSY:
623624
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_CCA);
624-
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_CCA_BUSY);
625+
ieee802154_inner_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_CCA_BUSY);
625626
NEEDS_NEXT_OPT(true);
626627
break;
627628
default:
@@ -635,18 +636,18 @@ static IRAM_ATTR void isr_handle_ed_done(void)
635636
if (s_ieee802154_state == IEEE802154_STATE_CCA) {
636637
esp_ieee802154_cca_done(ieee802154_ll_is_cca_busy());
637638
} else if (s_ieee802154_state == IEEE802154_STATE_ED) {
638-
esp_ieee802154_energy_detect_done(ieee802154_ll_get_ed_rss());
639+
ieee802154_inner_energy_detect_done(ieee802154_ll_get_ed_rss());
639640
}
640641

641642
NEEDS_NEXT_OPT(true);
642643
}
643644

644-
IEEE802154_STATIC IRAM_ATTR void ieee802154_enter_critical(void)
645+
IRAM_ATTR void ieee802154_enter_critical(void)
645646
{
646647
portENTER_CRITICAL(&s_ieee802154_spinlock);
647648
}
648649

649-
IEEE802154_STATIC IRAM_ATTR void ieee802154_exit_critical(void)
650+
IRAM_ATTR void ieee802154_exit_critical(void)
650651
{
651652
portEXIT_CRITICAL(&s_ieee802154_spinlock);
652653
}
@@ -672,7 +673,7 @@ IEEE802154_NOINLINE static void ieee802154_isr(void *arg)
672673
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX || s_ieee802154_state == IEEE802154_STATE_RX_ACK || s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
673674

674675
s_rx_frame_info[s_rx_index].timestamp = esp_timer_get_time();
675-
esp_ieee802154_receive_sfd_done();
676+
ieee802154_inner_receive_sfd_done();
676677

677678
events &= (uint16_t)(~IEEE802154_EVENT_RX_SFD_DONE);
678679
}
@@ -681,7 +682,7 @@ IEEE802154_NOINLINE static void ieee802154_isr(void *arg)
681682
// ZB-81: IEEE802154_STATE_TX_ACK is also a possible state
682683
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TEST_TX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ACK);
683684

684-
esp_ieee802154_transmit_sfd_done(s_tx_frame);
685+
ieee802154_inner_transmit_sfd_done(s_tx_frame);
685686

686687
events &= (uint16_t)(~IEEE802154_EVENT_TX_SFD_DONE);
687688
}
@@ -832,6 +833,11 @@ esp_err_t ieee802154_mac_deinit(void)
832833
return ret;
833834
}
834835

836+
bool ieee802154_mac_is_inited(void)
837+
{
838+
return s_ieee802154_isr_handle != NULL;
839+
}
840+
835841
IEEE802154_STATIC void start_ed(uint32_t duration)
836842
{
837843
ieee802154_ll_enable_events(IEEE802154_EVENT_ED_DONE);
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <string.h>
8+
#include "esp_check.h"
9+
#include "esp_ieee802154_dev.h"
10+
#include "esp_ieee802154_event.h"
11+
#include "esp_ieee802154_types.h"
12+
#include "esp_ieee802154_util.h"
13+
14+
static esp_ieee802154_event_cb_list_t s_event_cb_list;
15+
16+
esp_err_t ieee802154_event_callback_list_register(esp_ieee802154_event_cb_list_t cb_list)
17+
{
18+
ESP_RETURN_ON_FALSE(!ieee802154_mac_is_inited(), ESP_FAIL, IEEE802154_TAG,
19+
"The event callback register function should be called when the IEEE 802.15.4 subsystem is disabled");
20+
memcpy((void*)(&s_event_cb_list), (void*)(&cb_list), sizeof(esp_ieee802154_event_cb_list_t));
21+
return ESP_OK;
22+
}
23+
esp_err_t ieee802154_event_callback_list_unregister(void)
24+
{
25+
ESP_RETURN_ON_FALSE(!ieee802154_mac_is_inited(), ESP_FAIL, IEEE802154_TAG,
26+
"The event callback unregister function should be called when the IEEE 802.15.4 subsystem is disabled");
27+
memset((void*)(&s_event_cb_list), 0, sizeof(esp_ieee802154_event_cb_list_t));
28+
return ESP_OK;
29+
}
30+
31+
void ieee802154_inner_receive_done(uint8_t *data, esp_ieee802154_frame_info_t *frame_info)
32+
{
33+
if (s_event_cb_list.rx_done_cb) {
34+
s_event_cb_list.rx_done_cb(data, frame_info);
35+
} else {
36+
esp_ieee802154_receive_done(data, frame_info);
37+
}
38+
}
39+
40+
void ieee802154_inner_receive_sfd_done(void)
41+
{
42+
if (s_event_cb_list.rx_sfd_done_cb) {
43+
s_event_cb_list.rx_sfd_done_cb();
44+
} else {
45+
esp_ieee802154_receive_sfd_done();
46+
}
47+
}
48+
49+
void ieee802154_inner_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_ieee802154_frame_info_t *ack_frame_info)
50+
{
51+
if (s_event_cb_list.tx_done_cb) {
52+
s_event_cb_list.tx_done_cb(frame, ack, ack_frame_info);
53+
} else {
54+
esp_ieee802154_transmit_done(frame, ack, ack_frame_info);
55+
}
56+
}
57+
58+
void ieee802154_inner_transmit_failed(const uint8_t *frame, esp_ieee802154_tx_error_t error)
59+
{
60+
if (s_event_cb_list.tx_failed_cb) {
61+
s_event_cb_list.tx_failed_cb(frame, error);
62+
} else {
63+
esp_ieee802154_transmit_failed(frame, error);
64+
}
65+
}
66+
67+
void ieee802154_inner_transmit_sfd_done(uint8_t *frame)
68+
{
69+
if (s_event_cb_list.tx_sfd_done_cb) {
70+
s_event_cb_list.tx_sfd_done_cb(frame);
71+
} else {
72+
esp_ieee802154_transmit_sfd_done(frame);
73+
}
74+
}
75+
76+
void ieee802154_inner_energy_detect_done(int8_t power)
77+
{
78+
if (s_event_cb_list.ed_done_cb) {
79+
s_event_cb_list.ed_done_cb(power);
80+
} else {
81+
esp_ieee802154_energy_detect_done(power);
82+
}
83+
}
84+
85+
esp_err_t ieee802154_inner_enh_ack_generator(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info, uint8_t* enhack_frame)
86+
{
87+
esp_err_t err = ESP_FAIL;
88+
if (s_event_cb_list.enh_ack_generator_cb) {
89+
err = s_event_cb_list.enh_ack_generator_cb(frame, frame_info, enhack_frame);
90+
} else {
91+
err = esp_ieee802154_enh_ack_generator(frame, frame_info, enhack_frame);
92+
}
93+
return err;
94+
}

components/ieee802154/esp_ieee802154.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "esp_phy_init.h"
1313
#include "esp_ieee802154_ack.h"
1414
#include "esp_ieee802154_dev.h"
15+
#include "esp_ieee802154_event.h"
1516
#include "esp_ieee802154_frame.h"
1617
#include "esp_ieee802154_pib.h"
1718
#include "esp_ieee802154_sec.h"
@@ -21,6 +22,15 @@
2122
#include "hal/ieee802154_ll.h"
2223
#include "hal/ieee802154_common_ll.h"
2324

25+
esp_err_t esp_ieee802154_event_callback_list_register(esp_ieee802154_event_cb_list_t cb_list)
26+
{
27+
return ieee802154_event_callback_list_register(cb_list);
28+
}
29+
esp_err_t esp_ieee802154_event_callback_list_unregister(void)
30+
{
31+
return ieee802154_event_callback_list_unregister();
32+
}
33+
2434
esp_err_t esp_ieee802154_enable(void)
2535
{
2636
ieee802154_enable();

components/ieee802154/include/esp_ieee802154.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,32 @@ void esp_ieee802154_set_coex_config(esp_ieee802154_coex_config_t config);
724724
esp_ieee802154_coex_config_t esp_ieee802154_get_coex_config(void);
725725
#endif
726726

727+
/**
728+
* @brief Register process callbacks for events generated by the IEEE 802.15.4 subsystem.
729+
*
730+
* @param[in] cb_list The event process callback list, please refer to `esp_ieee802154_event_cb_list_t`.
731+
*
732+
* @note This API should be called only when IEEE 802.15.4 subsystem is not enabled
733+
* or after IEEE 802.15.4 subsystem is disabled (refer to `esp_ieee802154_disable`).
734+
*
735+
* @return
736+
* - ESP_OK on success.
737+
* - ESP_FAIL on failure.
738+
*/
739+
esp_err_t esp_ieee802154_event_callback_list_register(esp_ieee802154_event_cb_list_t cb_list);
740+
741+
/**
742+
* @brief Unregister process callbacks for events generated by the IEEE 802.15.4 subsystem.
743+
*
744+
* @note This API should be called only when IEEE 802.15.4 subsystem is not enabled
745+
* or after IEEE 802.15.4 subsystem is disabled (refer to `esp_ieee802154_disable`).
746+
*
747+
* @return
748+
* - ESP_OK on success.
749+
* - ESP_FAIL on failure.
750+
*/
751+
esp_err_t esp_ieee802154_event_callback_list_unregister(void);
752+
727753
#ifdef __cplusplus
728754
}
729755
#endif

0 commit comments

Comments
 (0)