Skip to content

Commit e118e32

Browse files
maje-embnordicjm
authored andcommitted
ESB: Fixes and improvements
- Improved `esb_suspend` to suspend the protocol. - Changed `esb_flush_tx` to allow clearing the FIFO queue when ESB is in the IDLE state. - Fixed `esb_pop_tx` to use the correct pointer. - Renamed `tx_fifo_remove_last` to `tx_fifo_remove_first` Ref: NCSDK-36153 Signed-off-by: Marcin Jelinski <[email protected]>
1 parent e4f2d9f commit e118e32

File tree

4 files changed

+89
-38
lines changed

4 files changed

+89
-38
lines changed

include/esb.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,15 +438,22 @@ int esb_stop_rx(void);
438438
*
439439
* This function clears the TX FIFO buffer.
440440
*
441-
* @retval 0 If successful.
442-
* Otherwise, a (negative) error code is returned.
441+
* @note The radio must not be in transmission state for this operation to succeed.
442+
* This requirement prevents erroneous operations on the FIFO queue that could
443+
* occur if the buffer is cleared while the radio is transmitting.
444+
*
445+
* @retval 0 If successful (FIFO cleared).
446+
* @retval -EACCES If ESB is not initialized.
447+
* @retval -EBUSY If radio is transmitting.
443448
*/
444449
int esb_flush_tx(void);
445450

446451
/** @brief Pop the first item from the TX buffer.
447452
*
448453
* @retval 0 If successful.
449-
* Otherwise, a (negative) error code is returned.
454+
* @retval -EACCES If ESB is not initialized.
455+
* @retval -EBUSY If radio is transmitting.
456+
* @retval -ENODATA If TX FIFO is empty.
450457
*/
451458
int esb_pop_tx(void);
452459

subsys/esb/esb.c

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,7 @@ static void initialize_fifos(void)
10721072
}
10731073
}
10741074

1075-
static void tx_fifo_remove_last(void)
1075+
static void tx_fifo_remove_first(void)
10761076
{
10771077
if (tx_fifo.count == 0) {
10781078
return;
@@ -1332,7 +1332,7 @@ static void on_timer_compare1_tx_noack(void)
13321332
esb_ppi_for_wait_for_rx_clear();
13331333

13341334
interrupt_flags |= INT_TX_SUCCESS_MSK;
1335-
tx_fifo_remove_last();
1335+
tx_fifo_remove_first();
13361336

13371337
if (tx_fifo.count == 0) {
13381338
esb_state = ESB_STATE_PTX_TXIDLE;
@@ -1349,7 +1349,7 @@ static void on_radio_disabled_tx_noack(void)
13491349
esb_ppi_for_txrx_clear(false, false);
13501350

13511351
interrupt_flags |= INT_TX_SUCCESS_MSK;
1352-
tx_fifo_remove_last();
1352+
tx_fifo_remove_first();
13531353

13541354
if (tx_fifo.count == 0) {
13551355
esb_state = ESB_STATE_IDLE;
@@ -1440,7 +1440,7 @@ static void on_radio_disabled_tx_wait_for_ack(void)
14401440
interrupt_flags |= INT_TX_SUCCESS_MSK;
14411441
last_tx_attempts = esb_cfg.retransmit_count - retransmits_remaining + 1;
14421442

1443-
tx_fifo_remove_last();
1443+
tx_fifo_remove_first();
14441444

14451445
if ((esb_cfg.protocol != ESB_PROTOCOL_ESB) && (rx_pdu->type.dpl_pdu.length > 0)) {
14461446
if (rx_fifo_push_rfbuf(
@@ -2100,15 +2100,31 @@ int esb_init(const struct esb_config *config)
21002100

21012101
int esb_suspend(void)
21022102
{
2103-
if (esb_state != ESB_STATE_IDLE) {
2104-
return -EBUSY;
2103+
if (esb_state == ESB_STATE_IDLE) {
2104+
return -EALREADY;
2105+
}
2106+
on_radio_disabled = NULL;
2107+
2108+
/* Stop radio */
2109+
nrf_radio_shorts_disable(NRF_RADIO, 0xFFFFFFFF);
2110+
nrf_radio_int_disable(NRF_RADIO, 0xFFFFFFFF);
2111+
2112+
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
2113+
nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
2114+
2115+
while (!nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_DISABLED)) {
2116+
/* wait for register to settle */
21052117
}
21062118

2107-
/* Clear PPI */
2119+
/* Stop timer */
2120+
nrf_timer_shorts_disable(esb_timer.p_reg, 0xFFFFFFFF);
2121+
nrf_timer_int_disable(esb_timer.p_reg, 0xFFFFFFFF);
2122+
21082123
esb_ppi_disable_all();
2124+
esb_fem_reset();
21092125

2110-
esb_state = ESB_STATE_IDLE;
21112126
errata_216_off();
2127+
esb_state = ESB_STATE_IDLE;
21122128

21132129
return 0;
21142130
}
@@ -2313,34 +2329,20 @@ int esb_stop_rx(void)
23132329
return -EINVAL;
23142330
}
23152331

2316-
on_radio_disabled = NULL;
2317-
2318-
esb_ppi_for_txrx_clear(true, false);
2319-
esb_fem_reset();
2320-
2321-
nrf_radio_shorts_disable(NRF_RADIO, 0xFFFFFFFF);
2322-
nrf_radio_int_disable(NRF_RADIO, 0xFFFFFFFF);
2323-
2324-
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
2325-
nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
2326-
2327-
while (!nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_DISABLED)) {
2328-
/* wait for register to settle */
2329-
}
2330-
2331-
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
2332-
2333-
esb_state = ESB_STATE_IDLE;
2334-
errata_216_off();
2335-
2336-
return 0;
2332+
return esb_suspend();
23372333
}
23382334

23392335
int esb_flush_tx(void)
23402336
{
23412337
if (!esb_initialized) {
23422338
return -EACCES;
23432339
}
2340+
if (esb_state != ESB_STATE_IDLE) {
2341+
return -EBUSY;
2342+
}
2343+
if (tx_fifo.count == 0) {
2344+
return 0;
2345+
}
23442346

23452347
unsigned int key = irq_lock();
23462348

@@ -2367,14 +2369,17 @@ int esb_pop_tx(void)
23672369
if (!esb_initialized) {
23682370
return -EACCES;
23692371
}
2372+
if (esb_state != ESB_STATE_IDLE) {
2373+
return -EBUSY;
2374+
}
23702375
if (tx_fifo.count == 0) {
23712376
return -ENODATA;
23722377
}
23732378

23742379
unsigned int key = irq_lock();
23752380

2376-
if (++tx_fifo.back >= CONFIG_ESB_TX_FIFO_SIZE) {
2377-
tx_fifo.back = 0;
2381+
if (++tx_fifo.front >= CONFIG_ESB_TX_FIFO_SIZE) {
2382+
tx_fifo.front = 0;
23782383
}
23792384
tx_fifo.count--;
23802385

subsys/esb/esb_dppi.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,11 +289,35 @@ void esb_ppi_disable_all(void)
289289
BIT(egu_timer_start) |
290290
BIT(radio_address_timer_stop) |
291291
BIT(timer_compare0_radio_disable) |
292-
BIT(radio_end_timer_start) |
292+
BIT(timer_compare1_radio_txen) |
293293
(IS_ENABLED(CONFIG_ESB_NEVER_DISABLE_TX) ?
294-
BIT(timer_compare1_radio_txen) : 0));
294+
BIT(radio_end_timer_start) : 0));
295295

296296
nrf_dppi_channels_disable(ESB_DPPIC, channels_mask);
297+
298+
/* Clear all publish/subscribe connections to fully disconnect peripherals */
299+
/* Clear EGU */
300+
nrf_egu_publish_clear(ESB_EGU, ESB_EGU_EVENT);
301+
nrf_egu_publish_clear(ESB_EGU, ESB_EGU_DPPI_EVENT);
302+
nrf_egu_subscribe_clear(ESB_EGU, ESB_EGU_TASK);
303+
nrf_egu_subscribe_clear(ESB_EGU, ESB_EGU_DPPI_TASK);
304+
305+
/* Clear Radio */
306+
nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS);
307+
nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_RXEN);
308+
nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN);
309+
nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
310+
311+
/* Clear Timer */
312+
nrf_timer_publish_clear(ESB_NRF_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE0);
313+
nrf_timer_publish_clear(ESB_NRF_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE1);
314+
nrf_timer_subscribe_clear(ESB_NRF_TIMER_INSTANCE, NRF_TIMER_TASK_START);
315+
nrf_timer_subscribe_clear(ESB_NRF_TIMER_INSTANCE, NRF_TIMER_TASK_STOP);
316+
317+
/* Clear DPPI */
318+
nrf_dppi_subscribe_clear(ESB_DPPIC,
319+
nrf_dppi_group_disable_task_get((uint8_t)ramp_up_dppi_group));
320+
nrf_dppi_channels_remove_from_group(ESB_DPPIC, BIT(egu_ramp_up), ramp_up_dppi_group);
297321
}
298322

299323
void esb_ppi_deinit(void)

subsys/esb/esb_ppi.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,26 @@ void esb_ppi_disable_all(void)
249249
BIT(egu_timer_start) |
250250
BIT(radio_address_timer_stop) |
251251
BIT(timer_compare0_radio_disable) |
252-
BIT(radio_end_timer_start) |
252+
BIT(timer_compare1_radio_txen) |
253253
(IS_ENABLED(CONFIG_ESB_NEVER_DISABLE_TX) ?
254-
BIT(timer_compare1_radio_txen) : 0));
254+
BIT(radio_end_timer_start) : 0));
255255

256256
nrf_ppi_channels_disable(NRF_PPI, channels_mask);
257+
258+
/* Clear all PPI endpoints to fully disconnect peripherals */
259+
nrf_ppi_channel_and_fork_endpoint_setup(NRF_PPI, egu_ramp_up, 0, 0, 0);
260+
nrf_ppi_channel_endpoint_setup(NRF_PPI, disabled_egu, 0, 0);
261+
nrf_ppi_channel_endpoint_setup(NRF_PPI, egu_timer_start, 0, 0);
262+
nrf_ppi_channel_endpoint_setup(NRF_PPI, radio_address_timer_stop, 0, 0);
263+
nrf_ppi_channel_endpoint_setup(NRF_PPI, timer_compare0_radio_disable, 0, 0);
264+
nrf_ppi_channel_endpoint_setup(NRF_PPI, radio_end_timer_start, 0, 0);
265+
266+
if (IS_ENABLED(CONFIG_ESB_NEVER_DISABLE_TX)) {
267+
nrf_ppi_channel_endpoint_setup(NRF_PPI, timer_compare1_radio_txen, 0, 0);
268+
}
269+
270+
/* Remove channel from group */
271+
nrf_ppi_channel_remove_from_group(NRF_PPI, egu_ramp_up, ramp_up_ppi_group);
257272
}
258273

259274
void esb_ppi_deinit(void)

0 commit comments

Comments
 (0)