@@ -46,6 +46,9 @@ STATS_SECT_START(ble_phy_stats)
46
46
STATS_SECT_ENTRY (tx_good )
47
47
STATS_SECT_ENTRY (tx_fail )
48
48
STATS_SECT_ENTRY (tx_late )
49
+ STATS_SECT_ENTRY (tx_late_sched )
50
+ STATS_SECT_ENTRY (tx_late_frame )
51
+ STATS_SECT_ENTRY (tx_late_field )
49
52
STATS_SECT_ENTRY (tx_bytes )
50
53
STATS_SECT_ENTRY (rx_starts )
51
54
STATS_SECT_ENTRY (rx_aborts )
@@ -63,6 +66,9 @@ STATS_NAME_START(ble_phy_stats)
63
66
STATS_NAME (ble_phy_stats , tx_good )
64
67
STATS_NAME (ble_phy_stats , tx_fail )
65
68
STATS_NAME (ble_phy_stats , tx_late )
69
+ STATS_NAME (ble_phy_stats , tx_late_sched )
70
+ STATS_NAME (ble_phy_stats , tx_late_frame )
71
+ STATS_NAME (ble_phy_stats , tx_late_field )
66
72
STATS_NAME (ble_phy_stats , tx_bytes )
67
73
STATS_NAME (ble_phy_stats , rx_starts )
68
74
STATS_NAME (ble_phy_stats , rx_aborts )
@@ -1242,6 +1248,15 @@ ble_phy_init(void)
1242
1248
g_ble_phy_encrypt_data .ai [0 ] = 0x01 ;
1243
1249
#endif
1244
1250
1251
+ /*
1252
+ * Disable FIELD1, FIELD2 and FRAME errors since they can happen
1253
+ * sometimes if we are too late on scheduling and trigger CMAC
1254
+ * error. We can detect if tx_late happened and recover properly.
1255
+ */
1256
+ CMAC -> CM_ERROR_DIS_REG |= CMAC_CM_ERROR_DIS_REG_CM_FIELD1_ERR_Msk |
1257
+ CMAC_CM_ERROR_DIS_REG_CM_FIELD2_ERR_Msk |
1258
+ CMAC_CM_ERROR_DIS_REG_CM_FRAME_ERR_Msk ;
1259
+
1245
1260
return 0 ;
1246
1261
}
1247
1262
@@ -1274,8 +1289,6 @@ ble_phy_disable(void)
1274
1289
os_arch_cmac_bs_ctrl_irq_unblock ();
1275
1290
g_sw_mac_exc = 0 ;
1276
1291
1277
- CMAC -> CM_ERROR_DIS_REG = 0 ;
1278
-
1279
1292
ble_rf_stop ();
1280
1293
1281
1294
/*
@@ -1455,6 +1468,7 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans)
1455
1468
if (CMAC -> CM_EXC_STAT_REG & CMAC_CM_EXC_STAT_REG_EXC_FIELD_ON_THR_EXP_Msk ) {
1456
1469
ble_phy_disable ();
1457
1470
g_ble_phy_data .end_transition = BLE_PHY_TRANSITION_NONE ;
1471
+ STATS_INC (ble_phy_stats , tx_late_field );
1458
1472
STATS_INC (ble_phy_stats , tx_late );
1459
1473
rc = BLE_PHY_ERR_RADIO_STATE ;
1460
1474
} else {
@@ -1467,7 +1481,6 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans)
1467
1481
}
1468
1482
1469
1483
/* Now we can handle BS_CTRL */
1470
- CMAC -> CM_ERROR_DIS_REG &= ~CMAC_CM_ERROR_DIS_REG_CM_FIELD1_ERR_Msk ;
1471
1484
NVIC_EnableIRQ (FRAME_IRQn );
1472
1485
NVIC_EnableIRQ (FIELD_IRQn );
1473
1486
@@ -1499,20 +1512,17 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
1499
1512
assert ((int32_t )(ll_val32 - cmac_timer_read32 ()) < 1024 );
1500
1513
1501
1514
/*
1502
- * We do not want FIELD/FRAME interrupts or FIELD1_ERR until ble_phy_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.
1515
+ * We do not want FIELD/FRAME interrupts until ble_phy_tx() has
1516
+ * pushed all fields.
1506
1517
*/
1507
1518
NVIC_DisableIRQ (FRAME_IRQn );
1508
1519
NVIC_DisableIRQ (FIELD_IRQn );
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 ;
1511
1520
1512
1521
CMAC -> CM_LL_TIMER1_9_0_EQ_X_REG = ll_val32 ;
1513
1522
CMAC -> CM_EV_LINKUP_REG = CMAC_CM_EV_LINKUP_REG_LU_FRAME_START_2_TMR1_9_0_EQ_X_Msk ;
1514
1523
1515
1524
if ((int32_t )(ll_val32 - cmac_timer_read32 ()) < 0 ) {
1525
+ STATS_INC (ble_phy_stats , tx_late_sched );
1516
1526
goto tx_late ;
1517
1527
}
1518
1528
@@ -1529,10 +1539,10 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
1529
1539
* need to assume tx_late and abort.
1530
1540
*/
1531
1541
if (CMAC -> CM_EXC_STAT_REG & CMAC_CM_EXC_STAT_REG_EXC_FRAME_START_Msk ) {
1542
+ STATS_INC (ble_phy_stats , tx_late_frame );
1532
1543
goto tx_late ;
1533
1544
}
1534
1545
1535
- CMAC -> CM_ERROR_DIS_REG &= ~CMAC_CM_ERROR_DIS_REG_CM_FRAME_ERR_Msk ;
1536
1546
rc = 0 ;
1537
1547
1538
1548
goto done ;
0 commit comments