Skip to content

Commit f4305d9

Browse files
committed
nimble/phy: Do not disable radio if TIFS is short
If TIFS is short then TX_TX and RX_RX transitions can be done without disabling radio in between, just by triggering START.
1 parent fe53865 commit f4305d9

File tree

4 files changed

+108
-27
lines changed

4 files changed

+108
-27
lines changed

nimble/drivers/nrf5x/src/ble_phy.c

Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,17 @@ ble_phy_get_ccm_datarate(void)
920920
}
921921
#endif
922922

923+
static void
924+
ble_phy_end_handling_setup(void)
925+
{
926+
if (g_ble_phy_data.tifs_usecs >= BLE_LL_IFS) {
927+
NRF_RADIO->SHORTS |= RADIO_SHORTS_END_DISABLE_Msk;
928+
nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_DISABLED_Msk);
929+
} else {
930+
nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_END_Msk);
931+
}
932+
};
933+
923934
/**
924935
* Setup transceiver for receive.
925936
*/
@@ -969,6 +980,7 @@ ble_phy_rx_xcvr_setup(void)
969980

970981
/* Turn off trigger TXEN on output compare match and AAR on bcmatch */
971982
phy_ppi_timer0_compare0_to_radio_txen_disable();
983+
phy_ppi_timer0_compare0_to_radio_start_disable();
972984
phy_ppi_radio_bcmatch_to_aar_start_disable();
973985

974986
/* Reset the rx started flag. Used for the wait for response */
@@ -997,14 +1009,11 @@ ble_phy_rx_xcvr_setup(void)
9971009
NRF_RADIO->EVENTS_BCMATCH = 0;
9981010
NRF_RADIO->EVENTS_RSSIEND = 0;
9991011
NRF_RADIO->EVENTS_CRCOK = 0;
1000-
NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
1001-
RADIO_SHORTS_READY_START_Msk |
1012+
NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk |
10021013
RADIO_SHORTS_ADDRESS_BCSTART_Msk |
10031014
RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
10041015
RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
1005-
1006-
nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_ADDRESS_Msk |
1007-
RADIO_INTENSET_DISABLED_Msk);
1016+
nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_ADDRESS_Msk);
10081017
}
10091018

10101019
static uint32_t
@@ -1047,6 +1056,11 @@ ble_transition_to_tx(uint8_t tifs_anchor, uint16_t tifs_usecs, uint8_t phy_state
10471056
uint8_t next_phy_mode;
10481057
uint8_t prev_phy_mode = g_ble_phy_data.phy_cur_phy_mode;
10491058

1059+
if (NRF_RADIO->STATE == RADIO_STATE_STATE_RxIdle) {
1060+
nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
1061+
nrf_wait_disabled();
1062+
}
1063+
10501064
#if MYNEWT_VAL(BLE_LL_PHY)
10511065
ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode);
10521066
#endif
@@ -1064,11 +1078,19 @@ ble_transition_to_tx(uint8_t tifs_anchor, uint16_t tifs_usecs, uint8_t phy_state
10641078
phy_fem_enable_pa();
10651079
#endif
10661080

1067-
/* Adjust for TX rump-up */
1068-
radio_time -= BLE_PHY_T_TXENFAST;
1069-
/* Adjust for delay between EVENT_READY and actual TX start time */
1070-
radio_time -= g_ble_phy_t_txdelay[next_phy_mode];
1071-
phy_ppi_timer0_compare0_to_radio_txen_enable();
1081+
if (NRF_RADIO->STATE == RADIO_STATE_STATE_Disabled) {
1082+
/* Adjust for TX rump-up */
1083+
radio_time -= BLE_PHY_T_TXENFAST;
1084+
/* Adjust for delay between EVENT_READY and actual TX start time */
1085+
radio_time -= g_ble_phy_t_txdelay[next_phy_mode];
1086+
phy_ppi_timer0_compare0_to_radio_txen_enable();
1087+
} else {
1088+
/* Fast TX_TX transition */
1089+
BLE_LL_ASSERT(NRF_RADIO->STATE == RADIO_STATE_STATE_TxIdle);
1090+
/* TODO: Adjust for delay between TASK_START and actual TX start time */
1091+
radio_time -= g_ble_phy_t_txdelay[next_phy_mode];
1092+
phy_ppi_timer0_compare0_to_radio_start_enable();
1093+
}
10721094

10731095
nrf_timer_cc_set(NRF_TIMER0, 0, radio_time);
10741096
NRF_TIMER0->EVENTS_COMPARE[0] = 0;
@@ -1101,6 +1123,11 @@ ble_transition_to_rx(uint8_t tifs_anchor, uint16_t tifs_usecs, uint8_t phy_state
11011123
uint32_t radio_time;
11021124
uint32_t start_time;
11031125

1126+
if (NRF_RADIO->STATE == RADIO_STATE_STATE_TxIdle) {
1127+
nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
1128+
nrf_wait_disabled();
1129+
}
1130+
11041131
#if MYNEWT_VAL(BLE_LL_PHY)
11051132
ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode);
11061133
#endif
@@ -1119,11 +1146,19 @@ ble_transition_to_rx(uint8_t tifs_anchor, uint16_t tifs_usecs, uint8_t phy_state
11191146
phy_fem_enable_lna();
11201147
#endif
11211148

1122-
/* Adjust for RX rump-up */
1123-
radio_time -= BLE_PHY_T_RXENFAST;
1124-
/* Start listening a bit earlier due to allowed active clock accuracy */
1125-
radio_time -= 2;
1126-
phy_ppi_timer0_compare0_to_radio_rxen_enable();
1149+
if (NRF_RADIO->STATE == RADIO_STATE_STATE_Disabled) {
1150+
/* Adjust for RX rump-up */
1151+
radio_time -= BLE_PHY_T_RXENFAST;
1152+
/* Start listening a bit earlier due to allowed active clock accuracy */
1153+
radio_time -= 2;
1154+
phy_ppi_timer0_compare0_to_radio_rxen_enable();
1155+
} else {
1156+
/* Fast RX_RX transition */
1157+
BLE_LL_ASSERT(NRF_RADIO->STATE == RADIO_STATE_STATE_RxIdle);
1158+
/* Start listening a bit earlier due to allowed active clock accuracy */
1159+
radio_time -= 2;
1160+
phy_ppi_timer0_compare0_to_radio_start_enable();
1161+
}
11271162

11281163
/* Setup wfr relative to expected radio/PDU start */
11291164
g_ble_phy_data.phy_start_time = start_time;
@@ -1148,6 +1183,7 @@ ble_transition_to_none(void)
11481183
nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP);
11491184
NRF_TIMER0->TASKS_SHUTDOWN = 1;
11501185
phy_ppi_wfr_disable();
1186+
phy_ppi_timer0_compare0_to_radio_start_disable();
11511187
phy_ppi_timer0_compare0_to_radio_txen_disable();
11521188
phy_ppi_rtc0_compare0_to_timer0_start_disable();
11531189
ble_phy_disable();
@@ -1164,7 +1200,9 @@ ble_phy_transition(uint8_t transition, uint8_t tifs_anchor, uint16_t tifs_usecs,
11641200
{
11651201
int rc = 1;
11661202

1167-
if (transition == PHY_TRANS_TO_TX) {
1203+
if (ble_ll_state_get() == BLE_LL_STATE_STANDBY) {
1204+
rc = 1;
1205+
} else if (transition == PHY_TRANS_TO_TX) {
11681206
rc = ble_transition_to_tx(tifs_anchor, tifs_usecs, phy_state);
11691207
} else if (transition == PHY_TRANS_TO_RX) {
11701208
rc = ble_transition_to_rx(tifs_anchor, tifs_usecs, phy_state);
@@ -1224,8 +1262,12 @@ ble_phy_tx_end_isr(void)
12241262

12251263
ble_phy_transition(transition, tifs_anchor, tifs_usecs, BLE_PHY_STATE_TX);
12261264

1227-
if (transition == BLE_PHY_TRANSITION_TO_RX) {
1228-
ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_TXRX, 0, g_ble_phy_data.wfr_usecs);
1265+
if (g_ble_phy_data.phy_state != BLE_PHY_STATE_IDLE) {
1266+
ble_phy_end_handling_setup();
1267+
1268+
if (transition == BLE_PHY_TRANSITION_TO_RX) {
1269+
ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_TXRX, 0, g_ble_phy_data.wfr_usecs);
1270+
}
12291271
}
12301272
}
12311273

@@ -1266,6 +1308,8 @@ ble_phy_rx_end_isr(void)
12661308

12671309
/* Disable automatic RXEN */
12681310
phy_ppi_timer0_compare0_to_radio_rxen_disable();
1311+
/* Disable automatic RX START */
1312+
phy_ppi_timer0_compare0_to_radio_start_disable();
12691313

12701314
/* Set RSSI and CRC status flag in header */
12711315
ble_hdr = &g_ble_phy_data.rxhdr;
@@ -1349,8 +1393,12 @@ ble_phy_rx_end_isr(void)
13491393
return;
13501394
}
13511395

1352-
if (transition == BLE_PHY_TRANSITION_TO_RX) {
1353-
ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RXRX, 0, g_ble_phy_data.wfr_usecs);
1396+
if (g_ble_phy_data.phy_state != BLE_PHY_STATE_IDLE) {
1397+
ble_phy_end_handling_setup();
1398+
1399+
if (transition == BLE_PHY_TRANSITION_TO_RX) {
1400+
ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RXRX, 0, g_ble_phy_data.wfr_usecs);
1401+
}
13541402
}
13551403
}
13561404

@@ -1519,13 +1567,15 @@ ble_phy_isr(void)
15191567
* need to check phy_rx_started flag to make sure we actually were receiving
15201568
* a PDU, otherwise this is due to wfr.
15211569
*/
1522-
if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
1570+
if (((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) ||
1571+
((irq_en & RADIO_INTENCLR_END_Msk) && NRF_RADIO->EVENTS_END)) {
1572+
15231573
BLE_LL_ASSERT(NRF_RADIO->EVENTS_END ||
15241574
((g_ble_phy_data.phy_state == BLE_PHY_STATE_RX) &&
15251575
!g_ble_phy_data.phy_rx_started));
15261576
NRF_RADIO->EVENTS_END = 0;
15271577
NRF_RADIO->EVENTS_DISABLED = 0;
1528-
nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_DISABLED_Msk);
1578+
nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_DISABLED_Msk | RADIO_INTENCLR_END_Msk);
15291579

15301580
switch (g_ble_phy_data.phy_state) {
15311581
case BLE_PHY_STATE_RX:
@@ -1755,6 +1805,8 @@ ble_phy_rx(void)
17551805
/* Setup for rx */
17561806
ble_phy_rx_xcvr_setup();
17571807

1808+
ble_phy_end_handling_setup();
1809+
17581810
return 0;
17591811
}
17601812

@@ -1849,6 +1901,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
18491901
/* XXX: This should not be necessary, but paranoia is good! */
18501902
/* Clear timer0 compare to RXEN since we are transmitting */
18511903
phy_ppi_timer0_compare0_to_radio_rxen_disable();
1904+
phy_ppi_timer0_compare0_to_radio_start_disable();
18521905

18531906
if (ble_phy_set_start_time(cputime, rem_usecs, true) != 0) {
18541907
STATS_INC(ble_phy_stats, tx_late);
@@ -1891,6 +1944,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
18911944
/* XXX: This should not be necessary, but paranoia is good! */
18921945
/* Clear timer0 compare to TXEN since we are transmitting */
18931946
phy_ppi_timer0_compare0_to_radio_txen_disable();
1947+
phy_ppi_timer0_compare0_to_radio_start_disable();
18941948

18951949
if (ble_phy_set_start_time(cputime, rem_usecs, false) != 0) {
18961950
STATS_INC(ble_phy_stats, rx_late);
@@ -1927,7 +1981,6 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg)
19271981
uint8_t payload_len;
19281982
uint8_t hdr_byte;
19291983
uint32_t state;
1930-
uint32_t shortcuts;
19311984
uint8_t end_trans;
19321985

19331986
if (g_ble_phy_data.phy_transition_late) {
@@ -2010,9 +2063,8 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg)
20102063
NRF_RADIO->EVENTS_DISABLED = 0;
20112064

20122065
/* Enable shortcuts for transmit start/end. */
2013-
shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk;
2014-
NRF_RADIO->SHORTS = shortcuts;
2015-
nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_DISABLED_Msk);
2066+
NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk;
2067+
ble_phy_end_handling_setup();
20162068

20172069
/* Set the PHY transition */
20182070
g_ble_phy_data.phy_transition = end_trans;

nimble/drivers/nrf5x/src/nrf52/phy.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,18 @@ phy_ppi_init(void)
169169
* Channel 4: Captures TIMER0 in CC[3] when EVENTS_ADDRESS occurs. Used
170170
* to cancel the wait for response timer.
171171
* Channel 5: TIMER0 CC[3] to TASKS_DISABLE on radio. This is the wait
172-
* for response timer.
172+
* for response timer (or measurement timer)
173+
* Channel 8: TIMER0 CC[0] to TASKS_START on radio.
173174
*/
174175
nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL4,
175176
(uint32_t)&(NRF_RADIO->EVENTS_ADDRESS),
176177
(uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[3]));
177178
nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL5,
178179
(uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]),
179180
(uint32_t)&(NRF_RADIO->TASKS_DISABLE));
181+
nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL8,
182+
(uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]),
183+
(uint32_t)&(NRF_RADIO->TASKS_START));
180184
}
181185

182186
void

nimble/drivers/nrf5x/src/nrf52/phy_ppi.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ phy_ppi_timer0_compare0_to_radio_rxen_disable(void)
5858
nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH21_Msk);
5959
}
6060

61+
static inline void
62+
phy_ppi_timer0_compare0_to_radio_start_enable(void)
63+
{
64+
nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH8_Msk);
65+
}
66+
67+
static inline void
68+
phy_ppi_timer0_compare0_to_radio_start_disable(void)
69+
{
70+
nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH8_Msk);
71+
}
72+
6173
static inline void
6274
phy_ppi_radio_bcmatch_to_aar_start_enable(void)
6375
{
@@ -105,6 +117,7 @@ phy_ppi_disable(void)
105117
{
106118
nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk |
107119
PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk |
120+
PPI_CHEN_CH8_Msk |
108121
PPI_CHEN_CH20_Msk | PPI_CHEN_CH21_Msk |
109122
PPI_CHEN_CH23_Msk | PPI_CHEN_CH25_Msk |
110123
PPI_CHEN_CH31_Msk);

nimble/drivers/nrf5x/src/nrf53/phy_ppi.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ phy_ppi_timer0_compare0_to_radio_rxen_disable(void)
8686
NRF_RADIO->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0);
8787
}
8888

89+
static inline void
90+
phy_ppi_timer0_compare0_to_radio_start_enable(void)
91+
{
92+
NRF_RADIO->SUBSCRIBE_START = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0);
93+
}
94+
95+
static inline void
96+
phy_ppi_timer0_compare0_to_radio_start_disable(void)
97+
{
98+
NRF_RADIO->SUBSCRIBE_START = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0);
99+
}
100+
89101
static inline void
90102
phy_ppi_radio_address_to_ccm_crypt_enable(void)
91103
{

0 commit comments

Comments
 (0)