ieee802154: support driver opensrc

This commit is contained in:
zhangwenxu 2023-03-20 18:25:10 +08:00
parent 8be8a1cd22
commit c8c1cd1c55
32 changed files with 5827 additions and 72 deletions

View File

@ -0,0 +1,13 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "hal/ieee802154_common_ll.h"
#define IEEE802154_TXPOWER_VALUE_MAX 21
#define IEEE802154_TXPOWER_VALUE_MIN -24

View File

@ -0,0 +1,13 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "hal/ieee802154_common_ll.h"
#define IEEE802154_TXPOWER_VALUE_MAX 21
#define IEEE802154_TXPOWER_VALUE_MIN -24

View File

@ -0,0 +1,454 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#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

View File

@ -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 $<TARGET_FILE:${ieee802154_lib}>
$<TARGET_FILE:${esp_phy_lib}> libphy.a libbtbb.a $<TARGET_FILE:${esp_phy_lib}>)
else()
target_link_directories(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/lib/${idf_target}")
target_link_libraries(${COMPONENT_LIB} INTERFACE $<TARGET_FILE:${esp_phy_lib}> lib802154.a libphy.a libbtbb.a
$<TARGET_FILE:${esp_phy_lib}> $<TARGET_FILE:${esp_system_lib}>)
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
)

View File

@ -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

View File

@ -0,0 +1,164 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "hal/ieee802154_ll.h"
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_ieee802154_ack.h"
#include "esp_ieee802154_dev.h"
#include "esp_ieee802154_frame.h"
#include "esp_ieee802154_pib.h"
#include "esp_ieee802154_types.h"
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;
}

View File

@ -0,0 +1,770 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#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;
}

View File

@ -0,0 +1,418 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#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;
}

View File

@ -0,0 +1,220 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <string.h>
#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;
}

View File

@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#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;
}

View File

@ -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();
}

View File

@ -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));
}

View File

@ -0,0 +1,382 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <string.h>
#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;
}

View File

@ -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
}

View File

@ -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;
/**

View File

@ -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)

View File

@ -0,0 +1,75 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#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

View File

@ -0,0 +1,206 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#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

View File

@ -0,0 +1,199 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#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

View File

@ -0,0 +1,234 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#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

View File

@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#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

View File

@ -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

View File

@ -0,0 +1,92 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#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

View File

@ -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"
@ -188,13 +190,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;
@ -614,7 +614,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;
@ -626,6 +626,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);
@ -643,8 +644,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;
@ -653,6 +657,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)

View File

@ -95,6 +95,12 @@ if(CONFIG_SOC_TWAI_SUPPORTED)
list(APPEND srcs "${target}/twai_periph.c")
endif()
if(CONFIG_SOC_IEEE802154_SUPPORTED)
if(NOT target STREQUAL "esp32h4")
list(APPEND srcs "${target}/ieee802154_periph.c")
endif()
endif()
if(CONFIG_SOC_USB_OTG_SUPPORTED)
list(APPEND srcs "${target}/usb_periph.c"
"${target}/usb_otg_periph.c")

View File

@ -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,
};

View File

@ -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

View File

@ -0,0 +1,462 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#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

View File

@ -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,
};

View File

@ -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

View File

@ -0,0 +1,480 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#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

View File

@ -0,0 +1,26 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#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