-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ieee802154: copy component from ESP-IDF
Commit hash in ESP-IDF: a2f420a36ecf8cd19b443adde1d75e5eaecc6309 Signed-off-by: Martin Jäger <[email protected]>
- Loading branch information
1 parent
8d35aa7
commit 3efa906
Showing
28 changed files
with
5,293 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
idf_build_get_property(target IDF_TARGET) | ||
|
||
if(${target} STREQUAL "linux") | ||
return() # This component is not supported by the POSIX/Linux simulator | ||
endif() | ||
|
||
set(srcs "") | ||
set(include "include") | ||
set(private_include "") | ||
|
||
if(CONFIG_IEEE802154_ENABLED) | ||
list(APPEND srcs "esp_ieee802154.c" | ||
"driver/esp_ieee802154_ack.c" | ||
"driver/esp_ieee802154_dev.c" | ||
"driver/esp_ieee802154_frame.c" | ||
"driver/esp_ieee802154_pib.c" | ||
"driver/esp_ieee802154_util.c" | ||
"driver/esp_ieee802154_sec.c" | ||
"driver/esp_ieee802154_timer.c") | ||
list(APPEND private_include "private_include") | ||
|
||
if(CONFIG_IEEE802154_TEST) | ||
list(REMOVE_ITEM private_include "private_include") | ||
list(APPEND include "private_include") | ||
endif() | ||
|
||
endif() | ||
|
||
if(CONFIG_IEEE802154_DEBUG) | ||
list(APPEND srcs "driver/esp_ieee802154_debug.c") | ||
endif() | ||
|
||
idf_component_register( | ||
SRCS "${srcs}" | ||
INCLUDE_DIRS "${include}" | ||
PRIV_INCLUDE_DIRS "${private_include}" | ||
LDFRAGMENTS linker.lf | ||
PRIV_REQUIRES esp_phy esp_timer esp_coex soc hal esp_pm | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
menu "IEEE 802.15.4" | ||
visible if SOC_IEEE802154_SUPPORTED | ||
|
||
config IEEE802154_ENABLED | ||
bool "IEEE802154 Enable" | ||
default "y" if SOC_IEEE802154_SUPPORTED | ||
|
||
config IEEE802154_RX_BUFFER_SIZE | ||
int "The number of 802.15.4 receive buffers" | ||
depends on IEEE802154_ENABLED | ||
default 20 | ||
range 2 100 | ||
help | ||
The number of 802.15.4 receive buffers | ||
|
||
choice IEEE802154_CCA_MODE | ||
depends on IEEE802154_ENABLED | ||
prompt "Clear Channel Assessment (CCA) mode" | ||
default IEEE802154_CCA_ED | ||
help | ||
configure the CCA mode | ||
|
||
config IEEE802154_CCA_CARRIER | ||
bool "Carrier sense only" | ||
help | ||
configure the CCA mode to Energy above threshold | ||
|
||
config IEEE802154_CCA_ED | ||
bool "Energy above threshold" | ||
help | ||
configure the CCA mode to Energy above threshold | ||
|
||
config IEEE802154_CCA_CARRIER_OR_ED | ||
bool "Carrier sense OR energy above threshold" | ||
help | ||
configure the CCA mode to Carrier sense OR energy above threshold | ||
|
||
config IEEE802154_CCA_CARRIER_AND_ED | ||
bool "Carrier sense AND energy above threshold" | ||
help | ||
configure the CCA mode to Carrier sense AND energy above threshold | ||
endchoice | ||
|
||
config IEEE802154_CCA_MODE | ||
depends on IEEE802154_ENABLED | ||
int | ||
default 0 if IEEE802154_CCA_CARRIER | ||
default 1 if IEEE802154_CCA_ED | ||
default 2 if IEEE802154_CCA_CARRIER_OR_ED | ||
default 3 if IEEE802154_CCA_CARRIER_AND_ED | ||
|
||
config IEEE802154_CCA_THRESHOLD | ||
int "CCA detection threshold" | ||
depends on IEEE802154_ENABLED | ||
range -120 0 | ||
default -60 | ||
help | ||
set the CCA threshold, in dB | ||
|
||
config IEEE802154_PENDING_TABLE_SIZE | ||
int "Pending table size" | ||
depends on IEEE802154_ENABLED | ||
range 1 100 | ||
default 20 | ||
help | ||
set the pending table size | ||
|
||
config IEEE802154_MULTI_PAN_ENABLE | ||
bool "Enable multi-pan feature for frame filter" | ||
depends on IEEE802154_ENABLED | ||
default n | ||
help | ||
Enable IEEE802154 multi-pan | ||
|
||
config IEEE802154_TIMING_OPTIMIZATION | ||
bool "Enable throughput optimization" | ||
depends on IEEE802154_ENABLED | ||
default n | ||
help | ||
Enabling this option increases throughput by ~5% at the expense of ~2.1k | ||
IRAM code size increase. | ||
|
||
config IEEE802154_SLEEP_ENABLE | ||
# Todo: Remove when support safe power-down of the power domain (IDF-7317) | ||
bool "Enable IEEE802154 light sleep" | ||
depends on PM_ENABLE && IEEE802154_ENABLED | ||
default n | ||
help | ||
Enabling this option allows the IEEE802.15.4 module to be powered down during automatic light sleep, | ||
which reduces current consumption. | ||
|
||
menuconfig IEEE802154_DEBUG | ||
bool "Enable IEEE802154 Debug" | ||
depends on IEEE802154_ENABLED | ||
default n | ||
help | ||
Enabling this option allows different kinds of IEEE802154 debug output. | ||
All IEEE802154 debug features increase the size of the final binary. | ||
|
||
config IEEE802154_ASSERT | ||
bool "Enrich the assert information with IEEE802154 state and event" | ||
depends on IEEE802154_DEBUG | ||
default n | ||
help | ||
Enabling this option to add some probe codes in the driver, and these informations | ||
will be printed when assert. | ||
|
||
config IEEE802154_RECORD_EVENT | ||
bool "Enable record event information for debugging" | ||
depends on IEEE802154_DEBUG | ||
default n | ||
help | ||
Enabling this option to record event, when assert, the recorded event will be printed. | ||
|
||
config IEEE802154_RECORD_EVENT_SIZE | ||
int "Record event table size" | ||
depends on IEEE802154_RECORD_EVENT | ||
range 1 50 | ||
default 30 | ||
help | ||
set the record event table size | ||
|
||
config IEEE802154_RECORD_STATE | ||
bool "Enable record state information for debugging" | ||
depends on IEEE802154_DEBUG | ||
default n | ||
help | ||
Enabling this option to record state, when assert, the recorded state will be printed. | ||
|
||
config IEEE802154_RECORD_STATE_SIZE | ||
int "Record state table size" | ||
depends on IEEE802154_RECORD_STATE | ||
range 1 50 | ||
default 10 | ||
help | ||
set the record state table size | ||
|
||
config IEEE802154_RECORD_CMD | ||
bool "Enable record command information for debugging" | ||
depends on IEEE802154_DEBUG | ||
default n | ||
help | ||
Enabling this option to record the command, when assert, the recorded | ||
command will be printed. | ||
|
||
config IEEE802154_RECORD_CMD_SIZE | ||
int "Record command table size" | ||
depends on IEEE802154_RECORD_CMD | ||
range 1 50 | ||
default 10 | ||
help | ||
set the record command table size | ||
|
||
config IEEE802154_RECORD_ABORT | ||
bool "Enable record abort information for debugging" | ||
depends on IEEE802154_DEBUG | ||
default n | ||
help | ||
Enabling this option to record the abort, when assert, the recorded | ||
abort will be printed. | ||
|
||
config IEEE802154_RECORD_ABORT_SIZE | ||
int "Record abort table size" | ||
depends on IEEE802154_RECORD_ABORT | ||
range 1 50 | ||
default 10 | ||
help | ||
set the record abort table size | ||
|
||
config IEEE802154_TXRX_STATISTIC | ||
bool "Enable record tx/rx packets information for debugging" | ||
depends on IEEE802154_DEBUG | ||
default n | ||
help | ||
Enabling this option to record the tx and rx | ||
endmenu # IEEE 802.15.4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <string.h> | ||
#include "hal/ieee802154_ll.h" | ||
#include "esp_attr.h" | ||
#include "esp_err.h" | ||
#include "esp_ieee802154_ack.h" | ||
#include "esp_ieee802154_dev.h" | ||
#include "esp_ieee802154_frame.h" | ||
#include "esp_ieee802154_pib.h" | ||
#include "esp_ieee802154_types.h" | ||
#include "esp_ieee802154_util.h" | ||
|
||
static ieee802154_pending_table_t ieee802154_pending_table; | ||
|
||
#define GET_MASK_ITEM_FROM_TABLE(mask, pos) (mask[(pos) / IEEE802154_PENDING_TABLE_MASK_BITS]) | ||
|
||
#define BIT_SET(mask, pos) (GET_MASK_ITEM_FROM_TABLE(mask, pos) |= (1UL << (pos % IEEE802154_PENDING_TABLE_MASK_BITS))) | ||
#define BIT_CLR(mask, pos) (GET_MASK_ITEM_FROM_TABLE(mask, pos) &= ~(1UL << (pos % IEEE802154_PENDING_TABLE_MASK_BITS))) | ||
#define BIT_IST(mask, pos) (GET_MASK_ITEM_FROM_TABLE(mask, pos) & (1UL << (pos % IEEE802154_PENDING_TABLE_MASK_BITS))) | ||
|
||
static IRAM_ATTR bool ieee802154_addr_in_pending_table(const uint8_t *addr, bool is_short) | ||
{ | ||
bool ret = false; | ||
if (is_short) { | ||
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) { | ||
if (BIT_IST(ieee802154_pending_table.short_addr_mask, index) && | ||
memcmp(addr, ieee802154_pending_table.short_addr[index], IEEE802154_FRAME_SHORT_ADDR_SIZE) == 0) { | ||
ret = true; | ||
break; | ||
} | ||
} | ||
} else { | ||
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) { | ||
if (BIT_IST(ieee802154_pending_table.ext_addr_mask, index) && | ||
memcmp(addr, ieee802154_pending_table.ext_addr[index], IEEE802154_FRAME_EXT_ADDR_SIZE) == 0) { | ||
ret = true; | ||
break; | ||
} | ||
} | ||
} | ||
return ret; | ||
} | ||
|
||
esp_err_t ieee802154_add_pending_addr(const uint8_t *addr, bool is_short) | ||
{ | ||
esp_err_t ret = ESP_FAIL; | ||
int8_t first_empty_index = -1; | ||
if (is_short) { | ||
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) { | ||
if (!BIT_IST(ieee802154_pending_table.short_addr_mask, index)) { | ||
// record the first empty index | ||
first_empty_index = (first_empty_index == -1 ? index : first_empty_index); | ||
} else if (memcmp(addr, ieee802154_pending_table.short_addr[index], IEEE802154_FRAME_SHORT_ADDR_SIZE) == 0) { | ||
// The address is in the table already. | ||
ret = ESP_OK; | ||
return ret; | ||
} | ||
} | ||
if (first_empty_index != -1) { | ||
memcpy(ieee802154_pending_table.short_addr[first_empty_index], addr, IEEE802154_FRAME_SHORT_ADDR_SIZE); | ||
BIT_SET(ieee802154_pending_table.short_addr_mask, first_empty_index); | ||
ret = ESP_OK; | ||
} | ||
} else { | ||
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) { | ||
if (!BIT_IST(ieee802154_pending_table.ext_addr_mask, index)) { | ||
first_empty_index = (first_empty_index == -1 ? index : first_empty_index); | ||
} else if (memcmp(addr, ieee802154_pending_table.ext_addr[index], IEEE802154_FRAME_EXT_ADDR_SIZE) == 0) { | ||
// The address is already in the pending table. | ||
ret = ESP_OK; | ||
return ret; | ||
} | ||
} | ||
if (first_empty_index != -1) { | ||
memcpy(ieee802154_pending_table.ext_addr[first_empty_index], addr, IEEE802154_FRAME_EXT_ADDR_SIZE); | ||
BIT_SET(ieee802154_pending_table.ext_addr_mask, first_empty_index); | ||
ret = ESP_OK; | ||
} | ||
} | ||
return ret; | ||
} | ||
|
||
esp_err_t ieee802154_clear_pending_addr(const uint8_t *addr, bool is_short) | ||
{ | ||
esp_err_t ret = ESP_FAIL; | ||
// Consider this function may be called in ISR, only clear the mask bits for finishing the process quickly. | ||
if (is_short) { | ||
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) { | ||
if (BIT_IST(ieee802154_pending_table.short_addr_mask, index) && | ||
memcmp(addr, ieee802154_pending_table.short_addr[index], IEEE802154_FRAME_SHORT_ADDR_SIZE) == 0) { | ||
BIT_CLR(ieee802154_pending_table.short_addr_mask, index); | ||
ret = ESP_OK; | ||
break; | ||
} | ||
} | ||
} else { | ||
for (uint8_t index = 0; index < CONFIG_IEEE802154_PENDING_TABLE_SIZE; index++) { | ||
if (BIT_IST(ieee802154_pending_table.ext_addr_mask, index) && | ||
memcmp(addr, ieee802154_pending_table.ext_addr[index], IEEE802154_FRAME_EXT_ADDR_SIZE) == 0) { | ||
BIT_CLR(ieee802154_pending_table.ext_addr_mask, index); | ||
ret = ESP_OK; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
void ieee802154_reset_pending_table(bool is_short) | ||
{ | ||
// Consider this function may be called in ISR, only clear the mask bits for finishing the process quickly. | ||
if (is_short) { | ||
memset(ieee802154_pending_table.short_addr_mask, 0, IEEE802154_PENDING_TABLE_MASK_SIZE); | ||
} else { | ||
memset(ieee802154_pending_table.ext_addr_mask, 0, IEEE802154_PENDING_TABLE_MASK_SIZE); | ||
} | ||
} | ||
|
||
bool ieee802154_ack_config_pending_bit(const uint8_t *frame) | ||
{ | ||
bool pending_bit = false; | ||
uint8_t addr[IEEE802154_FRAME_EXT_ADDR_SIZE] = {0}; | ||
uint8_t src_mode = 0; | ||
// Only set the HW pending bit for the frames with version 0b00 or 0b01. | ||
bool set_to_hw = (ieee802154_frame_get_version(frame) <= IEEE802154_FRAME_VERSION_1); | ||
|
||
ieee802154_ll_pending_mode_t pending_mode = ieee802154_pib_get_pending_mode(); | ||
|
||
switch (pending_mode) { | ||
case IEEE802154_AUTO_PENDING_DISABLE: | ||
// HW will check whether the frame is data request or not | ||
pending_bit = true; | ||
break; | ||
case IEEE802154_AUTO_PENDING_ENABLE: | ||
case IEEE802154_AUTO_PENDING_ENHANCED: | ||
src_mode = ieee802154_frame_get_src_addr(frame, addr); | ||
|
||
if (src_mode == IEEE802154_FRAME_SRC_MODE_SHORT || src_mode == IEEE802154_FRAME_SRC_MODE_EXT) { | ||
if (ieee802154_addr_in_pending_table(addr, src_mode == IEEE802154_FRAME_SRC_MODE_SHORT)) { | ||
pending_bit = true; | ||
} | ||
} | ||
break; | ||
case IEEE802154_AUTO_PENDING_ZIGBEE: | ||
// If the address type is short and in pending table, set 'pending_bit' false, otherwise set true. | ||
src_mode = ieee802154_frame_get_src_addr(frame, addr); | ||
pending_bit = true; | ||
if (src_mode == IEEE802154_FRAME_SRC_MODE_SHORT && ieee802154_addr_in_pending_table(addr, src_mode == IEEE802154_FRAME_SRC_MODE_SHORT)) { | ||
pending_bit = false; | ||
} | ||
break; | ||
default: | ||
IEEE802154_ASSERT(false); | ||
} | ||
|
||
if (set_to_hw) { | ||
ieee802154_ll_set_pending_bit(pending_bit); | ||
} | ||
|
||
return pending_bit; | ||
} |
Oops, something went wrong.