29
29
#include "controller/ble_phy.h"
30
30
#include "controller/ble_phy_trace.h"
31
31
#include "controller/ble_ll.h"
32
+ #include "controller/ble_ll_plna.h"
32
33
#include "nrfx.h"
33
34
#if MYNEWT
34
35
#include "mcu/nrf52_clock.h"
49
50
* using PPI somewhere else.
50
51
*
51
52
* Pre-programmed channels: CH20, CH21, CH23, CH25, CH31
52
- * Regular channels: CH4, CH5 and optionally CH17, CH18, CH19
53
+ * Regular channels: CH4, CH5 and optionally CH6, CH7, CH17, CH18, CH19
53
54
* - CH4 = cancel wfr timer on address match
54
55
* - CH5 = disable radio on wfr timer expiry
56
+ * - CH6 = PA/LNA control (enable)
57
+ * - CH7 = PA/LNA control (disable)
55
58
* - CH17 = (optional) gpio debug for radio ramp-up
56
59
* - CH18 = (optional) gpio debug for wfr timer RX enabled
57
60
* - CH19 = (optional) gpio debug for wfr timer radio disabled
@@ -277,6 +280,27 @@ struct nrf_ccm_data
277
280
struct nrf_ccm_data g_nrf_ccm_data ;
278
281
#endif
279
282
283
+ static int g_ble_phy_gpiote_idx ;
284
+
285
+ #if MYNEWT_VAL (BLE_LL_PA ) || MYNEWT_VAL (BLE_LL_LNA )
286
+
287
+ #define PLNA_SINGLE_GPIO \
288
+ (!MYNEWT_VAL(BLE_LL_PA) || !MYNEWT_VAL(BLE_LL_LNA) || \
289
+ (MYNEWT_VAL(BLE_LL_PA_GPIO) == MYNEWT_VAL(BLE_LL_LNA_GPIO)))
290
+
291
+ #if PLNA_SINGLE_GPIO
292
+ static uint8_t plna_idx ;
293
+ #else
294
+ #if MYNEWT_VAL (BLE_LL_PA )
295
+ static uint8_t plna_pa_idx ;
296
+ #endif
297
+ #if MYNEWT_VAL (BLE_LL_LNA )
298
+ static uint8_t plna_lna_idx ;
299
+ #endif
300
+ #endif
301
+
302
+ #endif
303
+
280
304
static void
281
305
ble_phy_apply_errata_102_106_107 (void )
282
306
{
@@ -400,6 +424,36 @@ ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode)
400
424
}
401
425
#endif
402
426
427
+ static void
428
+ ble_phy_plna_enable_pa (void )
429
+ {
430
+ #if MYNEWT_VAL (BLE_LL_PA )
431
+ ble_ll_plna_pa_enable ();
432
+
433
+ #if !PLNA_SINGLE_GPIO
434
+ NRF_PPI -> CH [6 ].TEP = (uint32_t ) & (NRF_GPIOTE -> TASKS_SET [plna_pa_idx ]);
435
+ NRF_PPI -> CH [7 ].TEP = (uint32_t ) & (NRF_GPIOTE -> TASKS_CLR [plna_pa_idx ]);
436
+ #endif
437
+
438
+ NRF_PPI -> CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk ;
439
+ #endif
440
+ }
441
+
442
+ static void
443
+ ble_phy_plna_enable_lna (void )
444
+ {
445
+ #if MYNEWT_VAL (BLE_LL_LNA )
446
+ ble_ll_plna_lna_enable ();
447
+
448
+ #if !PLNA_SINGLE_GPIO
449
+ NRF_PPI -> CH [6 ].TEP = (uint32_t ) & (NRF_GPIOTE -> TASKS_SET [plna_lna_idx ]);
450
+ NRF_PPI -> CH [7 ].TEP = (uint32_t ) & (NRF_GPIOTE -> TASKS_CLR [plna_lna_idx ]);
451
+ #endif
452
+
453
+ NRF_PPI -> CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk ;
454
+ #endif
455
+ }
456
+
403
457
int
404
458
ble_phy_get_cur_phy (void )
405
459
{
@@ -925,6 +979,8 @@ ble_phy_tx_end_isr(void)
925
979
NRF_TIMER0 -> CC [0 ] = rx_time ;
926
980
NRF_TIMER0 -> EVENTS_COMPARE [0 ] = 0 ;
927
981
NRF_PPI -> CHENSET = PPI_CHEN_CH21_Msk ;
982
+
983
+ ble_phy_plna_enable_lna ();
928
984
} else {
929
985
/*
930
986
* XXX: not sure we need to stop the timer here all the time. Or that
@@ -1053,6 +1109,8 @@ ble_phy_rx_end_isr(void)
1053
1109
NRF_TIMER0 -> EVENTS_COMPARE [0 ] = 0 ;
1054
1110
NRF_PPI -> CHENSET = PPI_CHEN_CH20_Msk ;
1055
1111
1112
+ ble_phy_plna_enable_pa ();
1113
+
1056
1114
/*
1057
1115
* XXX: Hack warning!
1058
1116
*
@@ -1255,13 +1313,21 @@ ble_phy_isr(void)
1255
1313
1256
1314
switch (g_ble_phy_data .phy_state ) {
1257
1315
case BLE_PHY_STATE_RX :
1316
+ #if MYNEWT_VAL (BLE_LL_LNA )
1317
+ NRF_PPI -> CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk ;
1318
+ ble_ll_plna_lna_disable ();
1319
+ #endif
1258
1320
if (g_ble_phy_data .phy_rx_started ) {
1259
1321
ble_phy_rx_end_isr ();
1260
1322
} else {
1261
1323
ble_ll_wfr_timer_exp (NULL );
1262
1324
}
1263
1325
break ;
1264
1326
case BLE_PHY_STATE_TX :
1327
+ #if MYNEWT_VAL (BLE_LL_PA )
1328
+ NRF_PPI -> CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk ;
1329
+ ble_ll_plna_pa_disable ();
1330
+ #endif
1265
1331
ble_phy_tx_end_isr ();
1266
1332
break ;
1267
1333
default :
@@ -1278,13 +1344,17 @@ ble_phy_isr(void)
1278
1344
}
1279
1345
1280
1346
#if MYNEWT_VAL (BLE_PHY_DBG_TIME_TXRXEN_READY_PIN ) >= 0 || \
1281
- MYNEWT_VAL (BLE_PHY_DBG_TIME_ADDRESS_END_PIN ) >= 0 || \
1282
- MYNEWT_VAL (BLE_PHY_DBG_TIME_WFR_PIN ) >= 0
1283
- static inline void
1284
- ble_phy_dbg_time_setup_gpiote (int index , int pin )
1347
+ MYNEWT_VAL (BLE_PHY_DBG_TIME_ADDRESS_END_PIN ) >= 0 || \
1348
+ MYNEWT_VAL (BLE_PHY_DBG_TIME_WFR_PIN ) >= 0 || \
1349
+ MYNEWT_VAL (BLE_LL_PA ) || \
1350
+ MYNEWT_VAL (BLE_LL_LNA )
1351
+ static int
1352
+ ble_phy_gpiote_configure (int pin )
1285
1353
{
1286
1354
NRF_GPIO_Type * port ;
1287
1355
1356
+ g_ble_phy_gpiote_idx -- ;
1357
+
1288
1358
#if NRF52840_XXAA
1289
1359
port = pin > 31 ? NRF_P1 : NRF_P0 ;
1290
1360
pin &= 0x1f ;
@@ -1296,21 +1366,25 @@ ble_phy_dbg_time_setup_gpiote(int index, int pin)
1296
1366
port -> DIRSET = (1 << pin );
1297
1367
port -> OUTCLR = (1 << pin );
1298
1368
1299
- NRF_GPIOTE -> CONFIG [index ] =
1369
+ NRF_GPIOTE -> CONFIG [g_ble_phy_gpiote_idx ] =
1300
1370
(GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos ) |
1301
1371
((pin & 0x1F ) << GPIOTE_CONFIG_PSEL_Pos ) |
1302
1372
#if NRF52840_XXAA
1303
1373
((port == NRF_P1 ) << GPIOTE_CONFIG_PORT_Pos );
1304
1374
#else
1305
1375
0 ;
1306
1376
#endif
1377
+
1378
+ BLE_LL_ASSERT (g_ble_phy_gpiote_idx >= 0 );
1379
+
1380
+ return g_ble_phy_gpiote_idx ;
1307
1381
}
1308
1382
#endif
1309
1383
1310
1384
static void
1311
1385
ble_phy_dbg_time_setup (void )
1312
1386
{
1313
- int gpiote_idx __attribute__((unused )) = 8 ;
1387
+ int idx __attribute__((unused ));
1314
1388
1315
1389
/*
1316
1390
* We setup GPIOTE starting from last configuration index to minimize risk
@@ -1319,44 +1393,41 @@ ble_phy_dbg_time_setup(void)
1319
1393
*/
1320
1394
1321
1395
#if MYNEWT_VAL (BLE_PHY_DBG_TIME_TXRXEN_READY_PIN ) >= 0
1322
- ble_phy_dbg_time_setup_gpiote (-- gpiote_idx ,
1323
- MYNEWT_VAL (BLE_PHY_DBG_TIME_TXRXEN_READY_PIN ));
1396
+ idx = ble_phy_gpiote_configure (MYNEWT_VAL (BLE_PHY_DBG_TIME_TXRXEN_READY_PIN ));
1324
1397
1325
1398
NRF_PPI -> CH [17 ].EEP = (uint32_t )& (NRF_RADIO -> EVENTS_READY );
1326
- NRF_PPI -> CH [17 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_CLR [gpiote_idx ]);
1399
+ NRF_PPI -> CH [17 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_CLR [idx ]);
1327
1400
NRF_PPI -> CHENSET = PPI_CHEN_CH17_Msk ;
1328
1401
1329
1402
/* CH[20] and PPI CH[21] are on to trigger TASKS_TXEN or TASKS_RXEN */
1330
- NRF_PPI -> FORK [20 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_SET [gpiote_idx ]);
1331
- NRF_PPI -> FORK [21 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_SET [gpiote_idx ]);
1403
+ NRF_PPI -> FORK [20 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_SET [idx ]);
1404
+ NRF_PPI -> FORK [21 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_SET [idx ]);
1332
1405
#endif
1333
1406
1334
1407
#if MYNEWT_VAL (BLE_PHY_DBG_TIME_ADDRESS_END_PIN ) >= 0
1335
- ble_phy_dbg_time_setup_gpiote (-- gpiote_idx ,
1336
- MYNEWT_VAL (BLE_PHY_DBG_TIME_ADDRESS_END_PIN ));
1408
+ idx = ble_phy_gpiote_configure (MYNEWT_VAL (BLE_PHY_DBG_TIME_ADDRESS_END_PIN ));
1337
1409
1338
1410
/* CH[26] and CH[27] are always on for EVENT_ADDRESS and EVENT_END */
1339
- NRF_PPI -> FORK [26 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_SET [gpiote_idx ]);
1340
- NRF_PPI -> FORK [27 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_CLR [gpiote_idx ]);
1411
+ NRF_PPI -> FORK [26 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_SET [idx ]);
1412
+ NRF_PPI -> FORK [27 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_CLR [idx ]);
1341
1413
#endif
1342
1414
1343
1415
#if MYNEWT_VAL (BLE_PHY_DBG_TIME_WFR_PIN ) >= 0
1344
- ble_phy_dbg_time_setup_gpiote (-- gpiote_idx ,
1345
- MYNEWT_VAL (BLE_PHY_DBG_TIME_WFR_PIN ));
1416
+ idx = ble_phy_gpiote_configure (MYNEWT_VAL (BLE_PHY_DBG_TIME_WFR_PIN ));
1346
1417
1347
1418
#if NRF52840_XXAA
1348
1419
NRF_PPI -> CH [18 ].EEP = (uint32_t )& (NRF_RADIO -> EVENTS_RXREADY );
1349
1420
#else
1350
1421
NRF_PPI -> CH [18 ].EEP = (uint32_t )& (NRF_RADIO -> EVENTS_READY );
1351
1422
#endif
1352
- NRF_PPI -> CH [18 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_SET [gpiote_idx ]);
1423
+ NRF_PPI -> CH [18 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_SET [idx ]);
1353
1424
NRF_PPI -> CH [19 ].EEP = (uint32_t )& (NRF_RADIO -> EVENTS_DISABLED );
1354
- NRF_PPI -> CH [19 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_CLR [gpiote_idx ]);
1425
+ NRF_PPI -> CH [19 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_CLR [idx ]);
1355
1426
NRF_PPI -> CHENSET = PPI_CHEN_CH18_Msk | PPI_CHEN_CH19_Msk ;
1356
1427
1357
1428
/* CH[4] and CH[5] are always on for wfr */
1358
- NRF_PPI -> FORK [4 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_CLR [gpiote_idx ]);
1359
- NRF_PPI -> FORK [5 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_CLR [gpiote_idx ]);
1429
+ NRF_PPI -> FORK [4 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_CLR [idx ]);
1430
+ NRF_PPI -> FORK [5 ].TEP = (uint32_t )& (NRF_GPIOTE -> TASKS_CLR [idx ]);
1360
1431
#endif
1361
1432
}
1362
1433
@@ -1372,6 +1443,8 @@ ble_phy_init(void)
1372
1443
{
1373
1444
int rc ;
1374
1445
1446
+ g_ble_phy_gpiote_idx = 8 ;
1447
+
1375
1448
/* Default phy to use is 1M */
1376
1449
g_ble_phy_data .phy_cur_phy_mode = BLE_PHY_MODE_1M ;
1377
1450
g_ble_phy_data .phy_tx_phy_mode = BLE_PHY_MODE_1M ;
@@ -1455,6 +1528,27 @@ ble_phy_init(void)
1455
1528
NRF_PPI -> CH [5 ].EEP = (uint32_t )& (NRF_TIMER0 -> EVENTS_COMPARE [3 ]);
1456
1529
NRF_PPI -> CH [5 ].TEP = (uint32_t )& (NRF_RADIO -> TASKS_DISABLE );
1457
1530
1531
+ #if MYNEWT_VAL (BLE_LL_PA ) || MYNEWT_VAL (BLE_LL_LNA )
1532
+ #if PLNA_SINGLE_GPIO
1533
+ plna_idx = ble_phy_gpiote_configure (MYNEWT_VAL (BLE_LL_PA_GPIO ));
1534
+ NRF_PPI -> CH [6 ].TEP = (uint32_t ) & (NRF_GPIOTE -> TASKS_SET [plna_idx ]);
1535
+ NRF_PPI -> CH [7 ].TEP = (uint32_t ) & (NRF_GPIOTE -> TASKS_CLR [plna_idx ]);
1536
+ #else
1537
+ #if MYNEWT_VAL (BLE_LL_PA )
1538
+ plna_pa_idx = ble_phy_gpiote_configure (MYNEWT_VAL (BLE_LL_PA_GPIO ));
1539
+ NRF_GPIOTE -> TASKS_CLR [plna_pa_idx ] = 1 ;
1540
+ #endif
1541
+ #if MYNEWT_VAL (BLE_LL_LNA )
1542
+ plna_lna_idx = ble_phy_gpiote_configure (MYNEWT_VAL (BLE_LL_LNA_GPIO ));
1543
+ NRF_GPIOTE -> TASKS_CLR [plna_lna_idx ] = 1 ;
1544
+ #endif
1545
+ #endif
1546
+
1547
+ NRF_PPI -> CH [6 ].EEP = (uint32_t )& (NRF_RADIO -> EVENTS_READY );
1548
+ NRF_PPI -> CH [7 ].EEP = (uint32_t )& (NRF_RADIO -> EVENTS_DISABLED );
1549
+ NRF_PPI -> CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk ;
1550
+ #endif
1551
+
1458
1552
/* Set isr in vector table and enable interrupt */
1459
1553
#ifndef RIOT_VERSION
1460
1554
NVIC_SetPriority (RADIO_IRQn , 0 );
@@ -1617,7 +1711,10 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
1617
1711
/* Enable PPI to automatically start TXEN */
1618
1712
NRF_PPI -> CHENSET = PPI_CHEN_CH20_Msk ;
1619
1713
rc = 0 ;
1714
+
1715
+ ble_phy_plna_enable_pa ();
1620
1716
}
1717
+
1621
1718
return rc ;
1622
1719
}
1623
1720
@@ -1662,6 +1759,8 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
1662
1759
/* Enable PPI to automatically start RXEN */
1663
1760
NRF_PPI -> CHENSET = PPI_CHEN_CH21_Msk ;
1664
1761
1762
+ ble_phy_plna_enable_lna ();
1763
+
1665
1764
/* Start rx */
1666
1765
rc = ble_phy_rx ();
1667
1766
@@ -1959,6 +2058,7 @@ ble_phy_disable_irq_and_ppi(void)
1959
2058
NRF_PPI -> CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | PPI_CHEN_CH20_Msk |
1960
2059
PPI_CHEN_CH21_Msk | PPI_CHEN_CH23_Msk |
1961
2060
PPI_CHEN_CH25_Msk | PPI_CHEN_CH31_Msk ;
2061
+ NRF_PPI -> CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk ;
1962
2062
NVIC_ClearPendingIRQ (RADIO_IRQn );
1963
2063
g_ble_phy_data .phy_state = BLE_PHY_STATE_IDLE ;
1964
2064
}
0 commit comments