nimble/phy/nrf: Add PA/LNA turn-on time configuration

This allows to define PA/LNA turn-on time which allows it to fully turn
on before actual rx/tx. Currently only supported by nRF53 PHY.
This commit is contained in:
Andrzej Kaczmarek
2022-08-11 14:46:36 +02:00
parent 9b3feb5ee1
commit c4a2b2e695
2 changed files with 53 additions and 20 deletions
+8
View File
@@ -414,6 +414,10 @@ syscfg.defs:
GPIO pin number to control PA. Pin is set to high state when PA
should be enabled.
value: -1
BLE_LL_PA_TURN_ON_US:
description: >
Time required for PA to turn on, in microseconds.
value: 1
BLE_LL_LNA:
description: Enable LNA support
value: 0
@@ -422,6 +426,10 @@ syscfg.defs:
GPIO pin number to control LNA. Pin is set to high state when LNA
should be enabled.
value: -1
BLE_LL_LNA_TURN_ON_US:
description: >
Time required for LNA to turn on, in microseconds.
value: 1
BLE_LL_SYSINIT_STAGE:
description: >
+45 -20
View File
@@ -42,7 +42,7 @@
/* Channels 0..5 are always used.
* Channels 6 and 7 are used for PA/LNA (optionally).
* Channels 6..8 are used for GPIO debugging (optionally).
* Channels 7..9 are used for GPIO debugging (optionally).
*/
#define DPPI_CH_TIMER0_EVENTS_COMPARE_0 0
@@ -51,14 +51,15 @@
#define DPPI_CH_RADIO_EVENTS_BCMATCH 3
#define DPPI_CH_RADIO_EVENTS_ADDRESS 4
#define DPPI_CH_RTC0_EVENTS_COMPARE_0 5
#define DPPI_CH_RADIO_EVENTS_READY 6
#define DPPI_CH_TIMER0_EVENTS_COMPARE_4 6
#define DPPI_CH_RADIO_EVENTS_DISABLED 7
#define DPPI_CH_RADIO_EVENTS_RXREADY 8
#define DPPI_CH_RADIO_EVENTS_READY 8
#define DPPI_CH_RADIO_EVENTS_RXREADY 9
#define DPPI_CH_ENABLE_ALL (DPPIC_CHEN_CH0_Msk | DPPIC_CHEN_CH1_Msk | DPPIC_CHEN_CH2_Msk | \
DPPIC_CHEN_CH3_Msk | DPPIC_CHEN_CH4_Msk | DPPIC_CHEN_CH5_Msk)
#define DPPI_CH_MASK_PLNA (DPPI_CH_MASK(RADIO_EVENTS_READY) | \
#define DPPI_CH_MASK_PLNA (DPPI_CH_MASK(TIMER0_EVENTS_COMPARE_4) | \
DPPI_CH_MASK(RADIO_EVENTS_DISABLED))
extern uint8_t g_nrf_num_irks;
@@ -333,10 +334,14 @@ ble_phy_plna_enable_pa(void)
#if MYNEWT_VAL(BLE_LL_PA)
ble_ll_plna_pa_enable();
/* CC[0] is set to radio enable */
NRF_TIMER0_NS->CC[4] = NRF_TIMER0_NS->CC[0] + BLE_PHY_T_RXENFAST -
MYNEWT_VAL(BLE_LL_PA_TURN_ON_US);
#if PLNA_SINGLE_GPIO
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4);
#else
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4);
#endif
#endif
}
@@ -348,9 +353,9 @@ ble_phy_plna_disable_pa(void)
ble_ll_plna_pa_disable();
#if PLNA_SINGLE_GPIO
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4);
#else
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4);
#endif
#endif
}
@@ -361,10 +366,14 @@ ble_phy_plna_enable_lna(void)
#if MYNEWT_VAL(BLE_LL_LNA)
ble_ll_plna_lna_enable();
/* CC[0] is set to radio enable */
NRF_TIMER0_NS->CC[4] = NRF_TIMER0_NS->CC[0] + BLE_PHY_T_RXENFAST -
MYNEWT_VAL(BLE_LL_LNA_TURN_ON_US);
#if PLNA_SINGLE_GPIO
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4);
#else
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4);
#endif
#endif
}
@@ -376,9 +385,9 @@ ble_phy_plna_disable_lna(void)
ble_ll_plna_lna_disable();
#if PLNA_SINGLE_GPIO
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4);
#else
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4);
#endif
#endif
}
@@ -548,6 +557,22 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx)
rem_usecs -= 30;
}
/* If PA/LNA is used, make sure CC[0] is set to more than turn-on time since
* it's used as a base for turn-on time calculation and thus cannot wrap
* around on subtraction.
*/
if (MYNEWT_VAL(BLE_LL_PA) && tx &&
(rem_usecs + BLE_PHY_T_RXENFAST <= MYNEWT_VAL(BLE_LL_PA_TURN_ON_US))) {
cputime--;
rem_usecs += 30;
}
if (MYNEWT_VAL(BLE_LL_LNA) && !tx &&
(rem_usecs + BLE_PHY_T_RXENFAST <= MYNEWT_VAL(BLE_LL_LNA_TURN_ON_US))) {
cputime--;
rem_usecs += 30;
}
/*
* Can we set the RTC compare to start TIMER0? We can do it if:
* a) Current compare value is not N+1 or N+2 ticks from current
@@ -1428,28 +1453,28 @@ ble_phy_init(void)
* TODO: figure out if this affects power consumption
*/
/* Publish RADIO->EVENTS_READY */
NRF_RADIO_NS->PUBLISH_READY = DPPI_CH_PUB(RADIO_EVENTS_READY);
NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_READY);
/* Publish TIMER0->EVENTS_COMPARE4 */
NRF_TIMER0_NS->PUBLISH_COMPARE[4] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_4);
NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(TIMER0_EVENTS_COMPARE_4);
/* Publish RADIO->EVENTS_DISABLED */
NRF_RADIO_NS->PUBLISH_DISABLED = DPPI_CH_PUB(RADIO_EVENTS_DISABLED);
NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_DISABLED);
#if PLNA_SINGLE_GPIO
plna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO));
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0);
NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED);
NRF_GPIOTE_NS->TASKS_CLR[plna_idx] = 1;
#else
#if MYNEWT_VAL(BLE_LL_PA)
plna_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO));
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4);
NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_pa_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED);
NRF_GPIOTE_NS->TASKS_CLR[plna_pa_idx] = 1;
#endif
#if MYNEWT_VAL(BLE_LL_LNA)
plna_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_LNA_GPIO));
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4);
NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_lna_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED);
NRF_GPIOTE_NS->TASKS_CLR[plna_lna_idx] = 1;
#endif
@@ -1903,10 +1928,10 @@ ble_phy_disable_irq_and_ppi(void)
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY);
#else
#if MYNEWT_VAL(BLE_LL_PA)
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4);
#endif
#if MYNEWT_VAL(BLE_LL_LNA)
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY);
NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4);
#endif
#endif