diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index d5767c56b..ab0f88505 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -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;