diff --git a/components/esp_phy/lib b/components/esp_phy/lib index 03c270c901..0e8bbc5b3e 160000 --- a/components/esp_phy/lib +++ b/components/esp_phy/lib @@ -1 +1 @@ -Subproject commit 03c270c901c1106931ea6299523928c64d457b91 +Subproject commit 0e8bbc5b3e9d8aa99b00a2eba5acfd29f5fd3a66 diff --git a/components/hal/esp32c6/include/hal/ieee802154_ll.h b/components/hal/esp32c6/include/hal/ieee802154_ll.h new file mode 100644 index 0000000000..43b90e0925 --- /dev/null +++ b/components/hal/esp32c6/include/hal/ieee802154_ll.h @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "hal/ieee802154_common_ll.h" + +#define IEEE802154_TXPOWER_VALUE_MAX 21 +#define IEEE802154_TXPOWER_VALUE_MIN -24 diff --git a/components/hal/esp32h2/include/hal/ieee802154_ll.h b/components/hal/esp32h2/include/hal/ieee802154_ll.h new file mode 100644 index 0000000000..43b90e0925 --- /dev/null +++ b/components/hal/esp32h2/include/hal/ieee802154_ll.h @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "hal/ieee802154_common_ll.h" + +#define IEEE802154_TXPOWER_VALUE_MAX 21 +#define IEEE802154_TXPOWER_VALUE_MIN -24 diff --git a/components/hal/include/hal/ieee802154_common_ll.h b/components/hal/include/hal/ieee802154_common_ll.h new file mode 100644 index 0000000000..45f077bb4a --- /dev/null +++ b/components/hal/include/hal/ieee802154_common_ll.h @@ -0,0 +1,454 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "soc/ieee802154_reg.h" +#include "soc/ieee802154_struct.h" +#include "esp_attr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief IEEE802154 opcode. + */ +typedef enum { + IEEE802154_CMD_TX_START = 0x41, + IEEE802154_CMD_RX_START = 0x42, + IEEE802154_CMD_CCA_TX_START = 0x43, + IEEE802154_CMD_ED_START = 0x44, + IEEE802154_CMD_STOP = 0x45, + IEEE802154_CMD_TEST_TX_START = 0x46, + IEEE802154_CMD_TEST_RX_START = 0x47, + IEEE802154_CMD_TEST_STOP = 0x48, + IEEE802154_CMD_TIMER0_START = 0x4C, + IEEE802154_CMD_TIMER0_STOP = 0x4D, + IEEE802154_CMD_TIMER1_START = 0x4E, + IEEE802154_CMD_TIMER1_STOP = 0x4F, +} ieee802154_ll_cmd_t; + +/** + * @brief IEEE802154 interrupt. + */ +typedef enum { + IEEE802154_EVENT_TX_DONE = BIT(0), + IEEE802154_EVENT_RX_DONE = BIT(1), + IEEE802154_EVENT_ACK_TX_DONE = BIT(2), + IEEE802154_EVENT_ACK_RX_DONE = BIT(3), + IEEE802154_EVENT_RX_ABORT = BIT(4), + IEEE802154_EVENT_TX_ABORT = BIT(5), + IEEE802154_EVENT_ED_DONE = BIT(6), + IEEE802154_EVENT_TIMER0_OVERFLOW = BIT(8), + IEEE802154_EVENT_TIMER1_OVERFLOW = BIT(9), + IEEE802154_EVENT_CLOCK_COUNT_MATCH = BIT(10), + IEEE802154_EVENT_TX_SFD_DONE = BIT(11), + IEEE802154_EVENT_RX_SFD_DONE = BIT(12), + IEEE802154_EVENT_MASK = IEEE802154_EVENT_EN, +} ieee802154_ll_event_t; + +typedef uint16_t ieee802154_ll_events; + +/** + * @brief IEEE802154 security transmission failed reason. + */ +typedef enum { + IEEE802154_TX_SEC_FRAME_CTRL_NOT_SET = 0x1, + IEEE802154_TX_SEC_RESERVED_SEC_LEVEL = 0x2, + IEEE802154_TX_SEC_HEADER_PARSE = 0x3, + IEEE802154_TX_SEC_PAYLOAD_ERROR = 0x4, + IEEE802154_TX_SEC_FRAME_COUNTER_SUP = 0x5, +} ieee802154_ll_tx_security_failed_reason_t; + +/** + * @brief IEEE802154 receiving failed reason. + */ +typedef enum { + IEEE802154_RX_ABORT_BY_RX_STOP = 1, + IEEE802154_RX_ABORT_BY_SFD_TIMEOUT = 2, + IEEE802154_RX_ABORT_BY_CRC_ERROR = 3, + IEEE802154_RX_ABORT_BY_INVALID_LEN = 4, + IEEE802154_RX_ABORT_BY_FILTER_FAIL = 5, + IEEE802154_RX_ABORT_BY_NO_RSS = 6, + IEEE802154_RX_ABORT_BY_COEX_BREAK = 7, + IEEE802154_RX_ABORT_BY_UNEXPECTED_ACK = 8, + IEEE802154_RX_ABORT_BY_RX_RESTART = 9, + IEEE802154_RX_ABORT_BY_TX_ACK_TIMEOUT = 16, + IEEE802154_RX_ABORT_BY_TX_ACK_STOP = 17, + IEEE802154_RX_ABORT_BY_TX_ACK_COEX_BREAK = 18, + IEEE802154_RX_ABORT_BY_ENHACK_SECURITY_ERROR = 19, + IEEE802154_RX_ABORT_BY_ED_ABORT = 24, + IEEE802154_RX_ABORT_BY_ED_STOP = 25, + IEEE802154_RX_ABORT_BY_ED_COEX_REJECT = 26, +} ieee802154_ll_rx_abort_reason_t; + +typedef uint32_t ieee802154_ll_rx_abort_events; + +/** + * @brief IEEE802154 transmission failed reason. + */ +typedef enum { + IEEE802154_TX_ABORT_BY_RX_ACK_STOP = 1, + IEEE802154_TX_ABORT_BY_RX_ACK_SFD_TIMEOUT = 2, + IEEE802154_TX_ABORT_BY_RX_ACK_CRC_ERROR = 3, + IEEE802154_TX_ABORT_BY_RX_ACK_INVALID_LEN = 4, + IEEE802154_TX_ABORT_BY_RX_ACK_FILTER_FAIL = 5, + IEEE802154_TX_ABORT_BY_RX_ACK_NO_RSS = 6, + IEEE802154_TX_ABORT_BY_RX_ACK_COEX_BREAK = 7, + IEEE802154_TX_ABORT_BY_RX_ACK_TYPE_NOT_ACK = 8, + IEEE802154_TX_ABORT_BY_RX_ACK_RESTART = 9, + IEEE802154_TX_ABORT_BY_RX_ACK_TIMEOUT = 16, + IEEE802154_TX_ABORT_BY_TX_STOP = 17, + IEEE802154_TX_ABORT_BY_TX_COEX_BREAK = 18, + IEEE802154_TX_ABORT_BY_TX_SECURITY_ERROR = 19, + IEEE802154_TX_ABORT_BY_CCA_FAILED = 24, + IEEE802154_TX_ABORT_BY_CCA_BUSY = 25, +} ieee802154_ll_tx_abort_reason_t; + +typedef uint32_t ieee802154_ll_tx_abort_events; + +/** + * @brief IEEE802154 CCA mode. + */ +typedef enum { + IEEE802154_CCA_MODE_CARRIER = 0x00, + IEEE802154_CCA_MODE_ED = 0x01, + IEEE802154_CCA_MODE_CARRIER_OR_ED = 0x02, + IEEE802154_CCA_MODE_CARRIER_AND_ED = 0x03, +} ieee802154_ll_cca_mode_t; + +/** + * @brief IEEE802154 pending mode. + */ +typedef enum { + IEEE802154_AUTO_PENDING_DISABLE = 0x0, + IEEE802154_AUTO_PENDING_ENABLE = 0x1, + IEEE802154_AUTO_PENDING_ENHANCED = 0x2, + IEEE802154_AUTO_PENDING_ZIGBEE = 0x3, +} ieee802154_ll_pending_mode_t; + +/** + * @brief IEEE802154 ED sample duration. + */ +typedef enum { + IEEE802154_ED_SAMPLE_1_PER_US = 0x00, + IEEE802154_ED_SAMPLE_2_PER_US = 0x01, + IEEE802154_ED_SAMPLE_4_PER_US = 0x02, + IEEE802154_ED_SAMPLE_8_PER_US = 0x03, +} ieee802154_ll_ed_sample_dur_t; + +/** + * @brief IEEE802154 multi-pan index. + */ +typedef enum { + IEEE802154_MULTIPAN_0 = 0, + IEEE802154_MULTIPAN_1 = 1, + IEEE802154_MULTIPAN_2 = 2, + IEEE802154_MULTIPAN_3 = 3, + IEEE802154_MULTIPAN_MAX = 4, +} ieee802154_ll_multipan_index_t; + +/** + * @brief IEEE802154 ED sample mode. + */ +typedef enum { + IEEE802154_ED_SAMPLE_MAX = 0x00, + IEEE802154_ED_SAMPLE_AVG = 0x01, +} ieee802154_ll_ed_sample_mode_t; + +FORCE_INLINE_ATTR void ieee802154_ll_set_cmd(ieee802154_ll_cmd_t cmd) +{ + IEEE802154.cmd.cmd = cmd; +} + +static inline void ieee802154_ll_enable_events(ieee802154_ll_events events) +{ + IEEE802154.event_en.events |= events; +} + +static inline void ieee802154_ll_disable_events(ieee802154_ll_events events) +{ + IEEE802154.event_en.events &= ~events; +} + +FORCE_INLINE_ATTR void ieee802154_ll_clear_events(ieee802154_ll_events events) +{ + IEEE802154.event_status.events &= events; +} + +FORCE_INLINE_ATTR ieee802154_ll_events ieee802154_ll_get_events(void) +{ + return IEEE802154.event_status.events; +} + +static inline void ieee802154_ll_enable_rx_abort_events(ieee802154_ll_rx_abort_events events) +{ + IEEE802154.rx_abort_event_en.rx_abort_en |= events; +} + +static inline void ieee802154_ll_disable_rx_abort_events(ieee802154_ll_rx_abort_events events) +{ + IEEE802154.rx_abort_event_en.rx_abort_en &= ~events; +} + +static inline void ieee802154_ll_enable_tx_abort_events(ieee802154_ll_rx_abort_events events) +{ + IEEE802154.tx_abort_event_en.tx_abort_en |= events; +} + +static inline void ieee802154_ll_disable_tx_abort_events(ieee802154_ll_rx_abort_events events) +{ + IEEE802154.tx_abort_event_en.tx_abort_en &= ~events; +} + +FORCE_INLINE_ATTR void ieee802154_ll_set_rx_addr(uint8_t *addr) +{ + IEEE802154.dma_rx_addr = (uint32_t)addr; +} + +FORCE_INLINE_ATTR void ieee802154_ll_enhack_generate_done_notify(void) +{ + IEEE802154.enhack_generate_done_notify = true; +} + +FORCE_INLINE_ATTR void ieee802154_ll_set_tx_addr(uint8_t *addr) +{ + IEEE802154.dma_tx_addr = (uint32_t)addr; +} + +FORCE_INLINE_ATTR uint32_t ieee802154_ll_get_rx_status(void) +{ + return IEEE802154.rx_status.val; +} + +FORCE_INLINE_ATTR ieee802154_ll_rx_abort_reason_t ieee802154_ll_get_rx_abort_reason(void) +{ + return IEEE802154.rx_status.rx_abort_reason; +} + +FORCE_INLINE_ATTR uint32_t ieee802154_ll_get_tx_status(void) +{ + return IEEE802154.tx_status.val; +} + +FORCE_INLINE_ATTR ieee802154_ll_tx_abort_reason_t ieee802154_ll_get_tx_abort_reason(void) +{ + return IEEE802154.tx_status.tx_abort_reason; +} + +FORCE_INLINE_ATTR ieee802154_ll_tx_security_failed_reason_t ieee802154_ll_get_tx_security_failed_reason(void) +{ + return IEEE802154.tx_status.tx_security_error; +} + +static inline uint8_t ieee802154_ll_get_freq(void) +{ + return IEEE802154.channel.freq; +} + +static inline void ieee802154_ll_set_freq(uint8_t freq) +{ + IEEE802154.channel.freq = freq; +} + +static inline void ieee802154_ll_set_power(uint8_t power) +{ + IEEE802154.txpower.power = power; +} + +static inline void ieee802154_ll_set_multipan_panid(ieee802154_ll_multipan_index_t index, uint16_t panid) +{ + IEEE802154.conf.multipan_mask |= BIT(index); + IEEE802154.multipan[index].panid.id = panid; +} + +static inline uint16_t ieee802154_ll_get_multipan_panid(ieee802154_ll_multipan_index_t index) +{ + return IEEE802154.multipan[index].panid.id; +} + +static inline void ieee802154_ll_set_multipan_short_addr(ieee802154_ll_multipan_index_t index, uint16_t short_addr) +{ + IEEE802154.conf.multipan_mask |= BIT(index); + IEEE802154.multipan[index].short_addr.addr = short_addr; +} + +static inline uint16_t ieee802154_ll_get_multipan_short_addr(ieee802154_ll_multipan_index_t index) +{ + return IEEE802154.multipan[index].short_addr.addr; +} + +static inline void ieee802154_ll_set_multipan_ext_addr(ieee802154_ll_multipan_index_t index, const uint8_t *ext_addr) +{ + IEEE802154.conf.multipan_mask |= BIT(index); + IEEE802154.multipan[index].ext_addr0 = (ext_addr[0] << 0) | (ext_addr[1] << 8) | (ext_addr[2] << 16) | (ext_addr[3] << 24); + IEEE802154.multipan[index].ext_addr1 = (ext_addr[4] << 0) | (ext_addr[5] << 8) | (ext_addr[6] << 16) | (ext_addr[7] << 24); +} + +static inline void ieee802154_ll_get_multipan_ext_addr(ieee802154_ll_multipan_index_t index, uint8_t *ext_addr) +{ + for (uint8_t i = 0; i < 4; i ++) { + ext_addr[i] = (IEEE802154.multipan[index].ext_addr0 >> (8 * i)) & 0xff; + ext_addr[i + 4] = (IEEE802154.multipan[index].ext_addr1 >> (8 * i)) & 0xff; + } +} + +static inline void ieee802154_ll_set_multipan_enable_mask(uint8_t mask) +{ + IEEE802154.conf.multipan_mask = mask; +} + +static inline uint8_t ieee802154_ll_get_multipan_enable_mask(void) +{ + return IEEE802154.conf.multipan_mask; +} + +FORCE_INLINE_ATTR bool ieee802154_ll_is_cca_busy(void) +{ + return IEEE802154.ed_cfg.cca_busy; +} + +FORCE_INLINE_ATTR int8_t ieee802154_ll_get_ed_rss(void) +{ + return IEEE802154.ed_cfg.ed_rss; +} + +static inline void ieee802154_ll_set_cca_mode(ieee802154_ll_cca_mode_t cca_mode) +{ + IEEE802154.ed_cfg.cca_mode = cca_mode; +} + +static inline void ieee802154_ll_set_cca_threshold(int8_t cca_threshold) +{ + IEEE802154.ed_cfg.cca_threshold = cca_threshold; +} + +static inline void ieee802154_ll_set_ed_sample_rate(ieee802154_ll_ed_sample_dur_t ed_sample_rate) +{ + IEEE802154.ed_cfg.ed_sample_rate = ed_sample_rate; +} + +static inline void ieee802154_ll_set_ed_sample_mode(ieee802154_ll_ed_sample_mode_t ed_sample_mode) +{ + IEEE802154.ed_cfg.ed_sample_mode = ed_sample_mode; +} + +static inline void ieee802154_ll_set_ed_duration(uint16_t duration) +{ + IEEE802154.ed_duration.duration = duration; +} + +FORCE_INLINE_ATTR bool ieee802154_ll_get_tx_auto_ack(void) +{ + return IEEE802154.conf.auto_ack_tx; +} + +static inline void ieee802154_ll_set_tx_auto_ack(bool enable) +{ + IEEE802154.conf.auto_ack_tx = enable; +} + +FORCE_INLINE_ATTR bool ieee802154_ll_get_rx_auto_ack(void) +{ + return IEEE802154.conf.auto_ack_rx; +} + +static inline void ieee802154_ll_set_rx_auto_ack(bool enable) +{ + IEEE802154.conf.auto_ack_rx = enable; +} + +FORCE_INLINE_ATTR bool ieee802154_ll_get_tx_enhance_ack(void) +{ + return IEEE802154.conf.auto_enhack; +} + +static inline void ieee802154_ll_set_tx_enhance_ack(bool enable) +{ + IEEE802154.conf.auto_enhack = enable; +} + +static inline void ieee802154_ll_set_coordinator(bool enable) +{ + IEEE802154.conf.coordinator = enable; +} + +static inline void ieee802154_ll_set_promiscuous(bool enable) +{ + IEEE802154.conf.promiscuous = enable; +} + +static inline void ieee802154_ll_set_pending_mode(bool enable) +{ + IEEE802154.conf.pending_enhance = enable; +} + +FORCE_INLINE_ATTR void ieee802154_ll_set_pending_bit(bool pending) +{ + IEEE802154.pending_cfg.pending = pending; +} + +FORCE_INLINE_ATTR void ieee802154_ll_timer0_set_threshold(uint32_t value) +{ + IEEE802154.timer0_threshold = value; +} + +static inline uint32_t ieee802154_ll_timer0_get_value(void) +{ + return IEEE802154.timer0_value; +} + +static inline void ieee802154_ll_timer1_set_threshold(uint32_t value) +{ + IEEE802154.timer1_threshold = value; +} + +static inline uint32_t ieee802154_ll_timer1_get_value(void) +{ + return IEEE802154.timer1_value; +} + +FORCE_INLINE_ATTR void ieee802154_ll_set_transmit_security(bool enable) +{ + IEEE802154.security_ctrl.tx_security_en = enable; +} + +static inline void ieee802154_ll_set_security_offset(uint8_t offset) +{ + IEEE802154.security_ctrl.security_offset = offset; +} + +static inline uint8_t ieee802154_ll_get_security_offset(void) +{ + return IEEE802154.security_ctrl.security_offset; +} + +static inline void ieee802154_ll_set_security_addr(uint8_t *security_addr) +{ + IEEE802154.security_addr0 = (security_addr[0] << 0) | (security_addr[1] << 8) | (security_addr[2] << 16) | (security_addr[3] << 24); + IEEE802154.security_addr1 = (security_addr[4] << 0) | (security_addr[5] << 8) | (security_addr[6] << 16) | (security_addr[7] << 24); +} + +static inline void ieee802154_ll_set_security_key(uint8_t *security_key) +{ + IEEE802154.security_key0 = (security_key[0] << 0) | (security_key[1] << 8) | (security_key[2] << 16) | (security_key[3] << 24); + IEEE802154.security_key1 = (security_key[4] << 0) | (security_key[5] << 8) | (security_key[6] << 16) | (security_key[7] << 24); + IEEE802154.security_key2 = (security_key[8] << 0) | (security_key[9] << 8) | (security_key[10] << 16) | (security_key[11] << 24); + IEEE802154.security_key3 = (security_key[12] << 0) | (security_key[13] << 8) | (security_key[14] << 16) | (security_key[15] << 24); +} + +static inline void ieee802154_ll_disable_coex(void) +{ + IEEE802154.pti.pti = 1; + IEEE802154.pti.hw_ack_pti = 1; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/ieee802154/CMakeLists.txt b/components/ieee802154/CMakeLists.txt index 55a1ec7b09..3323332401 100644 --- a/components/ieee802154/CMakeLists.txt +++ b/components/ieee802154/CMakeLists.txt @@ -1,20 +1,25 @@ idf_build_get_property(idf_target IDF_TARGET) -idf_component_register( - INCLUDE_DIRS include - REQUIRES esp_phy - ) +set(srcs "") +set(include "include") +set(private_include "") if(CONFIG_IEEE802154_ENABLED) - idf_component_get_property(esp_phy_lib esp_phy COMPONENT_LIB) - idf_component_get_property(esp_system_lib esp_system COMPONENT_LIB) - if($ENV{IEEE802154_LIB_FROM_INTERNAL_SRC}) - idf_component_get_property(ieee802154_lib ieee802154_driver COMPONENT_LIB) - target_link_libraries(${COMPONENT_LIB} INTERFACE $ - $ libphy.a libbtbb.a $) - else() - target_link_directories(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/lib/${idf_target}") - target_link_libraries(${COMPONENT_LIB} INTERFACE $ lib802154.a libphy.a libbtbb.a - $ $) - endif() + 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") endif() + +idf_component_register( + SRCS "${srcs}" + INCLUDE_DIRS "${include}" + PRIV_INCLUDE_DIRS "${private_include}" + LDFRAGMENTS linker.lf + PRIV_REQUIRES esp_phy driver esp_timer esp_coex soc hal +) diff --git a/components/ieee802154/Kconfig b/components/ieee802154/Kconfig index 99bf1d1a90..4ca8ab64c2 100644 --- a/components/ieee802154/Kconfig +++ b/components/ieee802154/Kconfig @@ -10,5 +10,68 @@ menu "IEEE 802.15.4" depends on IEEE802154_ENABLED default 20 range 2 100 + help + The number of 802.15.4 receive buffers + + choice IEEE802154_CCA_MODE + 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 + 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" + range -120 0 + default -60 + help + set the CCA threshold, in dB + + config IEEE802154_PENDING_TABLE_SIZE + int "Pending table size" + range 1 100 + default 20 + help + set the pending table size + + config IEEE802154_MULTI_PAN_ENABLE + bool "Enable multi-pan feature for frame filter" + default n + help + Enable IEEE802154 multi-pan + + config IEEE802154_TIMING_OPTIMIZATION + bool "Enable throughput optimization" + default n + help + Enabling this option increases throughput by ~5% at the expense of ~2.1k + IRAM code size increase. endmenu # IEEE 802.15.4 diff --git a/components/ieee802154/driver/esp_ieee802154_ack.c b/components/ieee802154/driver/esp_ieee802154_ack.c new file mode 100644 index 0000000000..99bdecff7d --- /dev/null +++ b/components/ieee802154/driver/esp_ieee802154_ack.c @@ -0,0 +1,164 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#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" + +static ieee802154_pending_table_t ieee802154_pending_table; + +#define BIT_SET(mask, pos) ((mask) |= (1UL << (pos))) +#define BIT_CLR(mask, pos) ((mask) &= ~(1UL << (pos))) +#define BIT_IST(mask, pos) ((mask) & (1UL << (pos))) + +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) { + ieee802154_pending_table.short_addr_mask = 0; + } else { + ieee802154_pending_table.ext_addr_mask = 0; + } +} + +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: + assert(false); + } + + if (set_to_hw) { + ieee802154_ll_set_pending_bit(pending_bit); + } + + return pending_bit; +} diff --git a/components/ieee802154/driver/esp_ieee802154_dev.c b/components/ieee802154/driver/esp_ieee802154_dev.c new file mode 100644 index 0000000000..0b5214b661 --- /dev/null +++ b/components/ieee802154/driver/esp_ieee802154_dev.c @@ -0,0 +1,770 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "freertos/portmacro.h" +#include "soc/periph_defs.h" +#include "soc/soc.h" +#include "soc/ieee802154_periph.h" +#include "esp_private/esp_modem_clock.h" +#include "esp_check.h" +#include "esp_coex_i154.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_timer.h" +#include "esp_ieee802154_ack.h" +#include "esp_ieee802154_dev.h" +#include "esp_ieee802154_frame.h" +#include "esp_ieee802154_pib.h" +#include "esp_ieee802154_sec.h" +#include "esp_ieee802154_util.h" +#include "esp_ieee802154_timer.h" +#include "hal/ieee802154_ll.h" +#include "esp_attr.h" + +#define CCA_DETECTION_TIME 8 + +extern void bt_bb_set_zb_tx_on_delay(uint16_t time); + +static volatile ieee802154_state_t s_ieee802154_state; +static uint8_t *s_tx_frame = NULL; +static uint8_t s_rx_frame[CONFIG_IEEE802154_RX_BUFFER_SIZE][127 + 1 + 1]; // +1: len, +1: for dma test +static esp_ieee802154_frame_info_t s_rx_frame_info[CONFIG_IEEE802154_RX_BUFFER_SIZE]; +static uint8_t s_rx_index = 0; +static uint8_t s_enh_ack_frame[128]; +static uint8_t s_recent_rx_frame_info_index; +static portMUX_TYPE s_ieee802154_spinlock = portMUX_INITIALIZER_UNLOCKED; + +static IRAM_ATTR void event_end_process(void) +{ + ieee802154_etm_channel_clear(IEEE802154_ETM_CHANNEL0); + ieee802154_etm_channel_clear(IEEE802154_ETM_CHANNEL1); + ieee802154_ll_set_transmit_security(false); + ieee802154_timer0_stop(); +} + +static IRAM_ATTR void receive_ack_timeout_timer_start(uint32_t duration) +{ + ieee802154_ll_enable_events(IEEE802154_EVENT_TIMER0_OVERFLOW); + ieee802154_timer0_set_threshold(duration); + ieee802154_timer0_start(); +} + +static void ieee802154_rx_frame_info_update(void) +{ + uint8_t len = s_rx_frame[s_rx_index][0]; + int8_t rssi = s_rx_frame[s_rx_index][len - 1]; // crc is not written to rx buffer + uint8_t lqi = s_rx_frame[s_rx_index][len]; + + s_rx_frame_info[s_rx_index].channel = ieee802154_freq_to_channel(ieee802154_ll_get_freq()); + s_rx_frame_info[s_rx_index].rssi = rssi; + s_rx_frame_info[s_rx_index].lqi = lqi; + + s_recent_rx_frame_info_index = s_rx_index; +} + +int8_t ieee802154_get_recent_rssi(void) +{ + return s_rx_frame_info[s_recent_rx_frame_info_index].rssi; +} + +uint8_t ieee802154_get_recent_lqi(void) +{ + return s_rx_frame_info[s_recent_rx_frame_info_index].lqi; +} + +static void set_next_rx_buffer(void) +{ + if (s_rx_frame[s_rx_index][0] != 0) { + s_rx_index++; + if (s_rx_index == CONFIG_IEEE802154_RX_BUFFER_SIZE) { + s_rx_index = 0; + } + memset(s_rx_frame[s_rx_index], 0, sizeof(s_rx_frame[s_rx_index])); + } + + ieee802154_ll_set_rx_addr((uint8_t *)&s_rx_frame[s_rx_index]); +} + +static bool stop_rx(void) +{ + ieee802154_ll_events events; + + ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + + events = ieee802154_ll_get_events(); + if (events & IEEE802154_EVENT_RX_DONE) { + esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); + } + + ieee802154_ll_clear_events(IEEE802154_EVENT_RX_DONE | IEEE802154_EVENT_RX_ABORT | IEEE802154_EVENT_RX_SFD_DONE); + + return true; +} + +static bool stop_tx_ack(void) +{ + ieee802154_ll_events events; + + ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + + events = ieee802154_ll_get_events(); + if (events & IEEE802154_EVENT_ACK_TX_DONE) { + esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); + } + + ieee802154_ll_clear_events(IEEE802154_EVENT_ACK_TX_DONE | IEEE802154_EVENT_RX_ABORT | IEEE802154_EVENT_TX_SFD_DONE); // ZB-81: clear TX_SFD_DONE event + + return true; +} + +static bool stop_tx(void) +{ + ieee802154_ll_events events; + + ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + + events = ieee802154_ll_get_events(); + + if (s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK) { + // if current operation is sending 2015 Enh-ack, SW should create the receive-done event. + esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); + ieee802154_ll_clear_events(IEEE802154_EVENT_ACK_TX_DONE); + } else if ((events & IEEE802154_EVENT_TX_DONE) && (!ieee802154_frame_is_ack_required(s_tx_frame) || !ieee802154_ll_get_rx_auto_ack())) { + // if the tx is already done, and the frame is not ack request OR auto ack rx is disabled. + esp_ieee802154_transmit_done(s_tx_frame, NULL, NULL); + } else { + esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_ABORT); + } + + ieee802154_ll_clear_events(IEEE802154_EVENT_TX_DONE | IEEE802154_EVENT_TX_ABORT | IEEE802154_EVENT_TX_SFD_DONE); + + return true; +} + +static bool stop_cca(void) +{ + ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + ieee802154_ll_clear_events(IEEE802154_EVENT_ED_DONE | IEEE802154_EVENT_RX_ABORT); + return true; +} + +static bool stop_tx_cca(void) +{ + stop_tx(); // in case the transmission already started + ieee802154_ll_clear_events(IEEE802154_EVENT_TX_ABORT); + return true; +} + +static bool stop_rx_ack(void) +{ + ieee802154_ll_events events; + + ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + + events = ieee802154_ll_get_events(); + + ieee802154_timer0_stop(); + ieee802154_ll_disable_events(IEEE802154_EVENT_TIMER0_OVERFLOW); + + if (events & IEEE802154_EVENT_TIMER0_OVERFLOW) { + esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK); + } + + if (events & IEEE802154_EVENT_ACK_RX_DONE) { + esp_ieee802154_transmit_done(s_tx_frame, (uint8_t *)&s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); + } + + ieee802154_ll_clear_events(IEEE802154_EVENT_ACK_RX_DONE | IEEE802154_EVENT_RX_SFD_DONE | IEEE802154_EVENT_TX_ABORT); + + return true; +} + +static bool stop_ed(void) +{ + ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + + ieee802154_ll_clear_events(IEEE802154_EVENT_ED_DONE | IEEE802154_EVENT_RX_ABORT); + + return true; +} + +static bool stop_current_operation(void) +{ + event_end_process(); + switch (s_ieee802154_state) { + case IEEE802154_STATE_DISABLE: + break; + + case IEEE802154_STATE_IDLE: + // do nothing + break; + + case IEEE802154_STATE_RX: + stop_rx(); + break; + + case IEEE802154_STATE_TX_ACK: + stop_tx_ack(); + break; + + case IEEE802154_STATE_TX_CCA: + stop_tx_cca(); + break; + case IEEE802154_STATE_CCA: + stop_cca(); + break; + + case IEEE802154_STATE_TX: + case IEEE802154_STATE_TX_ENH_ACK: + stop_tx(); + break; + + case IEEE802154_STATE_RX_ACK: + stop_rx_ack(); + break; + + case IEEE802154_STATE_ED: + stop_ed(); + break; + + default: + assert(false); + break; + } + + return true; +} + +static void enable_rx(void) +{ + set_next_rx_buffer(); + IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_RX); + + ieee802154_ll_set_cmd(IEEE802154_CMD_RX_START); + + s_ieee802154_state = IEEE802154_STATE_RX; +} + +static IRAM_ATTR void next_operation(void) +{ + if (ieee802154_pib_get_rx_when_idle()) { + enable_rx(); + } else { + s_ieee802154_state = IEEE802154_STATE_IDLE; + } +} + +static void isr_handle_timer0_done(void) +{ + if (s_ieee802154_state == IEEE802154_STATE_RX_ACK) { + esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK); + next_operation(); + } +} + +static void isr_handle_timer1_done(void) +{ + // timer 1 is now unused. +} + +static IRAM_ATTR void isr_handle_tx_done(void) +{ + event_end_process(); + if (s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK) { + esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); + next_operation(); + } else { + if (s_ieee802154_state == IEEE802154_STATE_TEST_TX) { + esp_ieee802154_transmit_done(s_tx_frame, NULL, NULL); + next_operation(); + } else if (s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA) { + if (ieee802154_frame_is_ack_required(s_tx_frame) && ieee802154_ll_get_rx_auto_ack()) { + s_ieee802154_state = IEEE802154_STATE_RX_ACK; + receive_ack_timeout_timer_start(200000); // 200ms for receive ack timeout + } else { + esp_ieee802154_transmit_done(s_tx_frame, NULL, NULL); + next_operation(); + } + } + } +} + +static IRAM_ATTR void isr_handle_rx_done(void) +{ + event_end_process(); + ieee802154_rx_frame_info_update(); + + if (s_ieee802154_state == IEEE802154_STATE_RX) { + if (ieee802154_frame_is_ack_required(s_rx_frame[s_rx_index]) && ieee802154_frame_get_version(s_rx_frame[s_rx_index]) <= IEEE802154_FRAME_VERSION_1 + && ieee802154_ll_get_tx_auto_ack()) { + // auto tx ack only works for the frame with version 0b00 and 0b01 + s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index]); + s_ieee802154_state = IEEE802154_STATE_TX_ACK; + } else if (ieee802154_frame_is_ack_required(s_rx_frame[s_rx_index]) && ieee802154_frame_get_version(s_rx_frame[s_rx_index]) == IEEE802154_FRAME_VERSION_2 + && ieee802154_ll_get_tx_enhance_ack()) { + s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index]); + // For 2015 enh-ack, SW should generate an enh-ack then send it manually + 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) { + // Send the Enh-Ack frame if generator succeeds. + ieee802154_ll_set_tx_addr(s_enh_ack_frame); + s_tx_frame = s_enh_ack_frame; + ieee802154_sec_update(); + ieee802154_ll_enhack_generate_done_notify(); + s_ieee802154_state = IEEE802154_STATE_TX_ENH_ACK; + } else { + // Stop current process if generator returns errors. + ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); + next_operation(); + } + } else { + esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); + next_operation(); + } + } +} + +static IRAM_ATTR void isr_handle_ack_tx_done(void) +{ + esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); + next_operation(); +} + +static IRAM_ATTR void isr_handle_ack_rx_done(void) +{ + ieee802154_timer0_stop(); + ieee802154_ll_disable_events(IEEE802154_EVENT_TIMER0_OVERFLOW); + ieee802154_rx_frame_info_update(); + esp_ieee802154_transmit_done(s_tx_frame, (uint8_t *)&s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); + next_operation(); +} + +static IRAM_ATTR void isr_handle_rx_abort(void) +{ + event_end_process(); + uint32_t rx_status = ieee802154_ll_get_rx_status(); + ieee802154_ll_rx_abort_reason_t rx_abort_reason = ieee802154_ll_get_rx_abort_reason(); + switch (rx_abort_reason) { + case IEEE802154_RX_ABORT_BY_RX_STOP: + case IEEE802154_RX_ABORT_BY_TX_ACK_STOP: + case IEEE802154_RX_ABORT_BY_ED_STOP: + // do nothing + break; + case IEEE802154_RX_ABORT_BY_SFD_TIMEOUT: + case IEEE802154_RX_ABORT_BY_CRC_ERROR: + case IEEE802154_RX_ABORT_BY_INVALID_LEN: + case IEEE802154_RX_ABORT_BY_FILTER_FAIL: + case IEEE802154_RX_ABORT_BY_NO_RSS: + case IEEE802154_RX_ABORT_BY_UNEXPECTED_ACK: + case IEEE802154_RX_ABORT_BY_RX_RESTART: + assert(s_ieee802154_state == IEEE802154_STATE_RX); + break; + case IEEE802154_RX_ABORT_BY_COEX_BREAK: + assert(s_ieee802154_state == IEEE802154_STATE_RX); + esp_ieee802154_receive_failed(rx_status); + break; + case IEEE802154_RX_ABORT_BY_ED_ABORT: + case IEEE802154_RX_ABORT_BY_ED_COEX_REJECT: + assert(s_ieee802154_state == IEEE802154_STATE_ED || s_ieee802154_state == IEEE802154_STATE_CCA); + esp_ieee802154_ed_failed(rx_status); + next_operation(); + break; + case IEEE802154_RX_ABORT_BY_TX_ACK_TIMEOUT: + case IEEE802154_RX_ABORT_BY_TX_ACK_COEX_BREAK: + assert(s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); + esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); + next_operation(); + break; + case IEEE802154_RX_ABORT_BY_ENHACK_SECURITY_ERROR: + assert(s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); + esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); + next_operation(); + break; + default: + assert(false); + } +} + +static IRAM_ATTR void isr_handle_tx_abort(void) +{ + event_end_process(); + ieee802154_ll_tx_abort_reason_t tx_abort_reason = ieee802154_ll_get_tx_abort_reason(); + switch (tx_abort_reason) { + case IEEE802154_TX_ABORT_BY_RX_ACK_STOP: + case IEEE802154_TX_ABORT_BY_TX_STOP: + // do nothing + break; + case IEEE802154_TX_ABORT_BY_RX_ACK_SFD_TIMEOUT: + case IEEE802154_TX_ABORT_BY_RX_ACK_CRC_ERROR: + case IEEE802154_TX_ABORT_BY_RX_ACK_INVALID_LEN: + case IEEE802154_TX_ABORT_BY_RX_ACK_FILTER_FAIL: + case IEEE802154_TX_ABORT_BY_RX_ACK_NO_RSS: + case IEEE802154_TX_ABORT_BY_RX_ACK_COEX_BREAK: + case IEEE802154_TX_ABORT_BY_RX_ACK_TYPE_NOT_ACK: + case IEEE802154_TX_ABORT_BY_RX_ACK_RESTART: + assert(s_ieee802154_state == IEEE802154_STATE_RX_ACK); + esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_INVALID_ACK); + break; + case IEEE802154_TX_ABORT_BY_RX_ACK_TIMEOUT: + assert(s_ieee802154_state == IEEE802154_STATE_RX_ACK); + ieee802154_ll_disable_events(IEEE802154_EVENT_TIMER0_OVERFLOW); + esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK); + next_operation(); + break; + case IEEE802154_TX_ABORT_BY_TX_COEX_BREAK: + assert(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA); + esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_COEXIST); + next_operation(); + break; + case IEEE802154_TX_ABORT_BY_TX_SECURITY_ERROR: + assert(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA); + esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_SECURITY); + next_operation(); + break; + case IEEE802154_TX_ABORT_BY_CCA_FAILED: + assert(s_ieee802154_state == IEEE802154_STATE_TX_CCA); + esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_ABORT); + next_operation(); + break; + case IEEE802154_TX_ABORT_BY_CCA_BUSY: + assert(s_ieee802154_state == IEEE802154_STATE_TX_CCA); + esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_CCA_BUSY); + next_operation(); + break; + default: + assert(false); + break; + } +} + +static IRAM_ATTR void isr_handle_ed_done(void) +{ + if (s_ieee802154_state == IEEE802154_STATE_CCA) { + esp_ieee802154_cca_done(ieee802154_ll_is_cca_busy()); + } else if (s_ieee802154_state == IEEE802154_STATE_ED) { + esp_ieee802154_energy_detect_done(ieee802154_ll_get_ed_rss()); + } + + next_operation(); +} + +static void ieee802154_isr(void *arg) +{ + ieee802154_ll_events events = ieee802154_ll_get_events(); + + ieee802154_ll_clear_events(events); + + if (events & IEEE802154_EVENT_RX_SFD_DONE) { + // IEEE802154_STATE_TX && IEEE802154_STATE_TX_CCA && IEEE802154_STATE_TX_ENH_ACK for isr processing delay + 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); + + s_rx_frame_info[s_rx_index].timestamp = esp_timer_get_time(); + esp_ieee802154_receive_sfd_done(); + + events &= (uint16_t)(~IEEE802154_EVENT_RX_SFD_DONE); + } + + if (events & IEEE802154_EVENT_TX_SFD_DONE) { + // ZB-81: IEEE802154_STATE_TX_ACK is also a possible state + 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); + + esp_ieee802154_transmit_sfd_done(s_tx_frame); + + events &= (uint16_t)(~IEEE802154_EVENT_TX_SFD_DONE); + } + + if (events & IEEE802154_EVENT_TX_DONE) { + 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); + + isr_handle_tx_done(); + + events &= (uint16_t)(~IEEE802154_EVENT_TX_DONE); + } + + if (events & IEEE802154_EVENT_RX_DONE) { + assert(s_ieee802154_state == IEEE802154_STATE_RX); + + isr_handle_rx_done(); + + events &= (uint16_t)(~IEEE802154_EVENT_RX_DONE); + } + + if (events & IEEE802154_EVENT_ACK_TX_DONE) { + // IEEE802154_STATE_RX for isr processing delay + assert(s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_RX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); + + isr_handle_ack_tx_done(); + + events &= (uint16_t)(~IEEE802154_EVENT_ACK_TX_DONE); + } + + if (events & IEEE802154_EVENT_ACK_RX_DONE) { + // IEEE802154_STATE_TX && IEEE802154_STATE_TX_CCA && IEEE802154_STATE_TX_ENH_ACK for isr processing delay + assert(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); + + isr_handle_ack_rx_done(); + + events &= (uint16_t)(~IEEE802154_EVENT_ACK_RX_DONE); + } + + if (events & IEEE802154_EVENT_RX_ABORT) { + isr_handle_rx_abort(); + + events &= (uint16_t)(~IEEE802154_EVENT_RX_ABORT); + } + + if (events & IEEE802154_EVENT_TX_ABORT) { + isr_handle_tx_abort(); + + events &= (uint16_t)(~IEEE802154_EVENT_TX_ABORT); + } + + if (events & IEEE802154_EVENT_ED_DONE) { + assert(s_ieee802154_state == IEEE802154_STATE_ED || s_ieee802154_state == IEEE802154_STATE_CCA); + + isr_handle_ed_done(); + + events &= (uint16_t)(~IEEE802154_EVENT_ED_DONE); + } + + if (events & IEEE802154_EVENT_TIMER0_OVERFLOW) { + assert(s_ieee802154_state == IEEE802154_STATE_RX_ACK); + isr_handle_timer0_done(); + + events &= (uint16_t)(~IEEE802154_EVENT_TIMER0_OVERFLOW); + } + + if (events & IEEE802154_EVENT_TIMER1_OVERFLOW) { + isr_handle_timer1_done(); + + events &= (uint16_t)(~IEEE802154_EVENT_TIMER1_OVERFLOW); + } + + // all events should be handled + assert(events == 0); + +} + +static IRAM_ATTR void ieee802154_enter_critical(void) +{ + portENTER_CRITICAL(&s_ieee802154_spinlock); +} + +static IRAM_ATTR void ieee802154_exit_critical(void) +{ + portEXIT_CRITICAL(&s_ieee802154_spinlock); +} + +void ieee802154_enable(void) +{ + modem_clock_module_enable(ieee802154_periph.module); +} + +void ieee802154_disable(void) +{ + s_ieee802154_state = IEEE802154_STATE_DISABLE; +} + +esp_err_t ieee802154_mac_init(void) +{ + esp_err_t ret = ESP_OK; + ieee802154_pib_init(); + + ieee802154_ll_enable_events(IEEE802154_EVENT_MASK); + ieee802154_ll_disable_events((IEEE802154_EVENT_TIMER0_OVERFLOW) | (IEEE802154_EVENT_TIMER1_OVERFLOW)); + + 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)); + + ieee802154_ll_set_ed_sample_mode(IEEE802154_ED_SAMPLE_AVG); +#if CONFIG_ESP_COEX_SW_COEXIST_ENABLE + esp_coex_ieee802154_ack_pti_set(IEEE802154_MIDDLE); + IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_IDLE); +#else + ieee802154_ll_disable_coex(); +#endif + +#if CONFIG_IDF_ENV_FPGA + bt_bb_set_zb_tx_on_delay(80); +#else + bt_bb_set_zb_tx_on_delay(50); + REG_WRITE(IEEE802154_RXON_DELAY_REG, 50); +#endif + + memset(s_rx_frame, 0, sizeof(s_rx_frame)); + s_ieee802154_state = IEEE802154_STATE_IDLE; + + // TODO: Add flags for IEEE802154 ISR allocating. TZ-102 + ret = esp_intr_alloc(ieee802154_periph.irq_id, 0, ieee802154_isr, NULL, NULL); + ESP_RETURN_ON_FALSE(ret == ESP_OK, ESP_FAIL, IEEE802154_TAG, "IEEE802154 MAC init failed"); + + return ret; +} + +static void start_ed(uint32_t duration) +{ + ieee802154_ll_enable_events(IEEE802154_EVENT_ED_DONE); + ieee802154_ll_set_ed_duration(duration); + ieee802154_ll_set_cmd(IEEE802154_CMD_ED_START); +} + +static void tx_init(const uint8_t *frame) +{ + s_tx_frame = (uint8_t *)frame; + stop_current_operation(); + ieee802154_pib_update(); + ieee802154_sec_update(); + + ieee802154_ll_set_tx_addr(s_tx_frame); + + if (ieee802154_frame_is_ack_required(frame)) { + // set rx pointer for ack frame + set_next_rx_buffer(); + } +} + +esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca) +{ + ieee802154_enter_critical(); + tx_init(frame); + + IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_TX); + + if (cca) { + ieee802154_ll_set_cmd(IEEE802154_CMD_CCA_TX_START); + s_ieee802154_state = IEEE802154_STATE_TX_CCA; + } else { + ieee802154_ll_set_cmd(IEEE802154_CMD_TX_START); + s_ieee802154_state = IEEE802154_STATE_TX; + } + + ieee802154_exit_critical(); + + return ESP_OK; +} + +static inline 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) +{ + uint32_t tx_target_time; + uint32_t current_time; + tx_init(frame); + IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_TX_AT); + if (cca) { + tx_target_time = time - IEEE802154_ED_TRIG_TX_RAMPUP_TIME_US; + s_ieee802154_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_exit_critical(); + } else { + tx_target_time = time - IEEE802154_TX_RAMPUP_TIME_US; + if (ieee802154_frame_get_type(frame) == IEEE802154_FRAME_TYPE_ACK && ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_2) { + s_ieee802154_state = IEEE802154_STATE_TX_ENH_ACK; + } else { + s_ieee802154_state = IEEE802154_STATE_TX; + } + 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_exit_critical(); + } + + return ESP_OK; +} + +static void rx_init(void) +{ + stop_current_operation(); + ieee802154_pib_update(); +} + +esp_err_t ieee802154_receive(void) +{ + if (((s_ieee802154_state == IEEE802154_STATE_RX) || (s_ieee802154_state == IEEE802154_STATE_TX_ACK)) && (!ieee802154_pib_is_pending())) { + // already in rx state, don't abort current rx operation + return ESP_OK; + } + + ieee802154_enter_critical(); + rx_init(); + enable_rx(); + ieee802154_exit_critical(); + return ESP_OK; +} + +esp_err_t ieee802154_receive_at(uint32_t time) +{ + uint32_t rx_target_time = time - IEEE802154_RX_RAMPUP_TIME_US; + uint32_t current_time; + + rx_init(); + IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_RX_AT); + set_next_rx_buffer(); + s_ieee802154_state = IEEE802154_STATE_RX; + ieee802154_enter_critical(); + 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_exit_critical(); + return ESP_OK; +} + +esp_err_t ieee802154_sleep(void) +{ + ieee802154_enter_critical(); + + stop_current_operation(); + s_ieee802154_state = IEEE802154_STATE_IDLE; + + ieee802154_exit_critical(); + return ESP_OK; +} + +esp_err_t ieee802154_energy_detect(uint32_t duration) +{ + ieee802154_enter_critical(); + + stop_current_operation(); + + ieee802154_pib_update(); + + start_ed(duration); + s_ieee802154_state = IEEE802154_STATE_ED; + + ieee802154_exit_critical(); + return ESP_OK; +} + +esp_err_t ieee802154_cca(void) +{ + ieee802154_enter_critical(); + + stop_current_operation(); + + ieee802154_pib_update(); + + start_ed(CCA_DETECTION_TIME); + s_ieee802154_state = IEEE802154_STATE_CCA; + + ieee802154_exit_critical(); + return ESP_OK; +} + +ieee802154_state_t ieee802154_get_state(void) +{ + return s_ieee802154_state; +} diff --git a/components/ieee802154/driver/esp_ieee802154_frame.c b/components/ieee802154/driver/esp_ieee802154_frame.c new file mode 100644 index 0000000000..3935ed642f --- /dev/null +++ b/components/ieee802154/driver/esp_ieee802154_frame.c @@ -0,0 +1,418 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_check.h" +#include "esp_attr.h" +#include "esp_ieee802154_dev.h" +#include "esp_ieee802154_frame.h" + +static const char *TAG = "ieee802154 frame"; + +static inline bool is_security_enabled(const uint8_t *frame) +{ + return frame[IEEE802154_FRAME_SECURITY_OFFSET] & IEEE802154_FRAME_SECURITY_BIT; +} + +static inline bool is_ie_present(const uint8_t *frame) +{ + return frame[IEEE802154_FRAME_IE_OFFSET] & IEEE802154_FRAME_IE_BIT; +} + +static inline bool is_dsn_present(const uint8_t *frame) +{ + return ((ieee802154_frame_get_version(frame) != IEEE802154_FRAME_VERSION_2) || + !(frame[IEEE802154_FRAME_DSN_OFFSET] & IEEE802154_FRAME_DSN_BIT)); +} + +static inline uint8_t dst_addr_mode(const uint8_t *frame) +{ + return frame[IEEE802154_FRAME_DST_MODE_OFFSET] & IEEE802154_FRAME_DST_MODE_MASK; +} + +static inline uint8_t src_addr_mode(const uint8_t *frame) +{ + return frame[IEEE802154_FRAME_SRC_MODE_OFFSET] & IEEE802154_FRAME_SRC_MODE_MASK; +} + +static inline bool is_panid_compression(const uint8_t *frame) +{ + return frame[IEEE802154_FRAME_PANID_COMP_OFFSET] & IEEE802154_FRAME_PANID_COMP_BIT; +} + +static inline bool is_suported_frame_type(uint8_t frame_type) +{ + // HW supports 4 kinds of frame type: Beacon, Ack, Data, Command. + return (frame_type == IEEE802154_FRAME_TYPE_BEACON || frame_type == IEEE802154_FRAME_TYPE_DATA || + frame_type == IEEE802154_FRAME_TYPE_ACK || frame_type == IEEE802154_FRAME_TYPE_COMMAND); +} + +static bool is_dst_panid_present(const uint8_t *frame) +{ + uint8_t dst_mode = dst_addr_mode(frame); + bool dst_panid_present = false; + + if (ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_2) { + uint8_t src_mode = src_addr_mode(frame); + bool panid_compression = is_panid_compression(frame); + + if (dst_mode != IEEE802154_FRAME_DST_MODE_NONE) { // dest address is present/short/extented + if ((src_mode == IEEE802154_FRAME_SRC_MODE_NONE && panid_compression) || + (dst_mode == IEEE802154_FRAME_DST_MODE_EXT && src_mode == IEEE802154_FRAME_SRC_MODE_EXT && panid_compression)) { + dst_panid_present = false; + } else { + dst_panid_present = true; + } + } else { // dest address is not present + if (src_mode == IEEE802154_FRAME_SRC_MODE_NONE && panid_compression) { + dst_panid_present = true; + } else { + dst_panid_present = false; + } + } + } else { // frame version: 0b00, 0b01 + dst_panid_present = (dst_mode != IEEE802154_FRAME_DST_MODE_NONE); + } + + return dst_panid_present; +} + +static bool is_src_panid_present(const uint8_t *frame) +{ + uint8_t src_mode = src_addr_mode(frame); + bool panid_compression = is_panid_compression(frame); + bool src_panid_present = false; + + if (ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_2) { + uint8_t dst_mode = dst_addr_mode(frame); + + if (src_mode != IEEE802154_FRAME_SRC_MODE_NONE) { + if (dst_mode == IEEE802154_FRAME_DST_MODE_EXT && src_mode == IEEE802154_FRAME_SRC_MODE_EXT && !panid_compression) { + src_panid_present = false; + } else { + src_panid_present = !panid_compression; + } + } else { + src_panid_present = false; + } + } else { // frame version: 0b00, 0b01 + if (src_mode != IEEE802154_FRAME_SRC_MODE_NONE) { + src_panid_present = !panid_compression; + } else { + src_panid_present = false; + } + } + + return src_panid_present; +} + +static uint8_t inline ieee802154_frame_address_offset(const uint8_t *frame) +{ + return IEEE802154_FRAME_PHR_SIZE + IEEE802154_FRAME_FCF_SIZE + (is_dsn_present(frame) ? IEEE802154_FRAME_DSN_SIZE : 0); +} + +static IRAM_ATTR uint8_t ieee802154_frame_address_size(const uint8_t *frame) +{ + uint8_t address_size = 0; + + if (is_dst_panid_present(frame)) { + address_size += IEEE802154_FRAME_PANID_SIZE; + } + + switch (dst_addr_mode(frame)) { + case IEEE802154_FRAME_DST_MODE_NONE: + break; + + case IEEE802154_FRAME_DST_MODE_SHORT: + address_size += IEEE802154_FRAME_SHORT_ADDR_SIZE; + break; + + case IEEE802154_FRAME_DST_MODE_EXT: + address_size += IEEE802154_FRAME_EXT_ADDR_SIZE; + break; + + default: + return IEEE802154_FRAME_INVALID_OFFSET; + } + + if (is_src_panid_present(frame)) { + address_size += IEEE802154_FRAME_PANID_SIZE; + } + + switch (src_addr_mode(frame)) { + case IEEE802154_FRAME_SRC_MODE_NONE: + break; + + case IEEE802154_FRAME_SRC_MODE_SHORT: + address_size += IEEE802154_FRAME_SHORT_ADDR_SIZE; + break; + + case IEEE802154_FRAME_SRC_MODE_EXT: + address_size += IEEE802154_FRAME_EXT_ADDR_SIZE; + break; + + default: + return IEEE802154_FRAME_INVALID_OFFSET; + } + + return address_size; +} + +static uint8_t ieee802154_frame_security_header_offset(const uint8_t *frame) +{ + ESP_RETURN_ON_FALSE_ISR(is_suported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_ADDR_MODE, TAG, "invalid frame type"); + uint8_t offset = ieee802154_frame_address_offset(frame); + uint8_t address_size = ieee802154_frame_address_size(frame); + + ESP_RETURN_ON_FALSE_ISR(offset != IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_FRAME_INVALID_OFFSET, TAG, "invalid offset"); + ESP_RETURN_ON_FALSE_ISR(address_size != IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_FRAME_INVALID_OFFSET, TAG, "invalid offset"); + + offset += address_size; + + return offset; +} + +static uint8_t ieee802154_frame_get_security_field_len(const uint8_t *frame) +{ + ESP_RETURN_ON_FALSE_ISR(is_suported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_OFFSET, TAG, "invalid frame type"); + + uint8_t security_field_len = 0; + uint8_t offset = ieee802154_frame_security_header_offset(frame); + + ESP_RETURN_ON_FALSE_ISR(offset != IEEE802154_FRAME_INVALID_OFFSET, IEEE802154_FRAME_INVALID_OFFSET, TAG, "invalid offset"); + + security_field_len += IEEE802154_FRAME_SE_HEAD_SIZE; + uint8_t security_header = frame[offset]; + + if (security_header & IEEE802154_FRAME_COUNTER_SUPPRESS_BIT) { + security_field_len += 0; + } else { + security_field_len += IEEE802154_FRAME_COUNTER_SIZE; + } + + switch (security_header & IEEE802154_FRAME_KEY_ID_MODE_MASK) { + case IEEE802154_FRAME_KEY_ID_MODE_1: + security_field_len += IEEE802154_FRAME_KEY_ID_MODE_1_SIZE; + break; + case IEEE802154_FRAME_KEY_ID_MODE_2: + security_field_len += IEEE802154_FRAME_KEY_ID_MODE_2_SIZE; + break; + case IEEE802154_FRAME_KEY_ID_MODE_3: + security_field_len += IEEE802154_FRAME_KEY_ID_MODE_3_SIZE; + break; + default: + security_field_len += 0; + break; + } + + return security_field_len; +} + +static uint8_t ieee802154_frame_ie_header_offset(const uint8_t *frame) +{ + uint8_t offset = ieee802154_frame_security_header_offset(frame); + uint8_t security_field_len = ieee802154_frame_get_security_field_len(frame); + + offset += security_field_len; + + return offset; +} + +static uint8_t ieee802154_frame_get_mic_len(const uint8_t *frame) +{ + uint8_t offset = ieee802154_frame_security_header_offset(frame); + uint8_t mic_len = 0; + uint8_t security_header = frame[offset]; + + switch (security_header & IEEE802154_FRAME_SECURITY_MASK) { + case IEEE802154_FRAME_SECURITY_MIC_32: + case IEEE802154_FRAME_SECURITY_ENC_MIC_32: + mic_len = IEEE802154_FRAME_SECURITY_MIC_32_SIZE; + break; + case IEEE802154_FRAME_SECURITY_MIC_64: + case IEEE802154_FRAME_SECURITY_ENC_MIC_64: + mic_len = IEEE802154_FRAME_SECURITY_MIC_64_SIZE; + break; + case IEEE802154_FRAME_SECURITY_MIC_128: + case IEEE802154_FRAME_SECURITY_ENC_MIC_128: + mic_len = IEEE802154_FRAME_SECURITY_MIC_128_SIZE; + break; + default: + mic_len = 0; + break; + } + return mic_len; +} + +static uint8_t ieee802154_frame_get_ie_field_len(const uint8_t *frame) +{ + uint8_t offset = ieee802154_frame_ie_header_offset(frame); + uint8_t ie_field_len = 0; + uint8_t frame_footer_len = ieee802154_frame_get_mic_len(frame) + IEEE802154_FRAME_FCS_SIZE; + + /* If the `offset + frame_footer_len == frame_len`, we exit the `while()` + loop. This covers the case where frame contains one or more Header IEs + but no data payload. In this case, 2015-spec does not + require Header IE termination to be included (it is optional) + since the end of frame can be determined from frame length and + footer length. (for details, please reference 2015 - spec table 7 - 6 in page 169) */ + + while (frame[0] > offset + ie_field_len + frame_footer_len) { + uint16_t ie_header = frame[offset + ie_field_len + 1] << 8 | frame[offset + ie_field_len]; + // Header Termination IE 2 is used in to signal end of the MHR and beginning of the MAC Payload. + if ((ie_header & IEEE802154_FRAME_IE_HEAD_ID_MASK) == IEEE802154_IE_TYPE_HT2) { + ie_field_len += IEEE802154_FRAME_IE_HEAD_LEN; + break; + } else { + uint8_t ie_subfield_len = (ie_header & IEEE802154_FRAME_IE_SUBFIELD_LEN_MASK); + ie_field_len += IEEE802154_FRAME_IE_HEAD_LEN + ie_subfield_len; + } + } + return ie_field_len; +} + +static IRAM_ATTR uint8_t ieee802154_frame_payload_offset(const uint8_t *frame) +{ + uint8_t offset = ieee802154_frame_security_header_offset(frame); + if (is_security_enabled(frame)) { + // skip security field. + offset += ieee802154_frame_get_security_field_len(frame); + } + + if (ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_2 && is_ie_present(frame)) { + // skip IE fields. + offset += ieee802154_frame_get_ie_field_len(frame); + } + if (ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_0 || ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_1) { + if (ieee802154_frame_get_type(frame) == IEEE802154_FRAME_TYPE_BEACON) { + // TODO: skip beacon payload. + } + if (ieee802154_frame_get_type(frame) == IEEE802154_FRAME_TYPE_COMMAND) { + offset += IEEE802154_FRAME_COMMAND_ID_LEN; + } + } + + return offset - 1; +} + +uint8_t inline ieee802154_frame_get_type(const uint8_t *frame) +{ + return frame[IEEE802154_FRAME_TYPE_OFFSET] & IEEE802154_FRAME_TYPE_MASK; +} + +uint8_t inline ieee802154_frame_get_version(const uint8_t *frame) +{ + return frame[IEEE802154_FRAME_VERSION_OFFSET] & IEEE802154_FRAME_VERSION_MASK; +} + +bool inline ieee802154_frame_is_ack_required(const uint8_t *frame) +{ + return frame[IEEE802154_FRAME_AR_OFFSET] & IEEE802154_FRAME_AR_BIT; +} + +uint8_t ieee802154_frame_get_dst_addr(const uint8_t *frame, uint8_t *addr) +{ + ESP_RETURN_ON_FALSE_ISR(is_suported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_ADDR_MODE, TAG, "invalid frame type"); + + uint8_t offset = ieee802154_frame_address_offset(frame); + uint8_t dst_mode = dst_addr_mode(frame); + uint8_t addr_size; + + ESP_RETURN_ON_FALSE_ISR(dst_mode == IEEE802154_FRAME_DST_MODE_SHORT || dst_mode == IEEE802154_FRAME_DST_MODE_EXT, dst_mode, TAG, "invalid address mode"); + + addr_size = (dst_mode == IEEE802154_FRAME_DST_MODE_SHORT) ? IEEE802154_FRAME_SHORT_ADDR_SIZE : IEEE802154_FRAME_EXT_ADDR_SIZE; + + if (is_dst_panid_present(frame)) { + offset += IEEE802154_FRAME_PANID_SIZE; + } + + memcpy(addr, frame + offset, addr_size); + + return dst_mode; +} + +uint8_t ieee802154_frame_get_src_addr(const uint8_t *frame, uint8_t *addr) +{ + ESP_RETURN_ON_FALSE_ISR(is_suported_frame_type(ieee802154_frame_get_type(frame)), IEEE802154_FRAME_INVALID_ADDR_MODE, TAG, "invalid frame type"); + + uint8_t offset = ieee802154_frame_address_offset(frame); + uint8_t dst_mode = dst_addr_mode(frame); + uint8_t src_mode = src_addr_mode(frame); + uint8_t addr_size; + + ESP_RETURN_ON_FALSE_ISR(src_mode == IEEE802154_FRAME_SRC_MODE_SHORT || src_mode == IEEE802154_FRAME_SRC_MODE_EXT, src_mode, TAG, "invalid address mode"); + + addr_size = (src_mode == IEEE802154_FRAME_SRC_MODE_SHORT) ? IEEE802154_FRAME_SHORT_ADDR_SIZE : IEEE802154_FRAME_EXT_ADDR_SIZE; + + if (is_dst_panid_present(frame)) { + offset += IEEE802154_FRAME_PANID_SIZE; + } + + switch (dst_mode) { + case IEEE802154_FRAME_DST_MODE_SHORT: + offset += IEEE802154_FRAME_SHORT_ADDR_SIZE; + break; + + case IEEE802154_FRAME_DST_MODE_EXT: + offset += IEEE802154_FRAME_EXT_ADDR_SIZE; + break; + + default: + break; + } + + if (is_src_panid_present(frame)) { + offset += IEEE802154_FRAME_PANID_SIZE; + } + + memcpy(addr, frame + offset, addr_size); + + return src_mode; +} + +uint8_t ieee802154_frame_get_security_payload_offset(uint8_t *frame) +{ + return ieee802154_frame_payload_offset(frame); +} + +esp_err_t ieee802154_frame_get_dest_panid(const uint8_t *frame, uint8_t *panid) +{ + uint8_t offset = ieee802154_frame_address_offset(frame); + + if (is_dst_panid_present(frame)) { + memcpy(panid, frame + offset, IEEE802154_FRAME_PANID_SIZE); + return ESP_OK; + } + return ESP_FAIL; +} + +esp_err_t ieee802154_frame_get_src_panid(const uint8_t *frame, uint8_t *panid) +{ + uint8_t offset = ieee802154_frame_address_offset(frame); + uint8_t dst_mode = dst_addr_mode(frame); + + if (is_src_panid_present(frame)) { + if (is_dst_panid_present(frame)) { + offset += IEEE802154_FRAME_PANID_SIZE; + } + + switch (dst_mode) { + case IEEE802154_FRAME_DST_MODE_SHORT: + offset += IEEE802154_FRAME_SHORT_ADDR_SIZE; + break; + + case IEEE802154_FRAME_DST_MODE_EXT: + offset += IEEE802154_FRAME_EXT_ADDR_SIZE; + break; + + default: + break; + } + memcpy(panid, frame + offset, IEEE802154_FRAME_PANID_SIZE); + return ESP_OK; + } + return ESP_FAIL; +} diff --git a/components/ieee802154/driver/esp_ieee802154_pib.c b/components/ieee802154/driver/esp_ieee802154_pib.c new file mode 100644 index 0000000000..81b7a57da4 --- /dev/null +++ b/components/ieee802154/driver/esp_ieee802154_pib.c @@ -0,0 +1,220 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "hal/ieee802154_ll.h" +#include "esp_ieee802154_pib.h" +#include "esp_ieee802154_util.h" + +static ieee802154_pib_t s_ieee802154_pib; +static bool is_pending = false; + +static inline void set_pending(void) +{ + is_pending = true; +} + +static inline void clr_pending(void) +{ + is_pending = false; +} + +bool inline ieee802154_pib_is_pending(void) +{ + return is_pending; +} + +void ieee802154_pib_init(void) +{ + memset(&s_ieee802154_pib, 0, sizeof(ieee802154_pib_t)); + s_ieee802154_pib.auto_ack_rx = true; + s_ieee802154_pib.auto_ack_tx = true; + s_ieee802154_pib.enhance_ack_tx = true; + s_ieee802154_pib.coordinator = false; + s_ieee802154_pib.promiscuous = true; + s_ieee802154_pib.rx_when_idle = false; + s_ieee802154_pib.channel = 11; + s_ieee802154_pib.cca_threshold = CONFIG_IEEE802154_CCA_THRESHOLD; + s_ieee802154_pib.cca_mode = CONFIG_IEEE802154_CCA_MODE; + s_ieee802154_pib.txpower = IEEE802154_TXPOWER_VALUE_MAX; + + set_pending(); +} + +static uint8_t ieee802154_txpower_convert(int8_t txpower) +{ + uint8_t ieee820154_txpower_value = 0; + if (txpower > IEEE802154_TXPOWER_VALUE_MAX) { + ieee820154_txpower_value = 15; + } else if (txpower < IEEE802154_TXPOWER_VALUE_MIN) { + ieee820154_txpower_value = 0; + } else { + ieee820154_txpower_value = (uint8_t)((txpower - IEEE802154_TXPOWER_VALUE_MIN) / 3); + } + return ieee820154_txpower_value; +} + +void ieee802154_pib_update(void) +{ + if (ieee802154_pib_is_pending()) { + ieee802154_ll_set_freq(ieee802154_channel_to_freq(s_ieee802154_pib.channel)); + ieee802154_ll_set_power(ieee802154_txpower_convert(s_ieee802154_pib.txpower)); + + ieee802154_ll_set_cca_mode(s_ieee802154_pib.cca_mode); + ieee802154_ll_set_cca_threshold(s_ieee802154_pib.cca_threshold); + + ieee802154_ll_set_tx_auto_ack(s_ieee802154_pib.auto_ack_tx); + ieee802154_ll_set_rx_auto_ack(s_ieee802154_pib.auto_ack_rx); + ieee802154_ll_set_tx_enhance_ack(s_ieee802154_pib.enhance_ack_tx); + + ieee802154_ll_set_coordinator(s_ieee802154_pib.coordinator); + ieee802154_ll_set_promiscuous(s_ieee802154_pib.promiscuous); + ieee802154_ll_set_pending_mode(s_ieee802154_pib.pending_mode == IEEE802154_AUTO_PENDING_ENHANCED); + + clr_pending(); + } +} + +uint8_t ieee802154_pib_get_channel(void) +{ + return s_ieee802154_pib.channel; +} + +void ieee802154_pib_set_channel(uint8_t channel) +{ + if (s_ieee802154_pib.channel != channel) { + s_ieee802154_pib.channel = channel; + set_pending(); + } +} + +int8_t ieee802154_pib_get_power(void) +{ + return s_ieee802154_pib.txpower; +} + +void ieee802154_pib_set_power(int8_t power) +{ + if (s_ieee802154_pib.txpower != power) { + s_ieee802154_pib.txpower = power; + set_pending(); + } +} + +bool ieee802154_pib_get_promiscuous(void) +{ + return s_ieee802154_pib.promiscuous; +} + +void ieee802154_pib_set_promiscuous(bool enable) +{ + if (s_ieee802154_pib.promiscuous != enable) { + s_ieee802154_pib.promiscuous = enable; + set_pending(); + } +} + +int8_t ieee802154_pib_get_cca_threshold(void) +{ + return s_ieee802154_pib.cca_threshold; +} + +void ieee802154_pib_set_cca_threshold(int8_t cca_threshold) +{ + if (s_ieee802154_pib.cca_threshold != cca_threshold) { + s_ieee802154_pib.cca_threshold = cca_threshold; + set_pending(); + } +} + +ieee802154_ll_cca_mode_t ieee802154_pib_get_cca_mode(void) +{ + return s_ieee802154_pib.cca_mode; +} + +void ieee802154_pib_set_cca_mode(ieee802154_ll_cca_mode_t cca_mode) +{ + if (s_ieee802154_pib.cca_mode != cca_mode) { + s_ieee802154_pib.cca_mode = cca_mode; + set_pending(); + } +} + +bool ieee802154_pib_get_auto_ack_tx(void) +{ + return s_ieee802154_pib.auto_ack_tx; +} + +void ieee802154_pib_set_auto_ack_tx(bool enable) +{ + if (s_ieee802154_pib.auto_ack_tx != enable) { + s_ieee802154_pib.auto_ack_tx = enable; + set_pending(); + } +} + +bool ieee802154_pib_get_auto_ack_rx(void) +{ + return s_ieee802154_pib.auto_ack_rx; +} + +void ieee802154_pib_set_auto_ack_rx(bool enable) +{ + if (s_ieee802154_pib.auto_ack_rx != enable) { + s_ieee802154_pib.auto_ack_rx = enable; + set_pending(); + } +} + +bool ieee802154_pib_get_enhance_ack_tx(void) +{ + return s_ieee802154_pib.enhance_ack_tx; +} + +void ieee802154_pib_set_enhance_ack_tx(bool enable) +{ + if (s_ieee802154_pib.enhance_ack_tx != enable) { + s_ieee802154_pib.enhance_ack_tx = enable; + set_pending(); + } +} + +bool ieee802154_pib_get_coordinator(void) +{ + return s_ieee802154_pib.coordinator; +} + +void ieee802154_pib_set_coordinator(bool enable) +{ + if (s_ieee802154_pib.coordinator != enable) { + s_ieee802154_pib.coordinator = enable; + set_pending(); + } +} + +ieee802154_ll_pending_mode_t ieee802154_pib_get_pending_mode(void) +{ + return s_ieee802154_pib.pending_mode; +} + +void ieee802154_pib_set_pending_mode(ieee802154_ll_pending_mode_t pending_mode) +{ + if (s_ieee802154_pib.pending_mode != pending_mode) { + s_ieee802154_pib.pending_mode = pending_mode; + set_pending(); + } +} + +void ieee802154_pib_set_rx_when_idle(bool enable) +{ + s_ieee802154_pib.rx_when_idle = enable; +} + +bool ieee802154_pib_get_rx_when_idle(void) +{ + return s_ieee802154_pib.rx_when_idle; +} diff --git a/components/ieee802154/driver/esp_ieee802154_sec.c b/components/ieee802154/driver/esp_ieee802154_sec.c new file mode 100644 index 0000000000..2192550ab3 --- /dev/null +++ b/components/ieee802154/driver/esp_ieee802154_sec.c @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_err.h" +#include "hal/ieee802154_ll.h" +#include "esp_ieee802154_frame.h" +#include "esp_ieee802154_sec.h" + +#include "esp_ieee802154.h" +static bool s_is_security = false; + +void ieee802154_transmit_security_config(uint8_t *frame, uint8_t *key, uint8_t *addr) +{ + ieee802154_ll_set_security_addr(addr); + ieee802154_ll_set_security_key(key); + ieee802154_ll_set_security_offset(ieee802154_frame_get_security_payload_offset(frame)); + s_is_security = true; +} + +void ieee802154_sec_update(void) +{ + ieee802154_ll_set_transmit_security(s_is_security); + s_is_security = false; +} diff --git a/components/ieee802154/driver/esp_ieee802154_timer.c b/components/ieee802154/driver/esp_ieee802154_timer.c new file mode 100644 index 0000000000..fb564cbcb5 --- /dev/null +++ b/components/ieee802154/driver/esp_ieee802154_timer.c @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc.h" +#include "hal/ieee802154_ll.h" +#include "esp_check.h" +#include "esp_ieee802154_timer.h" + +static const char *TAG = "ieee802154_timer"; + +void ieee802154_timer0_start(void) +{ + ieee802154_ll_set_cmd(IEEE802154_CMD_TIMER0_START); +} + +void ieee802154_timer0_stop(void) +{ + ieee802154_ll_set_cmd(IEEE802154_CMD_TIMER0_STOP); +} + +esp_err_t ieee802154_timer0_set_threshold(uint32_t value) +{ + ESP_RETURN_ON_FALSE((value < IEEE802154_TIMER0_THRESHOLD), ESP_ERR_INVALID_ARG, TAG, "invalid timer0 threshold\r\n"); + + ieee802154_ll_timer0_set_threshold(value); + + return ESP_OK; +} + +uint32_t ieee802154_timer0_get_value(void) +{ + return ieee802154_ll_timer0_get_value(); +} + +void ieee802154_timer1_start(void) +{ + ieee802154_ll_set_cmd(IEEE802154_CMD_TIMER1_START); +} + +void ieee802154_timer1_stop(void) +{ + ieee802154_ll_set_cmd(IEEE802154_CMD_TIMER1_STOP); +} + +esp_err_t ieee802154_timer1_set_threshold(uint32_t value) +{ + ESP_RETURN_ON_FALSE((value < IEEE802154_TIMER1_THRESHOLD), ESP_ERR_INVALID_ARG, TAG, "invalid timer1 threshold\r\n"); + + ieee802154_ll_timer1_set_threshold(value); + + return ESP_OK; +} + +uint32_t ieee802154_timer1_get_value(void) +{ + return ieee802154_ll_timer1_get_value(); +} diff --git a/components/ieee802154/driver/esp_ieee802154_util.c b/components/ieee802154/driver/esp_ieee802154_util.c new file mode 100644 index 0000000000..544fd19056 --- /dev/null +++ b/components/ieee802154/driver/esp_ieee802154_util.c @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/esp_modem_clock.h" +#include "soc/soc.h" +#include "soc/periph_defs.h" +#include "hal/ieee802154_ll.h" +#include "esp_coex_i154.h" +#include "esp_ieee802154_util.h" + +uint8_t ieee802154_freq_to_channel(uint8_t freq) +{ + return (freq - 3) / 5 + 11; +} + +uint8_t ieee802154_channel_to_freq(uint8_t channel) +{ + return (channel - 11) * 5 + 3; +} + +#if CONFIG_ESP_COEX_SW_COEXIST_ENABLE + +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); + break; + case IEEE802154_SCENE_TX: + case IEEE802154_SCENE_RX: + esp_coex_ieee802154_txrx_pti_set(IEEE802154_LOW); + break; + case IEEE802154_SCENE_TX_AT: + case IEEE802154_SCENE_RX_AT: + esp_coex_ieee802154_txrx_pti_set(IEEE802154_MIDDLE); + break; + default: + assert(false); + break; + } + +} + +#endif // CONFIG_ESP_COEX_SW_COEXIST_ENABLE + +// 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))) { + REG_WRITE(ETM_CHENCLR_AD0_REG, (REG_READ(ETM_CHENCLR_AD0_REG)) | 1 << channel); + } +} + +void ieee802154_etm_set_event_task(uint32_t channel, uint32_t event, uint32_t task) +{ + ieee802154_etm_channel_clear(channel); + + REG_WRITE((ETM_CH0_EVT_ID_REG + ETM_CH_OFFSET * channel), event); + REG_WRITE((ETM_CH0_TASK_ID_REG + ETM_CH_OFFSET * channel), task); + + REG_WRITE(ETM_CHENSET_AD0_REG, (REG_READ(ETM_CHENSET_AD0_REG) | 1 << channel)); +} diff --git a/components/ieee802154/esp_ieee802154.c b/components/ieee802154/esp_ieee802154.c new file mode 100644 index 0000000000..ac971d5226 --- /dev/null +++ b/components/ieee802154/esp_ieee802154.c @@ -0,0 +1,382 @@ +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_ieee802154.h" +#include "esp_phy_init.h" +#include "esp_ieee802154_ack.h" +#include "esp_ieee802154_dev.h" +#include "esp_ieee802154_frame.h" +#include "esp_ieee802154_pib.h" +#include "esp_ieee802154_sec.h" +#include "esp_ieee802154_util.h" +#include "esp_log.h" +#include "esp_coex_i154.h" +#include "hal/ieee802154_ll.h" + +esp_err_t esp_ieee802154_enable(void) +{ + + ieee802154_enable(); + esp_phy_enable(); + esp_btbb_enable(); + return ieee802154_mac_init(); +} + +esp_err_t esp_ieee802154_disable(void) +{ + ieee802154_disable(); + return ESP_OK; +} + +uint8_t esp_ieee802154_get_channel(void) +{ + return ieee802154_pib_get_channel(); +} + +esp_err_t esp_ieee802154_set_channnel(uint8_t channel) +{ + ieee802154_pib_set_channel(channel); + return ESP_OK; +} + +int8_t esp_ieee802154_get_txpower(void) +{ + return ieee802154_pib_get_power(); +} + +esp_err_t esp_ieee802154_set_txpower(int8_t power) +{ + ieee802154_pib_set_power(power); + return ESP_OK; +} + +bool esp_ieee802154_get_promiscuous(void) +{ + return ieee802154_pib_get_promiscuous(); +} + +esp_err_t esp_ieee802154_set_promiscuous(bool enable) +{ + ieee802154_pib_set_promiscuous(enable); + ieee802154_pib_set_auto_ack_rx(!enable); + ieee802154_pib_set_auto_ack_tx(!enable); + ieee802154_pib_set_enhance_ack_tx(!enable); + return ESP_OK; +} + +int8_t esp_ieee802154_get_cca_threshold(void) +{ + return ieee802154_pib_get_cca_threshold(); +} + +esp_err_t esp_ieee802154_set_cca_threshold(int8_t cca_threshold) +{ + ieee802154_pib_set_cca_threshold(cca_threshold); + return ESP_OK; +} + +esp_ieee802154_cca_mode_t esp_ieee802154_get_cca_mode(void) +{ + return ieee802154_pib_get_cca_mode(); +} + +esp_err_t esp_ieee802154_set_cca_mode(esp_ieee802154_cca_mode_t cca_mode) +{ + ieee802154_pib_set_cca_mode(cca_mode); + return ESP_OK; +} + +bool esp_ieee802154_get_auto_ack_tx(void) +{ + return ieee802154_pib_get_auto_ack_tx(); +} + +esp_err_t esp_ieee802154_set_auto_ack_tx(bool enable) +{ + ieee802154_pib_set_auto_ack_tx(enable); + return ESP_OK; +} + +bool esp_ieee802154_get_auto_ack_rx(void) +{ + return ieee802154_pib_get_auto_ack_rx(); +} + +esp_err_t esp_ieee802154_set_auto_ack_rx(bool enable) +{ + ieee802154_pib_set_auto_ack_rx(enable); + return ESP_OK; +} + +bool esp_ieee802154_get_coordinator(void) +{ + return ieee802154_pib_get_coordinator(); +} + +esp_err_t esp_ieee802154_set_coordinator(bool enable) +{ + ieee802154_pib_set_coordinator(enable); + return ESP_OK; +} + +#if CONFIG_IEEE802154_MULTI_PAN_ENABLE + +uint16_t esp_ieee802154_get_multipan_panid(esp_ieee802154_multipan_index_t index) +{ + assert(index < ESP_IEEE802154_MULTIPAN_MAX); + return ieee802154_ll_get_multipan_panid(index); +} + +esp_err_t esp_ieee802154_set_multipan_panid(esp_ieee802154_multipan_index_t index, uint16_t panid) +{ + assert(index < ESP_IEEE802154_MULTIPAN_MAX); + ieee802154_ll_set_multipan_panid(index, panid); + return ESP_OK; +} + +uint16_t esp_ieee802154_get_multipan_short_address(esp_ieee802154_multipan_index_t index) +{ + assert(index < ESP_IEEE802154_MULTIPAN_MAX); + return ieee802154_ll_get_multipan_short_addr(index); +} + +esp_err_t esp_ieee802154_set_multipan_short_address(esp_ieee802154_multipan_index_t index, uint16_t short_address) +{ + assert(index < ESP_IEEE802154_MULTIPAN_MAX); + ieee802154_ll_set_multipan_short_addr(index, short_address); + return ESP_OK; +} + +esp_err_t esp_ieee802154_get_multipan_extended_address(esp_ieee802154_multipan_index_t index, uint8_t *ext_addr) +{ + assert(index < ESP_IEEE802154_MULTIPAN_MAX); + ieee802154_ll_get_multipan_ext_addr(index, ext_addr); + return ESP_OK; +} + +esp_err_t esp_ieee802154_set_multipan_extended_address(esp_ieee802154_multipan_index_t index, const uint8_t *ext_addr) +{ + assert(index < ESP_IEEE802154_MULTIPAN_MAX); + ieee802154_ll_set_multipan_ext_addr(index, ext_addr); + return ESP_OK; +} + +uint8_t esp_ieee802154_get_multipan_enable(void) +{ + return ieee802154_pib_get_multipan_enable(); +} + +esp_err_t esp_ieee802154_set_multipan_enable(uint8_t mask) +{ + assert(mask < ((1 << ESP_IEEE802154_MULTIPAN_MAX) - 1)); + ieee802154_pib_set_multipan_enable(mask); + return ESP_OK; +} + +#else + +uint16_t esp_ieee802154_get_panid(void) +{ + return ieee802154_ll_get_multipan_panid(ESP_IEEE802154_MULTIPAN_0); +} + +esp_err_t esp_ieee802154_set_panid(uint16_t panid) +{ + ieee802154_ll_set_multipan_panid(ESP_IEEE802154_MULTIPAN_0, panid); + return ESP_OK; +} + +uint16_t esp_ieee802154_get_short_address(void) +{ + return ieee802154_ll_get_multipan_short_addr(ESP_IEEE802154_MULTIPAN_0); +} + +esp_err_t esp_ieee802154_set_short_address(uint16_t short_address) +{ + ieee802154_ll_set_multipan_short_addr(ESP_IEEE802154_MULTIPAN_0, short_address); + return ESP_OK; +} + +esp_err_t esp_ieee802154_get_extended_address(uint8_t *ext_addr) +{ + ieee802154_ll_get_multipan_ext_addr(ESP_IEEE802154_MULTIPAN_0, ext_addr); + return ESP_OK; +} + +esp_err_t esp_ieee802154_set_extended_address(const uint8_t *ext_addr) +{ + ieee802154_ll_set_multipan_ext_addr(ESP_IEEE802154_MULTIPAN_0, 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(); +} + +esp_err_t esp_ieee802154_set_pending_mode(esp_ieee802154_pending_mode_t pending_mode) +{ + ieee802154_pib_set_pending_mode(pending_mode); + return ESP_OK; +} + +esp_err_t esp_ieee802154_set_rx_when_idle(bool enable) +{ + ieee802154_pib_set_rx_when_idle(enable); + return ESP_OK; +} + +bool esp_ieee802154_get_rx_when_idle(void) +{ + return ieee802154_pib_get_rx_when_idle(); +} + +esp_err_t esp_ieee802154_transmit(const uint8_t *frame, bool cca) +{ + return ieee802154_transmit(frame, cca); +} + +esp_err_t esp_ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time) +{ + return ieee802154_transmit_at(frame, cca, time); +} + +esp_err_t esp_ieee802154_sleep(void) +{ + return ieee802154_sleep(); +} + +esp_err_t esp_ieee802154_receive(void) +{ + return ieee802154_receive(); +} + +esp_err_t esp_ieee802154_receive_at(uint32_t time) +{ + return ieee802154_receive_at(time); +} + +esp_err_t esp_ieee802154_energy_detect(uint32_t duration) +{ + return ieee802154_energy_detect(duration); +} + +esp_err_t esp_ieee802154_cca(void) +{ + return ieee802154_cca(); +} + +esp_ieee802154_state_t esp_ieee802154_get_state(void) +{ + switch (ieee802154_get_state()) { + case IEEE802154_STATE_DISABLE: + return ESP_IEEE802154_RADIO_DISABLE; + + case IEEE802154_STATE_IDLE: + return ESP_IEEE802154_RADIO_SLEEP; + + case IEEE802154_STATE_RX: + case IEEE802154_STATE_TX_ACK: + case IEEE802154_STATE_ED: + return ESP_IEEE802154_RADIO_RECEIVE; + + case IEEE802154_STATE_TX_CCA: + case IEEE802154_STATE_CCA: + case IEEE802154_STATE_TX: + case IEEE802154_STATE_RX_ACK: + return ESP_IEEE802154_RADIO_TRANSMIT; + + default: + assert(false); + return ESP_IEEE802154_RADIO_DISABLE; + } +} + +esp_err_t esp_ieee802154_set_transmit_security(uint8_t *frame, uint8_t *key, uint8_t *addr) +{ + ieee802154_transmit_security_config(frame, key, addr); + return ESP_OK; +} + +esp_err_t esp_ieee802154_add_pending_addr(const uint8_t *addr, bool is_short) +{ + return ieee802154_add_pending_addr(addr, is_short); +} + +esp_err_t esp_ieee802154_clear_pending_addr(const uint8_t *addr, bool is_short) +{ + return ieee802154_clear_pending_addr(addr, is_short); +} + +esp_err_t esp_ieee802154_reset_pending_table(bool is_short) +{ + ieee802154_reset_pending_table(is_short); + return ESP_OK; +} + +int8_t esp_ieee802154_get_recent_rssi(void) +{ + return ieee802154_get_recent_rssi(); +} + +uint8_t esp_ieee802154_get_recent_lqi(void) +{ + return ieee802154_get_recent_lqi(); +} + +__attribute__((weak)) void esp_ieee802154_receive_done(uint8_t *data, esp_ieee802154_frame_info_t *frame_info) +{ + +} + +__attribute__((weak)) void esp_ieee802154_receive_sfd_done(void) +{ + +} + +__attribute__((weak)) void esp_ieee802154_receive_failed(uint16_t error) +{ + +} + +__attribute__((weak)) void esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_ieee802154_frame_info_t *ack_frame_info) +{ + +} + +__attribute__((weak)) void esp_ieee802154_transmit_failed(const uint8_t *frame, esp_ieee802154_tx_error_t error) +{ + +} + +__attribute__((weak)) void esp_ieee802154_transmit_sfd_done(uint8_t *frame) +{ + +} + +__attribute__((weak)) void esp_ieee802154_cca_done(bool channel_free) +{ + +} + +__attribute__((weak)) void esp_ieee802154_energy_detect_done(int8_t power) +{ + +} + +__attribute__((weak)) void esp_ieee802154_ed_failed(uint16_t error) +{ + +} + +__attribute__((weak)) esp_err_t esp_ieee802154_enh_ack_generator(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info, uint8_t* enhack_frame) +{ + return ESP_OK; +} diff --git a/components/ieee802154/include/esp_ieee802154.h b/components/ieee802154/include/esp_ieee802154.h index 3d8860a493..f814fe1fa0 100644 --- a/components/ieee802154/include/esp_ieee802154.h +++ b/components/ieee802154/include/esp_ieee802154.h @@ -18,14 +18,21 @@ extern "C" { /** * @brief Initialize the IEEE 802.15.4 subsystem. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. + * */ -void esp_ieee802154_enable(void); +esp_err_t esp_ieee802154_enable(void); /** * @brief Deinitialize the IEEE 802.15.4 subsystem. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_disable(void); +esp_err_t esp_ieee802154_disable(void); /** * @brief Get the operational channel. @@ -40,8 +47,11 @@ uint8_t esp_ieee802154_get_channel(void); * * @param[in] channel The channel number (11-26). * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_channnel(uint8_t channel); +esp_err_t esp_ieee802154_set_channnel(uint8_t channel); /** * @brief Get the transmit power. @@ -56,8 +66,11 @@ int8_t esp_ieee802154_get_txpower(void); * * @param[in] power The transmit power in dBm. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_txpower(int8_t power); +esp_err_t esp_ieee802154_set_txpower(int8_t power); /** * @brief Get the promiscuous mode. @@ -74,8 +87,11 @@ bool esp_ieee802154_get_promiscuous(void); * * @param[in] enable The promiscuous mode to be set. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_promiscuous(bool enable); +esp_err_t esp_ieee802154_set_promiscuous(bool enable); /** * @brief Get the IEEE 802.15.4 Radio state. @@ -133,8 +149,11 @@ esp_err_t esp_ieee802154_transmit(const uint8_t *frame, bool cca); * @param[in] timeout The time to wait for the ack frame, in symbol unit (16 us). * Default: 0x006C, Range: 0x0000 - 0xFFFF. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_ack_timeout(uint32_t timeout); +esp_err_t esp_ieee802154_set_ack_timeout(uint32_t timeout); /** * @brief Get the device PAN ID. @@ -149,8 +168,11 @@ uint16_t esp_ieee802154_get_panid(void); * * @param[in] panid The device PAN ID. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_panid(uint16_t panid); +esp_err_t esp_ieee802154_set_panid(uint16_t panid); /** * @brief Get the device short address. @@ -165,24 +187,33 @@ uint16_t esp_ieee802154_get_short_address(void); * * @param[in] short_address The device short address. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_short_address(uint16_t short_address); +esp_err_t esp_ieee802154_set_short_address(uint16_t short_address); /** * @brief Get the device extended address. * * @param[out] ext_addr The pointer to the device extended address. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_get_extended_address(uint8_t *ext_addr); +esp_err_t esp_ieee802154_get_extended_address(uint8_t *ext_addr); /** * @brief Set the device extended address. * * @param[in] ext_addr The pointer to the device extended address. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_extended_address(const uint8_t *ext_addr); +esp_err_t esp_ieee802154_set_extended_address(const uint8_t *ext_addr); /** * @brief Get the device PAN ID for specific interface. @@ -200,8 +231,11 @@ uint16_t esp_ieee802154_get_multipan_panid(esp_ieee802154_multipan_index_t index * @param[in] index The interface index. * @param[in] panid The device PAN ID. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_multipan_panid(esp_ieee802154_multipan_index_t index, uint16_t panid); +esp_err_t esp_ieee802154_set_multipan_panid(esp_ieee802154_multipan_index_t index, uint16_t panid); /** * @brief Get the device short address for specific interface. @@ -219,8 +253,11 @@ uint16_t esp_ieee802154_get_multipan_short_address(esp_ieee802154_multipan_index * @param[in] index The interface index. * @param[in] short_address The device short address. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_multipan_short_address(esp_ieee802154_multipan_index_t index, uint16_t short_address); +esp_err_t esp_ieee802154_set_multipan_short_address(esp_ieee802154_multipan_index_t index, uint16_t short_address); /** * @brief Get the device extended address for specific interface. @@ -228,8 +265,11 @@ void esp_ieee802154_set_multipan_short_address(esp_ieee802154_multipan_index_t i * @param[in] index The interface index. * @param[out] ext_addr The pointer to the device extended address. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_get_multipan_extended_address(esp_ieee802154_multipan_index_t index, uint8_t *ext_addr); +esp_err_t esp_ieee802154_get_multipan_extended_address(esp_ieee802154_multipan_index_t index, uint8_t *ext_addr); /** * @brief Set the device extended address for specific interface. @@ -237,8 +277,11 @@ void esp_ieee802154_get_multipan_extended_address(esp_ieee802154_multipan_index_ * @param[in] index The interface index. * @param[in] ext_addr The pointer to the device extended address. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_multipan_extended_address(esp_ieee802154_multipan_index_t index, const uint8_t *ext_addr); +esp_err_t esp_ieee802154_set_multipan_extended_address(esp_ieee802154_multipan_index_t index, const uint8_t *ext_addr); /** * @brief Get the device current multipan interface enable mask. @@ -256,8 +299,11 @@ uint8_t esp_ieee802154_get_multipan_enable(void); * * @param[in] mask The multipan interface bit mask. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_multipan_enable(uint8_t mask); +esp_err_t esp_ieee802154_set_multipan_enable(uint8_t mask); /** * @brief Get the device coordinator. @@ -274,8 +320,11 @@ bool esp_ieee802154_get_coordinator(void); * * @param[in] enable The coordinator role to be set. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_coordinator(bool enable); +esp_err_t esp_ieee802154_set_coordinator(bool enable); /** * @brief Get the auto frame pending mode. @@ -290,8 +339,11 @@ esp_ieee802154_pending_mode_t esp_ieee802154_get_pending_mode(void); * * @param[in] pending_mode The auto frame pending mode, refer to esp_ieee802154_pending_mode_t. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_pending_mode(esp_ieee802154_pending_mode_t pending_mode); +esp_err_t esp_ieee802154_set_pending_mode(esp_ieee802154_pending_mode_t pending_mode); /** * @brief Add address to the source matching table. @@ -324,8 +376,11 @@ esp_err_t esp_ieee802154_clear_pending_addr(const uint8_t *addr, bool is_short); * * @param[in] is_short Clear Short address table or Extended address table. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_reset_pending_table(bool is_short); +esp_err_t esp_ieee802154_reset_pending_table(bool is_short); /** * @brief Get the CCA threshold. @@ -340,8 +395,11 @@ int8_t esp_ieee802154_get_cca_threshold(void); * * @param[in] cca_threshold The CCA threshold in dBm. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_cca_threshold(int8_t cca_threshold); +esp_err_t esp_ieee802154_set_cca_threshold(int8_t cca_threshold); /** * @brief Get the CCA mode. @@ -356,16 +414,22 @@ esp_ieee802154_cca_mode_t esp_ieee802154_get_cca_mode(void); * * @param[in] cca_mode The CCA mode, refer to esp_ieee802154_cca_mode_t. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_cca_mode(esp_ieee802154_cca_mode_t cca_mode); +esp_err_t esp_ieee802154_set_cca_mode(esp_ieee802154_cca_mode_t cca_mode); /** * @brief Enable rx_on_when_idle mode, radio will receive during idle. * * @param[in] enable Enable/Disable rx_on_when_idle mode. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_rx_when_idle(bool enable); +esp_err_t esp_ieee802154_set_rx_when_idle(bool enable); /** * @brief Get the rx_on_when_idle mode. @@ -388,22 +452,6 @@ bool esp_ieee802154_get_rx_when_idle(void); */ esp_err_t esp_ieee802154_energy_detect(uint32_t duration); -/** - * @brief Start the one-shot timer 0 in IEEE 802.15.4 subsystem. - * - * @param[in] interval The timer interval in microseconds. - * - */ -void esp_ieee802154_timer0_start(uint32_t interval); - -/** - * @brief Start the one-shot timer 1 in IEEE 802.15.4 subsystem. - * - * @param[in] interval The timer interval in 625 microseconds. - * - */ -void esp_ieee802154_timer1_start(uint32_t interval); - /** Below are the events generated by IEEE 802.15.4 subsystem, which are in ISR context **/ /** * @brief A Frame was received. @@ -462,18 +510,6 @@ extern void esp_ieee802154_transmit_sfd_done(uint8_t *frame); */ extern void esp_ieee802154_energy_detect_done(int8_t power); -/** - * @brief The timer 0 has expired. - * - */ -extern void esp_ieee802154_timer0_done(void); - -/** - * @brief The timer 1 has expired. - * - */ -extern void esp_ieee802154_timer1_done(void); - /** * @brief Set the IEEE 802.15.4 Radio to receive state at a specific time. * @@ -529,8 +565,11 @@ uint8_t esp_ieee802154_get_recent_lqi(void); * @param[in] key A 16-bytes key for encryption. * @param[in] addr An 8-bytes addr for HW to generate nonce, in general, is the device extended address. * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. */ -void esp_ieee802154_set_transmit_security(uint8_t *frame, uint8_t *key, uint8_t *addr); +esp_err_t esp_ieee802154_set_transmit_security(uint8_t *frame, uint8_t *key, uint8_t *addr); /** * @brief This function will be called when a received frame needs to be acked with Enh-Ack, the upper @@ -540,8 +579,12 @@ void esp_ieee802154_set_transmit_security(uint8_t *frame, uint8_t *key, uint8_t * @param[in] frame_info The frame information. Refer to `esp_ieee802154_frame_info_t`. * @param[out] enhack_frame The Enh-ack frame need to be generated via this function, HW will send it back after AIFS. * + * @return + * - ESP_OK if Enh-Ack generates done. + * - ESP_FAIL if Enh-Ack generates failed. + * */ -void esp_ieee802154_enh_ack_generator(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info, uint8_t* enhack_frame); +esp_err_t esp_ieee802154_enh_ack_generator(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info, uint8_t* enhack_frame); #ifdef __cplusplus } diff --git a/components/ieee802154/include/esp_ieee802154_types.h b/components/ieee802154/include/esp_ieee802154_types.h index 5769c4cc3a..2606053b3c 100644 --- a/components/ieee802154/include/esp_ieee802154_types.h +++ b/components/ieee802154/include/esp_ieee802154_types.h @@ -33,8 +33,6 @@ typedef enum { ESP_IEEE802154_TX_ERR_NO_ACK, /*!< No Ack frame received until timeout */ ESP_IEEE802154_TX_ERR_INVALID_ACK, /*!< Invalid Ack frame */ ESP_IEEE802154_TX_ERR_COEXIST, /*!< Rejected by coexist system */ - ESP_IEEE802154_TX_ERR_COEXIST_REJ, /*!< Rejected by coexist system before transmitting frame */ - ESP_IEEE802154_TX_ERR_COEXIST_ACK, /*!< Rejected by coexist system when receiving ack */ ESP_IEEE802154_TX_ERR_SECURITY, /*!< Invalid security configuration */ } esp_ieee802154_tx_error_t; @@ -66,6 +64,7 @@ typedef enum { ESP_IEEE802154_MULTIPAN_1 = 1, ESP_IEEE802154_MULTIPAN_2 = 2, ESP_IEEE802154_MULTIPAN_3 = 3, + ESP_IEEE802154_MULTIPAN_MAX } esp_ieee802154_multipan_index_t; /** diff --git a/components/ieee802154/lib b/components/ieee802154/lib index 54ceb75476..102b03c809 160000 --- a/components/ieee802154/lib +++ b/components/ieee802154/lib @@ -1 +1 @@ -Subproject commit 54ceb75476f7bdbb8a2557d2a8a012a9342e7a37 +Subproject commit 102b03c8095de8a337c293f79dce189be63186f3 diff --git a/components/ieee802154/linker.lf b/components/ieee802154/linker.lf new file mode 100644 index 0000000000..3c32c33352 --- /dev/null +++ b/components/ieee802154/linker.lf @@ -0,0 +1,59 @@ +[mapping:ieee802154] +archive: libieee802154.a +entries: + if IEEE802154_ENABLED = y: + 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_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_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_stop (noflash) + esp_ieee802154_util: ieee802154_etm_channel_clear (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_pib: ieee802154_set_panid_addr (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) + esp_ieee802154_pib: ieee802154_pib_get_extended_address (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_dev: ieee802154_get_recent_lqi (noflash) diff --git a/components/ieee802154/private_include/esp_ieee802154_ack.h b/components/ieee802154/private_include/esp_ieee802154_ack.h new file mode 100644 index 0000000000..1b44f608b5 --- /dev/null +++ b/components/ieee802154/private_include/esp_ieee802154_ack.h @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" +#include "esp_ieee802154_frame.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The radio pending table, which is utilized to determine whether the received frame should be responded to with pending bit enabled. + */ +typedef struct { + uint8_t short_addr[CONFIG_IEEE802154_PENDING_TABLE_SIZE][IEEE802154_FRAME_SHORT_ADDR_SIZE]; /*!< Short address table */ + uint8_t ext_addr[CONFIG_IEEE802154_PENDING_TABLE_SIZE][IEEE802154_FRAME_EXT_ADDR_SIZE]; /*!< Extend address table */ + uint32_t short_addr_mask; /*!< The mask which the index of short address table is used */ + uint32_t ext_addr_mask; /*!< The mask which the index of extended address table is used */ +} ieee802154_pending_table_t; + +/** + * @brief Add an address to the pending table. + * + * @param[in] addr The pointer to the address needs to be added. + * @param[in] is_short The type of address, true for short address, false for extended. + * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure due to the table is full. + * + */ +esp_err_t ieee802154_add_pending_addr(const uint8_t *addr, bool is_short); + +/** + * @brief Remove an address in pending table. + * + * @param[in] addr The pointer to the address needs to be cleared. + * @param[in] is_short The type of address, true for short address, false for extended. + * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure if the given address is not present in the pending table. + * + */ +esp_err_t ieee802154_clear_pending_addr(const uint8_t *addr, bool is_short); + +/** + * @brief Reset the pending table, only clear the mask bits for finishing the process quickly. + * + * @param[in] is_short The type of address, true for resetting short address table, false for extended. + * + */ +void ieee802154_reset_pending_table(bool is_short); + +/** + * @brief Check whether the pending bit should be set or not in the ack frame. + * + * @param[in] frame The pointer to the received frame. + * + * @return + * - True The pending bit should be set, otherwise False. + * + */ +bool ieee802154_ack_config_pending_bit(const uint8_t *frame); + +#ifdef __cplusplus +} +#endif diff --git a/components/ieee802154/private_include/esp_ieee802154_dev.h b/components/ieee802154/private_include/esp_ieee802154_dev.h new file mode 100644 index 0000000000..fbf3d9ca9b --- /dev/null +++ b/components/ieee802154/private_include/esp_ieee802154_dev.h @@ -0,0 +1,206 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_log.h" +#include "esp_err.h" +#include "soc/soc.h" +#include "esp_ieee802154_frame.h" +#include "esp_ieee802154.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IEEE802154_TAG "ieee802154" + +// These three macros are in microseconds, used for transmit_at +#define IEEE802154_ED_TRIG_TX_RAMPUP_TIME_US 256 +#define IEEE802154_TX_RAMPUP_TIME_US 98 +#define IEEE802154_RX_RAMPUP_TIME_US 146 + +/** + * @brief The state of IEEE802154 radio process. + */ +typedef enum { + IEEE802154_STATE_DISABLE, /*!< IEEE802154 radio state disable */ + IEEE802154_STATE_IDLE, /*!< IEEE802154 radio state idle */ + IEEE802154_STATE_RX, /*!< IEEE802154 radio state rx */ + IEEE802154_STATE_TX_ACK, /*!< IEEE802154 radio state tx ack */ + IEEE802154_STATE_TX_ENH_ACK, /*!< IEEE802154 radio state tx enh-ack */ + IEEE802154_STATE_TX_CCA, /*!< IEEE802154 radio state cca trigger tx */ + IEEE802154_STATE_TX, /*!< IEEE802154 radio state tx */ + IEEE802154_STATE_TEST_TX, /*!< IEEE802154 radio state test mode tx */ + IEEE802154_STATE_RX_ACK, /*!< IEEE802154 radio state rx ack */ + IEEE802154_STATE_ED, /*!< IEEE802154 radio state ED */ + IEEE802154_STATE_CCA, /*!< IEEE802154 radio state CCA */ +} ieee802154_state_t; + +/** + * @brief Initialize the clock of IEEE 802.15.4 subsystem. + * + */ +void ieee802154_enable(void); + +/** + * @brief Deinitialize the clock of IEEE 802.15.4 subsystem. + * + */ +void ieee802154_disable(void); + +/** + * @brief Initialize the IEEE 802.15.4 MAC. + * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure. + * + */ +esp_err_t ieee802154_mac_init(void); + +/** + * @brief Transmit the given frame. + * + * @param[in] frame The pointer to the frame + * @param[in] cca Perform CCA before transmission if it's true, otherwise transmit the frame directly. + * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure due to invalid state. + * + */ +esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca); + +/** + * @brief Set the IEEE 802.15.4 Radio to receive state. + * + * @return + * - ESP_OK on success + * - ESP_FAIL on failure due to invalid state. + * + */ +esp_err_t ieee802154_receive(void); + +/** + * @brief Transmit the given frame at a specific time. + * + * @param[in] frame The pointer to the frame. Refer to `esp_ieee802154_transmit()`. + * @param[in] cca Perform CCA before transmission if it's true, otherwise transmit the frame directly. + * @param[in] time A specific timestamp for starting transmission. + * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure due to invalid state. + * + * Note: The transmit result will be reported via esp_ieee802154_transmit_done() + * or esp_ieee802154_transmit_failed(). + * + */ +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. + * + * + * @param[in] time A specific timestamp for starting receiving. + * @return + * - ESP_OK on success + * - ESP_FAIL on failure due to invalid state. + * + * Note: Radio will start receiving after the timestamp, and continue receiving until it receives a valid frame. + * Ref to esp_ieee802154_receive_done(). + * + */ +esp_err_t ieee802154_receive_at(uint32_t time); + +/** + * @brief Set the IEEE 802.15.4 Radio to sleep state. + * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure due to invalid state. + * + */ +esp_err_t ieee802154_sleep(void); + +/** + * @brief Perform energy detection(ED). + * + * @param[in] duration The duration of energy detection, in symbol unit (16 us). + * The result will be reported via esp_ieee802154_energy_detect_done(). + * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure due to invalid state. + * + */ +esp_err_t ieee802154_energy_detect(uint32_t duration); + +/** + * @brief Perform clear channel assessment(CCA). + * + * @return + * - ESP_OK on success. + * - ESP_FAIL on failure due to invalid state. + * + */ +esp_err_t ieee802154_cca(void); + +/** + * @brief Get the RSSI of the most recent received frame. + * + * @return The value of RSSI. + * + */ +int8_t ieee802154_get_recent_rssi(void); + +/** + * @brief Get the LQI of the most recent received frame. + * + * @return The value of LQI. + * + */ +uint8_t ieee802154_get_recent_lqi(void); + +/** + * @brief Get the IEEE 802.15.4 Radio state. + * + * @return + * - Current state of IEEE 802.15.4 Radio. + * + */ +ieee802154_state_t ieee802154_get_state(void); + +/** The following three functions are only used for internal test. **/ +/** + * @brief The clear channel assessment done. + * + * @param[in] channel_free True if the channel is clear, otherwise false. + * + */ +extern void esp_ieee802154_cca_done(bool channel_free); + +/** + * @brief Current receiving process is failed due to some reasons. + * + * @param[in] error The specific received failed reason. + * + */ +extern void esp_ieee802154_receive_failed(uint16_t error); + +/** + * @brief Current energy detection(ED) is failed due to some reasons. + * + * @param[in] error The specific ED failed reason. + * + */ +extern void esp_ieee802154_ed_failed(uint16_t error); +#ifdef __cplusplus +} +#endif diff --git a/components/ieee802154/private_include/esp_ieee802154_frame.h b/components/ieee802154/private_include/esp_ieee802154_frame.h new file mode 100644 index 0000000000..497c1f7ee7 --- /dev/null +++ b/components/ieee802154/private_include/esp_ieee802154_frame.h @@ -0,0 +1,199 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IEEE802154_FRAME_INVALID_OFFSET 0xff +#define IEEE802154_FRAME_INVALID_ADDR_MODE 0xff + +#define IEEE802154_FRAME_TYPE_OFFSET 1 +#define IEEE802154_FRAME_TYPE_MASK 0x07 +#define IEEE802154_FRAME_TYPE_BEACON 0x00 +#define IEEE802154_FRAME_TYPE_DATA 0x01 +#define IEEE802154_FRAME_TYPE_ACK 0x02 +#define IEEE802154_FRAME_TYPE_COMMAND 0x03 +#define IEEE802154_FRAME_TYPE_MULTIPURPOSE 0x05 +#define IEEE802154_FRAME_TYPE_FRAGMENT 0x06 +#define IEEE802154_FRAME_TYPE_EXTENDED 0x07 + +#define IEEE802154_FRAME_SECURITY_OFFSET 1 +#define IEEE802154_FRAME_SECURITY_BIT BIT(3) +#define IEEE802154_FRAME_SECURITY_MASK 0x07 +#define IEEE802154_FRAME_SECURITY_MIC_32 0x01 +#define IEEE802154_FRAME_SECURITY_MIC_64 0x02 +#define IEEE802154_FRAME_SECURITY_MIC_128 0x03 +#define IEEE802154_FRAME_SECURITY_ENC_MIC_32 0x05 +#define IEEE802154_FRAME_SECURITY_ENC_MIC_64 0x06 +#define IEEE802154_FRAME_SECURITY_ENC_MIC_128 0x07 +#define IEEE802154_FRAME_SECURITY_MIC_32_SIZE 4 +#define IEEE802154_FRAME_SECURITY_MIC_64_SIZE 8 +#define IEEE802154_FRAME_SECURITY_MIC_128_SIZE 16 + +#define IEEE802154_FRAME_KEY_ID_MODE_MASK 0x18 +#define IEEE802154_FRAME_KEY_ID_MODE_1 0x08 +#define IEEE802154_FRAME_KEY_ID_MODE_2 0x10 +#define IEEE802154_FRAME_KEY_ID_MODE_3 0x18 +#define IEEE802154_FRAME_KEY_ID_MODE_1_SIZE 1 +#define IEEE802154_FRAME_KEY_ID_MODE_2_SIZE 5 +#define IEEE802154_FRAME_KEY_ID_MODE_3_SIZE 9 + +#define IEEE802154_FRAME_COUNTER_SUPPRESS_BIT 0x20 +#define IEEE802154_FRAME_COUNTER_SIZE 4 + +#define IEEE802154_FRAME_AR_OFFSET 1 +#define IEEE802154_FRAME_AR_BIT BIT(5) + +#define IEEE802154_FRAME_PANID_COMP_OFFSET 1 +#define IEEE802154_FRAME_PANID_COMP_BIT BIT(6) + +#define IEEE802154_FRAME_VERSION_OFFSET 2 +#define IEEE802154_FRAME_VERSION_MASK 0x30 +#define IEEE802154_FRAME_VERSION_0 0x00 // IEEE 802.15.4 - 2003 +#define IEEE802154_FRAME_VERSION_1 0x10 // IEEE 802.15.4 - 2006 & 2011 +#define IEEE802154_FRAME_VERSION_2 0x20 // IEEE 802.15.4 - 2015 +#define IEEE802154_FRAME_VERSION_R 0x30 // Reserved + +#define IEEE802154_FRAME_DSN_OFFSET 2 +#define IEEE802154_FRAME_DSN_BIT BIT(0) +#define IEEE802154_FRAME_IE_OFFSET 2 +#define IEEE802154_FRAME_IE_BIT BIT(1) + +#define IEEE802154_FRAME_IE_HEAD_ID_MASK 0x3f80 +#define IEEE802154_IE_TYPE_HT2 0x3f80 +#define IEEE802154_FRAME_IE_SUBFIELD_LEN_MASK 0x007f +#define IEEE802154_FRAME_IE_HEAD_LEN 2 + +#define IEEE802154_FRAME_DST_MODE_OFFSET 2 +#define IEEE802154_FRAME_DST_MODE_MASK 0x0C +#define IEEE802154_FRAME_DST_MODE_NONE 0x00 +#define IEEE802154_FRAME_DST_MODE_SHORT 0x08 +#define IEEE802154_FRAME_DST_MODE_EXT 0x0C + +#define IEEE802154_FRAME_SRC_MODE_OFFSET 2 +#define IEEE802154_FRAME_SRC_MODE_MASK 0xC0 +#define IEEE802154_FRAME_SRC_MODE_NONE 0x00 +#define IEEE802154_FRAME_SRC_MODE_SHORT 0x80 +#define IEEE802154_FRAME_SRC_MODE_EXT 0xC0 + +#define IEEE802154_CMD_INVALID 0x00 +#define IEEE802154_CMD_DATA_REQ 0x04 + +#define IEEE802154_FRAME_PHR_SIZE 1 +#define IEEE802154_FRAME_FCF_SIZE 2 +#define IEEE802154_FRAME_FCS_SIZE 2 +#define IEEE802154_FRAME_DSN_SIZE 1 +#define IEEE802154_FRAME_PANID_SIZE 2 +#define IEEE802154_FRAME_SHORT_ADDR_SIZE 2 +#define IEEE802154_FRAME_EXT_ADDR_SIZE 8 +#define IEEE802154_FRAME_SE_HEAD_SIZE 1 +#define IEEE802154_FRAME_COMMAND_ID_LEN 1 + +/** + * @brief Get the frame type. + * + * @param[in] frame The pointer to the frame. + * + * @return + * - The type of the frame. + * + */ +uint8_t ieee802154_frame_get_type(const uint8_t *frame); + +/** + * @brief Get the frame version. + * + * @param[in] frame The pointer to the frame. + * + * @return + * - The version of the frame. + * + */ +uint8_t ieee802154_frame_get_version(const uint8_t *frame); + +/** + * @brief Is the frame ack required. + * + * @param[in] frame The pointer to the frame. + * + * @return + * - True if the frame is ack required, otherwise false. + * + */ +bool ieee802154_frame_is_ack_required(const uint8_t *frame); + +/** + * @brief Get the destination address of the frame. + * + * @param[in] frame The pointer to the frame. + * @param[out] addr The pointer to the address. + * + * @return + * - IEEE802154_FRAME_DST_MODE_NONE if destination adress mode is none. + * - IEEE802154_FRAME_DST_MODE_SHORT if destination adress mode is short. + * - IEEE802154_FRAME_DST_MODE_EXT if destination adress mode is extended. + * + */ +uint8_t ieee802154_frame_get_dst_addr(const uint8_t *frame, uint8_t *addr); + +/** + * @brief Get the source address of the frame. + * + * @param[in] frame The pointer to the frame. + * @param[out] addr The pointer to the address. + * + * @return + * - IEEE802154_FRAME_SRC_MODE_NONE if source adress mode is none. + * - IEEE802154_FRAME_SRC_MODE_SHORT if source adress mode is short. + * - IEEE802154_FRAME_SRC_MODE_EXT if source adress mode is extended. + * + */ +uint8_t ieee802154_frame_get_src_addr(const uint8_t *frame, uint8_t *addr); + +/** + * @brief Get the offset of the private payload. + * + * @param[in] frame The pointer to the frame. + * + * @return + * - The offset of the private payload + * + */ +uint8_t ieee802154_frame_get_security_payload_offset(uint8_t *frame); + +/** + * @brief Get the destination PAN ID of the frame. + * + * @param[in] frame The pointer to the frame. + * @param[out] panid The pointer to the destination PAN ID. + * + * @return + * - ESP_OK if destination PAN ID is present, otherwise ESP_FAIL. + * + */ +esp_err_t ieee802154_frame_get_dest_panid(const uint8_t *frame, uint8_t *panid); + +/** + * @brief Get the source PAN ID of the frame. + * + * @param[in] frame The pointer to the frame. + * @param[out] panid The pointer to the source PAN ID. + * + * @return + * - ESP_OK if source PAN ID is present, otherwise ESP_FAIL. + * + */ +esp_err_t ieee802154_frame_get_src_panid(const uint8_t *frame, uint8_t *panid); +#ifdef __cplusplus +} +#endif diff --git a/components/ieee802154/private_include/esp_ieee802154_pib.h b/components/ieee802154/private_include/esp_ieee802154_pib.h new file mode 100644 index 0000000000..d26ea6b7d2 --- /dev/null +++ b/components/ieee802154/private_include/esp_ieee802154_pib.h @@ -0,0 +1,234 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "hal/ieee802154_ll.h" +#include "esp_ieee802154_frame.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The PAN information base(PIB) of IEEE802154 radio. + */ +typedef struct { + bool auto_ack_tx; /*!< A flag indicates auto-tx ack mode is enabled or not */ + bool auto_ack_rx; /*!< A flag indicates auto-rx ack mode is enabled or not */ + bool enhance_ack_tx; /*!< A flag indicates enh-ack timing mode is enabled or not */ + bool promiscuous; /*!< A flag indicates promiscuous mode is enabled or not */ + bool coordinator; /*!< A flag indicates the device is coordinator or not*/ + bool rx_when_idle; /*!< A flag indicates the device is rx on when idle or not */ + int8_t txpower; /*!< Tx power configuration */ + uint8_t channel; /*!< Channel configuration */ + ieee802154_ll_pending_mode_t pending_mode; /*!< Pending mode configuration */ + int8_t cca_threshold; /*!< CCA threshold */ + ieee802154_ll_cca_mode_t cca_mode; /*!< CCA mode */ +} ieee802154_pib_t; + +/** + * @brief Initialize the PAN information base(PIB) of IEEE802154 radio. + * + */ +void ieee802154_pib_init(void); + +/** + * @brief Update the PAN information base(PIB) of IEEE802154 radio. + * + */ +void ieee802154_pib_update(void); + +/** + * @brief Get the state of PIB, if is pending, the PIB should be updated to hardware. + * + * @return + * - True if the PIB is pending, otherwise false. + */ +bool ieee802154_pib_is_pending(void); + +/** + * @brief Set a specific channel to the PIB. + * + * @param[in] channel The channel. + * + */ +void ieee802154_pib_set_channel(uint8_t channel); + +/** + * @brief Get the channel from the PIB. + * + * @return + * - The channel has been set in the PIB. + */ +uint8_t ieee802154_pib_get_channel(void); + +/** + * @brief Set a specific transmission power to the PIB. + * + * @param[in] power The power. + * + */ +void ieee802154_pib_set_power(int8_t power); + +/** + * @brief Get the transmission power from the PIB. + * + * @return + * - The transmission power has been set in the PIB. + */ +int8_t ieee802154_pib_get_power(void); + +/** + * @brief Set the promiscuous mode to the PIB. + * + * @param[in] enable True for enabling the promiscuous mode, otherwise false. + * + */ +void ieee802154_pib_set_promiscuous(bool enable); + +/** + * @brief Get the promiscuous mode from the PIB. + * + * @return + * - The promiscuous mode has been set in the PIB. + */ +bool ieee802154_pib_get_promiscuous(void); + +/** + * @brief Set a specific CCA threshold to the PIB. + * + * @param[in] cca_threshold The CCA threshold. + * + */ +void ieee802154_pib_set_cca_threshold(int8_t cca_threshold); + +/** + * @brief Get the CCA threshold from the PIB. + * + * @return + * - The CCA threshold has been set in the PIB. + */ + int8_t ieee802154_pib_get_cca_threshold(void); + +/** + * @brief Set the CCA mode to the PIB. + * + * @param[in] cca_mode The CCA mode. + * + */ +void ieee802154_pib_set_cca_mode(ieee802154_ll_cca_mode_t cca_mode); + +/** + * @brief Get the CCA mode from the PIB. + * + * @return + * - The CCA mode has been set in the PIB. + */ +ieee802154_ll_cca_mode_t ieee802154_pib_get_cca_mode(void); + +/** + * @brief Configure the auto-ack transmission mode to the PIB. + * + * @param[in] enable True for enabling the auto-ack transmission mode, otherwise false. + * + */ +void ieee802154_pib_set_auto_ack_tx(bool enable); + +/** + * @brief Get the auto-ack transmission mode from the PIB. + * + * @return + * - The auto-ack transmission mode has been set in the PIB. + */ +bool ieee802154_pib_get_auto_ack_tx(void); + +/** + * @brief Configure the auto-ack receiving mode to the PIB. + * + * @param[in] enable True for enabling the auto-ack receiving mode, otherwise false. + * + */ +void ieee802154_pib_set_auto_ack_rx(bool enable); + +/** + * @brief Get the auto-ack receiving mode from the PIB. + * + * @return + * - The auto-ack receiving mode has been set in the PIB. + */ +bool ieee802154_pib_get_auto_ack_rx(void); + +/** + * @brief Configure the enh-ack timing mode to the PIB. + * + * @param[in] enable True for enabling the enh-ack timing mode, otherwise false. + * + */ +void ieee802154_pib_set_enhance_ack_tx(bool enable); + +/** + * @brief Get the enh-ack timing mode from the PIB. + * + * @return + * - The enh-ack timing mode has been set in the PIB. + */ +bool ieee802154_pib_get_enhance_ack_tx(void); + +/** + * @brief Configure this bit to the PIB to indicate the device is coordinator. + * + * @param[in] enable True for configuring the device coordinator, otherwise false. + * + */ +void ieee802154_pib_set_coordinator(bool enable); + +/** + * @brief Get the coordinator configuration of device from the PIB. + * + * @return + * - The coordinator configuration of device has been set in the PIB. + */ +bool ieee802154_pib_get_coordinator(void); + +/** + * @brief Configure the pending mode to the PIB. + * + * @param[in] pending_mode The pending mode. + * + */ +void ieee802154_pib_set_pending_mode(ieee802154_ll_pending_mode_t pending_mode); + +/** + * @brief Get the pending mode from the PIB. + * + * @return + * - The pending mode has been set in the PIB. + */ +ieee802154_ll_pending_mode_t ieee802154_pib_get_pending_mode(void); + +/** + * @brief Configure the radio mode when the radio is going to enter idle to the PIB. + * + * @param[in] enable True for continuing to receive when the radio is going to enter ilde, otherwise false. + * + */ +void ieee802154_pib_set_rx_when_idle(bool enable); + +/** + * @brief Get the radio mode when the radio is going to enter ilde to the PIB. + * + * @return + * - True for continuing to receive when the radio is going to enter ilde, otherwise false. + * + */ +bool ieee802154_pib_get_rx_when_idle(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/ieee802154/private_include/esp_ieee802154_sec.h b/components/ieee802154/private_include/esp_ieee802154_sec.h new file mode 100644 index 0000000000..7c822a82da --- /dev/null +++ b/components/ieee802154/private_include/esp_ieee802154_sec.h @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#define IEEE802154_SECURITY_ADDR_SIZE 8 +#define IEEE802154_SECURITY_KEY_SIZE 16 +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configure the encryption of transmission. + * + * @param[in] frame The frame needs to be encrypted. + * @param[in] key The key using in the encryption process. + * @param[in] addr The address using in the encryption process. + * + */ +void ieee802154_transmit_security_config(uint8_t *frame, uint8_t *key, uint8_t *addr); + +/** + * @brief Update the encryption enabled configuration of the next transmission. + * + * + */ +void ieee802154_sec_update(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/ieee802154/private_include/esp_ieee802154_timer.h b/components/ieee802154/private_include/esp_ieee802154_timer.h new file mode 100644 index 0000000000..aee1230720 --- /dev/null +++ b/components/ieee802154/private_include/esp_ieee802154_timer.h @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "esp_log.h" +#include "esp_err.h" + +/** + * @brief Start the IEEE802154 MAC internal timer0. + * + */ +void ieee802154_timer0_start(void); + +/** + * @brief Stop the IEEE802154 MAC internal timer0. + * + */ +void ieee802154_timer0_stop(void); + +/** + * @brief Set the overflow threshold to the IEEE802154 MAC internal timer0. + * + * @param[in] value The threshold. + * + * @return + * ESP_OK if the threshold is valid. + * ESP_ERR_INVALID_ARG if the threshold is invalid. + * + */ +esp_err_t ieee802154_timer0_set_threshold(uint32_t value); + +/** + * @brief Get the current IEEE802154 MAC internal timer0 count. + * + * @return + * The timer0 count. + * + */ +uint32_t ieee802154_timer0_get_value(void); + +/** + * @brief Start the IEEE802154 MAC internal timer1. + * + */ +void ieee802154_timer1_start(void); + +/** + * @brief Stop the IEEE802154 MAC internal timer1. + * + */ +void ieee802154_timer1_stop(void); + +/** + * @brief Set the overflow threshold to the IEEE802154 MAC internal timer1. + * + * @param[in] value The threshold. + * + * @return + * ESP_OK if the threshold is valid. + * ESP_ERR_INVALID_ARG if the threshold is invalid. + * + */ +esp_err_t ieee802154_timer1_set_threshold(uint32_t value); + +/** + * @brief Get the current IEEE802154 MAC internal timer1 count. + * + * @return + * The timer1 count. + * + */ +uint32_t ieee802154_timer1_get_value(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/ieee802154/private_include/esp_ieee802154_util.h b/components/ieee802154/private_include/esp_ieee802154_util.h new file mode 100644 index 0000000000..a41576c5ab --- /dev/null +++ b/components/ieee802154/private_include/esp_ieee802154_util.h @@ -0,0 +1,92 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#ifdef __cplusplus +extern "C" { +#endif +// TODO: replace etm code using common interface + +#define IEEE802154_ETM_CHANNEL0 0 +#define IEEE802154_ETM_CHANNEL1 1 + +/** + * @brief The scene of IEEE802154 radio coexistence. + */ +typedef enum { + IEEE802154_SCENE_IDLE, /*!< IEEE802154 radio coexistence scene IDLE */ + IEEE802154_SCENE_TX, /*!< IEEE802154 radio coexistence scene TX */ + IEEE802154_SCENE_RX, /*!< IEEE802154 radio coexistence scene RX */ + IEEE802154_SCENE_TX_AT, /*!< IEEE802154 radio coexistence scene TX AT */ + IEEE802154_SCENE_RX_AT, /*!< IEEE802154 radio coexistence scene RX AT */ +} ieee802154_txrx_scene_t; + +#if CONFIG_ESP_COEX_SW_COEXIST_ENABLE + +/** + * @brief Set the IEEE802154 radio coexistence scene during transmitting or receiving. + * + * @param[in] txrx_scene The scene of IEEE802154 radio coexistence. + * + */ +void ieee802154_set_txrx_pti(ieee802154_txrx_scene_t txrx_scene); + +#define IEEE802154_SET_TXRX_PTI(txrx_scene) ieee802154_set_txrx_pti(txrx_scene) + +#else + +#define IEEE802154_SET_TXRX_PTI(txrx_scene) + +#endif // CONFIG_ESP_COEX_SW_COEXIST_ENABLE + +/** + * @brief Convert the frequence to the index of channel. + * + * @param[in] freq The frequence where the radio is processing. + * + * @return + * The channel index. + * + */ +uint8_t ieee802154_freq_to_channel(uint8_t freq); + +/** + * @brief Convert the index of channel to the frequence. + * + * @param[in] channel The index of channel where the radio is processing. + * + * @return + * The frequence. + * + */ +uint8_t ieee802154_channel_to_freq(uint8_t channel); + +// TZ-97: implement these two functions using ETM common interface +/** + * @brief Configure the ETM module, using [channel] for monitoring the event, when event appears + * hardware will operate the [task]. + * + * @param[in] channel The ETM channel. + * @param[in] event The ETM event. + * @param[in] task The ETM task. + * + */ +void ieee802154_etm_set_event_task(uint32_t channel, uint32_t event, uint32_t task); + +/** + * @brief Clear the ETM module [channel]. + * + * @param[in] channel The ETM channel. + * + */ +void ieee802154_etm_channel_clear(uint32_t channel); + +#ifdef __cplusplus +} +#endif diff --git a/components/openthread/port/esp_openthread_radio.c b/components/openthread/port/esp_openthread_radio.c index 5d777d20e0..892df41862 100644 --- a/components/openthread/port/esp_openthread_radio.c +++ b/components/openthread/port/esp_openthread_radio.c @@ -6,6 +6,8 @@ #include "esp_openthread_radio.h" +#include "error.h" +#include "esp_err.h" #include "sdkconfig.h" #include "esp_check.h" #include "esp_ieee802154.h" @@ -189,13 +191,11 @@ esp_err_t esp_openthread_radio_process(otInstance *aInstance, const esp_openthre case ESP_IEEE802154_TX_ERR_CCA_BUSY: case ESP_IEEE802154_TX_ERR_ABORT: case ESP_IEEE802154_TX_ERR_COEXIST: - case ESP_IEEE802154_TX_ERR_COEXIST_REJ: err = OT_ERROR_CHANNEL_ACCESS_FAILURE; break; case ESP_IEEE802154_TX_ERR_NO_ACK: case ESP_IEEE802154_TX_ERR_INVALID_ACK: - case ESP_IEEE802154_TX_ERR_COEXIST_ACK: err = OT_ERROR_NO_ACK; break; @@ -615,7 +615,7 @@ static void IRAM_ATTR enh_ack_set_security_addr_and_key(otRadioFrame *ack_frame) esp_ieee802154_set_transmit_security(&ack_frame->mPsdu[-1], s_security_key, s_security_addr); } -void IRAM_ATTR esp_ieee802154_enh_ack_generator(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info, +esp_err_t IRAM_ATTR esp_ieee802154_enh_ack_generator(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info, uint8_t *enhack_frame) { otRadioFrame ack_frame; @@ -627,6 +627,7 @@ void IRAM_ATTR esp_ieee802154_enh_ack_generator(uint8_t *frame, esp_ieee802154_f uint8_t link_metrics_data[OT_ENH_PROBING_IE_DATA_MAX_SIZE]; otMacAddress mac_addr; #endif + otError err; ack_frame.mPsdu = enhack_frame + 1; convert_to_ot_frame(frame, frame_info, &ot_frame); @@ -644,8 +645,11 @@ void IRAM_ATTR esp_ieee802154_enh_ack_generator(uint8_t *frame, esp_ieee802154_f offset += otMacFrameGenerateEnhAckProbingIe(ack_ie_data, link_metrics_data, link_metrics_data_len); } #endif + err = otMacFrameGenerateEnhAck(&ot_frame, frame_info->pending, ack_ie_data, offset, &ack_frame); - ETS_ASSERT(otMacFrameGenerateEnhAck(&ot_frame, frame_info->pending, ack_ie_data, offset, &ack_frame) == OT_ERROR_NONE); + if (err != OT_ERROR_NONE) { + return ESP_FAIL; + } enhack_frame[0] = ack_frame.mLength; s_enhack = enhack_frame; @@ -654,6 +658,7 @@ void IRAM_ATTR esp_ieee802154_enh_ack_generator(uint8_t *frame, esp_ieee802154_f otMacFrameSetFrameCounter(&ack_frame, s_mac_frame_counter++); enh_ack_set_security_addr_and_key(&ack_frame); } + return ESP_OK; } void IRAM_ATTR esp_ieee802154_receive_done(uint8_t *data, esp_ieee802154_frame_info_t *frame_info) diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index 4c4fb9160c..e8f8f4cccb 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -95,6 +95,10 @@ if(CONFIG_SOC_TWAI_SUPPORTED) list(APPEND srcs "${target}/twai_periph.c") endif() +if(CONFIG_SOC_IEEE802154_SUPPORTED) + list(APPEND srcs "${target}/ieee802154_periph.c") +endif() + if(CONFIG_SOC_USB_OTG_SUPPORTED) list(APPEND srcs "${target}/usb_periph.c" "${target}/usb_otg_periph.c") diff --git a/components/soc/esp32c6/ieee802154_periph.c b/components/soc/esp32c6/ieee802154_periph.c new file mode 100644 index 0000000000..275c83bc59 --- /dev/null +++ b/components/soc/esp32c6/ieee802154_periph.c @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/ieee802154_periph.h" + +const ieee802154_conn_t ieee802154_periph = { + .module = PERIPH_IEEE802154_MODULE, + .irq_id = ETS_ZB_MAC_SOURCE, +}; diff --git a/components/soc/esp32c6/include/soc/ieee802154_reg.h b/components/soc/esp32c6/include/soc/ieee802154_reg.h new file mode 100644 index 0000000000..2788c4badd --- /dev/null +++ b/components/soc/esp32c6/include/soc/ieee802154_reg.h @@ -0,0 +1,524 @@ +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc.h" + +#ifdef __cplusplus +extern "C" { +#endif +// TODO: ZB-93, rewrite this file using regdesc tools when IEEE802154.csv is ready. +#define IEEE802154_REG_BASE 0x600A3000 + +#define IEEE802154_COMMAND_REG (IEEE802154_REG_BASE + 0x0000) +#define IEEE802154_OPCODE 0x000000FF +#define IEEE802154_OPCODE_S 0 + +#define IEEE802154_CTRL_CFG_REG (IEEE802154_REG_BASE + 0x0004) +#define IEEE802154_MAC_INF3_ENABLE (BIT(31)) +#define IEEE802154_MAC_INF3_ENABLE_S 31 +#define IEEE802154_MAC_INF2_ENABLE (BIT(30)) +#define IEEE802154_MAC_INF2_ENABLE_S 30 +#define IEEE802154_MAC_INF1_ENABLE (BIT(29)) +#define IEEE802154_MAC_INF1_ENABLE_S 29 +#define IEEE802154_MAC_INF0_ENABLE (BIT(28)) +#define IEEE802154_MAC_INF0_ENABLE_S 28 +#define IEEE802154_RX_DONE_TRIGGER_IDLE (BIT(27)) +#define IEEE802154_RX_DONE_TRIGGER_IDLE_S 27 +#define IEEE802154_FORCE_RX_ENB (BIT(26)) +#define IEEE802154_FORCE_RX_ENB_S 26 +#define IEEE802154_NO_RSS_TRK_ENB (BIT(25)) +#define IEEE802154_NO_RSS_TRK_ENB_S 25 +#define IEEE802154_BIT_ORDER (BIT(24)) +#define IEEE802154_BIT_ORDER_S 24 +#define IEEE802154_COEX_ARB_DELAY 0x0000001F +#define IEEE802154_COEX_ARB_DELAY_S 16 +#define IEEE802154_FILTER_ENHANCE (BIT(14)) +#define IEEE802154_FILTER_ENHANCE_S 14 +#define IEEE802154_AUTOPEND_ENHANCE (BIT(12)) +#define IEEE802154_AUTOPEND_ENHANCE_S 12 +#define IEEE802154_DIS_FRAME_VERSION_RSV_FILTER (BIT(11)) +#define IEEE802154_DIS_FRAME_VERSION_RSV_FILTER_S 11 +#define IEEE802154_PROMISCUOUS_MODE (BIT(7)) +#define IEEE802154_PROMISCUOUS_MODE_S 7 +#define IEEE802154_PAN_COORDINATOR (BIT(6)) +#define IEEE802154_PAN_COORDINATOR_S 6 +#define IEEE802154_DIS_IFS_CONTROL (BIT(5)) +#define IEEE802154_DIS_IFS_CONTROL_S 5 +#define IEEE802154_HW_AUTO_ACK_RX_EN (BIT(3)) +#define IEEE802154_HW_AUTO_ACK_RX_EN_S 3 +#define HW_ENHANCE_ACK_TX_EN (BIT(1)) +#define HW_ENHANCE_ACK_TX_EN_S 1 +#define IEEE802154_HW_AUTO_ACK_TX_EN (BIT(0)) +#define IEEE802154_HW_AUTO_ACK_TX_EN_S 0 + +#define IEEE802154_INF0_SHORT_ADDR_REG (IEEE802154_REG_BASE + 0x0008) +#define IEEE802154_MAC_INF0_SHORT_ADDR 0x0000FFFF +#define IEEE802154_MAC_INF0_SHORT_ADDR_S 0 + +#define IEEE802154_INF0_PAN_ID_REG (IEEE802154_REG_BASE + 0x000C) +#define IEEE802154_MAC_INF0_PAN_ID 0x0000FFFF +#define IEEE802154_MAC_INF0_PAN_ID_S 0 + +#define IEEE802154_INF0_EXTEND_ADDR0_REG (IEEE802154_REG_BASE + 0x0010) +#define IEEE802154_MAC_INF0_EXTEND_ADDR0 0xFFFFFFFF +#define IEEE802154_MAC_INF0_EXTEND_ADDR0_S 0 + +#define IEEE802154_INF0_EXTEND_ADDR1_REG (IEEE802154_REG_BASE + 0x0014) +#define IEEE802154_MAC_INF0_EXTEND_ADDR1 0xFFFFFFFF +#define IEEE802154_MAC_INF0_EXTEND_ADDR1_S 0 + +#define IEEE802154_INF1_SHORT_ADDR_REG (IEEE802154_REG_BASE + 0x0018) +#define IEEE802154_MAC_INF1_SHORT_ADDR 0x0000FFFF +#define IEEE802154_MAC_INF1_SHORT_ADDR_S 0 + +#define IEEE802154_INF1_PAN_ID_REG (IEEE802154_REG_BASE + 0x001C) +#define IEEE802154_MAC_INF1_PAN_ID 0x0000FFFF +#define IEEE802154_MAC_INF1_PAN_ID_S 0 + +#define IEEE802154_INF1_EXTEND_ADDR0_REG (IEEE802154_REG_BASE + 0x0020) +#define IEEE802154_MAC_INF1_EXTEND_ADDR0 0xFFFFFFFF +#define IEEE802154_MAC_INF1_EXTEND_ADDR0_S 0 + +#define IEEE802154_INF1_EXTEND_ADDR1_REG (IEEE802154_REG_BASE + 0x0024) +#define IEEE802154_MAC_INF1_EXTEND_ADDR1 0xFFFFFFFF +#define IEEE802154_MAC_INF1_EXTEND_ADDR1_S 0 + +#define IEEE802154_INF2_SHORT_ADDR_REG (IEEE802154_REG_BASE + 0x0028) +#define IEEE802154_MAC_INF2_SHORT_ADDR 0x0000FFFF +#define IEEE802154_MAC_INF2_SHORT_ADDR_S 0 + +#define IEEE802154_INF2_PAN_ID_REG (IEEE802154_REG_BASE + 0x002C) +#define IEEE802154_MAC_INF2_PAN_ID 0x0000FFFF +#define IEEE802154_MAC_INF2_PAN_ID_S 0 + +#define IEEE802154_INF2_EXTEND_ADDR0_REG (IEEE802154_REG_BASE + 0x0030) +#define IEEE802154_MAC_INF2_EXTEND_ADDR0 0xFFFFFFFF +#define IEEE802154_MAC_INF2_EXTEND_ADDR0_S 0 + +#define IEEE802154_INF2_EXTEND_ADDR1_REG (IEEE802154_REG_BASE + 0x0034) +#define IEEE802154_MAC_INF2_EXTEND_ADDR1 0xFFFFFFFF +#define IEEE802154_MAC_INF2_EXTEND_ADDR1_S 0 + +#define IEEE802154_INF3_SHORT_ADDR_REG (IEEE802154_REG_BASE + 0x0038) +#define IEEE802154_MAC_INF3_SHORT_ADDR 0x0000FFFF +#define IEEE802154_MAC_INF3_SHORT_ADDR_S 0 + +#define IEEE802154_INF3_PAN_ID_REG (IEEE802154_REG_BASE + 0x003C) +#define IEEE802154_MAC_INF3_PAN_ID 0x0000FFFF +#define IEEE802154_MAC_INF3_PAN_ID_S 0 + +#define IEEE802154_INF3_EXTEND_ADDR0_REG (IEEE802154_REG_BASE + 0x0040) +#define IEEE802154_MAC_INF3_EXTEND_ADDR0 0xFFFFFFFF +#define IEEE802154_MAC_INF3_EXTEND_ADDR0_S 0 + +#define IEEE802154_INF3_EXTEND_ADDR1_REG (IEEE802154_REG_BASE + 0x0044) +#define IEEE802154_MAC_INF3_EXTEND_ADDR1 0xFFFFFFFF +#define IEEE802154_MAC_INF3_EXTEND_ADDR1_S 0 + +#define IEEE802154_CHANNEL_REG (IEEE802154_REG_BASE + 0x0048) +#define IEEE802154_HOP 0x0000007F +#define IEEE802154_HOP_S 0 + +#define IEEE802154_TX_POWER_REG (IEEE802154_REG_BASE + 0x004C) +#define IEEE802154_TX_POWER 0x0000001F +#define IEEE802154_TX_POWER_S 0 + +#define IEEE802154_ED_SCAN_DURATION_REG (IEEE802154_REG_BASE + 0x0050) +#define IEEE802154_ED_SCAN_WAIT_DLY 0x0000000F +#define IEEE802154_ED_SCAN_WAIT_DLY_S 24 +#define IEEE802154_ED_SCAN_DURATION 0x00FFFFFF +#define IEEE802154_ED_SCAN_DURATION_S 0 + +#define IEEE802154_ED_SCAN_CFG_REG (IEEE802154_REG_BASE + 0x0054) +#define IEEE802154_CCA_BUSY (BIT(24)) +#define IEEE802154_CCA_BUSY_S 24 +#define IEEE802154_ED_RSS 0x000000FF +#define IEEE802154_ED_RSS_S 16 +#define IEEE802154_CCA_MODE 0x00000003 +#define IEEE802154_CCA_MODE_S 14 +#define IEEE802154_DIS_ED_POWER_SEL (BIT(13)) +#define IEEE802154_DIS_ED_POWER_SEL_S 13 +#define IEEE802154_ED_SAMPLE_MODE 0x00000003 +#define IEEE802154_ED_SAMPLE_MODE_S 11 +#define IEEE802154_CCA_ED_THRESHOLD 0x000000FF +#define IEEE802154_CCA_ED_THRESHOLD_S 0 + +#define IEEE802154_IFS_REG (IEEE802154_REG_BASE + 0x0058) +#define IEEE802154_LIFS 0x000003FF +#define IEEE802154_LIFS_S 16 +#define IEEE802154_SIFS 0x000000FF +#define IEEE802154_SIFS_S 0 + +#define IEEE802154_ACK_TIMEOUT_REG (IEEE802154_REG_BASE + 0x005C) +#define IEEE802154_ACK_TIMEOUT 0x0000FFFF +#define IEEE802154_ACK_TIMEOUT_S 0 + +#define IEEE802154_EVENT_EN_REG (IEEE802154_REG_BASE + 0x0060) +#define IEEE802154_EVENT_EN 0x00001FFF +#define IEEE802154_EVENT_EN_S 0 + +#define IEEE802154_EVENT_STATUS_REG (IEEE802154_REG_BASE + 0x0064) +#define IEEE802154_EVENT_STATUS 0x00001FFF +#define IEEE802154_EVENT_STATUS_S 0 + +#define IEEE802154_RX_ABORT_INTR_CTRL_REG (IEEE802154_REG_BASE + 0x0068) +#define IEEE802154_RX_ABORT_INTR_CTRL 0x7FFFFFFF +#define IEEE802154_RX_ABORT_INTR_CTRL_S 0 + +#define IEEE802154_ACK_FRAME_PENDING_EN_REG (IEEE802154_REG_BASE + 0x006c) +#define IEEE802154_ACK_TX_ACK_TIMEOUT 0x0000FFFF +#define IEEE802154_ACK_TX_ACK_TIMEOUT_S 16 +#define IEEE802154_ACK_FRAME_PENDING_EN (BIT(0)) +#define IEEE802154_ACK_FRAME_PENDING_EN_S 0 + +#define IEEE802154_COEX_PTI_REG (IEEE802154_REG_BASE + 0x0070) +#define IEEE802154_CLOSE_RF_SEL (BIT(8)) +#define IEEE802154_CLOSE_RF_SEL_S 8 +#define IEEE802154_COEX_ACK_PTI 0x0000000F +#define IEEE802154_COEX_ACK_PTI_S 4 +#define IEEE802154_COEX_PTI 0x0000000F +#define IEEE802154_COEX_PTI_S 0 + +#define IEEE802154_TX_ABORT_INTERRUPT_CONTROL_REG (IEEE802154_REG_BASE + 0x0078) +#define IEEE802154_TX_ABORT_INTERRUPT_CONTROL 0x7FFFFFFF +#define IEEE802154_TX_ABORT_INTERRUPT_CONTROL_S 0 + +#define IEEE802154_ENHANCE_ACK_CFG_REG (IEEE802154_REG_BASE + 0x7C) +#define IEEE802154_TX_ENH_ACK_GENERATE_DONE_NOTIFY 0xFFFFFFFF +#define IEEE802154_TX_ENH_ACK_GENERATE_DONE_NOTIFY_S 0 + +#define IEEE802154_RX_STATUS_REG (IEEE802154_REG_BASE + 0x0080) +#define IEEE802154_SFD_MATCH (BIT(21)) +#define IEEE802154_SFD_MATCH_S 21 +#define IEEE802154_PREAMBLE_MATCH (BIT(20)) +#define IEEE802154_PREAMBLE_MATCH_S 20 +#define IEEE802154_RX_STATE 0x00000007 +#define IEEE802154_RX_STATE_S 16 +#define IEEE802154_RX_ABORT_STATUS 0x0000001F +#define IEEE802154_RX_ABORT_STATUS_S 4 +#define IEEE802154_FILTER_FAIL_STATUS 0x0000000F +#define IEEE802154_FILTER_FAIL_STATUS_S 0 + +#define IEEE802154_TX_STATUS_REG (IEEE802154_REG_BASE + 0x0084) +#define IEEE802154_TX_SEC_ERROR_CODE 0x0000000F +#define IEEE802154_TX_SEC_ERROR_CODE_S 16 +#define IEEE802154_TX_ABORT_STATUS 0x0000001F +#define IEEE802154_TX_ABORT_STATUS_S 4 +#define IEEE802154_TX_STATE 0x0000000F +#define IEEE802154_TX_STATE_S 0 + +#define IEEE802154_TXRX_STATUS_REG (IEEE802154_REG_BASE + 0x0088) +#define IEEE802154_RF_CTRL_STATE 0x0000000F +#define IEEE802154_RF_CTRL_STATE_S 16 +#define IEEE802154_ED_TRIGGER_TX_PROC (BIT(11)) +#define IEEE802154_ED_TRIGGER_TX_PROC_S 11 +#define IEEE802154_ED_PROC (BIT(10)) +#define IEEE802154_ED_PROC_S 10 +#define IEEE802154_RX_PROC (BIT(9)) +#define IEEE802154_RX_PROC_S 9 +#define IEEE802154_TX_PROC (BIT(8)) +#define IEEE802154_TX_PROC_S 8 +#define IEEE802154_TXRX_STATE 0x0000000F +#define IEEE802154_TXRX_STATE_S 0 + +#define IEEE802154_TX_CCM_SCHEDULE_STATUS_REG (IEEE802154_REG_BASE + 0x008c) +#define IEEE802154_TX_CCM_SCHEDULE_STATUS 0x7FFFFFFF +#define IEEE802154_TX_CCM_SCHEDULE_STATUS_S 0 + +#define IEEE802154_RX_LENGTH_REG (IEEE802154_REG_BASE + 0x00a4) +#define IEEE802154_RX_LENGTH 0x0000007F +#define IEEE802154_RX_LENGTH_S 0 + +#define IEEE802154_TIME0_THRESHOLD_REG (IEEE802154_REG_BASE + 0x00a8) +#define IEEE802154_TIMER0_THRESHOLD 0xFFFFFFFF +#define IEEE802154_TIMER0_THRESHOLD_S 0 + +#define IEEE802154_TIME0_VALUE_REG (IEEE802154_REG_BASE + 0x00ac) +#define IEEE802154_TIMER0_VALUE 0xFFFFFFFF +#define IEEE802154_TIMER0_VALUE_S 0 + +#define IEEE802154_TIME1_THRESHOLD_REG (IEEE802154_REG_BASE + 0x00b0) +#define IEEE802154_TIMER1_THRESHOLD 0xFFFFFFFF +#define IEEE802154_TIMER1_THRESHOLD_S 0 + +#define IEEE802154_TIME1_VALUE_REG (IEEE802154_REG_BASE + 0x00b4) +#define IEEE802154_TIMER1_VALUE 0xFFFFFFFF +#define IEEE802154_TIMER1_VALUE_S 0 + +#define IEEE802154_CLK_COUNTER_MATCH_VAL_REG (IEEE802154_REG_BASE + 0x00b8) +#define IEEE802154_CLK_COUNT_MATCH_VAL 0x0000FFFF +#define IEEE802154_CLK_COUNT_MATCH_VAL_S 0 + +#define IEEE802154_CLK_COUNTER_REG (IEEE802154_REG_BASE + 0x00bc) +#define IEEE802154_CLK_625US_CNT 0x0000FFFF +#define IEEE802154_CLK_625US_CNT_S 0 + +#define IEEE802154_IFS_COUNTER_REG (IEEE802154_REG_BASE + 0x00c0) +#define IEEE802154_IFS_COUNTER_EN (BIT(16)) +#define IEEE802154_IFS_COUNTER_EN_S 16 +#define IEEE802154_IFS_COUNTER 0x000003FF +#define IEEE802154_IFS_COUNTER_S 0 + +#define IEEE802154_SFD_WAIT_SYMBOL_REG (IEEE802154_REG_BASE + 0x00c4) +#define IEEE802154_SFD_WAIT_SYMBOL_NUM 0x0000000F +#define IEEE802154_SFD_WAIT_SYMBOL_NUM_S 0 + +#define IEEE802154_TXRX_PATH_DELAY_REG (IEEE802154_REG_BASE + 0x00c8) +#define IEEE802154_RX_PATH_DELAY 0x0000003F +#define IEEE802154_RX_PATH_DELAY_S 16 +#define IEEE802154_TX_PATH_DELAY 0x0000003F +#define IEEE802154_TX_PATH_DELAY_S 0 + +#define IEEE802154_BB_CLK_REG (IEEE802154_REG_BASE + 0x00cc) +#define IEEE802154_BB_CLK_FREQ_MINUS_1 0x0000001F +#define IEEE802154_BB_CLK_FREQ_MINUS_1_S 0 + +#define IEEE802154_TXDMA_ADDR_REG (IEEE802154_REG_BASE + 0x00D0) +#define IEEE802154_TXDMA_ADDR 0xFFFFFFFF +#define IEEE802154_TXDMA_ADDR_S 0 + +#define IEEE802154_TXDMA_CTRL_STATE_REG (IEEE802154_REG_BASE + 0x00D4) +#define IEEE802154_TXDMA_FETCH_BYTE_CNT 0x0000007F +#define IEEE802154_TXDMA_FETCH_BYTE_CNT_S 24 +#define IEEE802154_TXDMA_STATE 0x0000001F +#define IEEE802154_TXDMA_STATE_S 16 +#define IEEE802154_TXDMA_FILL_ENTRY 0x00000007 +#define IEEE802154_TXDMA_FILL_ENTRY_S 4 +#define IEEE802154_TXDMA_WATER_LEVEL 0x00000007 +#define IEEE802154_TXDMA_WATER_LEVEL_S 0 + +#define IEEE802154_TXDMA_ERR_REG (IEEE802154_REG_BASE + 0x00D8) +#define IEEE802154_TXDMA_ERR 0x0000000F +#define IEEE802154_TXDMA_ERR_S 0 + +#define IEEE802154_RXDMA_ADDR_REG (IEEE802154_REG_BASE + 0x00E0) +#define IEEE802154_RXDMA_ADDR 0xFFFFFFFF +#define IEEE802154_RXDMA_ADDR_S 0 + +#define IEEE802154_RXDMA_CTRL_STATE_REG (IEEE802154_REG_BASE + 0x00E4) +#define IEEE802154_RXDMA_APPEND_FREQ_OFFSET (BIT(25)) +#define IEEE802154_RXDMA_APPEND_FREQ_OFFSET_S 25 +#define IEEE802154_RXDMA_APPEND_LQI_OFFSET (BIT(24)) +#define IEEE802154_RXDMA_APPEND_LQI_OFFSET_S 24 +#define IEEE802154_RXDMA_STATE 0x0000001F +#define IEEE802154_RXDMA_STATE_S 16 +#define IEEE802154_RXDMA_WATER_LEVEL 0x00000007 +#define IEEE802154_RXDMA_WATER_LEVEL_S 0 + +#define IEEE802154_RXDMA_ERR_REG (IEEE802154_REG_BASE + 0x00E8) +#define IEEE802154_RXDMA_ERR 0x0000000F +#define IEEE802154_RXDMA_ERR_S 0 + +#define IEEE802154_DMA_GCK_CFG_REG (IEEE802154_REG_BASE + 0x00F0) +#define IEEE802154_DMA_GCK_CFG (BIT(0)) +#define IEEE802154_DMA_GCK_CFG_S 0 + +#define IEEE802154_DMA_DUMMY_REG (IEEE802154_REG_BASE + 0x00F4) +#define IEEE802154_DMA_DUMMY_DATA 0xFFFFFFFF +#define IEEE802154_DMA_DUMMY_DATA_S + +#define IEEE802154_PAON_DELAY_REG (IEEE802154_REG_BASE + 0x0100) +#define IEEE802154_PAON_DELAY 0x000003FF +#define IEEE802154_PAON_DELAY_S 0 + +#define IEEE802154_TXON_DELAY_REG (IEEE802154_REG_BASE + 0x0104) +#define IEEE802154_TXON_DELAY 0x000003FF +#define IEEE802154_TXON_DELAY_S 0 + +#define IEEE802154_TXEN_STOP_DELAY_REG (IEEE802154_REG_BASE + 0x0108) +#define IEEE802154_TXEN_STOP_DLY 0x0000003F +#define IEEE802154_TXEN_STOP_DLY_S 0 + +#define IEEE802154_TXOFF_DELAY_REG (IEEE802154_REG_BASE + 0x010c) +#define IEEE802154_TXOFF_DELAY 0x0000003F +#define IEEE802154_TXOFF_DELAY_S 0 + +#define IEEE802154_RXON_DELAY_REG (IEEE802154_REG_BASE + 0x0110) +#define IEEE802154_RXON_DELAY 0x000007FF +#define IEEE802154_RXON_DELAY_S 0 + +#define IEEE802154_TXRX_SWITCH_DELAY_REG (IEEE802154_REG_BASE + 0x0114) +#define IEEE802154_TXRX_SWITCH_DELAY 0x000003FF +#define IEEE802154_TXRX_SWITCH_DELAY_S 0 + +#define IEEE802154_CONT_RX_DELAY_REG (IEEE802154_REG_BASE + 0x0118) +#define IEEE802154_CONT_RX_DELAY 0x0000003F +#define IEEE802154_CONT_RX_DELAY_S 0 + +#define IEEE802154_DCDC_CTRL_REG (IEEE802154_REG_BASE + 0x011c) +#define IEEE802154_TX_DCDC_UP (BIT(31)) +#define IEEE802154_TX_DCDC_UP_S 31 +#define IEEE802154_DCDC_CTRL_EN (BIT(16)) +#define IEEE802154_DCDC_CTRL_EN_S 16 +#define IEEE802154_DCDC_DOWN_DELAY 0x000000FF +#define IEEE802154_DCDC_DOWN_DELAY_S 8 +#define IEEE802154_DCDC_PRE_UP_DELAY 0x000000FF +#define IEEE802154_DCDC_PRE_UP_DELAY_S 0 + +#define IEEE802154_DEBUG_CTRL_REG (IEEE802154_REG_BASE + 0x0120) +#define IEEE802154_DEBUG_TRIGGER_DUMP_EN (BIT(31)) +#define IEEE802154_DEBUG_TRIGGER_DUMP_EN_S 31 +#define IEEE802154_DEBUG_STATE_MATCH_DUMP_EN (BIT(30)) +#define IEEE802154_DEBUG_STATE_MATCH_DUMP_EN_S 30 +#define IEEE802154_DEBUG_TRIGGER_PULSE_SELECT 0x00000007 +#define IEEE802154_DEBUG_TRIGGER_PULSE_SELECT_S 24 +#define IEEE802154_DEBUG_TRIGGER_STATE_MATCH_VALUE 0x0000001F +#define IEEE802154_DEBUG_TRIGGER_STATE_MATCH_VALUE_S 16 +#define IEEE802154_DEBUG_SER_DEBUG_SEL 0x0000000F +#define IEEE802154_DEBUG_SER_DEBUG_SEL_S 12 +#define IEEE802154_DEBUG_TRIGGER_STATE_SELECT 0x0000000F +#define IEEE802154_DEBUG_TRIGGER_STATE_SELECT_S 8 +#define IEEE802154_DEBUG_SIGNAL_SEL 0x00000007 +#define IEEE802154_DEBUG_SIGNAL_SEL_S 0 + +#define IEEE802154_SEC_CTRL_REG (IEEE802154_REG_BASE + 0x0128) +#define IEEE802154_SEC_PAYLOAD_OFFSET 0x0000007F +#define IEEE802154_SEC_PAYLOAD_OFFSET_S 8 +#define IEEE802154_SEC_EN (BIT(0)) +#define IEEE802154_SEC_EN_S 0 + +#define IEEE802154_SEC_EXTEND_ADDRESS0_REG (IEEE802154_REG_BASE + 0x012c) +#define IEEE802154_SEC_EXTEND_ADDRESS0 0xFFFFFFFF +#define IEEE802154_SEC_EXTEND_ADDRESS0_S 0 + +#define IEEE802154_SEC_EXTEND_ADDRESS1_REG (IEEE802154_REG_BASE + 0x0130) +#define IEEE802154_SEC_EXTEND_ADDRESS1 0xFFFFFFFF +#define IEEE802154_SEC_EXTEND_ADDRESS1_S 0 + +#define IEEE802154_SEC_KEY0_REG (IEEE802154_REG_BASE + 0x0134) +#define IEEE802154_SEC_KEY0 0xFFFFFFFF +#define IEEE802154_SEC_KEY0_S 0 + +#define IEEE802154_SEC_KEY1_REG (IEEE802154_REG_BASE + 0x0138) +#define IEEE802154_SEC_KEY1 0xFFFFFFFF +#define IEEE802154_SEC_KEY1_S 0 + +#define IEEE802154_SEC_KEY2_REG (IEEE802154_REG_BASE + 0x013c) +#define IEEE802154_SEC_KEY2 0xFFFFFFFF +#define IEEE802154_SEC_KEY2_S 0 + +#define IEEE802154_SEC_KEY3_REG (IEEE802154_REG_BASE + 0x0140) +#define IEEE802154_SEC_KEY3 0xFFFFFFFF +#define IEEE802154_SEC_KEY3_S 0 + +#define IEEE802154_SFD_TIMEOUT_CNT_REG (IEEE802154_REG_BASE + 0x0144) +#define IEEE802154_SFD_TIMEOUT_CNT 0x0000FFFF +#define IEEE802154_SFD_TIMEOUT_CNT_S 0 + +#define IEEE802154_CRC_ERROR_CNT_REG (IEEE802154_REG_BASE + 0x0148) +#define IEEE802154_CRC_ERROR_CNT 0x0000FFFF +#define IEEE802154_CRC_ERROR_CNT_S 0 + +#define IEEE802154_ED_ABORT_CNT_REG (IEEE802154_REG_BASE + 0x014c) +#define IEEE802154_ED_ABORT_CNT 0x0000FFFF +#define IEEE802154_ED_ABORT_CNT_S 0 + +#define IEEE802154_CCA_FAIL_CNT_REG (IEEE802154_REG_BASE + 0x0150) +#define IEEE802154_CCA_FAIL_CNT 0x0000FFFF +#define IEEE802154_CCA_FAIL_CNT_S 0 + +#define IEEE802154_RX_FILTER_FAIL_CNT_REG (IEEE802154_REG_BASE + 0x0154) +#define IEEE802154_RX_FILTER_FAIL_CNT 0x0000FFFF +#define IEEE802154_RX_FILTER_FAIL_CNT_S 0 + +#define IEEE802154_NO_RSS_DETECT_CNT_REG (IEEE802154_REG_BASE + 0x0158) +#define IEEE802154_NO_RSS_DETECT_CNT 0x0000FFFF +#define IEEE802154_NO_RSS_DETECT_CNT_S 0 + +#define IEEE802154_RX_ABORT_COEX_CNT_REG (IEEE802154_REG_BASE + 0x015c) +#define IEEE802154_RX_ABORT_COEX_CNT 0x0000FFFF +#define IEEE802154_RX_ABORT_COEX_CNT_S 0 + +#define IEEE802154_RX_RESTART_CNT_REG (IEEE802154_REG_BASE + 0x0160) +#define IEEE802154_RX_RESTART_CNT 0x0000FFFF +#define IEEE802154_RX_RESTART_CNT_S 0 + +#define IEEE802154_TX_ACK_ABORT_COEX_CNT_REG (IEEE802154_REG_BASE + 0x0164) +#define IEEE802154_TX_ACK_ABORT_COEX_CNT 0x0000FFFF +#define IEEE802154_TX_ACK_ABORT_COEX_CNT_S 0 + +#define IEEE802154_ED_SCAN_COEX_CNT_REG (IEEE802154_REG_BASE + 0x0168) +#define IEEE802154_ED_SCAN_COEX_CNT 0x0000FFFF +#define IEEE802154_ED_SCAN_COEX_CNT_S 0 + +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_REG (IEEE802154_REG_BASE + 0x016c) +#define IEEE802154_RX_ACK_ABORT_COEX_CNT 0x0000FFFF +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_S 0 + +#define IEEE802154_RX_ACK_TIMEOUT_CNT_REG (IEEE802154_REG_BASE + 0x0170) +#define IEEE802154_RX_ACK_TIMEOUT_CNT 0x0000FFFF +#define IEEE802154_RX_ACK_TIMEOUT_CNT_S 0 + +#define IEEE802154_TX_BREAK_COEX_CNT_REG (IEEE802154_REG_BASE + 0x0174) +#define IEEE802154_TX_BREAK_COEX_CNT 0x0000FFFF +#define IEEE802154_TX_BREAK_COEX_CNT_S 0 + +#define IEEE802154_TX_SECURITY_ERROR_CNT_REG (IEEE802154_REG_BASE + 0x0178) +#define IEEE802154_TX_SECURITY_ERROR_CNT 0x0000FFFF +#define IEEE802154_TX_SECURITY_ERROR_CNT_S 0 + +#define IEEE802154_CCA_BUSY_CNT_REG (IEEE802154_REG_BASE + 0x017c) +#define IEEE802154_CCA_BUSY_CNT 0x0000FFFF +#define IEEE802154_CCA_BUSY_CNT_S 0 + +#define IEEE802154_ERROR_CNT_CLEAR_REG (IEEE802154_REG_BASE + 0x0180) +#define IEEE802154_SFD_TIMEOUT_CNT_CLEAR (BIT(14)) +#define IEEE802154_SFD_TIMEOUT_CNT_CLEAR_S 14 +#define IEEE802154_CRC_ERROR_CNT_CLEAR (BIT(13)) +#define IEEE802154_CRC_ERROR_CNT_CLEAR_S 13 +#define IEEE802154_ED_ABORT_CNT_CLEAR (BIT(12)) +#define IEEE802154_ED_ABORT_CNT_CLEAR_S 12 +#define IEEE802154_CCA_FAIL_CNT_CLEAR (BIT(11)) +#define IEEE802154_CCA_FAIL_CNT_CLEAR_S 11 +#define IEEE802154_RX_FILTER_FAIL_CNT_CLEAR (BIT(10)) +#define IEEE802154_RX_FILTER_FAIL_CNT_CLEAR_S 10 +#define IEEE802154_NO_RSS_DETECT_CNT_CLEAR (BIT(9)) +#define IEEE802154_NO_RSS_DETECT_CNT_CLEAR_S 9 +#define IEEE802154_RX_ABORT_COEX_CNT_CLEAR (BIT(8)) +#define IEEE802154_RX_ABORT_COEX_CNT_CLEAR_S 8 +#define IEEE802154_RX_RESTART_CNT_CLEAR (BIT(7)) +#define IEEE802154_RX_RESTART_CNT_CLEAR_S 7 +#define IEEE802154_TX_ACK_ABORT_COEX_CNT_CLEAR (BIT(6)) +#define IEEE802154_TX_ACK_ABORT_COEX_CNT_CLEAR_S 6 +#define IEEE802154_ED_SCAN_COEX_CNT_CLEAR (BIT(5)) +#define IEEE802154_ED_SCAN_COEX_CNT_CLEAR_S 5 +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_CLEAR (BIT(4)) +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_CLEAR_S 4 +#define IEEE802154_RX_ACK_TIMEOUT_CNT_CLEAR (BIT(3)) +#define IEEE802154_RX_ACK_TIMEOUT_CNT_CLEAR_S 3 +#define IEEE802154_TX_BREAK_COEX_CNT_CLEAR (BIT(2)) +#define IEEE802154_TX_BREAK_COEX_CNT_CLEAR_S 2 +#define IEEE802154_TX_SECURITY_ERROR_CNT_CLEAR (BIT(1)) +#define IEEE802154_TX_SECURITY_ERROR_CNT_CLEAR_S 1 +#define IEEE802154_CCA_BUSY_CNT_CLEAR (BIT(0)) +#define IEEE802154_CCA_BUSY_CNT_CLEAR_S 0 + +#define IEEE802154_MAC_DATE_REG (IEEE802154_REG_BASE + 0x0184) +#define IEEE802154_MAC_DATE 0xFFFFFFFF +#define IEEE802154_MAC_DATE_S 0 +#define IEEE802154_MAC_DATE_VERSION 0x220622 + +// For ETM feature. +#define ETM_REG_BASE 0x600A8800 +#define ETM_CHEN_AD0_REG (ETM_REG_BASE + 0x0000) +#define ETM_CHENSET_AD0_REG (ETM_REG_BASE + 0x0004) +#define ETM_CHENCLR_AD0_REG (ETM_REG_BASE + 0x0008) +#define ETM_CH0_EVT_ID_REG (ETM_REG_BASE + 0x0018) +#define ETM_CH0_TASK_ID_REG (ETM_REG_BASE + 0x001C) + +#define ETM_CH_OFFSET 0x08 + +#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 + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/ieee802154_struct.h b/components/soc/esp32c6/include/soc/ieee802154_struct.h new file mode 100644 index 0000000000..b28c7d9c84 --- /dev/null +++ b/components/soc/esp32c6/include/soc/ieee802154_struct.h @@ -0,0 +1,462 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#ifdef __cplusplus +extern "C" { +#endif + +// TODO: ZB-93, rewrite this file using regdesc tools when IEEE802154.csv is ready. +typedef volatile struct esp_ieee802154_s { + union { + struct { + uint32_t cmd: 8; + uint32_t reserved8: 24; + }; + uint32_t val; + } cmd; // 0x00 + + union { + struct { + uint32_t auto_ack_tx: 1; + uint32_t auto_enhack: 1; + uint32_t reserved2: 1; + uint32_t auto_ack_rx: 1; + uint32_t reserved4: 1; + uint32_t ifs_dis: 1; + uint32_t coordinator: 1; + uint32_t promiscuous: 1; + uint32_t reserved8: 3; + uint32_t version_filter_dis: 1; + uint32_t pending_enhance: 1; + uint32_t reserved13: 1; + uint32_t filter_enhance_dis: 1; + uint32_t reserved15: 1; + uint32_t coex_arb_delay: 8; + uint32_t bit_order: 1; + uint32_t no_rssi_trigger_break_en: 1; + uint32_t coex_force_rx: 1; + uint32_t rx_done_trig_idle: 1; + uint32_t multipan_mask: 4; + }; + uint32_t val; + } conf; // 0x04 + + struct { + union { + struct { + uint32_t addr: 16; + uint32_t reserved16: 16; + }; + uint32_t val; + } short_addr; // 0x08 + + union { + struct { + uint32_t id: 16; + uint32_t reserved16: 16; + }; + uint32_t val; + } panid; // 0x0c + + uint32_t ext_addr0; // 0x10 + uint32_t ext_addr1; // 0x14 + } multipan[4]; + + union { + struct { + uint32_t freq: 7; + uint32_t reserved7: 25; + }; + uint32_t val; + } channel; //0x48 + + union { + struct { + uint32_t power: 5; + uint32_t reserved5: 27; + }; + uint32_t val; + } txpower; //0x4c + + union { + struct { + uint32_t duration: 24; + uint32_t delay: 4; + uint32_t reserved28: 4; + }; + uint32_t val; + } ed_duration; //0x50 + + union { + struct { + uint32_t cca_threshold: 8; + uint32_t reserved8: 3; + uint32_t ed_sample_rate: 2; + uint32_t ed_sample_mode: 1; + uint32_t cca_mode: 2; + uint32_t ed_rss: 8; + uint32_t cca_busy: 1; + uint32_t reserved25: 7; + }; + uint32_t val; + } ed_cfg; //0x54 + + union { + struct { + uint32_t sifs: 8; + uint32_t reserved8: 8; + uint32_t lifs: 10; + uint32_t reserved26: 6; + }; + uint32_t val; + } ifs_cfg; //0x58 + + union { + struct { + uint32_t timeout: 16; + uint32_t reserved16: 16; + }; + uint32_t val; + } ack_timeout; //0x5c + + union { + struct { + uint32_t events: 13; + uint32_t reserved13: 19; + }; + uint32_t val; + } event_en; //0x60 + + union { + struct { + uint32_t events: 13; + uint32_t reserved13: 19; + }; + uint32_t val; + } event_status; //0x64 + + union { + struct { + uint32_t rx_abort_en: 31; + uint32_t reserved31: 1; + }; + uint32_t val; + } rx_abort_event_en; //0x68 + + union { + struct { + uint32_t pending: 1; + uint32_t reserved1: 15; + uint32_t pending_timeout: 16; + }; + uint32_t val; + } pending_cfg; //0x6c + + union { + struct { + uint32_t pti: 4; + uint32_t hw_ack_pti: 4; + uint32_t close_rf_sel: 1; + uint32_t reserved9: 23; + }; + uint32_t val; + } pti; //0x70 + + uint32_t reserved_74; //0x74 + + union { + struct { + uint32_t tx_abort_en: 31; + uint32_t reserved31: 1; + }; + uint32_t val; + } tx_abort_event_en; //0x78 + + uint32_t enhack_generate_done_notify; //0x7c + + union { + struct { + uint32_t filter_fail_reason: 4; + uint32_t rx_abort_reason: 5; + uint32_t reserved9: 7; + uint32_t rx_state: 3; + uint32_t reserved19: 1; + uint32_t preamble_match: 1; + uint32_t sfd_match: 1; + uint32_t reserved22: 10; + }; + uint32_t val; + } rx_status; // 0x80 + + union { + struct { + uint32_t tx_state: 4; + uint32_t tx_abort_reason: 5; + uint32_t reserved9: 7; + uint32_t tx_security_error: 4; + uint32_t reserved20: 12; + }; + uint32_t val; + } tx_status; //0x84 + + union { + struct { + uint32_t txrx_status: 4; + uint32_t reserved4: 4; + uint32_t tx_proc: 1; + uint32_t rx_proc: 1; + uint32_t ed_proc: 1; + uint32_t ed_trig_tx_proc: 1; + uint32_t reserved12: 4; + uint32_t rf_ctrl_state: 4; + uint32_t reserved20: 12; + }; + uint32_t val; + } txrx_status; //0x88 + + uint32_t tx_sec_schedule_state; //0x8c + + union { + struct { + uint32_t pkt_gck: 1; + uint32_t ctrl_gck: 1; + uint32_t reserved2: 30; + }; + uint32_t val; + } core_gck_cfg; //0x90 + + uint32_t reserved_94; //0x94 + uint32_t reserved_98; //0x98 + uint32_t reserved_9c; //0x9c + uint32_t reserved_a0; //0xa0 + + uint32_t rx_length; //0xa4 + + uint32_t timer0_threshold; //0xa8 + uint32_t timer0_value; //0xac + uint32_t timer1_threshold; //0xb0 + uint32_t timer1_value; //0xb4 + uint32_t clk_counter_threshold; //0xb8 + uint32_t clk_counter_value; //0xbc + + union { + struct { + uint32_t ifs_counter: 10; + uint32_t reserved10: 6; + uint32_t ifs_counter_en: 1; + uint32_t reserved17: 15; + }; + uint32_t val; + } ifs_counter_cfg; //0xc0 + + union { + struct { + uint32_t sfd_wait_symbol_num: 4; + uint32_t reserved4: 28; + }; + uint32_t val; + } sfd_wait; //0xc4 + + union { + struct { + uint32_t tx_path_delay: 6; + uint32_t reserved6: 10; + uint32_t rx_path_delay: 6; + uint32_t reserved624: 10; + }; + uint32_t val; + } txrx_path_delay; //0xc8 + + uint32_t bb_clk; //0xcc + uint32_t dma_tx_addr; //0xd0 + + union { + struct { + uint32_t txdma_water_level: 3; + uint32_t reserved3: 1; + uint32_t txdma_fill_entry: 3; + uint32_t reserved7: 9; + uint32_t txdma_ctrl_state: 5; + uint32_t reserved21: 3; + uint32_t txdma_fetch_byte_cnt: 7; + uint32_t reserved31: 1; + }; + uint32_t val; + } dma_tx_cfg; //0xd4 + + uint32_t dma_tx_err; //0xd8 + + uint32_t reserved_dc; //0xdc + + uint32_t dma_rx_addr; //0xe0 + + union { + struct { + uint32_t rxdma_water_level: 3; + uint32_t reserved3: 13; + uint32_t rxdma_ctrl_state: 5; + uint32_t reserved21: 3; + uint32_t rxdma_append_lqi: 1; + uint32_t rxdma_append_freq_offset: 1; + uint32_t reserved26: 6; + }; + uint32_t val; + } dma_rx_cfg; //0xe4 + + uint32_t dma_rx_err; //0xe8 + + uint32_t reserved_ec; //x0ec + + uint32_t dma_gck; //0xf0 + uint32_t dma_dummy_data; //0xf4 + uint32_t reserved_f8; //0xf8 + uint32_t reserved_fc; //0xfc + + union { + struct { + uint32_t delay: 10; + uint32_t reserved10: 22; + }; + uint32_t val; + } pa_on_delay; //0x100 + + union { + struct { + uint32_t delay: 10; + uint32_t reserved10: 22; + }; + uint32_t val; + } tx_on_delay; //0x104 + + union { + struct { + uint32_t delay: 6; + uint32_t reserved6: 26; + }; + uint32_t val; + } txen_stop_delay; //0x108 + + union { + struct { + uint32_t delay: 6; + uint32_t reserved6: 26; + }; + uint32_t val; + } tx_off_delay; //0x10c + + union { + struct { + uint32_t delay: 11; + uint32_t reserved11: 21; + }; + uint32_t val; + } rx_on_delay; //0x110 + + union { + struct { + uint32_t delay: 10; + uint32_t reserved10: 22; + }; + uint32_t val; + } txrx_switch_delay; //0x114 + + uint32_t cont_rx_delay; //0x118 + + union { + struct { + uint32_t dcdc_pre_up_delay: 8; + uint32_t dcdc_down_delay: 8; + uint32_t dcdc_ctrl_en: 1; + uint32_t reserved17: 14; + uint32_t tx_dcdc_up: 1; + }; + uint32_t val; + } dcdc_ctrl; //0x11c + + union { + struct { + uint32_t debug_sel: 3; + uint32_t reserved3: 5; + uint32_t trig_st_sel: 4; + uint32_t ser_debug_sel: 4; + uint32_t trig_st_match_val: 5; + uint32_t reserved21: 3; + uint32_t trig_pulse_sel: 3; + uint32_t reserved27: 3; + uint32_t trig_st_match_dump_en: 1; + uint32_t trig_pulse_dump_en: 1; + }; + uint32_t val; + } debug_ctrl; //0x120 + + uint32_t tx_dma_err_sts_reg; //0x124 + union { + struct { + uint32_t tx_security_en: 1; + uint32_t reserved1: 7; + uint32_t security_offset: 7; + uint32_t reserved15: 17; + }; + uint32_t val; + } security_ctrl; //0x128 + + uint32_t security_addr0; //0x12c + uint32_t security_addr1; //0x130 + uint32_t security_key0; //0x134 + uint32_t security_key1; //0x138 + uint32_t security_key2; //0x13c + uint32_t security_key3; //0x140 + + uint32_t debug_sfd_timeout_cnt; //0x144 + uint32_t debug_crc_error_cnt; //0x148 + uint32_t debug_ed_abort_cnt; //0x14c + uint32_t debug_cca_fail_cnt; //0x150 + uint32_t debug_rx_filter_fail_cnt; //0x154 + uint32_t debug_no_rss_detect_cnt; //0x158 + uint32_t debug_rx_abort_coex_cnt; //0x15c + uint32_t debug_rx_restart_cnt; //0x160 + uint32_t debug_tx_ack_abort_coex_cnt; //0x164 + uint32_t debug_ed_scan_break_coex_cnt; //0x168 + uint32_t debug_rx_ack_abort_coex_cnt; //0x16c + uint32_t debug_rx_ack_timeout_cnt; //0x170 + uint32_t debug_tx_break_coex_cnt; //0x174 + uint32_t debug_tx_security_error_cnt; //0x178 + uint32_t debug_cca_busy_cnt; //0x17c + + union { + struct { + uint32_t debug_ed_scan_break_coex_cnt: 1; + uint32_t debug_cca_busy_cnt: 1; + uint32_t debug_cca_fail_cnt: 1; + uint32_t debug_ed_abort_cnt: 1; + uint32_t debug_tx_security_error_cnt: 1; + uint32_t debug_tx_break_coex_cnt: 1; + uint32_t debug_tx_ack_abort_coex_cnt: 1; + uint32_t debug_rx_ack_timeout_cnt: 1; + uint32_t debug_rx_restart_cnt: 1; + uint32_t debug_rx_ack_abort_coex_cnt: 1; + uint32_t debug_rx_abort_coex_cnt: 1; + uint32_t debug_no_rss_detect_cnt: 1; + uint32_t debug_rx_filter_fail_cnt: 1; + uint32_t debug_crc_error_cnt: 1; + uint32_t debug_sfd_timeout_cnt: 1; + uint32_t reserved15: 17; + }; + uint32_t val; + } debug_cnt_clr; //0x180 + + uint32_t i154_version; //0x184 + +} esp_ieee802154_t; + +extern esp_ieee802154_t IEEE802154; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32h2/ieee802154_periph.c b/components/soc/esp32h2/ieee802154_periph.c new file mode 100644 index 0000000000..58cce6d7bb --- /dev/null +++ b/components/soc/esp32h2/ieee802154_periph.c @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/ieee802154_periph.h" + +const ieee802154_conn_t ieee802154_periph = { + .module = PERIPH_IEEE802154_MODULE, + .irq_id = ETS_ZB_MAC_INTR_SOURCE, +}; diff --git a/components/soc/esp32h2/include/soc/ieee802154_reg.h b/components/soc/esp32h2/include/soc/ieee802154_reg.h new file mode 100644 index 0000000000..30f3f8d906 --- /dev/null +++ b/components/soc/esp32h2/include/soc/ieee802154_reg.h @@ -0,0 +1,545 @@ +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// TODO: ZB-93, rewrite this file using regdesc tools when IEEE802154.csv is ready. +#define IEEE802154_REG_BASE 0x600A3000 + +#define IEEE802154_COMMAND_REG (IEEE802154_REG_BASE + 0x0000) +#define IEEE802154_OPCODE 0x000000FF +#define IEEE802154_OPCODE_S 0 + +#define IEEE802154_CTRL_CFG_REG (IEEE802154_REG_BASE + 0x0004) +#define IEEE802154_MAC_INF3_ENABLE (BIT(31)) +#define IEEE802154_MAC_INF3_ENABLE_S 31 +#define IEEE802154_MAC_INF2_ENABLE (BIT(30)) +#define IEEE802154_MAC_INF2_ENABLE_S 30 +#define IEEE802154_MAC_INF1_ENABLE (BIT(29)) +#define IEEE802154_MAC_INF1_ENABLE_S 29 +#define IEEE802154_MAC_INF0_ENABLE (BIT(28)) +#define IEEE802154_MAC_INF0_ENABLE_S 28 +#define IEEE802154_RX_DONE_TRIGGER_IDLE (BIT(27)) +#define IEEE802154_RX_DONE_TRIGGER_IDLE_S 27 +#define IEEE802154_FORCE_RX_ENB (BIT(26)) +#define IEEE802154_FORCE_RX_ENB_S 26 +#define IEEE802154_NO_RSS_TRK_ENB (BIT(25)) +#define IEEE802154_NO_RSS_TRK_ENB_S 25 +#define IEEE802154_BIT_ORDER (BIT(24)) +#define IEEE802154_BIT_ORDER_S 24 +#define IEEE802154_COEX_ARB_DELAY 0x0000001F +#define IEEE802154_COEX_ARB_DELAY_S 16 +#define IEEE802154_FILTER_ENHANCE (BIT(14)) +#define IEEE802154_FILTER_ENHANCE_S 14 +#define IEEE802154_AUTOPEND_ENHANCE (BIT(12)) +#define IEEE802154_AUTOPEND_ENHANCE_S 12 +#define IEEE802154_DIS_FRAME_VERSION_RSV_FILTER (BIT(11)) +#define IEEE802154_DIS_FRAME_VERSION_RSV_FILTER_S 11 +#define IEEE802154_PROMISCUOUS_MODE (BIT(7)) +#define IEEE802154_PROMISCUOUS_MODE_S 7 +#define IEEE802154_PAN_COORDINATOR (BIT(6)) +#define IEEE802154_PAN_COORDINATOR_S 6 +#define IEEE802154_DIS_IFS_CONTROL (BIT(5)) +#define IEEE802154_DIS_IFS_CONTROL_S 5 +#define IEEE802154_HW_AUTO_ACK_RX_EN (BIT(3)) +#define IEEE802154_HW_AUTO_ACK_RX_EN_S 3 +#define HW_ENHANCE_ACK_TX_EN (BIT(1)) +#define HW_ENHANCE_ACK_TX_EN_S 1 +#define IEEE802154_HW_AUTO_ACK_TX_EN (BIT(0)) +#define IEEE802154_HW_AUTO_ACK_TX_EN_S 0 + +#define IEEE802154_INF0_SHORT_ADDR_REG (IEEE802154_REG_BASE + 0x0008) +#define IEEE802154_MAC_INF0_SHORT_ADDR 0x0000FFFF +#define IEEE802154_MAC_INF0_SHORT_ADDR_S 0 + +#define IEEE802154_INF0_PAN_ID_REG (IEEE802154_REG_BASE + 0x000C) +#define IEEE802154_MAC_INF0_PAN_ID 0x0000FFFF +#define IEEE802154_MAC_INF0_PAN_ID_S 0 + +#define IEEE802154_INF0_EXTEND_ADDR0_REG (IEEE802154_REG_BASE + 0x0010) +#define IEEE802154_MAC_INF0_EXTEND_ADDR0 0xFFFFFFFF +#define IEEE802154_MAC_INF0_EXTEND_ADDR0_S 0 + +#define IEEE802154_INF0_EXTEND_ADDR1_REG (IEEE802154_REG_BASE + 0x0014) +#define IEEE802154_MAC_INF0_EXTEND_ADDR1 0xFFFFFFFF +#define IEEE802154_MAC_INF0_EXTEND_ADDR1_S 0 + +#define IEEE802154_INF1_SHORT_ADDR_REG (IEEE802154_REG_BASE + 0x0018) +#define IEEE802154_MAC_INF1_SHORT_ADDR 0x0000FFFF +#define IEEE802154_MAC_INF1_SHORT_ADDR_S 0 + +#define IEEE802154_INF1_PAN_ID_REG (IEEE802154_REG_BASE + 0x001C) +#define IEEE802154_MAC_INF1_PAN_ID 0x0000FFFF +#define IEEE802154_MAC_INF1_PAN_ID_S 0 + +#define IEEE802154_INF1_EXTEND_ADDR0_REG (IEEE802154_REG_BASE + 0x0020) +#define IEEE802154_MAC_INF1_EXTEND_ADDR0 0xFFFFFFFF +#define IEEE802154_MAC_INF1_EXTEND_ADDR0_S 0 + +#define IEEE802154_INF1_EXTEND_ADDR1_REG (IEEE802154_REG_BASE + 0x0024) +#define IEEE802154_MAC_INF1_EXTEND_ADDR1 0xFFFFFFFF +#define IEEE802154_MAC_INF1_EXTEND_ADDR1_S 0 + +#define IEEE802154_INF2_SHORT_ADDR_REG (IEEE802154_REG_BASE + 0x0028) +#define IEEE802154_MAC_INF2_SHORT_ADDR 0x0000FFFF +#define IEEE802154_MAC_INF2_SHORT_ADDR_S 0 + +#define IEEE802154_INF2_PAN_ID_REG (IEEE802154_REG_BASE + 0x002C) +#define IEEE802154_MAC_INF2_PAN_ID 0x0000FFFF +#define IEEE802154_MAC_INF2_PAN_ID_S 0 + +#define IEEE802154_INF2_EXTEND_ADDR0_REG (IEEE802154_REG_BASE + 0x0030) +#define IEEE802154_MAC_INF2_EXTEND_ADDR0 0xFFFFFFFF +#define IEEE802154_MAC_INF2_EXTEND_ADDR0_S 0 + +#define IEEE802154_INF2_EXTEND_ADDR1_REG (IEEE802154_REG_BASE + 0x0034) +#define IEEE802154_MAC_INF2_EXTEND_ADDR1 0xFFFFFFFF +#define IEEE802154_MAC_INF2_EXTEND_ADDR1_S 0 + +#define IEEE802154_INF3_SHORT_ADDR_REG (IEEE802154_REG_BASE + 0x0038) +#define IEEE802154_MAC_INF3_SHORT_ADDR 0x0000FFFF +#define IEEE802154_MAC_INF3_SHORT_ADDR_S 0 + +#define IEEE802154_INF3_PAN_ID_REG (IEEE802154_REG_BASE + 0x003C) +#define IEEE802154_MAC_INF3_PAN_ID 0x0000FFFF +#define IEEE802154_MAC_INF3_PAN_ID_S 0 + +#define IEEE802154_INF3_EXTEND_ADDR0_REG (IEEE802154_REG_BASE + 0x0040) +#define IEEE802154_MAC_INF3_EXTEND_ADDR0 0xFFFFFFFF +#define IEEE802154_MAC_INF3_EXTEND_ADDR0_S 0 + +#define IEEE802154_INF3_EXTEND_ADDR1_REG (IEEE802154_REG_BASE + 0x0044) +#define IEEE802154_MAC_INF3_EXTEND_ADDR1 0xFFFFFFFF +#define IEEE802154_MAC_INF3_EXTEND_ADDR1_S 0 + +#define IEEE802154_CHANNEL_REG (IEEE802154_REG_BASE + 0x0048) +#define IEEE802154_HOP 0x0000007F +#define IEEE802154_HOP_S 0 + +#define IEEE802154_TX_POWER_REG (IEEE802154_REG_BASE + 0x004C) +#define IEEE802154_TX_POWER 0x0000001F +#define IEEE802154_TX_POWER_S 0 + +#define IEEE802154_ED_SCAN_DURATION_REG (IEEE802154_REG_BASE + 0x0050) +#define IEEE802154_ED_SCAN_WAIT_DLY 0x0000000F +#define IEEE802154_ED_SCAN_WAIT_DLY_S 24 +#define IEEE802154_ED_SCAN_DURATION 0x00FFFFFF +#define IEEE802154_ED_SCAN_DURATION_S 0 + +#define IEEE802154_ED_SCAN_CFG_REG (IEEE802154_REG_BASE + 0x0054) +#define IEEE802154_CCA_BUSY (BIT(24)) +#define IEEE802154_CCA_BUSY_S 24 +#define IEEE802154_ED_RSS 0x000000FF +#define IEEE802154_ED_RSS_S 16 +#define IEEE802154_CCA_MODE 0x00000003 +#define IEEE802154_CCA_MODE_S 14 +#define IEEE802154_DIS_ED_POWER_SEL (BIT(13)) +#define IEEE802154_DIS_ED_POWER_SEL_S 13 +#define IEEE802154_ED_SAMPLE_MODE 0x00000003 +#define IEEE802154_ED_SAMPLE_MODE_S 11 +#define IEEE802154_CCA_ED_THRESHOLD 0x000000FF +#define IEEE802154_CCA_ED_THRESHOLD_S 0 + +#define IEEE802154_IFS_REG (IEEE802154_REG_BASE + 0x0058) +#define IEEE802154_LIFS 0x000003FF +#define IEEE802154_LIFS_S 16 +#define IEEE802154_SIFS 0x000000FF +#define IEEE802154_SIFS_S 0 + +#define IEEE802154_ACK_TIMEOUT_REG (IEEE802154_REG_BASE + 0x005C) +#define IEEE802154_ACK_TIMEOUT 0x0000FFFF +#define IEEE802154_ACK_TIMEOUT_S 0 + +#define IEEE802154_EVENT_EN_REG (IEEE802154_REG_BASE + 0x0060) +#define IEEE802154_EVENT_EN 0x00001FFF +#define IEEE802154_EVENT_EN_S 0 + +#define IEEE802154_EVENT_STATUS_REG (IEEE802154_REG_BASE + 0x0064) +#define IEEE802154_EVENT_STATUS 0x00001FFF +#define IEEE802154_EVENT_STATUS_S 0 + +#define IEEE802154_RX_ABORT_INTR_CTRL_REG (IEEE802154_REG_BASE + 0x0068) +#define IEEE802154_RX_ABORT_INTR_CTRL 0x7FFFFFFF +#define IEEE802154_RX_ABORT_INTR_CTRL_S 0 + +#define IEEE802154_ACK_FRAME_PENDING_EN_REG (IEEE802154_REG_BASE + 0x006c) +#define IEEE802154_ACK_TX_ACK_TIMEOUT 0x0000FFFF +#define IEEE802154_ACK_TX_ACK_TIMEOUT_S 16 +#define IEEE802154_ACK_FRAME_PENDING_EN (BIT(0)) +#define IEEE802154_ACK_FRAME_PENDING_EN_S 0 + +#define IEEE802154_COEX_PTI_REG (IEEE802154_REG_BASE + 0x0070) +#define IEEE802154_CLOSE_RF_SEL (BIT(8)) +#define IEEE802154_CLOSE_RF_SEL_S 8 +#define IEEE802154_COEX_ACK_PTI 0x0000000F +#define IEEE802154_COEX_ACK_PTI_S 4 +#define IEEE802154_COEX_PTI 0x0000000F +#define IEEE802154_COEX_PTI_S 0 + +#define IEEE802154_TX_ABORT_INTERRUPT_CONTROL_REG (IEEE802154_REG_BASE + 0x0078) +#define IEEE802154_TX_ABORT_INTERRUPT_CONTROL 0x7FFFFFFF +#define IEEE802154_TX_ABORT_INTERRUPT_CONTROL_S 0 + +#define IEEE802154_ENHANCE_ACK_CFG_REG (IEEE802154_REG_BASE + 0x7C) +#define IEEE802154_TX_ENH_ACK_GENERATE_DONE_NOTIFY 0xFFFFFFFF +#define IEEE802154_TX_ENH_ACK_GENERATE_DONE_NOTIFY_S 0 + +#define IEEE802154_RX_STATUS_REG (IEEE802154_REG_BASE + 0x0080) +#define IEEE802154_SFD_MATCH (BIT(21)) +#define IEEE802154_SFD_MATCH_S 21 +#define IEEE802154_PREAMBLE_MATCH (BIT(20)) +#define IEEE802154_PREAMBLE_MATCH_S 20 +#define IEEE802154_RX_STATE 0x00000007 +#define IEEE802154_RX_STATE_S 16 +#define IEEE802154_RX_ABORT_STATUS 0x0000001F +#define IEEE802154_RX_ABORT_STATUS_S 4 +#define IEEE802154_FILTER_FAIL_STATUS 0x0000000F +#define IEEE802154_FILTER_FAIL_STATUS_S 0 + +#define IEEE802154_TX_STATUS_REG (IEEE802154_REG_BASE + 0x0084) +#define IEEE802154_TX_SEC_ERROR_CODE 0x0000000F +#define IEEE802154_TX_SEC_ERROR_CODE_S 16 +#define IEEE802154_TX_ABORT_STATUS 0x0000001F +#define IEEE802154_TX_ABORT_STATUS_S 4 +#define IEEE802154_TX_STATE 0x0000000F +#define IEEE802154_TX_STATE_S 0 + +#define IEEE802154_TXRX_STATUS_REG (IEEE802154_REG_BASE + 0x0088) +#define IEEE802154_RF_CTRL_STATE 0x0000000F +#define IEEE802154_RF_CTRL_STATE_S 16 +#define IEEE802154_ED_TRIGGER_TX_PROC (BIT(11)) +#define IEEE802154_ED_TRIGGER_TX_PROC_S 11 +#define IEEE802154_ED_PROC (BIT(10)) +#define IEEE802154_ED_PROC_S 10 +#define IEEE802154_RX_PROC (BIT(9)) +#define IEEE802154_RX_PROC_S 9 +#define IEEE802154_TX_PROC (BIT(8)) +#define IEEE802154_TX_PROC_S 8 +#define IEEE802154_TXRX_STATE 0x0000000F +#define IEEE802154_TXRX_STATE_S 0 + +#define IEEE802154_TX_CCM_SCHEDULE_STATUS_REG (IEEE802154_REG_BASE + 0x008c) +#define IEEE802154_TX_CCM_SCHEDULE_STATUS 0x7FFFFFFF +#define IEEE802154_TX_CCM_SCHEDULE_STATUS_S 0 + +#define IEEE802154_RX_LENGTH_REG (IEEE802154_REG_BASE + 0x00a4) +#define IEEE802154_RX_LENGTH 0x0000007F +#define IEEE802154_RX_LENGTH_S 0 + +#define IEEE802154_TIME0_THRESHOLD_REG (IEEE802154_REG_BASE + 0x00a8) +#define IEEE802154_TIMER0_THRESHOLD 0xFFFFFFFF +#define IEEE802154_TIMER0_THRESHOLD_S 0 + +#define IEEE802154_TIME0_VALUE_REG (IEEE802154_REG_BASE + 0x00ac) +#define IEEE802154_TIMER0_VALUE 0xFFFFFFFF +#define IEEE802154_TIMER0_VALUE_S 0 + +#define IEEE802154_TIME1_THRESHOLD_REG (IEEE802154_REG_BASE + 0x00b0) +#define IEEE802154_TIMER1_THRESHOLD 0xFFFFFFFF +#define IEEE802154_TIMER1_THRESHOLD_S 0 + +#define IEEE802154_TIME1_VALUE_REG (IEEE802154_REG_BASE + 0x00b4) +#define IEEE802154_TIMER1_VALUE 0xFFFFFFFF +#define IEEE802154_TIMER1_VALUE_S 0 + +#define IEEE802154_CLK_COUNTER_MATCH_VAL_REG (IEEE802154_REG_BASE + 0x00b8) +#define IEEE802154_CLK_COUNT_MATCH_VAL 0x0000FFFF +#define IEEE802154_CLK_COUNT_MATCH_VAL_S 0 + +#define IEEE802154_CLK_COUNTER_REG (IEEE802154_REG_BASE + 0x00bc) +#define IEEE802154_CLK_625US_CNT 0x0000FFFF +#define IEEE802154_CLK_625US_CNT_S 0 + +#define IEEE802154_IFS_COUNTER_REG (IEEE802154_REG_BASE + 0x00c0) +#define IEEE802154_IFS_COUNTER_EN (BIT(16)) +#define IEEE802154_IFS_COUNTER_EN_S 16 +#define IEEE802154_IFS_COUNTER 0x000003FF +#define IEEE802154_IFS_COUNTER_S 0 + +#define IEEE802154_SFD_WAIT_SYMBOL_REG (IEEE802154_REG_BASE + 0x00c4) +#define IEEE802154_SFD_WAIT_SYMBOL_NUM 0x0000000F +#define IEEE802154_SFD_WAIT_SYMBOL_NUM_S 0 + +#define IEEE802154_TXRX_PATH_DELAY_REG (IEEE802154_REG_BASE + 0x00c8) +#define IEEE802154_RX_PATH_DELAY 0x0000003F +#define IEEE802154_RX_PATH_DELAY_S 16 +#define IEEE802154_TX_PATH_DELAY 0x0000003F +#define IEEE802154_TX_PATH_DELAY_S 0 + +#define IEEE802154_BB_CLK_REG (IEEE802154_REG_BASE + 0x00cc) +#define IEEE802154_BB_CLK_FREQ_MINUS_1 0x0000001F +#define IEEE802154_BB_CLK_FREQ_MINUS_1_S 0 + +#define IEEE802154_TXDMA_ADDR_REG (IEEE802154_REG_BASE + 0x00D0) +#define IEEE802154_TXDMA_ADDR 0xFFFFFFFF +#define IEEE802154_TXDMA_ADDR_S 0 + +#define IEEE802154_TXDMA_CTRL_STATE_REG (IEEE802154_REG_BASE + 0x00D4) +#define IEEE802154_TXDMA_FETCH_BYTE_CNT 0x0000007F +#define IEEE802154_TXDMA_FETCH_BYTE_CNT_S 24 +#define IEEE802154_TXDMA_STATE 0x0000001F +#define IEEE802154_TXDMA_STATE_S 16 +#define IEEE802154_TXDMA_FILL_ENTRY 0x00000007 +#define IEEE802154_TXDMA_FILL_ENTRY_S 4 +#define IEEE802154_TXDMA_WATER_LEVEL 0x00000007 +#define IEEE802154_TXDMA_WATER_LEVEL_S 0 + +#define IEEE802154_TXDMA_ERR_REG (IEEE802154_REG_BASE + 0x00D8) +#define IEEE802154_TXDMA_ERR 0x0000000F +#define IEEE802154_TXDMA_ERR_S 0 + +#define IEEE802154_RXDMA_ADDR_REG (IEEE802154_REG_BASE + 0x00E0) +#define IEEE802154_RXDMA_ADDR 0xFFFFFFFF +#define IEEE802154_RXDMA_ADDR_S 0 + +#define IEEE802154_RXDMA_CTRL_STATE_REG (IEEE802154_REG_BASE + 0x00E4) +#define IEEE802154_RXDMA_APPEND_FREQ_OFFSET (BIT(25)) +#define IEEE802154_RXDMA_APPEND_FREQ_OFFSET_S 25 +#define IEEE802154_RXDMA_APPEND_LQI_OFFSET (BIT(24)) +#define IEEE802154_RXDMA_APPEND_LQI_OFFSET_S 24 +#define IEEE802154_RXDMA_STATE 0x0000001F +#define IEEE802154_RXDMA_STATE_S 16 +#define IEEE802154_RXDMA_WATER_LEVEL 0x00000007 +#define IEEE802154_RXDMA_WATER_LEVEL_S 0 + +#define IEEE802154_RXDMA_ERR_REG (IEEE802154_REG_BASE + 0x00E8) +#define IEEE802154_RXDMA_ERR 0x0000000F +#define IEEE802154_RXDMA_ERR_S 0 + +#define IEEE802154_DMA_GCK_CFG_REG (IEEE802154_REG_BASE + 0x00F0) +#define IEEE802154_DMA_GCK_CFG (BIT(0)) +#define IEEE802154_DMA_GCK_CFG_S 0 + +#define IEEE802154_DMA_DUMMY_REG (IEEE802154_REG_BASE + 0x00F4) +#define IEEE802154_DMA_DUMMY_DATA 0xFFFFFFFF +#define IEEE802154_DMA_DUMMY_DATA_S + +#define IEEE802154_PAON_DELAY_REG (IEEE802154_REG_BASE + 0x0100) +#define IEEE802154_PAON_DELAY 0x000003FF +#define IEEE802154_PAON_DELAY_S 0 + +#define IEEE802154_TXON_DELAY_REG (IEEE802154_REG_BASE + 0x0104) +#define IEEE802154_TXON_DELAY 0x000003FF +#define IEEE802154_TXON_DELAY_S 0 + +#define IEEE802154_TXEN_STOP_DELAY_REG (IEEE802154_REG_BASE + 0x0108) +#define IEEE802154_TXEN_STOP_DLY 0x0000003F +#define IEEE802154_TXEN_STOP_DLY_S 0 + +#define IEEE802154_TXOFF_DELAY_REG (IEEE802154_REG_BASE + 0x010c) +#define IEEE802154_TXOFF_DELAY 0x0000003F +#define IEEE802154_TXOFF_DELAY_S 0 + +#define IEEE802154_RXON_DELAY_REG (IEEE802154_REG_BASE + 0x0110) +#define IEEE802154_RXON_DELAY 0x000007FF +#define IEEE802154_RXON_DELAY_S 0 + +#define IEEE802154_TXRX_SWITCH_DELAY_REG (IEEE802154_REG_BASE + 0x0114) +#define IEEE802154_TXRX_SWITCH_DELAY 0x000003FF +#define IEEE802154_TXRX_SWITCH_DELAY_S 0 + +#define IEEE802154_CONT_RX_DELAY_REG (IEEE802154_REG_BASE + 0x0118) +#define IEEE802154_CONT_RX_DELAY 0x0000003F +#define IEEE802154_CONT_RX_DELAY_S 0 + +#define IEEE802154_DCDC_CTRL_REG (IEEE802154_REG_BASE + 0x011c) +#define IEEE802154_TX_DCDC_UP (BIT(31)) +#define IEEE802154_TX_DCDC_UP_S 31 +#define IEEE802154_DCDC_CTRL_EN (BIT(16)) +#define IEEE802154_DCDC_CTRL_EN_S 16 +#define IEEE802154_DCDC_DOWN_DELAY 0x000000FF +#define IEEE802154_DCDC_DOWN_DELAY_S 8 +#define IEEE802154_DCDC_PRE_UP_DELAY 0x000000FF +#define IEEE802154_DCDC_PRE_UP_DELAY_S 0 + +#define IEEE802154_DEBUG_CTRL_REG (IEEE802154_REG_BASE + 0x0120) +#define IEEE802154_DEBUG_TRIGGER_DUMP_EN (BIT(31)) +#define IEEE802154_DEBUG_TRIGGER_DUMP_EN_S 31 +#define IEEE802154_DEBUG_STATE_MATCH_DUMP_EN (BIT(30)) +#define IEEE802154_DEBUG_STATE_MATCH_DUMP_EN_S 30 +#define IEEE802154_DEBUG_TRIGGER_PULSE_SELECT 0x00000007 +#define IEEE802154_DEBUG_TRIGGER_PULSE_SELECT_S 24 +#define IEEE802154_DEBUG_TRIGGER_STATE_MATCH_VALUE 0x0000001F +#define IEEE802154_DEBUG_TRIGGER_STATE_MATCH_VALUE_S 16 +#define IEEE802154_DEBUG_SER_DEBUG_SEL 0x0000000F +#define IEEE802154_DEBUG_SER_DEBUG_SEL_S 12 +#define IEEE802154_DEBUG_TRIGGER_STATE_SELECT 0x0000000F +#define IEEE802154_DEBUG_TRIGGER_STATE_SELECT_S 8 +#define IEEE802154_DEBUG_SIGNAL_SEL 0x00000007 +#define IEEE802154_DEBUG_SIGNAL_SEL_S 0 + +#define IEEE802154_SEC_CTRL_REG (IEEE802154_REG_BASE + 0x0128) +#define IEEE802154_SEC_PAYLOAD_OFFSET 0x0000007F +#define IEEE802154_SEC_PAYLOAD_OFFSET_S 8 +#define IEEE802154_SEC_EN (BIT(0)) +#define IEEE802154_SEC_EN_S 0 + +#define IEEE802154_SEC_EXTEND_ADDRESS0_REG (IEEE802154_REG_BASE + 0x012c) +#define IEEE802154_SEC_EXTEND_ADDRESS0 0xFFFFFFFF +#define IEEE802154_SEC_EXTEND_ADDRESS0_S 0 + +#define IEEE802154_SEC_EXTEND_ADDRESS1_REG (IEEE802154_REG_BASE + 0x0130) +#define IEEE802154_SEC_EXTEND_ADDRESS1 0xFFFFFFFF +#define IEEE802154_SEC_EXTEND_ADDRESS1_S 0 + +#define IEEE802154_SEC_KEY0_REG (IEEE802154_REG_BASE + 0x0134) +#define IEEE802154_SEC_KEY0 0xFFFFFFFF +#define IEEE802154_SEC_KEY0_S 0 + +#define IEEE802154_SEC_KEY1_REG (IEEE802154_REG_BASE + 0x0138) +#define IEEE802154_SEC_KEY1 0xFFFFFFFF +#define IEEE802154_SEC_KEY1_S 0 + +#define IEEE802154_SEC_KEY2_REG (IEEE802154_REG_BASE + 0x013c) +#define IEEE802154_SEC_KEY2 0xFFFFFFFF +#define IEEE802154_SEC_KEY2_S 0 + +#define IEEE802154_SEC_KEY3_REG (IEEE802154_REG_BASE + 0x0140) +#define IEEE802154_SEC_KEY3 0xFFFFFFFF +#define IEEE802154_SEC_KEY3_S 0 + +#define IEEE802154_SFD_TIMEOUT_CNT_REG (IEEE802154_REG_BASE + 0x0144) +#define IEEE802154_SFD_TIMEOUT_CNT 0x0000FFFF +#define IEEE802154_SFD_TIMEOUT_CNT_S 0 + +#define IEEE802154_CRC_ERROR_CNT_REG (IEEE802154_REG_BASE + 0x0148) +#define IEEE802154_CRC_ERROR_CNT 0x0000FFFF +#define IEEE802154_CRC_ERROR_CNT_S 0 + +#define IEEE802154_ED_ABORT_CNT_REG (IEEE802154_REG_BASE + 0x014c) +#define IEEE802154_ED_ABORT_CNT 0x0000FFFF +#define IEEE802154_ED_ABORT_CNT_S 0 + +#define IEEE802154_CCA_FAIL_CNT_REG (IEEE802154_REG_BASE + 0x0150) +#define IEEE802154_CCA_FAIL_CNT 0x0000FFFF +#define IEEE802154_CCA_FAIL_CNT_S 0 + +#define IEEE802154_RX_FILTER_FAIL_CNT_REG (IEEE802154_REG_BASE + 0x0154) +#define IEEE802154_RX_FILTER_FAIL_CNT 0x0000FFFF +#define IEEE802154_RX_FILTER_FAIL_CNT_S 0 + +#define IEEE802154_NO_RSS_DETECT_CNT_REG (IEEE802154_REG_BASE + 0x0158) +#define IEEE802154_NO_RSS_DETECT_CNT 0x0000FFFF +#define IEEE802154_NO_RSS_DETECT_CNT_S 0 + +#define IEEE802154_RX_ABORT_COEX_CNT_REG (IEEE802154_REG_BASE + 0x015c) +#define IEEE802154_RX_ABORT_COEX_CNT 0x0000FFFF +#define IEEE802154_RX_ABORT_COEX_CNT_S 0 + +#define IEEE802154_RX_RESTART_CNT_REG (IEEE802154_REG_BASE + 0x0160) +#define IEEE802154_RX_RESTART_CNT 0x0000FFFF +#define IEEE802154_RX_RESTART_CNT_S 0 + +#define IEEE802154_TX_ACK_ABORT_COEX_CNT_REG (IEEE802154_REG_BASE + 0x0164) +#define IEEE802154_TX_ACK_ABORT_COEX_CNT 0x0000FFFF +#define IEEE802154_TX_ACK_ABORT_COEX_CNT_S 0 + +#define IEEE802154_ED_SCAN_COEX_CNT_REG (IEEE802154_REG_BASE + 0x0168) +#define IEEE802154_ED_SCAN_COEX_CNT 0x0000FFFF +#define IEEE802154_ED_SCAN_COEX_CNT_S 0 + +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_REG (IEEE802154_REG_BASE + 0x016c) +#define IEEE802154_RX_ACK_ABORT_COEX_CNT 0x0000FFFF +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_S 0 + +#define IEEE802154_RX_ACK_TIMEOUT_CNT_REG (IEEE802154_REG_BASE + 0x0170) +#define IEEE802154_RX_ACK_TIMEOUT_CNT 0x0000FFFF +#define IEEE802154_RX_ACK_TIMEOUT_CNT_S 0 + +#define IEEE802154_TX_BREAK_COEX_CNT_REG (IEEE802154_REG_BASE + 0x0174) +#define IEEE802154_TX_BREAK_COEX_CNT 0x0000FFFF +#define IEEE802154_TX_BREAK_COEX_CNT_S 0 + +#define IEEE802154_TX_SECURITY_ERROR_CNT_REG (IEEE802154_REG_BASE + 0x0178) +#define IEEE802154_TX_SECURITY_ERROR_CNT 0x0000FFFF +#define IEEE802154_TX_SECURITY_ERROR_CNT_S 0 + +#define IEEE802154_CCA_BUSY_CNT_REG (IEEE802154_REG_BASE + 0x017c) +#define IEEE802154_CCA_BUSY_CNT 0x0000FFFF +#define IEEE802154_CCA_BUSY_CNT_S 0 + +#define IEEE802154_ERROR_CNT_CLEAR_REG (IEEE802154_REG_BASE + 0x0180) +#define IEEE802154_SFD_TIMEOUT_CNT_CLEAR (BIT(14)) +#define IEEE802154_SFD_TIMEOUT_CNT_CLEAR_S 14 +#define IEEE802154_CRC_ERROR_CNT_CLEAR (BIT(13)) +#define IEEE802154_CRC_ERROR_CNT_CLEAR_S 13 +#define IEEE802154_ED_ABORT_CNT_CLEAR (BIT(12)) +#define IEEE802154_ED_ABORT_CNT_CLEAR_S 12 +#define IEEE802154_CCA_FAIL_CNT_CLEAR (BIT(11)) +#define IEEE802154_CCA_FAIL_CNT_CLEAR_S 11 +#define IEEE802154_RX_FILTER_FAIL_CNT_CLEAR (BIT(10)) +#define IEEE802154_RX_FILTER_FAIL_CNT_CLEAR_S 10 +#define IEEE802154_NO_RSS_DETECT_CNT_CLEAR (BIT(9)) +#define IEEE802154_NO_RSS_DETECT_CNT_CLEAR_S 9 +#define IEEE802154_RX_ABORT_COEX_CNT_CLEAR (BIT(8)) +#define IEEE802154_RX_ABORT_COEX_CNT_CLEAR_S 8 +#define IEEE802154_RX_RESTART_CNT_CLEAR (BIT(7)) +#define IEEE802154_RX_RESTART_CNT_CLEAR_S 7 +#define IEEE802154_TX_ACK_ABORT_COEX_CNT_CLEAR (BIT(6)) +#define IEEE802154_TX_ACK_ABORT_COEX_CNT_CLEAR_S 6 +#define IEEE802154_ED_SCAN_COEX_CNT_CLEAR (BIT(5)) +#define IEEE802154_ED_SCAN_COEX_CNT_CLEAR_S 5 +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_CLEAR (BIT(4)) +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_CLEAR_S 4 +#define IEEE802154_RX_ACK_TIMEOUT_CNT_CLEAR (BIT(3)) +#define IEEE802154_RX_ACK_TIMEOUT_CNT_CLEAR_S 3 +#define IEEE802154_TX_BREAK_COEX_CNT_CLEAR (BIT(2)) +#define IEEE802154_TX_BREAK_COEX_CNT_CLEAR_S 2 +#define IEEE802154_TX_SECURITY_ERROR_CNT_CLEAR (BIT(1)) +#define IEEE802154_TX_SECURITY_ERROR_CNT_CLEAR_S 1 +#define IEEE802154_CCA_BUSY_CNT_CLEAR (BIT(0)) +#define IEEE802154_CCA_BUSY_CNT_CLEAR_S 0 + +#define DEBUG_SEL_CFG0_REG (IEEE802154_REG_BASE + 0x184) +#define DEBUG_FIELD3_SEL 0x0000001F +#define DEBUG_FIELD3_SEL_S 24 +#define DEBUG_FIELD2_SEL 0x0000001F +#define DEBUG_FIELD2_SEL_S 16 +#define DEBUG_FIELD1_SEL 0x0000001F +#define DEBUG_FIELD1_SEL_S 8 +#define DEBUG_FIELD0_SEL 0x0000001F +#define DEBUG_FIELD0_SEL_S 0 + +#define DEBUG_SEL_CFG1_REG (IEEE802154_REG_BASE + 0x188) +#define DEBUG_FIELD7_SEL 0x0000001F +#define DEBUG_FIELD7_SEL_S 24 +#define DEBUG_FIELD6_SEL 0x0000001F +#define DEBUG_FIELD6_SEL_S 16 +#define DEBUG_FIELD5_SEL 0x0000001F +#define DEBUG_FIELD5_SEL_S 8 +#define DEBUG_FIELD4_SEL 0x0000001F +#define DEBUG_FIELD4_SEL_S 0 + +#define IEEE802154_MAC_DATE_REG (IEEE802154_REG_BASE + 0x18c) +#define IEEE802154_MAC_DATE 0xFFFFFFFF +#define IEEE802154_MAC_DATE_S 0 +#define IEEE802154_MAC_DATE_VERSION 0x220907 + +// For ETM feature. +#define ETM_REG_BASE 0x600A4000 +#define ETM_CHEN_AD0_REG (ETM_REG_BASE + 0x0000) +#define ETM_CHENSET_AD0_REG (ETM_REG_BASE + 0x0004) +#define ETM_CHENCLR_AD0_REG (ETM_REG_BASE + 0x0008) +#define ETM_CH0_EVT_ID_REG (ETM_REG_BASE + 0x0018) +#define ETM_CH0_TASK_ID_REG (ETM_REG_BASE + 0x001C) + +#define ETM_CH_OFFSET 0x08 + +#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 + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32h2/include/soc/ieee802154_struct.h b/components/soc/esp32h2/include/soc/ieee802154_struct.h new file mode 100644 index 0000000000..9c7199f93a --- /dev/null +++ b/components/soc/esp32h2/include/soc/ieee802154_struct.h @@ -0,0 +1,480 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#ifdef __cplusplus +extern "C" { +#endif + +// TODO: ZB-93, rewrite this file using regdesc tools when IEEE802154.csv is ready. +typedef volatile struct esp_ieee802154_s { + union { + struct { + uint32_t cmd: 8; + uint32_t reserved8: 24; + }; + uint32_t val; + } cmd; // 0x00 + + union { + struct { + uint32_t auto_ack_tx: 1; + uint32_t auto_enhack: 1; + uint32_t reserved2: 1; + uint32_t auto_ack_rx: 1; + uint32_t reserved4: 1; + uint32_t ifs_dis: 1; + uint32_t coordinator: 1; + uint32_t promiscuous: 1; + uint32_t reserved8: 3; + uint32_t version_filter_dis: 1; + uint32_t pending_enhance: 1; + uint32_t reserved13: 1; + uint32_t filter_enhance_dis: 1; + uint32_t reserved15: 1; + uint32_t coex_arb_delay: 8; + uint32_t bit_order: 1; + uint32_t no_rssi_trigger_break_en: 1; + uint32_t coex_force_rx: 1; + uint32_t rx_done_trig_idle: 1; + uint32_t multipan_mask: 4; + }; + uint32_t val; + } conf; // 0x04 + + struct { + union { + struct { + uint32_t addr: 16; + uint32_t reserved16: 16; + }; + uint32_t val; + } short_addr; // 0x08 + + union { + struct { + uint32_t id: 16; + uint32_t reserved16: 16; + }; + uint32_t val; + } panid; // 0x0c + + uint32_t ext_addr0; // 0x10 + uint32_t ext_addr1; // 0x14 + } multipan[4]; + + union { + struct { + uint32_t freq: 7; + uint32_t reserved7: 25; + }; + uint32_t val; + } channel; //0x48 + + union { + struct { + uint32_t power: 5; + uint32_t reserved5: 27; + }; + uint32_t val; + } txpower; //0x4c + + union { + struct { + uint32_t duration: 24; + uint32_t delay: 4; + uint32_t reserved28: 4; + }; + uint32_t val; + } ed_duration; //0x50 + + union { + struct { + uint32_t cca_threshold: 8; + uint32_t reserved8: 3; + uint32_t ed_sample_rate: 2; + uint32_t ed_sample_mode: 1; + uint32_t cca_mode: 2; + uint32_t ed_rss: 8; + uint32_t cca_busy: 1; + uint32_t reserved25: 7; + }; + uint32_t val; + } ed_cfg; //0x54 + + union { + struct { + uint32_t sifs: 8; + uint32_t reserved8: 8; + uint32_t lifs: 10; + uint32_t reserved26: 6; + }; + uint32_t val; + } ifs_cfg; //0x58 + + union { + struct { + uint32_t timeout: 16; + uint32_t reserved16: 16; + }; + uint32_t val; + } ack_timeout; //0x5c + + union { + struct { + uint32_t events: 13; + uint32_t reserved13: 19; + }; + uint32_t val; + } event_en; //0x60 + + union { + struct { + uint32_t events: 13; + uint32_t reserved13: 19; + }; + uint32_t val; + } event_status; //0x64 + + union { + struct { + uint32_t rx_abort_en: 31; + uint32_t reserved31: 1; + }; + uint32_t val; + } rx_abort_event_en; //0x68 + + union { + struct { + uint32_t pending: 1; + uint32_t reserved1: 15; + uint32_t pending_timeout: 16; + }; + uint32_t val; + } pending_cfg; //0x6c + + union { + struct { + uint32_t pti: 4; + uint32_t hw_ack_pti: 4; + uint32_t close_rf_sel: 1; + uint32_t reserved9: 23; + }; + uint32_t val; + } pti; //0x70 + + uint32_t reserved_74; //0x74 + + union { + struct { + uint32_t tx_abort_en: 31; + uint32_t reserved31: 1; + }; + uint32_t val; + } tx_abort_event_en; //0x78 + + uint32_t enhack_generate_done_notify; //0x7c + + union { + struct { + uint32_t filter_fail_reason: 4; + uint32_t rx_abort_reason: 5; + uint32_t reserved9: 7; + uint32_t rx_state: 3; + uint32_t reserved19: 1; + uint32_t preamble_match: 1; + uint32_t sfd_match: 1; + uint32_t reserved22: 10; + }; + uint32_t val; + } rx_status; // 0x80 + + union { + struct { + uint32_t tx_state: 4; + uint32_t tx_abort_reason: 5; + uint32_t reserved9: 7; + uint32_t tx_security_error: 4; + uint32_t reserved20: 12; + }; + uint32_t val; + } tx_status; //0x84 + + union { + struct { + uint32_t txrx_status: 4; + uint32_t reserved4: 4; + uint32_t tx_proc: 1; + uint32_t rx_proc: 1; + uint32_t ed_proc: 1; + uint32_t ed_trig_tx_proc: 1; + uint32_t reserved12: 4; + uint32_t rf_ctrl_state: 4; + uint32_t reserved20: 12; + }; + uint32_t val; + } txrx_status; //0x88 + + uint32_t tx_sec_schedule_state; //0x8c + + union { + struct { + uint32_t pkt_gck: 1; + uint32_t ctrl_gck: 1; + uint32_t reserved2: 30; + }; + uint32_t val; + } core_gck_cfg; //0x90 + + uint32_t reserved_94; //0x94 + uint32_t reserved_98; //0x98 + uint32_t reserved_9c; //0x9c + uint32_t reserved_a0; //0xa0 + + uint32_t rx_length; //0xa4 + + uint32_t timer0_threshold; //0xa8 + uint32_t timer0_value; //0xac + uint32_t timer1_threshold; //0xb0 + uint32_t timer1_value; //0xb4 + uint32_t clk_counter_threshold; //0xb8 + uint32_t clk_counter_value; //0xbc + + union { + struct { + uint32_t ifs_counter: 10; + uint32_t reserved10: 6; + uint32_t ifs_counter_en: 1; + uint32_t reserved17: 15; + }; + uint32_t val; + } ifs_counter_cfg; //0xc0 + + union { + struct { + uint32_t sfd_wait_symbol_num: 4; + uint32_t reserved4: 28; + }; + uint32_t val; + } sfd_wait; //0xc4 + + union { + struct { + uint32_t tx_path_delay: 6; + uint32_t reserved6: 10; + uint32_t rx_path_delay: 6; + uint32_t reserved624: 10; + }; + uint32_t val; + } txrx_path_delay; //0xc8 + + uint32_t bb_clk; //0xcc + uint32_t dma_tx_addr; //0xd0 + + union { + struct { + uint32_t txdma_water_level: 3; + uint32_t reserved3: 1; + uint32_t txdma_fill_entry: 3; + uint32_t reserved7: 9; + uint32_t txdma_ctrl_state: 5; + uint32_t reserved21: 3; + uint32_t txdma_fetch_byte_cnt: 7; + uint32_t reserved31: 1; + }; + uint32_t val; + } dma_tx_cfg; //0xd4 + + uint32_t dma_tx_err; //0xd8 + + uint32_t reserved_dc; //0xdc + + uint32_t dma_rx_addr; //0xe0 + + union { + struct { + uint32_t rxdma_water_level: 3; + uint32_t reserved3: 13; + uint32_t rxdma_ctrl_state: 5; + uint32_t reserved21: 3; + uint32_t rxdma_append_lqi: 1; + uint32_t rxdma_append_freq_offset: 1; + uint32_t reserved26: 6; + }; + uint32_t val; + } dma_rx_cfg; //0xe4 + + uint32_t dma_rx_err; //0xe8 + + uint32_t reserved_ec; //x0ec + + uint32_t dma_gck; //0xf0 + uint32_t dma_dummy_data; //0xf4 + uint32_t reserved_f8; //0xf8 + uint32_t reserved_fc; //0xfc + + union { + struct { + uint32_t delay: 10; + uint32_t reserved10: 22; + }; + uint32_t val; + } pa_on_delay; //0x100 + + union { + struct { + uint32_t delay: 10; + uint32_t reserved10: 22; + }; + uint32_t val; + } tx_on_delay; //0x104 + + union { + struct { + uint32_t delay: 6; + uint32_t reserved6: 26; + }; + uint32_t val; + } txen_stop_delay; //0x108 + + union { + struct { + uint32_t delay: 6; + uint32_t reserved6: 26; + }; + uint32_t val; + } tx_off_delay; //0x10c + + union { + struct { + uint32_t delay: 11; + uint32_t reserved11: 21; + }; + uint32_t val; + } rx_on_delay; //0x110 + + union { + struct { + uint32_t delay: 10; + uint32_t reserved10: 22; + }; + uint32_t val; + } txrx_switch_delay; //0x114 + + uint32_t cont_rx_delay; //0x118 + + union { + struct { + uint32_t dcdc_pre_up_delay: 8; + uint32_t dcdc_down_delay: 8; + uint32_t dcdc_ctrl_en: 1; + uint32_t reserved17: 14; + uint32_t tx_dcdc_up: 1; + }; + uint32_t val; + } dcdc_ctrl; //0x11c + + union { + struct { + uint32_t debug_sel: 3; + uint32_t reserved3: 5; + uint32_t trig_st_sel: 4; + uint32_t ser_debug_sel: 4; + uint32_t trig_st_match_val: 5; + uint32_t reserved21: 3; + uint32_t trig_pulse_sel: 3; + uint32_t reserved27: 3; + uint32_t trig_st_match_dump_en: 1; + uint32_t trig_pulse_dump_en: 1; + }; + uint32_t val; + } debug_ctrl; //0x120 + + uint32_t tx_dma_err_sts_reg; //0x124 + union { + struct { + uint32_t tx_security_en: 1; + uint32_t reserved1: 7; + uint32_t security_offset: 7; + uint32_t reserved15: 17; + }; + uint32_t val; + } security_ctrl; //0x128 + + uint32_t security_addr0; //0x12c + uint32_t security_addr1; //0x130 + uint32_t security_key0; //0x134 + uint32_t security_key1; //0x138 + uint32_t security_key2; //0x13c + uint32_t security_key3; //0x140 + + uint32_t debug_sfd_timeout_cnt; //0x144 + uint32_t debug_crc_error_cnt; //0x148 + uint32_t debug_ed_abort_cnt; //0x14c + uint32_t debug_cca_fail_cnt; //0x150 + uint32_t debug_rx_filter_fail_cnt; //0x154 + uint32_t debug_no_rss_detect_cnt; //0x158 + uint32_t debug_rx_abort_coex_cnt; //0x15c + uint32_t debug_rx_restart_cnt; //0x160 + uint32_t debug_tx_ack_abort_coex_cnt; //0x164 + uint32_t debug_ed_scan_break_coex_cnt; //0x168 + uint32_t debug_rx_ack_abort_coex_cnt; //0x16c + uint32_t debug_rx_ack_timeout_cnt; //0x170 + uint32_t debug_tx_break_coex_cnt; //0x174 + uint32_t debug_tx_security_error_cnt; //0x178 + uint32_t debug_cca_busy_cnt; //0x17c + + union { + struct { + uint32_t debug_ed_scan_break_coex_cnt: 1; + uint32_t debug_cca_busy_cnt: 1; + uint32_t debug_cca_fail_cnt: 1; + uint32_t debug_ed_abort_cnt: 1; + uint32_t debug_tx_security_error_cnt: 1; + uint32_t debug_tx_break_coex_cnt: 1; + uint32_t debug_tx_ack_abort_coex_cnt: 1; + uint32_t debug_rx_ack_timeout_cnt: 1; + uint32_t debug_rx_restart_cnt: 1; + uint32_t debug_rx_ack_abort_coex_cnt: 1; + uint32_t debug_rx_abort_coex_cnt: 1; + uint32_t debug_no_rss_detect_cnt: 1; + uint32_t debug_rx_filter_fail_cnt: 1; + uint32_t debug_crc_error_cnt: 1; + uint32_t debug_sfd_timeout_cnt: 1; + uint32_t reserved15: 17; + }; + uint32_t val; + } debug_cnt_clr; //0x180 + union { + struct { + uint32_t debug_field0_sel: 8; + uint32_t debug_field1_sel: 8; + uint32_t debug_field2_sel: 8; + uint32_t debug_field3_sel: 8; + }; + uint32_t val; + } debug_sel_cfg0; //0x184 + union { + struct { + uint32_t debug_field4_sel: 8; + uint32_t debug_field5_sel: 8; + uint32_t debug_field6_sel: 8; + uint32_t debug_field7_sel: 8; + }; + uint32_t val; + } debug_sel_cfg1; //0x188 + + uint32_t i154_version; //0x18c + +} esp_ieee802154_t; + +extern esp_ieee802154_t IEEE802154; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/include/soc/ieee802154_periph.h b/components/soc/include/soc/ieee802154_periph.h new file mode 100644 index 0000000000..5c414e91f6 --- /dev/null +++ b/components/soc/include/soc/ieee802154_periph.h @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc_caps.h" +#include "soc/periph_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + const periph_module_t module; // peripheral module + const int irq_id; // interrupt source ID +} ieee802154_conn_t; + +extern const ieee802154_conn_t ieee802154_periph; + +#ifdef __cplusplus +} +#endif