mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-07-13 06:34:09 +00:00
nimble/phy: Fix for late RX-TX transition on nRF52
RX-TX transition on nRF52 is done by triggering TXEN using TIMER0 as we do T_IFS in software. However, it may happen that timer set for TIMER0 is behind current TIMER0 counter and thus we will not start TX and thus effectively block phy. For now we will use a little hack: just indicate that we were late on setting transition timer and this will make ble_phy_tx() fail so we can recover easily. This seems much cleaner than hacking extra handling in many other functions, so let's use such workaround for now. X-Original-Commit: dd132d43d5facb8e538e1e2277f9a47bba4bdd40
This commit is contained in:
@@ -100,6 +100,7 @@ struct ble_phy_obj
|
||||
uint8_t phy_chan;
|
||||
uint8_t phy_state;
|
||||
uint8_t phy_transition;
|
||||
uint8_t phy_transition_late;
|
||||
uint8_t phy_rx_started;
|
||||
uint8_t phy_encrypted;
|
||||
uint8_t phy_privacy;
|
||||
@@ -892,6 +893,24 @@ ble_phy_rx_end_isr(void)
|
||||
NRF_TIMER0->EVENTS_COMPARE[0] = 0;
|
||||
NRF_PPI->CHENSET = PPI_CHEN_CH20_Msk;
|
||||
|
||||
/*
|
||||
* XXX: Hack warning!
|
||||
*
|
||||
* It may happen (during flash erase) that CPU is stopped for a moment and
|
||||
* TIMER0 already counted past CC[0]. In such case we will be stuck waiting
|
||||
* for TX to start since EVENTS_COMPARE[0] will not happen any time soon.
|
||||
* For now let's set a flag denoting that we are late in RX-TX transition so
|
||||
* ble_phy_tx() will fail - this allows everything to cleanup nicely without
|
||||
* the need for extra handling in many places.
|
||||
*
|
||||
* Note: CC[3] is used only for wfr which we do not need here.
|
||||
*/
|
||||
NRF_TIMER0->TASKS_CAPTURE[3] = 1;
|
||||
if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) {
|
||||
NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
|
||||
g_ble_phy_data.phy_transition_late = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: This is a horrible ugly hack to deal with the RAM S1 byte
|
||||
* that is not sent over the air but is present here. Simply move the
|
||||
@@ -1079,6 +1098,8 @@ ble_phy_isr(void)
|
||||
ble_phy_rx_end_isr();
|
||||
}
|
||||
|
||||
g_ble_phy_data.phy_transition_late = 0;
|
||||
|
||||
/* Ensures IRQ is cleared */
|
||||
irq_en = NRF_RADIO->SHORTS;
|
||||
|
||||
@@ -1455,6 +1476,12 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans)
|
||||
uint32_t state;
|
||||
uint32_t shortcuts;
|
||||
|
||||
if (g_ble_phy_data.phy_transition_late) {
|
||||
ble_phy_disable();
|
||||
STATS_INC(ble_phy_stats, tx_late);
|
||||
return BLE_PHY_ERR_TX_LATE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This check is to make sure that the radio is not in a state where
|
||||
* it is moving to disabled state. If so, let it get there.
|
||||
|
||||
Reference in New Issue
Block a user