Skip to content

Commit f9623fc

Browse files
committed
ieee802154: copy component from ESP-IDF
Commit hash in ESP-IDF: a2f420a36ecf8cd19b443adde1d75e5eaecc6309 Signed-off-by: Martin Jäger <[email protected]>
1 parent 0399469 commit f9623fc

28 files changed

+5293
-0
lines changed

components/ieee802154/CMakeLists.txt

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
idf_build_get_property(target IDF_TARGET)
2+
3+
if(${target} STREQUAL "linux")
4+
return() # This component is not supported by the POSIX/Linux simulator
5+
endif()
6+
7+
set(srcs "")
8+
set(include "include")
9+
set(private_include "")
10+
11+
if(CONFIG_IEEE802154_ENABLED)
12+
list(APPEND srcs "esp_ieee802154.c"
13+
"driver/esp_ieee802154_ack.c"
14+
"driver/esp_ieee802154_dev.c"
15+
"driver/esp_ieee802154_frame.c"
16+
"driver/esp_ieee802154_pib.c"
17+
"driver/esp_ieee802154_util.c"
18+
"driver/esp_ieee802154_sec.c"
19+
"driver/esp_ieee802154_timer.c")
20+
list(APPEND private_include "private_include")
21+
22+
if(CONFIG_IEEE802154_TEST)
23+
list(REMOVE_ITEM private_include "private_include")
24+
list(APPEND include "private_include")
25+
endif()
26+
27+
endif()
28+
29+
if(CONFIG_IEEE802154_DEBUG)
30+
list(APPEND srcs "driver/esp_ieee802154_debug.c")
31+
endif()
32+
33+
idf_component_register(
34+
SRCS "${srcs}"
35+
INCLUDE_DIRS "${include}"
36+
PRIV_INCLUDE_DIRS "${private_include}"
37+
LDFRAGMENTS linker.lf
38+
PRIV_REQUIRES esp_phy esp_timer esp_coex soc hal esp_pm
39+
)

components/ieee802154/Kconfig

+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
menu "IEEE 802.15.4"
2+
visible if SOC_IEEE802154_SUPPORTED
3+
4+
config IEEE802154_ENABLED
5+
bool "IEEE802154 Enable"
6+
default "y" if SOC_IEEE802154_SUPPORTED
7+
8+
config IEEE802154_RX_BUFFER_SIZE
9+
int "The number of 802.15.4 receive buffers"
10+
depends on IEEE802154_ENABLED
11+
default 20
12+
range 2 100
13+
help
14+
The number of 802.15.4 receive buffers
15+
16+
choice IEEE802154_CCA_MODE
17+
depends on IEEE802154_ENABLED
18+
prompt "Clear Channel Assessment (CCA) mode"
19+
default IEEE802154_CCA_ED
20+
help
21+
configure the CCA mode
22+
23+
config IEEE802154_CCA_CARRIER
24+
bool "Carrier sense only"
25+
help
26+
configure the CCA mode to Energy above threshold
27+
28+
config IEEE802154_CCA_ED
29+
bool "Energy above threshold"
30+
help
31+
configure the CCA mode to Energy above threshold
32+
33+
config IEEE802154_CCA_CARRIER_OR_ED
34+
bool "Carrier sense OR energy above threshold"
35+
help
36+
configure the CCA mode to Carrier sense OR energy above threshold
37+
38+
config IEEE802154_CCA_CARRIER_AND_ED
39+
bool "Carrier sense AND energy above threshold"
40+
help
41+
configure the CCA mode to Carrier sense AND energy above threshold
42+
endchoice
43+
44+
config IEEE802154_CCA_MODE
45+
depends on IEEE802154_ENABLED
46+
int
47+
default 0 if IEEE802154_CCA_CARRIER
48+
default 1 if IEEE802154_CCA_ED
49+
default 2 if IEEE802154_CCA_CARRIER_OR_ED
50+
default 3 if IEEE802154_CCA_CARRIER_AND_ED
51+
52+
config IEEE802154_CCA_THRESHOLD
53+
int "CCA detection threshold"
54+
depends on IEEE802154_ENABLED
55+
range -120 0
56+
default -60
57+
help
58+
set the CCA threshold, in dB
59+
60+
config IEEE802154_PENDING_TABLE_SIZE
61+
int "Pending table size"
62+
depends on IEEE802154_ENABLED
63+
range 1 100
64+
default 20
65+
help
66+
set the pending table size
67+
68+
config IEEE802154_MULTI_PAN_ENABLE
69+
bool "Enable multi-pan feature for frame filter"
70+
depends on IEEE802154_ENABLED
71+
default n
72+
help
73+
Enable IEEE802154 multi-pan
74+
75+
config IEEE802154_TIMING_OPTIMIZATION
76+
bool "Enable throughput optimization"
77+
depends on IEEE802154_ENABLED
78+
default n
79+
help
80+
Enabling this option increases throughput by ~5% at the expense of ~2.1k
81+
IRAM code size increase.
82+
83+
config IEEE802154_SLEEP_ENABLE
84+
# Todo: Remove when support safe power-down of the power domain (IDF-7317)
85+
bool "Enable IEEE802154 light sleep"
86+
depends on PM_ENABLE && IEEE802154_ENABLED
87+
default n
88+
help
89+
Enabling this option allows the IEEE802.15.4 module to be powered down during automatic light sleep,
90+
which reduces current consumption.
91+
92+
menuconfig IEEE802154_DEBUG
93+
bool "Enable IEEE802154 Debug"
94+
depends on IEEE802154_ENABLED
95+
default n
96+
help
97+
Enabling this option allows different kinds of IEEE802154 debug output.
98+
All IEEE802154 debug features increase the size of the final binary.
99+
100+
config IEEE802154_ASSERT
101+
bool "Enrich the assert information with IEEE802154 state and event"
102+
depends on IEEE802154_DEBUG
103+
default n
104+
help
105+
Enabling this option to add some probe codes in the driver, and these informations
106+
will be printed when assert.
107+
108+
config IEEE802154_RECORD_EVENT
109+
bool "Enable record event information for debugging"
110+
depends on IEEE802154_DEBUG
111+
default n
112+
help
113+
Enabling this option to record event, when assert, the recorded event will be printed.
114+
115+
config IEEE802154_RECORD_EVENT_SIZE
116+
int "Record event table size"
117+
depends on IEEE802154_RECORD_EVENT
118+
range 1 50
119+
default 30
120+
help
121+
set the record event table size
122+
123+
config IEEE802154_RECORD_STATE
124+
bool "Enable record state information for debugging"
125+
depends on IEEE802154_DEBUG
126+
default n
127+
help
128+
Enabling this option to record state, when assert, the recorded state will be printed.
129+
130+
config IEEE802154_RECORD_STATE_SIZE
131+
int "Record state table size"
132+
depends on IEEE802154_RECORD_STATE
133+
range 1 50
134+
default 10
135+
help
136+
set the record state table size
137+
138+
config IEEE802154_RECORD_CMD
139+
bool "Enable record command information for debugging"
140+
depends on IEEE802154_DEBUG
141+
default n
142+
help
143+
Enabling this option to record the command, when assert, the recorded
144+
command will be printed.
145+
146+
config IEEE802154_RECORD_CMD_SIZE
147+
int "Record command table size"
148+
depends on IEEE802154_RECORD_CMD
149+
range 1 50
150+
default 10
151+
help
152+
set the record command table size
153+
154+
config IEEE802154_RECORD_ABORT
155+
bool "Enable record abort information for debugging"
156+
depends on IEEE802154_DEBUG
157+
default n
158+
help
159+
Enabling this option to record the abort, when assert, the recorded
160+
abort will be printed.
161+
162+
config IEEE802154_RECORD_ABORT_SIZE
163+
int "Record abort table size"
164+
depends on IEEE802154_RECORD_ABORT
165+
range 1 50
166+
default 10
167+
help
168+
set the record abort table size
169+
170+
config IEEE802154_TXRX_STATISTIC
171+
bool "Enable record tx/rx packets information for debugging"
172+
depends on IEEE802154_DEBUG
173+
default n
174+
help
175+
Enabling this option to record the tx and rx
176+
endmenu # IEEE 802.15.4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <string.h>
8+
#include "hal/ieee802154_ll.h"
9+
#include "esp_attr.h"
10+
#include "esp_err.h"
11+
#include "esp_ieee802154_ack.h"
12+
#include "esp_ieee802154_dev.h"
13+
#include "esp_ieee802154_frame.h"
14+
#include "esp_ieee802154_pib.h"
15+
#include "esp_ieee802154_types.h"
16+
#include "esp_ieee802154_util.h"
17+
18+
static ieee802154_pending_table_t ieee802154_pending_table;
19+
20+
#define GET_MASK_ITEM_FROM_TABLE(mask, pos) (mask[(pos) / IEEE802154_PENDING_TABLE_MASK_BITS])
21+
22+
#define BIT_SET(mask, pos) (GET_MASK_ITEM_FROM_TABLE(mask, pos) |= (1UL << (pos % IEEE802154_PENDING_TABLE_MASK_BITS)))
23+
#define BIT_CLR(mask, pos) (GET_MASK_ITEM_FROM_TABLE(mask, pos) &= ~(1UL << (pos % IEEE802154_PENDING_TABLE_MASK_BITS)))
24+
#define BIT_IST(mask, pos) (GET_MASK_ITEM_FROM_TABLE(mask, pos) & (1UL << (pos % IEEE802154_PENDING_TABLE_MASK_BITS)))
25+
26+
static IRAM_ATTR bool ieee802154_addr_in_pending_table(const uint8_t *addr, bool is_short)
27+
{
28+
bool ret = false;
29+
if (is_short) {
30+
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) {
31+
if (BIT_IST(ieee802154_pending_table.short_addr_mask, index) &&
32+
memcmp(addr, ieee802154_pending_table.short_addr[index], IEEE802154_FRAME_SHORT_ADDR_SIZE) == 0) {
33+
ret = true;
34+
break;
35+
}
36+
}
37+
} else {
38+
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) {
39+
if (BIT_IST(ieee802154_pending_table.ext_addr_mask, index) &&
40+
memcmp(addr, ieee802154_pending_table.ext_addr[index], IEEE802154_FRAME_EXT_ADDR_SIZE) == 0) {
41+
ret = true;
42+
break;
43+
}
44+
}
45+
}
46+
return ret;
47+
}
48+
49+
esp_err_t ieee802154_add_pending_addr(const uint8_t *addr, bool is_short)
50+
{
51+
esp_err_t ret = ESP_FAIL;
52+
int8_t first_empty_index = -1;
53+
if (is_short) {
54+
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) {
55+
if (!BIT_IST(ieee802154_pending_table.short_addr_mask, index)) {
56+
// record the first empty index
57+
first_empty_index = (first_empty_index == -1 ? index : first_empty_index);
58+
} else if (memcmp(addr, ieee802154_pending_table.short_addr[index], IEEE802154_FRAME_SHORT_ADDR_SIZE) == 0) {
59+
// The address is in the table already.
60+
ret = ESP_OK;
61+
return ret;
62+
}
63+
}
64+
if (first_empty_index != -1) {
65+
memcpy(ieee802154_pending_table.short_addr[first_empty_index], addr, IEEE802154_FRAME_SHORT_ADDR_SIZE);
66+
BIT_SET(ieee802154_pending_table.short_addr_mask, first_empty_index);
67+
ret = ESP_OK;
68+
}
69+
} else {
70+
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) {
71+
if (!BIT_IST(ieee802154_pending_table.ext_addr_mask, index)) {
72+
first_empty_index = (first_empty_index == -1 ? index : first_empty_index);
73+
} else if (memcmp(addr, ieee802154_pending_table.ext_addr[index], IEEE802154_FRAME_EXT_ADDR_SIZE) == 0) {
74+
// The address is already in the pending table.
75+
ret = ESP_OK;
76+
return ret;
77+
}
78+
}
79+
if (first_empty_index != -1) {
80+
memcpy(ieee802154_pending_table.ext_addr[first_empty_index], addr, IEEE802154_FRAME_EXT_ADDR_SIZE);
81+
BIT_SET(ieee802154_pending_table.ext_addr_mask, first_empty_index);
82+
ret = ESP_OK;
83+
}
84+
}
85+
return ret;
86+
}
87+
88+
esp_err_t ieee802154_clear_pending_addr(const uint8_t *addr, bool is_short)
89+
{
90+
esp_err_t ret = ESP_FAIL;
91+
// Consider this function may be called in ISR, only clear the mask bits for finishing the process quickly.
92+
if (is_short) {
93+
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) {
94+
if (BIT_IST(ieee802154_pending_table.short_addr_mask, index) &&
95+
memcmp(addr, ieee802154_pending_table.short_addr[index], IEEE802154_FRAME_SHORT_ADDR_SIZE) == 0) {
96+
BIT_CLR(ieee802154_pending_table.short_addr_mask, index);
97+
ret = ESP_OK;
98+
break;
99+
}
100+
}
101+
} else {
102+
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) {
103+
if (BIT_IST(ieee802154_pending_table.ext_addr_mask, index) &&
104+
memcmp(addr, ieee802154_pending_table.ext_addr[index], IEEE802154_FRAME_EXT_ADDR_SIZE) == 0) {
105+
BIT_CLR(ieee802154_pending_table.ext_addr_mask, index);
106+
ret = ESP_OK;
107+
break;
108+
}
109+
}
110+
}
111+
112+
return ret;
113+
}
114+
115+
void ieee802154_reset_pending_table(bool is_short)
116+
{
117+
// Consider this function may be called in ISR, only clear the mask bits for finishing the process quickly.
118+
if (is_short) {
119+
memset(ieee802154_pending_table.short_addr_mask, 0, IEEE802154_PENDING_TABLE_MASK_SIZE);
120+
} else {
121+
memset(ieee802154_pending_table.ext_addr_mask, 0, IEEE802154_PENDING_TABLE_MASK_SIZE);
122+
}
123+
}
124+
125+
bool ieee802154_ack_config_pending_bit(const uint8_t *frame)
126+
{
127+
bool pending_bit = false;
128+
uint8_t addr[IEEE802154_FRAME_EXT_ADDR_SIZE] = {0};
129+
uint8_t src_mode = 0;
130+
// Only set the HW pending bit for the frames with version 0b00 or 0b01.
131+
bool set_to_hw = (ieee802154_frame_get_version(frame) <= IEEE802154_FRAME_VERSION_1);
132+
133+
ieee802154_ll_pending_mode_t pending_mode = ieee802154_pib_get_pending_mode();
134+
135+
switch (pending_mode) {
136+
case IEEE802154_AUTO_PENDING_DISABLE:
137+
// HW will check whether the frame is data request or not
138+
pending_bit = true;
139+
break;
140+
case IEEE802154_AUTO_PENDING_ENABLE:
141+
case IEEE802154_AUTO_PENDING_ENHANCED:
142+
src_mode = ieee802154_frame_get_src_addr(frame, addr);
143+
144+
if (src_mode == IEEE802154_FRAME_SRC_MODE_SHORT || src_mode == IEEE802154_FRAME_SRC_MODE_EXT) {
145+
if (ieee802154_addr_in_pending_table(addr, src_mode == IEEE802154_FRAME_SRC_MODE_SHORT)) {
146+
pending_bit = true;
147+
}
148+
}
149+
break;
150+
case IEEE802154_AUTO_PENDING_ZIGBEE:
151+
// If the address type is short and in pending table, set 'pending_bit' false, otherwise set true.
152+
src_mode = ieee802154_frame_get_src_addr(frame, addr);
153+
pending_bit = true;
154+
if (src_mode == IEEE802154_FRAME_SRC_MODE_SHORT && ieee802154_addr_in_pending_table(addr, src_mode == IEEE802154_FRAME_SRC_MODE_SHORT)) {
155+
pending_bit = false;
156+
}
157+
break;
158+
default:
159+
IEEE802154_ASSERT(false);
160+
}
161+
162+
if (set_to_hw) {
163+
ieee802154_ll_set_pending_bit(pending_bit);
164+
}
165+
166+
return pending_bit;
167+
}

0 commit comments

Comments
 (0)