mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-27 23:41:18 +01:00
cpu/esp32: add IEEE802.15.4 HAL driver
This commit is contained in:
parent
9994782a8e
commit
3432fa8357
@ -28,6 +28,10 @@ ifneq (, $(filter esp_freertos, $(USEMODULE)))
|
||||
DIRS += freertos
|
||||
endif
|
||||
|
||||
ifneq (, $(filter esp_ieee802154, $(USEMODULE)))
|
||||
DIRS += esp-ieee802154
|
||||
endif
|
||||
|
||||
ifneq (, $(filter esp_lcd, $(USEMODULE)))
|
||||
DIRS += esp-lcd
|
||||
endif
|
||||
|
||||
@ -33,6 +33,19 @@ ifneq (,$(filter esp_ble,$(USEMODULE)))
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter esp_ieee802154,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += esp_ieee802154
|
||||
USEMODULE += esp_idf_ieee802154
|
||||
USEMODULE += esp_idf_phy
|
||||
USEMODULE += iolist
|
||||
ifneq (,$(filter netdev,$(USEMODULE)))
|
||||
USEMODULE += netdev_ieee802154_submac
|
||||
endif
|
||||
ifeq (esp32h2,$(CPU_FAM))
|
||||
USEPKG += esp32_sdk_lib_phy
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter esp_eth,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_eth
|
||||
USEMODULE += esp_idf_eth
|
||||
|
||||
@ -68,6 +68,10 @@ ifneq (,$(filter esp32 esp32s3,$(CPU_FAM)))
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq (esp32h2,$(CPU_FAM))
|
||||
FEATURES_PROVIDED += esp_ieee802154
|
||||
endif
|
||||
|
||||
ifneq (,$(filter esp32-wrover% esp32s2%r2 esp32s3%r2 esp32s3%r8 esp32s3%r8v,$(CPU_MODEL)))
|
||||
FEATURES_PROVIDED += esp_spi_ram
|
||||
ifneq (,$(filter esp32s3%r8 esp32s3%r8v,$(CPU_MODEL)))
|
||||
|
||||
@ -243,6 +243,12 @@ ifneq (,$(filter esp_eth,$(USEMODULE)))
|
||||
INCLUDES += -I$(ESP32_SDK_DIR)/components/esp_wifi/include
|
||||
endif
|
||||
|
||||
ifneq (,$(filter esp_ieee802154,$(USEMODULE)))
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/esp-ieee802154
|
||||
INCLUDES += -I$(ESP32_SDK_DIR)/components/ieee802154/include
|
||||
INCLUDES += -I$(ESP32_SDK_DIR)/components/esp_coex/include
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_sdmmc,$(USEMODULE)))
|
||||
INCLUDES += -I$(ESP32_SDK_DIR)/components/esp_driver_sdmmc/include
|
||||
INCLUDES += -I$(ESP32_SDK_DIR)/components/sdmmc/include
|
||||
@ -405,6 +411,15 @@ ifneq (,$(filter esp_ble,$(USEMODULE)))
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter esp_ieee802154,$(USEMODULE)))
|
||||
ifeq (esp32h2,$(CPU_FAM))
|
||||
LINKFLAGS += -L$(ESP32_SDK_LIB_PHY_DIR)/$(CPU_FAM)
|
||||
LINKFLAGS += -L$(ESP32_SDK_LIB_BT_DIR)
|
||||
ARCHIVES += -lbtbb
|
||||
ARCHIVES += -lphy
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter cpp,$(USEMODULE)))
|
||||
ARCHIVES += -lstdc++
|
||||
endif
|
||||
|
||||
3
cpu/esp32/esp-ieee802154/Makefile
Normal file
3
cpu/esp32/esp-ieee802154/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = esp_ieee802154
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
470
cpu/esp32/esp-ieee802154/esp_ieee802154_hal.c
Normal file
470
cpu/esp32/esp-ieee802154/esp_ieee802154_hal.c
Normal file
@ -0,0 +1,470 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
#include "esp_ieee802154.h"
|
||||
|
||||
#include "esp_ieee802154_hal.h"
|
||||
#include "iolist.h"
|
||||
#include "log.h"
|
||||
#include "net/ieee802154/radio.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
/* ACK frame timeout in microseconds, should be a multiple of 16 */
|
||||
#define ESP_IEEE802154_ACK_TIMEOUT_US (3456)
|
||||
|
||||
_Static_assert((3456 % 16 == 0), "ACK frame timeout should be a multiple of 16");
|
||||
|
||||
/* Although the device driver supports IEEE802154_CAP_IRQ_TX_START,
|
||||
* IEEE802154_CAP_IRQ_RX_START and IEEE802154_CAP_IRQ_CCA_DONE, we are not
|
||||
* using it for now to avoid unnecessary performance degradation as it is
|
||||
* not used by any link layer driver */
|
||||
#define _USE_RX_START 0
|
||||
#define _USE_TX_START 0
|
||||
#define _USE_CCA_DONE 0
|
||||
|
||||
#define _USE_SET_RX 1
|
||||
#define _USE_SET_IDLE 1
|
||||
|
||||
static const ieee802154_radio_ops_t esp_ieee802154_driver;
|
||||
static ieee802154_dev_t *esp_ieee802154_dev;
|
||||
|
||||
static uint8_t _tx_frame[IEEE802154_FRAME_LEN_MAX + 1]; /* additional byte 0 is used for length */
|
||||
static uint8_t *_rx_frame;
|
||||
static const uint8_t *_ack_frame;
|
||||
|
||||
static esp_ieee802154_frame_info_t *_rx_frame_info;
|
||||
static esp_ieee802154_frame_info_t *_ack_frame_info;
|
||||
|
||||
static bool _channel_clear;
|
||||
|
||||
static esp_ieee802154_tx_error_t _tx_error; /* error on last transmit */
|
||||
|
||||
static int _write(ieee802154_dev_t *dev, const iolist_t *psdu)
|
||||
{
|
||||
(void)dev;
|
||||
|
||||
DEBUG("[esp_ieee802154] %s\n", __func__);
|
||||
|
||||
assert(psdu);
|
||||
|
||||
/* copy packet data into the _tx_frame buffer */
|
||||
uint8_t *dst = &_tx_frame[1]; /* first byte is frame length */
|
||||
|
||||
for (; psdu; psdu = psdu->iol_next) {
|
||||
if (psdu->iol_len) {
|
||||
assert(((dst - &_tx_frame[1]) +
|
||||
psdu->iol_len + IEEE802154_FCS_LEN) < ARRAY_SIZE(_tx_frame));
|
||||
memcpy(dst, psdu->iol_base, psdu->iol_len);
|
||||
dst += psdu->iol_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* length of the package. */
|
||||
_tx_frame[0] = (dst - &_tx_frame[1]) + IEEE802154_FCS_LEN;
|
||||
|
||||
DEBUG("[esp_ieee802154] %s: put %d bytes to _tx_frame\n", __func__, _tx_frame[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _len(ieee802154_dev_t *dev)
|
||||
{
|
||||
(void)dev;
|
||||
DEBUG("[esp_ieee802154] %s\n", __func__);
|
||||
return _rx_frame[0] - IEEE802154_FCS_LEN;
|
||||
}
|
||||
|
||||
static int _read(ieee802154_dev_t *dev, void *buf, size_t size, ieee802154_rx_info_t *info)
|
||||
{
|
||||
(void)dev;
|
||||
|
||||
DEBUG("[esp_ieee802154] %s: buf=%p size=%u info=%p\n",
|
||||
__func__, buf, size, info);
|
||||
|
||||
unsigned len = _rx_frame[0] - IEEE802154_FCS_LEN;
|
||||
int res = 0;
|
||||
|
||||
if (size < len) {
|
||||
DEBUG("[esp_ieee802154] %s: buffer to small (%u < %u)\n",
|
||||
__func__, size, len);
|
||||
res = -ENOBUFS;
|
||||
}
|
||||
else if (buf) {
|
||||
DEBUG("[esp_ieee802154] %s: read packet of length %d\n", __func__, len);
|
||||
if (info) {
|
||||
info->rssi = ieee802154_dbm_to_rssi(_rx_frame[len]);
|
||||
info->lqi = _rx_frame[len+1];
|
||||
}
|
||||
memcpy(buf, &_rx_frame[1], len);
|
||||
res = len;
|
||||
}
|
||||
|
||||
esp_ieee802154_receive_handle_done(_rx_frame);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _off(ieee802154_dev_t *dev)
|
||||
{
|
||||
(void)dev;
|
||||
DEBUG("[esp_ieee802154] %s\n", __func__);
|
||||
esp_ieee802154_disable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _request_on(ieee802154_dev_t *dev)
|
||||
{
|
||||
(void)dev;
|
||||
DEBUG("[esp_ieee802154] %s\n", __func__);
|
||||
esp_ieee802154_enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _confirm_on(ieee802154_dev_t *dev)
|
||||
{
|
||||
(void)dev;
|
||||
DEBUG("[esp_ieee802154] %s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _request_op(ieee802154_dev_t *dev, ieee802154_hal_op_t op, void *ctx)
|
||||
{
|
||||
(void)dev;
|
||||
(void)ctx;
|
||||
|
||||
switch (op) {
|
||||
case IEEE802154_HAL_OP_TRANSMIT:
|
||||
DEBUG("[esp_ieee802154] %s: IEEE802154_HAL_OP_TRANSMIT\n", __func__);
|
||||
_tx_error = ESP_IEEE802154_TX_ERR_NONE;
|
||||
_ack_frame = NULL;
|
||||
_ack_frame_info = NULL;
|
||||
return esp_ieee802154_transmit(_tx_frame, true) ? -EIO : 0;
|
||||
case IEEE802154_HAL_OP_SET_RX:
|
||||
DEBUG("[esp_ieee802154] %s: IEEE802154_HAL_OP_SET_RX\n", __func__);
|
||||
return (IS_ACTIVE(_USE_SET_RX) && esp_ieee802154_receive()) ? -EIO : 0;
|
||||
case IEEE802154_HAL_OP_SET_IDLE:
|
||||
/* TODO: ctx = (bool *force) */
|
||||
DEBUG("[esp_ieee802154] %s: IEEE802154_HAL_OP_SET_IDLE\n", __func__);
|
||||
return (IS_ACTIVE(_USE_SET_IDLE) && esp_ieee802154_sleep()) ? -EIO : 0;
|
||||
return 0;
|
||||
case IEEE802154_HAL_OP_CCA:
|
||||
extern esp_err_t esp_ieee802154_cca(void);
|
||||
DEBUG("[esp_ieee802154] %s: IEEE802154_HAL_OP_CCA\n", __func__);
|
||||
return esp_ieee802154_cca();
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int _confirm_op(ieee802154_dev_t *dev, ieee802154_hal_op_t op, void *ctx)
|
||||
{
|
||||
(void)dev;
|
||||
|
||||
esp_ieee802154_state_t state = esp_ieee802154_get_state();
|
||||
|
||||
switch (op) {
|
||||
case IEEE802154_HAL_OP_TRANSMIT:
|
||||
DEBUG("[esp_ieee802154] %s: IEEE802154_HAL_OP_TRANSMIT\n", __func__);
|
||||
|
||||
if (ctx) {
|
||||
ieee802154_tx_info_t *info = ctx;
|
||||
|
||||
switch (_tx_error) {
|
||||
case ESP_IEEE802154_TX_ERR_NONE:
|
||||
info->status = TX_STATUS_SUCCESS;
|
||||
if (_ack_frame_info && _ack_frame_info->pending) {
|
||||
info->status = TX_STATUS_FRAME_PENDING;
|
||||
}
|
||||
break;
|
||||
case ESP_IEEE802154_TX_ERR_CCA_BUSY:
|
||||
info->status = TX_STATUS_MEDIUM_BUSY;
|
||||
break;
|
||||
case ESP_IEEE802154_TX_ERR_NO_ACK:
|
||||
info->status = TX_STATUS_NO_ACK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
esp_ieee802154_receive_handle_done(_ack_frame);
|
||||
return 0;
|
||||
case IEEE802154_HAL_OP_SET_RX:
|
||||
DEBUG("[esp_ieee802154] %s: IEEE802154_HAL_OP_SET_RX\n", __func__);
|
||||
return (!IS_ACTIVE(_USE_SET_RX) ||
|
||||
(state == ESP_IEEE802154_RADIO_RECEIVE)) ? 0 : -EAGAIN;
|
||||
case IEEE802154_HAL_OP_SET_IDLE:
|
||||
DEBUG("[esp_ieee802154] %s: IEEE802154_HAL_OP_SET_IDLE\n", __func__);
|
||||
return (!IS_ACTIVE(_USE_SET_IDLE) ||
|
||||
((state == ESP_IEEE802154_RADIO_IDLE) ||
|
||||
(state == ESP_IEEE802154_RADIO_SLEEP))) ? 0 : -EAGAIN;
|
||||
case IEEE802154_HAL_OP_CCA:
|
||||
DEBUG("[esp_ieee802154] %s: IEEE802154_HAL_OP_CCA\n", __func__);
|
||||
assert(ctx);
|
||||
*((bool *)ctx) = _channel_clear;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int _set_cca_threshold(ieee802154_dev_t *dev, int8_t threshold)
|
||||
{
|
||||
(void)dev;
|
||||
DEBUG("[esp_ieee802154] %s: threshold %i\n", __func__, threshold);
|
||||
return esp_ieee802154_set_cca_threshold(threshold) ? -EIO : 0;
|
||||
}
|
||||
|
||||
static int _set_cca_mode(ieee802154_dev_t *dev, ieee802154_cca_mode_t mode)
|
||||
{
|
||||
(void)dev;
|
||||
|
||||
switch (mode) {
|
||||
case IEEE802154_CCA_MODE_ED_THRESHOLD:
|
||||
DEBUG("[esp_ieee802154] %s: set IEEE802154_CCA_MODE_ED_THRESHOLD\n", __func__);
|
||||
return esp_ieee802154_set_cca_mode(ESP_IEEE802154_CCA_MODE_ED) ? -EIO : 0;
|
||||
case IEEE802154_CCA_MODE_CARRIER_SENSING:
|
||||
DEBUG("[esp_ieee802154] %s: set IEEE802154_CCA_MODE_CARRIER_SENSING\n", __func__);
|
||||
return esp_ieee802154_set_cca_mode(ESP_IEEE802154_CCA_MODE_CARRIER) ? -EIO : 0;
|
||||
case IEEE802154_CCA_MODE_ED_THRESH_AND_CS:
|
||||
DEBUG("[esp_ieee802154] %s: set IEEE802154_CCA_MODE_ED_THRESH_AND_CS\n", __func__);
|
||||
return esp_ieee802154_set_cca_mode(ESP_IEEE802154_CCA_MODE_CARRIER_AND_ED) ? -EIO : 0;
|
||||
case IEEE802154_CCA_MODE_ED_THRESH_OR_CS:
|
||||
DEBUG("[esp_ieee802154] %s: IEEE802154_CCA_MODE_ED_THRESH_OR_CS\n", __func__);
|
||||
return esp_ieee802154_set_cca_mode(ESP_IEEE802154_CCA_MODE_CARRIER_OR_ED) ? -EIO : 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int _config_phy(ieee802154_dev_t *dev, const ieee802154_phy_conf_t *conf)
|
||||
{
|
||||
(void)dev;
|
||||
|
||||
assert(conf);
|
||||
|
||||
DEBUG("[esp_ieee802154] %s\n", __func__);
|
||||
|
||||
if (esp_ieee802154_set_txpower(conf->pow) ||
|
||||
esp_ieee802154_set_channel(conf->channel)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _set_frame_retrans(ieee802154_dev_t *dev, uint8_t retrans)
|
||||
{
|
||||
(void)dev;
|
||||
DEBUG("[esp_ieee802154] %s\n", __func__);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int _set_csma_params(ieee802154_dev_t *dev, const ieee802154_csma_be_t *bd,
|
||||
int8_t retries)
|
||||
{
|
||||
(void)dev;
|
||||
DEBUG("[esp_ieee802154] %s\n", __func__);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int _set_frame_filter_mode(ieee802154_dev_t *dev, ieee802154_filter_mode_t mode)
|
||||
{
|
||||
(void)dev;
|
||||
DEBUG("[esp_ieee802154] %s\n", __func__);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int _config_addr_filter(ieee802154_dev_t *dev, ieee802154_af_cmd_t cmd, const void *value)
|
||||
{
|
||||
(void)dev;
|
||||
|
||||
assert(value);
|
||||
|
||||
const uint8_t *addr = value;
|
||||
|
||||
switch (cmd) {
|
||||
case IEEE802154_AF_SHORT_ADDR:
|
||||
DEBUG("[esp_ieee802154] %s: set IEEE802154_AF_SHORT_ADDR %02x:%02x\n",
|
||||
__func__, addr[0], addr[1]);
|
||||
return esp_ieee802154_set_short_address(*((const uint16_t *)value)) ? -EIO : 0;
|
||||
case IEEE802154_AF_EXT_ADDR:
|
||||
DEBUG("[esp_ieee802154] %s: set IEEE802154_AF_EXT_ADDR "
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", __func__,
|
||||
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]);
|
||||
return esp_ieee802154_set_extended_address(addr) ? -EIO : 0;
|
||||
case IEEE802154_AF_PANID:
|
||||
DEBUG("[esp_ieee802154] %s: set IEEE802154_AF_PANID %02x:%02x\n",
|
||||
__func__, addr[1], addr[0]);
|
||||
return esp_ieee802154_set_panid(*((const uint16_t *)value)) ? -EIO : 0;
|
||||
case IEEE802154_AF_PAN_COORD:
|
||||
DEBUG("[esp_ieee802154] %s: set IEEE802154_AF_PAN_COORD not supported\n", __func__);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int _config_src_addr_match(ieee802154_dev_t *dev, ieee802154_src_match_t cmd,
|
||||
const void *value)
|
||||
{
|
||||
(void)dev;
|
||||
|
||||
bool enable = *((bool*)value);
|
||||
|
||||
switch (cmd) {
|
||||
case IEEE802154_SRC_MATCH_EN:
|
||||
DEBUG("[esp_ieee802154] %s: IEEE802154_SRC_MATCH_EN %d\n", __func__, enable);
|
||||
return esp_ieee802154_set_pending_mode(enable
|
||||
? ESP_IEEE802154_AUTO_PENDING_ENABLE
|
||||
: ESP_IEEE802154_AUTO_PENDING_DISABLE) ? -EIO : 0;
|
||||
case IEEE802154_SRC_MATCH_SHORT_ADD:
|
||||
DEBUG("[esp_ieee802154] %s: set IEEE802154_SRC_MATCH_SHORT_ADD\n", __func__);
|
||||
return esp_ieee802154_add_pending_addr(value, true) ? -ENOMEM : 0;
|
||||
case IEEE802154_SRC_MATCH_SHORT_CLEAR:
|
||||
DEBUG("[esp_ieee802154] %s: set IEEE802154_SRC_MATCH_SHORT_CLEAR\n", __func__);
|
||||
return esp_ieee802154_clear_pending_addr(value, true) ? -ENOENT : 0;
|
||||
case IEEE802154_SRC_MATCH_EXT_ADD:
|
||||
DEBUG("[esp_ieee802154] %s: set IEEE802154_SRC_MATCH_EXT_ADD\n", __func__);
|
||||
return esp_ieee802154_add_pending_addr(value, false) ? -ENOMEM : 0;
|
||||
case IEEE802154_SRC_MATCH_EXT_CLEAR:
|
||||
DEBUG("[esp_ieee802154] %s: set IEEE802154_SRC_MATCH_EXT_CLEAR\n", __func__);
|
||||
return esp_ieee802154_clear_pending_addr(value, false) ? -ENOENT : 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* following functions are called back from ESP-IDF driver */
|
||||
|
||||
void esp_ieee802154_cca_done(bool channel_busy)
|
||||
{
|
||||
DEBUG("[esp_ieee802154] %s %d\n", __func__, channel_busy);
|
||||
_channel_clear = !channel_busy;
|
||||
|
||||
if (IS_ACTIVE(_USE_CCA_DONE)) {
|
||||
esp_ieee802154_dev->cb(esp_ieee802154_dev, IEEE802154_RADIO_CONFIRM_CCA);
|
||||
}
|
||||
}
|
||||
|
||||
void esp_ieee802154_receive_sfd_done(void)
|
||||
{
|
||||
DEBUG("[esp_ieee802154] %s\n", __func__);
|
||||
if (IS_ACTIVE(_USE_RX_START)) {
|
||||
esp_ieee802154_dev->cb(esp_ieee802154_dev, IEEE802154_RADIO_INDICATION_RX_START);
|
||||
}
|
||||
}
|
||||
|
||||
void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info)
|
||||
{
|
||||
assert(frame);
|
||||
assert(frame_info);
|
||||
|
||||
DEBUG("[esp_ieee802154] %s: frame=%p frame_info=%p\n",
|
||||
__func__, frame, frame_info);
|
||||
|
||||
_rx_frame = frame;
|
||||
_rx_frame_info = frame_info;
|
||||
|
||||
esp_ieee802154_dev->cb(esp_ieee802154_dev, IEEE802154_RADIO_INDICATION_RX_DONE);
|
||||
}
|
||||
|
||||
void esp_ieee802154_transmit_sfd_done(uint8_t *frame)
|
||||
{
|
||||
DEBUG("[esp_ieee802154] %s: frame=%p\n", __func__, frame);
|
||||
if (IS_ACTIVE(_USE_TX_START)) {
|
||||
esp_ieee802154_dev->cb(esp_ieee802154_dev, IEEE802154_RADIO_INDICATION_TX_START);
|
||||
}
|
||||
}
|
||||
|
||||
void esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack,
|
||||
esp_ieee802154_frame_info_t *ack_frame_info)
|
||||
{
|
||||
DEBUG("[esp_ieee802154] %s: frame=%p ack_frame=%p ack_frame_info=%p\n",
|
||||
__func__, frame, ack, ack_frame_info);
|
||||
|
||||
_ack_frame = ack;
|
||||
_ack_frame_info = ack_frame_info;
|
||||
|
||||
esp_ieee802154_dev->cb(esp_ieee802154_dev, IEEE802154_RADIO_CONFIRM_TX_DONE);
|
||||
}
|
||||
|
||||
void esp_ieee802154_transmit_failed(const uint8_t *frame, esp_ieee802154_tx_error_t error)
|
||||
{
|
||||
DEBUG("[esp_ieee802154] %s: frame=%p error=%u\n", __func__, frame, error);
|
||||
|
||||
_tx_error = error;
|
||||
|
||||
esp_ieee802154_dev->cb(esp_ieee802154_dev, IEEE802154_RADIO_CONFIRM_TX_DONE);
|
||||
}
|
||||
|
||||
void esp_ieee802154_energy_detect_done(int8_t power)
|
||||
{
|
||||
DEBUG("[esp_ieee802154] %s: power %i\n", __func__, power);
|
||||
}
|
||||
|
||||
void esp_ieee802154_setup(ieee802154_dev_t *dev)
|
||||
{
|
||||
assert(dev);
|
||||
|
||||
DEBUG("[esp_ieee802154] %s: dev=%p\n", __func__, dev);
|
||||
|
||||
dev->driver = &esp_ieee802154_driver;
|
||||
esp_ieee802154_dev = dev;
|
||||
}
|
||||
|
||||
int esp_ieee802154_init(void)
|
||||
{
|
||||
DEBUG("[esp_ieee802154] %s\n", __func__);
|
||||
|
||||
esp_ieee802154_enable();
|
||||
esp_ieee802154_reset_pending_table(true);
|
||||
esp_ieee802154_reset_pending_table(false);
|
||||
esp_ieee802154_set_rx_when_idle(true);
|
||||
esp_ieee802154_receive();
|
||||
esp_ieee802154_set_cca_mode(ESP_IEEE802154_CCA_MODE_ED);
|
||||
esp_ieee802154_set_ack_timeout(ESP_IEEE802154_ACK_TIMEOUT_US);
|
||||
esp_ieee802154_set_promiscuous(false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const ieee802154_radio_ops_t esp_ieee802154_driver = {
|
||||
.caps = IEEE802154_CAP_24_GHZ
|
||||
| IEEE802154_CAP_PHY_OQPSK
|
||||
| IEEE802154_CAP_AUTO_CSMA
|
||||
| IEEE802154_CAP_SRC_ADDR_MATCH
|
||||
#if _USE_CCA_DONE
|
||||
| IEEE802154_CAP_IRQ_CCA_DONE
|
||||
#endif
|
||||
#if _USE_RX_START
|
||||
| IEEE802154_CAP_IRQ_RX_START
|
||||
#endif
|
||||
#if _USE_TX_START
|
||||
| IEEE802154_CAP_IRQ_TX_START
|
||||
#endif
|
||||
| IEEE802154_CAP_IRQ_TX_DONE
|
||||
| IEEE802154_CAP_IRQ_ACK_TIMEOUT,
|
||||
.write = _write,
|
||||
.read = _read,
|
||||
.request_on = _request_on,
|
||||
.confirm_on = _confirm_on,
|
||||
.len = _len,
|
||||
.off = _off,
|
||||
.request_op = _request_op,
|
||||
.confirm_op = _confirm_op,
|
||||
.set_cca_threshold = _set_cca_threshold,
|
||||
.set_cca_mode = _set_cca_mode,
|
||||
.config_phy = _config_phy,
|
||||
.set_csma_params = _set_csma_params,
|
||||
.config_addr_filter = _config_addr_filter,
|
||||
.config_src_addr_match = _config_src_addr_match,
|
||||
.set_frame_filter_mode = _set_frame_filter_mode,
|
||||
.set_frame_retrans = _set_frame_retrans,
|
||||
};
|
||||
57
cpu/esp32/esp-ieee802154/esp_ieee802154_hal.h
Normal file
57
cpu/esp32/esp-ieee802154/esp_ieee802154_hal.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @defgroup cpu_esp32_esp_ieee802154 ESP32x IEEE 802.15.4 driver
|
||||
* @ingroup drivers_netdev
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ESP32x IEEE 802.15.4 driver
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "net/ieee802154/radio.h"
|
||||
|
||||
/**
|
||||
* @brief Setup ESP32x in order to be used with the IEEE 802.15.4 Radio HAL
|
||||
*
|
||||
* @param[in] dev pointer to the HAL descriptor associated to the device.
|
||||
*/
|
||||
void esp_ieee802154_setup(ieee802154_dev_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Initialize the ESP32x IEEE 802.15.4 module.
|
||||
*
|
||||
* The function
|
||||
* - initializes the ESP32x 802.15.4 subsystem,
|
||||
* - clears the source matching table for short and extended addresses,
|
||||
* - enables the radio in idle state,
|
||||
* - sets the CCA mode to energy detection only (IEEE802154_CCA_MODE_ED_THRESHOLD),
|
||||
* - sets the timeout for the ACK frame, and
|
||||
* - disables the promicuous mode.
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval negative errno on error
|
||||
*/
|
||||
int esp_ieee802154_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
@ -62,6 +62,7 @@ extern "C" {
|
||||
#define CPU_INUM_SDMMC 21 /**< Level interrupt with medium priority 2 */
|
||||
#define CPU_INUM_TIMER 22 /**< Edge interrupt with medium priority 2 */
|
||||
#define CPU_INUM_WDT 23 /**< Level interrupt with medium priority 3 */
|
||||
#define CPU_INUM_ZMAC 27 /**< Level interrupt with medium priority 3 */
|
||||
#define CPU_INUM_SOFTWARE 29 /**< Software interrupt with medium priority 3 */
|
||||
/** @} */
|
||||
|
||||
|
||||
@ -66,7 +66,14 @@ extern "C" {
|
||||
/**
|
||||
* @brief Length of the CPU_ID in octets
|
||||
*/
|
||||
#define CPUID_LEN (6U)
|
||||
#if defined(CPU_FAM_ESP32H2) && defined(CONFIG_IEEE802154_ENABLED)
|
||||
/* ESP32H2 has IEEE802.15.4 radio which has an EUI64 address. Function
|
||||
* esp_efuse_mac_get_default will return this 8 byte address if
|
||||
* CONFIG_IEEE802154_ENABLED */
|
||||
# define CPUID_LEN (8U)
|
||||
#else
|
||||
# define CPUID_LEN (6U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name GPIO configuration
|
||||
|
||||
@ -112,6 +112,18 @@
|
||||
# define CONFIG_SOC_PM_SUPPORT_BT_WAKEUP SOC_PM_SUPPORT_BT_WAKEUP
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ESP32-H2 IEEE 802.15.4 driver configuration (DO NOT CHANGE)
|
||||
*/
|
||||
#if MODULE_ESP_IEEE802154
|
||||
# define CONFIG_IEEE802154_ENABLED 1
|
||||
# define CONFIG_IEEE802154_CCA_ED 1
|
||||
# define CONFIG_IEEE802154_CCA_MODE 1
|
||||
# define CONFIG_IEEE802154_CCA_THRESHOLD -60
|
||||
# define CONFIG_IEEE802154_PENDING_TABLE_SIZE 20
|
||||
# define CONFIG_IEEE802154_RX_BUFFER_SIZE 20
|
||||
#endif
|
||||
|
||||
/**
|
||||
* SPI RAM configuration (DO NOT CHANGE)
|
||||
*/
|
||||
|
||||
@ -90,6 +90,9 @@ static const struct intr_handle_data_t _irq_data_table[] = {
|
||||
#if defined(SOC_EMAC_SUPPORTED)
|
||||
{ ETS_ETH_MAC_INTR_SOURCE, CPU_INUM_ETH, 1 },
|
||||
#endif
|
||||
#if SOC_IEEE802154_SUPPORTED
|
||||
{ ETS_ZB_MAC_INTR_SOURCE, CPU_INUM_ZMAC, 3},
|
||||
#endif
|
||||
#if defined(SOC_RMT_SUPPORTED)
|
||||
{ ETS_RMT_INTR_SOURCE, CPU_INUM_RMT, 1 },
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user