Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion cpu/esp32/esp-ieee802154/esp_ieee802154_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "esp_ieee802154.h"

#include "esp_ieee802154_hal.h"
#include "esp_timer.h"
#include "iolist.h"
#include "log.h"
#include "net/ieee802154/radio.h"
Comment on lines +9 to 12

@gschorcht gschorcht Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include "esp_timer.h"
#include "iolist.h"
#include "log.h"
#include "net/ieee802154/radio.h"
#include "iolist.h"
#include "log.h"
#include "net/ieee802154/radio.h"

Expand All @@ -31,9 +32,9 @@

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;

Check warning on line 37 in cpu/esp32/esp-ieee802154/esp_ieee802154_hal.c

View workflow job for this annotation

GitHub Actions / static-tests

clang-format proposes the following patch

@@ -35,3 +34,3 @@ -static uint8_t _tx_frame[IEEE802154_FRAME_LEN_MAX + 1]; /* additional byte 0 is used for length */ +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;
Expand Down Expand Up @@ -109,6 +110,12 @@
return res;
}

static uint32_t _get_time(ieee802154_dev_t *dev)
{
(void)dev;
return (uint32_t)esp_timer_get_time();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return (uint32_t)esp_timer_get_time();
return ztimer::get_now(ZTIMER_MSEC);

From the very beginning, the goal was to keep the RIOT code as independent as possible from ESP-IDF in order to limit the amount of source code that needed to be compiled in from ESP-IDF. The dependencies between the ESP-IDF modules are very complex and more and more ESP-IDF source code must be compiled in very quickly, which makes the manual maintenance of the Makefiles in cpu/esp32/esp-idf very hard. For this reason, various basic functions have been implemented in RIOT, including a system time in milliseconds that can be retrieved using system_get_time.

Since we already use ztimer_msec modul, the RIOT function should be used.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've given it some more thought. If the intention was to use a timer that is independent of RIOT's ztimer, you should use system_get_time to be independent of ESP-IDF, even though the ESP-IDF IEEE 802.15.4 driver uses esp_timer_get_time internally.

Suggested change
return (uint32_t)esp_timer_get_time();
return (uint32_t)system_get_time();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's some useful insight I didn't have. The idea behind it was if the radio has a dedicated only for the radio it should be used instead of ztimer if this not the case for example at86rf233 don't have such a timer the functionality would be offloaded to the submac instead. Going through the esp code I notice that the transmit_at function uses esp_timer_get_time() and thought it would use the dedicated timer then. But didn't seems like it would

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I've thought about it some more 🤔 As you suggested 👍, we should use esp_timer_get_time instead of system_get_time here. So please ignore my change request.

The reason for this is that system_get_time uses a different timer than esp_timer_get_time. While system_get_time uses a real timer (TIMER_0 from TIMER_GROUP_0) for the system time, esp_timer_get_time uses a special system timer peripheral. On the ESP32, an additional counter (the LACT) from TIMER_GROUP_0 is used; all other ESP32x SoC variants have a dedicated SYSTIMER peripheral that is used for the system time.

Since the implementation of esp_ieee80215_transmit_at uses the ESP-IDF system time as its time base, we should also use this for our interface. The time returned by esp_time_get_time is likely to differ slightly from the time returned by system_get_time.

Since the ESP-IDF esp_timer is compiled in anyway in cpu/esp32/esp-idf/common, using the esp_timer_get_time function here doesn't increase the dependency on ESP-IDF.

Sorry for the confusion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This discussion inspires me to clean up the implementation of the system time in RIOT for the ESP32. Since we’re including the ESP-IDF module esp_timer anyway, we could implement the function system_get_time based on esp_timer_get_time.

The reason system_get_time hasn’t relied on esp_time_get_time until now is that, in earlier versions of ESP-IDF, it wasn’t necessary to include the esp_timer module. This requirement was added over time, but system_get_time wasn’t updated accordingly.

}

static int _off(ieee802154_dev_t *dev)
{
(void)dev;
Expand Down Expand Up @@ -145,6 +152,10 @@
_tx_error = ESP_IEEE802154_TX_ERR_NONE;
_ack_frame = NULL;
_ack_frame_info = NULL;
if (ctx) {
uint32_t target_us = *(const uint32_t *)ctx;
return esp_ieee802154_transmit_at(_tx_frame, _cca_send_on, target_us) ? -EIO : 0;
}
return esp_ieee802154_transmit(_tx_frame, _cca_send_on) ? -EIO : 0;
case IEEE802154_HAL_OP_SET_RX:
DEBUG("[esp_ieee802154] %s: IEEE802154_HAL_OP_SET_RX\n", __func__);
Expand Down Expand Up @@ -195,15 +206,15 @@
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:

Check warning on line 212 in cpu/esp32/esp-ieee802154/esp_ieee802154_hal.c

View workflow job for this annotation

GitHub Actions / static-tests

clang-format proposes the following patch

@@ -209,4 +206,3 @@ DEBUG("[esp_ieee802154] %s: IEEE802154_HAL_OP_SET_RX\n", __func__); - return (!IS_ACTIVE(_USE_SET_RX) || - (state == ESP_IEEE802154_RADIO_RECEIVE)) ? 0 : -EAGAIN; + 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:

Check warning on line 217 in cpu/esp32/esp-ieee802154/esp_ieee802154_hal.c

View workflow job for this annotation

GitHub Actions / static-tests

clang-format proposes the following patch

@@ -214,4 +210,5 @@ return (!IS_ACTIVE(_USE_SET_IDLE) || - ((state == ESP_IEEE802154_RADIO_IDLE) || - (state == ESP_IEEE802154_RADIO_SLEEP))) ? 0 : -EAGAIN; + ((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;
Expand Down Expand Up @@ -249,18 +260,18 @@
assert(conf);

DEBUG("[esp_ieee802154] %s\n", __func__);

if (esp_ieee802154_set_txpower(conf->pow) ||
esp_ieee802154_set_channel(conf->channel)) {
return -EIO;

Check warning on line 266 in cpu/esp32/esp-ieee802154/esp_ieee802154_hal.c

View workflow job for this annotation

GitHub Actions / static-tests

clang-format proposes the following patch

@@ -263,4 +260,3 @@ - if (esp_ieee802154_set_txpower(conf->pow) || - esp_ieee802154_set_channel(conf->channel)) { + if (esp_ieee802154_set_txpower(conf->pow) || esp_ieee802154_set_channel(conf->channel)) { return -EIO;
}

return 0;
}

static int _set_csma_params(ieee802154_dev_t *dev, const ieee802154_csma_be_t *bd,
int8_t retries)
{

Check warning on line 274 in cpu/esp32/esp-ieee802154/esp_ieee802154_hal.c

View workflow job for this annotation

GitHub Actions / static-tests

clang-format proposes the following patch

@@ -271,4 +267,3 @@ -static int _set_csma_params(ieee802154_dev_t *dev, const ieee802154_csma_be_t *bd, - int8_t retries) +static int _set_csma_params(ieee802154_dev_t *dev, const ieee802154_csma_be_t *bd, int8_t retries) {
(void)dev;
DEBUG("[esp_ieee802154] %s %p %d\n", __func__, bd, retries);
if (retries > 0) {
Expand Down Expand Up @@ -303,21 +314,21 @@

switch (cmd) {
case IEEE802154_AF_SHORT_ADDR:
const network_uint16_t *short_addr = value;
DEBUG("[esp_ieee802154] %s: set IEEE802154_AF_SHORT_ADDR %02x:%02x\n",
__func__, addr[0], addr[1]);
return esp_ieee802154_set_short_address(byteorder_ntohs(*short_addr)) ? -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]);
const eui64_t *ext_addr = value;

Check warning on line 325 in cpu/esp32/esp-ieee802154/esp_ieee802154_hal.c

View workflow job for this annotation

GitHub Actions / static-tests

clang-format proposes the following patch

@@ -317,9 +312,9 @@ const network_uint16_t *short_addr = value; - DEBUG("[esp_ieee802154] %s: set IEEE802154_AF_SHORT_ADDR %02x:%02x\n", - __func__, addr[0], addr[1]); + DEBUG("[esp_ieee802154] %s: set IEEE802154_AF_SHORT_ADDR %02x:%02x\n", __func__, addr[0], + addr[1]); return esp_ieee802154_set_short_address(byteorder_ntohs(*short_addr)) ? -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]); + 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]); const eui64_t *ext_addr = value;
uint64_t le_addr = byteorder_swapll(ext_addr->uint64.u64);
return esp_ieee802154_set_extended_address((const uint8_t *)&le_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;

Check warning on line 331 in cpu/esp32/esp-ieee802154/esp_ieee802154_hal.c

View workflow job for this annotation

GitHub Actions / static-tests

clang-format proposes the following patch

@@ -328,4 +323,4 @@ case IEEE802154_AF_PANID: - DEBUG("[esp_ieee802154] %s: set IEEE802154_AF_PANID %02x:%02x\n", - __func__, addr[1], addr[0]); + 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;
Expand All @@ -330,16 +341,16 @@
const void *value)
{
(void)dev;

bool enable = *((bool*)value);

Check warning on line 346 in cpu/esp32/esp-ieee802154/esp_ieee802154_hal.c

View workflow job for this annotation

GitHub Actions / static-tests

clang-format proposes the following patch

@@ -344,3 +339,3 @@ - bool enable = *((bool*)value); + 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:

Check warning on line 353 in cpu/esp32/esp-ieee802154/esp_ieee802154_hal.c

View workflow job for this annotation

GitHub Actions / static-tests

clang-format proposes the following patch

@@ -349,5 +344,6 @@ 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; + 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:
Expand Down Expand Up @@ -465,7 +476,8 @@
| IEEE802154_CAP_IRQ_TX_START
#endif
| IEEE802154_CAP_IRQ_TX_DONE
| IEEE802154_CAP_IRQ_ACK_TIMEOUT,
| IEEE802154_CAP_IRQ_ACK_TIMEOUT
| IEEE802154_CAP_TIMED_TX,
.write = _write,
.read = _read,
.request_on = _request_on,
Expand All @@ -480,5 +492,6 @@
.set_csma_params = _set_csma_params,
.config_addr_filter = _config_addr_filter,
.config_src_addr_match = _config_src_addr_match,
.get_time = _get_time,
.set_frame_filter_mode = _set_frame_filter_mode,
};
117 changes: 113 additions & 4 deletions cpu/nrf52/radio/nrf802154/nrf802154_radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "nrf_clock.h"

#include "net/ieee802154.h"
#include "irq.h"
#include "periph/timer.h"
#include "nrf802154.h"
#include "net/ieee802154/radio.h"

Expand All @@ -31,6 +33,9 @@
#define ED_RSSISCALE (4U) /**< RSSI scale for internal HW value */
#define ED_RSSIOFFS (-92) /**< RSSI offset for internal HW value */

/* The MAC timer provides the radio time in us */
#define TIMER_FREQ (1000000UL)

#define TX_POWER_MIN (-40) /* in dBm */
#define TX_POWER_MAX ((int)RADIO_TXPOWER_TXPOWER_Max) /* in dBm */

Expand All @@ -56,6 +61,44 @@
RADIO_SHORTS_CCABUSY_DISABLE_Msk | \
RADIO_SHORTS_TXREADY_START_Msk)

#define MAC_TIMER_CHAN_TX (0U) /**< MAC timer channel for timed transmission */

/**
* @brief PPI channel connecting the MAC timer compare event of
* @ref MAC_TIMER_CHAN_TX to the TX task of the radio.
*/
#ifndef NRF802154_PPI_CH_TX
# define NRF802154_PPI_CH_TX (19U)
#endif

/**
* @brief Minimum lead time in us for a timed transmission
*
* A timed transmission closer than this to the current radio time starts
* immediately, as the timer compare event might be missed otherwise.
*/
#ifndef NRF802154_TIMED_TX_MIN_LEAD_US
# define NRF802154_TIMED_TX_MIN_LEAD_US (2U)
#endif

/**
* @brief Time in us from TXEN to the start of the transmission
*
* The radio uses the fast ramp-up mode.
*/
#ifndef NRF802154_FAST_RAMPUP_US
# define NRF802154_FAST_RAMPUP_US (40U)
#endif

/**
* @brief Time in us from RXEN to the start of the transmission with CCA
*
* Fast RX ramp-up + CCA (8 symbols x 16us per Symbol) + fast TX ramp-up.
*/
#ifndef NRF802154_CCA_TX_RAMPUP_US
# define NRF802154_CCA_TX_RAMPUP_US ((2 * NRF802154_FAST_RAMPUP_US) + 128U)
#endif

static uint8_t rxbuf[IEEE802154_FRAME_LEN_MAX + 3]; /* len PHR + PSDU + LQI */
static uint8_t txbuf[IEEE802154_FRAME_LEN_MAX + 3]; /* len PHR + PSDU + LQI */

Expand Down Expand Up @@ -86,6 +129,33 @@ static struct {
static const ieee802154_radio_ops_t nrf802154_ops;
static ieee802154_dev_t *nrf802154_hal_dev;

static void _cancel_timed_tx(void)
{
timer_clear(NRF802154_TIMER, MAC_TIMER_CHAN_TX);
NRF_PPI->CHENCLR = (1UL << NRF802154_PPI_CH_TX);
}

static void _start_tx_at(uint32_t time_us, volatile uint32_t *start_task)
{
/* no interruption between reading the time and arming the timer, so
* the compare event can't be missed */
unsigned irq_state = irq_disable();

if ((int32_t)(time_us - timer_read(NRF802154_TIMER)) < (int32_t)NRF802154_TIMED_TX_MIN_LEAD_US){
/* already passed or too close, start immediately */
*start_task = 1;
}
else {
NRF_PPI->CH[NRF802154_PPI_CH_TX].EEP =
(uint32_t)&timer_config[NRF802154_TIMER].dev->EVENTS_COMPARE[MAC_TIMER_CHAN_TX];
NRF_PPI->CH[NRF802154_PPI_CH_TX].TEP = (uint32_t)start_task;
NRF_PPI->CHENSET = (1UL << NRF802154_PPI_CH_TX);
timer_set_absolute(NRF802154_TIMER, MAC_TIMER_CHAN_TX, time_us);
}

irq_restore(irq_state);
}

static void _power_on(void)
{
if (NRF_RADIO->POWER == 0) {
Expand Down Expand Up @@ -200,14 +270,26 @@ static int _request_op(ieee802154_dev_t *dev, ieee802154_hal_op_t op, void *ctx)

switch (op) {
case IEEE802154_HAL_OP_TRANSMIT:
volatile uint32_t *start_task;

if (cfg.cca_send) {
NRF_RADIO->SHORTS = CCA_SHORTS;
NRF_RADIO->TASKS_RXEN = 1;
start_task = &NRF_RADIO->TASKS_RXEN;
}
else {
NRF_RADIO->SHORTS = DEFAULT_SHORTS;
NRF_RADIO->TASKS_TXEN = 1;
start_task = &NRF_RADIO->TASKS_TXEN;
}

if (ctx) {
uint32_t rampup_us = cfg.cca_send ?
NRF802154_CCA_TX_RAMPUP_US : NRF802154_FAST_RAMPUP_US;
_start_tx_at(*(const uint32_t *)ctx - rampup_us, start_task);
}
else {
*start_task = 1;
}

state = STATE_TX;
break;
case IEEE802154_HAL_OP_SET_RX:
Expand All @@ -226,6 +308,8 @@ static int _request_op(ieee802154_dev_t *dev, ieee802154_hal_op_t op, void *ctx)
if (!force && _state != STATE_IDLE && _state != STATE_RX) {
goto end;
}
/* a forced SET_IDLE also aborts a pending timed transmission */
_cancel_timed_tx();
_disable_blocking();
NRF_RADIO->SHORTS = DEFAULT_SHORTS;
NRF_RADIO->PACKETPTR = (uint32_t) txbuf;
Expand Down Expand Up @@ -394,6 +478,21 @@ static void _set_txpower(int16_t txpower)
}
}

static void _timer_cb(void *arg, int chan)
{
(void)arg;
if (chan == MAC_TIMER_CHAN_TX) {
/* TXEN/RXEN was already triggered via PPI, just clear */
NRF_PPI->CHENCLR = (1UL << NRF802154_PPI_CH_TX);
}
}

static uint32_t _get_time(ieee802154_dev_t *dev)
{
(void)dev;
return timer_read(NRF802154_TIMER);
}

/**
* @brief Set radio into DISABLED state
*/
Expand All @@ -404,6 +503,11 @@ int nrf802154_init(void)
rxbuf[0] = 0;
txbuf[0] = 0;

int result = timer_init(NRF802154_TIMER, TIMER_FREQ, _timer_cb, NULL);
assert(result >= 0);
(void)result;
timer_stop(NRF802154_TIMER);

/* power off peripheral (but do not release the HFXO as we never requested
* it so far) */
NRF_RADIO->POWER = 0;
Expand Down Expand Up @@ -511,6 +615,7 @@ static int _request_on(ieee802154_dev_t *dev)
_state = STATE_IDLE;
DEBUG("[nrf802154]: Request to turn on\n");
_power_on();
timer_start(NRF802154_TIMER);
/* make sure the radio is disabled/stopped */
_disable();
/* we configure it to run in IEEE802.15.4 mode */
Expand All @@ -531,7 +636,7 @@ static int _request_on(ieee802154_dev_t *dev)
NRF_RADIO->CRCPOLY = 0x011021;
NRF_RADIO->CRCINIT = 0;

/* Disable the hardware IFS handling */
/* Enable the fast ramp-up mode */
NRF_RADIO->MODECNF0 |= RADIO_MODECNF0_RU_Msk;

NRF_RADIO->SHORTS = DEFAULT_SHORTS;
Expand Down Expand Up @@ -575,7 +680,9 @@ static int _off(ieee802154_dev_t *dev)
{
(void)dev;
DEBUG("[nrf802154] Turning off the radio\n");
_cancel_timed_tx();
_power_off();
timer_stop(NRF802154_TIMER);
return 0;
}

Expand Down Expand Up @@ -746,7 +853,8 @@ static const ieee802154_radio_ops_t nrf802154_ops = {
| IEEE802154_CAP_IRQ_TX_DONE
| IEEE802154_CAP_IRQ_CCA_DONE
| IEEE802154_CAP_PHY_OQPSK
| IEEE802154_CAP_FRAME_RETENTION,
| IEEE802154_CAP_FRAME_RETENTION
| IEEE802154_CAP_TIMED_TX,

.write = _write,
.read = _read,
Expand All @@ -763,6 +871,7 @@ static const ieee802154_radio_ops_t nrf802154_ops = {
.set_csma_params = _set_csma_params,
.config_addr_filter = _config_addr_filter,
.config_src_addr_match = _config_src_addr_match,
.get_time = _get_time,
.set_frame_filter_mode = _set_frame_filter_mode,
.get_frame_filter_mode = _get_frame_filter_mode,
};
17 changes: 16 additions & 1 deletion drivers/kw41zrf/include/kw41zrf_intern.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ static inline void kw41zrf_abort_sequence(kw41zrf_t *dev)
/* Writing IDLE to XCVSEQ aborts any ongoing sequence */
ZLL->PHY_CTRL = (ZLL->PHY_CTRL &
~(ZLL_PHY_CTRL_XCVSEQ_MASK |
ZLL_PHY_CTRL_TC3TMOUT_MASK | ZLL_PHY_CTRL_TMRTRIGEN_MASK)) |
ZLL_PHY_CTRL_TC3TMOUT_MASK | ZLL_PHY_CTRL_TMRTRIGEN_MASK |
ZLL_PHY_CTRL_TMR2CMP_EN_MASK)) |
ZLL_PHY_CTRL_XCVSEQ(XCVSEQ_IDLE) | ZLL_PHY_CTRL_SEQMSK_MASK;
/* Spin until the sequence manager has acknowledged the sequence abort, this
* should not take many cycles */
Expand Down Expand Up @@ -264,6 +265,20 @@ static inline void kw41zrf_timer_set(kw41zrf_t *dev, volatile uint32_t *cmp_reg,
*cmp_reg = now + timeout;
}

/**
* @brief Set an absolute value for the given compare register of the Event Timer
*
* @param[in] dev kw41zrf device descriptor
* @param[out] cmp_reg pointer to timer compare register, &ZLL->TxCMP
* @param[in] ticks absolute timer value, truncated to 24 bit
*/
static inline void kw41zrf_timer_set_abs(kw41zrf_t *dev, volatile uint32_t *cmp_reg, uint32_t ticks)
{
(void) dev;
/* all compare registers T1CMP..T4CMP are 24 bit wide */
*cmp_reg = ticks & ZLL_T1CMP_T1CMP_MASK;
}

/**
* @brief Initialize the Event Timer Block (up counter)
*
Expand Down
Loading
Loading