Skip to content

Commit 82153e7

Browse files
nimble/phy: Improve tx_late handling
There is a very small window between setting timer comparator and configuring field_1 where frame_start event can happen due to match on that timer. To prevent this from generating a fatal error, let's disable corresponding error before setting comparator and check if frame_start event already happened after frame_1 is configured. If it did happen, assume we did not configure frame_1 on time and do tx_late.
1 parent 0da81a8 commit 82153e7

File tree

1 file changed

+35
-17
lines changed

1 file changed

+35
-17
lines changed

nimble/drivers/dialog_cmac/src/ble_phy.c

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,33 +1500,51 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
15001500

15011501
/*
15021502
* We do not want FIELD/FRAME interrupts or FIELD1_ERR until ble_phy_tx()
1503-
* has finished pushing all the fields. If we won't make it on time, we
1504-
* assume tx_late and abort TX.
1503+
* has finished pushing all the fields. Also we do not want premature
1504+
* FRAME_ERR so disable it until we program FRAME1 properly. If we won't
1505+
* make configuration on time, assume tx_late and abort TX.
15051506
*/
15061507
NVIC_DisableIRQ(FRAME_IRQn);
15071508
NVIC_DisableIRQ(FIELD_IRQn);
1508-
CMAC->CM_ERROR_DIS_REG |= CMAC_CM_ERROR_DIS_REG_CM_FIELD1_ERR_Msk;
1509+
CMAC->CM_ERROR_DIS_REG |= CMAC_CM_ERROR_DIS_REG_CM_FIELD1_ERR_Msk |
1510+
CMAC_CM_ERROR_DIS_REG_CM_FRAME_ERR_Msk;
15091511

15101512
CMAC->CM_LL_TIMER1_9_0_EQ_X_REG = ll_val32;
15111513
CMAC->CM_EV_LINKUP_REG = CMAC_CM_EV_LINKUP_REG_LU_FRAME_START_2_TMR1_9_0_EQ_X_Msk;
15121514

15131515
if ((int32_t)(ll_val32 - cmac_timer_read32()) < 0) {
1514-
STATS_INC(ble_phy_stats, tx_late);
1515-
ble_phy_disable();
1516-
NVIC_EnableIRQ(FRAME_IRQn);
1517-
NVIC_EnableIRQ(FIELD_IRQn);
1518-
rc = BLE_PHY_ERR_TX_LATE;
1519-
} else {
1520-
/*
1521-
* Program frame now since it needs to be ready for FRAME_START, we can
1522-
* push fields later
1523-
*/
1524-
CMAC->CM_FRAME_1_REG = CMAC_CM_FRAME_1_REG_FRAME_VALID_Msk |
1525-
CMAC_CM_FRAME_1_REG_FRAME_TX_Msk |
1526-
CMAC_CM_FRAME_2_REG_FRAME_EXC_ON_BS_START_Msk;
1527-
rc = 0;
1516+
goto tx_late;
1517+
}
1518+
1519+
/*
1520+
* Program frame now since it needs to be ready for FRAME_START, we can
1521+
* push fields later
1522+
*/
1523+
CMAC->CM_FRAME_1_REG = CMAC_CM_FRAME_1_REG_FRAME_VALID_Msk |
1524+
CMAC_CM_FRAME_1_REG_FRAME_TX_Msk |
1525+
CMAC_CM_FRAME_1_REG_FRAME_EXC_ON_BS_START_Msk;
1526+
1527+
/*
1528+
* There should be no EXC_FRAME_START here so if it already happened we
1529+
* need to assume tx_late and abort.
1530+
*/
1531+
if (CMAC->CM_EXC_STAT_REG & CMAC_CM_EXC_STAT_REG_EXC_FRAME_START_Msk) {
1532+
goto tx_late;
15281533
}
15291534

1535+
CMAC->CM_ERROR_DIS_REG &= ~CMAC_CM_ERROR_DIS_REG_CM_FRAME_ERR_Msk;
1536+
rc = 0;
1537+
1538+
goto done;
1539+
1540+
tx_late:
1541+
STATS_INC(ble_phy_stats, tx_late);
1542+
ble_phy_disable();
1543+
NVIC_EnableIRQ(FRAME_IRQn);
1544+
NVIC_EnableIRQ(FIELD_IRQn);
1545+
rc = BLE_PHY_ERR_TX_LATE;
1546+
1547+
done:
15301548
return rc;
15311549
}
15321550

0 commit comments

Comments
 (0)