mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-09-09 10:40:04 +00:00
Merge pull request #910 from andrzej-kaczmarek/cmac-tx-late-one-more-attempt
nimble/phy: Fix tx_late handling
This commit is contained in:
@@ -46,6 +46,9 @@ STATS_SECT_START(ble_phy_stats)
|
||||
STATS_SECT_ENTRY(tx_good)
|
||||
STATS_SECT_ENTRY(tx_fail)
|
||||
STATS_SECT_ENTRY(tx_late)
|
||||
STATS_SECT_ENTRY(tx_late_sched)
|
||||
STATS_SECT_ENTRY(tx_late_frame)
|
||||
STATS_SECT_ENTRY(tx_late_field)
|
||||
STATS_SECT_ENTRY(tx_bytes)
|
||||
STATS_SECT_ENTRY(rx_starts)
|
||||
STATS_SECT_ENTRY(rx_aborts)
|
||||
@@ -63,6 +66,9 @@ STATS_NAME_START(ble_phy_stats)
|
||||
STATS_NAME(ble_phy_stats, tx_good)
|
||||
STATS_NAME(ble_phy_stats, tx_fail)
|
||||
STATS_NAME(ble_phy_stats, tx_late)
|
||||
STATS_NAME(ble_phy_stats, tx_late_sched)
|
||||
STATS_NAME(ble_phy_stats, tx_late_frame)
|
||||
STATS_NAME(ble_phy_stats, tx_late_field)
|
||||
STATS_NAME(ble_phy_stats, tx_bytes)
|
||||
STATS_NAME(ble_phy_stats, rx_starts)
|
||||
STATS_NAME(ble_phy_stats, rx_aborts)
|
||||
@@ -1242,6 +1248,15 @@ ble_phy_init(void)
|
||||
g_ble_phy_encrypt_data.ai[0] = 0x01;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Disable FIELD1, FIELD2 and FRAME errors since they can happen
|
||||
* sometimes if we are too late on scheduling and trigger CMAC
|
||||
* error. We can detect if tx_late happened and recover properly.
|
||||
*/
|
||||
CMAC->CM_ERROR_DIS_REG |= CMAC_CM_ERROR_DIS_REG_CM_FIELD1_ERR_Msk |
|
||||
CMAC_CM_ERROR_DIS_REG_CM_FIELD2_ERR_Msk |
|
||||
CMAC_CM_ERROR_DIS_REG_CM_FRAME_ERR_Msk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1274,8 +1289,6 @@ ble_phy_disable(void)
|
||||
os_arch_cmac_bs_ctrl_irq_unblock();
|
||||
g_sw_mac_exc = 0;
|
||||
|
||||
CMAC->CM_ERROR_DIS_REG = 0;
|
||||
|
||||
ble_rf_stop();
|
||||
|
||||
/*
|
||||
@@ -1455,6 +1468,7 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans)
|
||||
if (CMAC->CM_EXC_STAT_REG & CMAC_CM_EXC_STAT_REG_EXC_FIELD_ON_THR_EXP_Msk) {
|
||||
ble_phy_disable();
|
||||
g_ble_phy_data.end_transition = BLE_PHY_TRANSITION_NONE;
|
||||
STATS_INC(ble_phy_stats, tx_late_field);
|
||||
STATS_INC(ble_phy_stats, tx_late);
|
||||
rc = BLE_PHY_ERR_RADIO_STATE;
|
||||
} else {
|
||||
@@ -1467,7 +1481,6 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans)
|
||||
}
|
||||
|
||||
/* Now we can handle BS_CTRL */
|
||||
CMAC->CM_ERROR_DIS_REG &= ~CMAC_CM_ERROR_DIS_REG_CM_FIELD1_ERR_Msk;
|
||||
NVIC_EnableIRQ(FRAME_IRQn);
|
||||
NVIC_EnableIRQ(FIELD_IRQn);
|
||||
|
||||
@@ -1499,20 +1512,17 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
|
||||
assert((int32_t)(ll_val32 - cmac_timer_read32()) < 1024);
|
||||
|
||||
/*
|
||||
* We do not want FIELD/FRAME interrupts or FIELD1_ERR until ble_phy_tx()
|
||||
* has finished pushing all the fields. Also we do not want premature
|
||||
* FRAME_ERR so disable it until we program FRAME1 properly. If we won't
|
||||
* make configuration on time, assume tx_late and abort TX.
|
||||
* We do not want FIELD/FRAME interrupts until ble_phy_tx() has
|
||||
* pushed all fields.
|
||||
*/
|
||||
NVIC_DisableIRQ(FRAME_IRQn);
|
||||
NVIC_DisableIRQ(FIELD_IRQn);
|
||||
CMAC->CM_ERROR_DIS_REG |= CMAC_CM_ERROR_DIS_REG_CM_FIELD1_ERR_Msk |
|
||||
CMAC_CM_ERROR_DIS_REG_CM_FRAME_ERR_Msk;
|
||||
|
||||
CMAC->CM_LL_TIMER1_9_0_EQ_X_REG = ll_val32;
|
||||
CMAC->CM_EV_LINKUP_REG = CMAC_CM_EV_LINKUP_REG_LU_FRAME_START_2_TMR1_9_0_EQ_X_Msk;
|
||||
|
||||
if ((int32_t)(ll_val32 - cmac_timer_read32()) < 0) {
|
||||
STATS_INC(ble_phy_stats, tx_late_sched);
|
||||
goto tx_late;
|
||||
}
|
||||
|
||||
@@ -1529,10 +1539,10 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
|
||||
* need to assume tx_late and abort.
|
||||
*/
|
||||
if (CMAC->CM_EXC_STAT_REG & CMAC_CM_EXC_STAT_REG_EXC_FRAME_START_Msk) {
|
||||
STATS_INC(ble_phy_stats, tx_late_frame);
|
||||
goto tx_late;
|
||||
}
|
||||
|
||||
CMAC->CM_ERROR_DIS_REG &= ~CMAC_CM_ERROR_DIS_REG_CM_FRAME_ERR_Msk;
|
||||
rc = 0;
|
||||
|
||||
goto done;
|
||||
|
||||
Reference in New Issue
Block a user