Skip to content

Commit 984e879

Browse files
committed
ll/nrf5340: Add support for PHY GPIO debug
1 parent 854f362 commit 984e879

File tree

2 files changed

+192
-0
lines changed

2 files changed

+192
-0
lines changed

nimble/drivers/nrf5340/src/ble_phy.c

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <assert.h>
2323
#include <syscfg/syscfg.h>
2424
#include <os/os.h>
25+
#include <bsp/bsp.h>
2526
#include <nimble/ble.h>
2627
#include <nimble/nimble_opt.h>
2728
#include <nimble/nimble_npl.h>
@@ -38,6 +39,8 @@
3839
* DPPI somewhere else.
3940
* TODO maybe we could reduce number of used channels if we reuse same channel
4041
* for mutually exclusive events but for now make it simpler to debug.
42+
*
43+
* Optionally channels 6,7,8 are used for GPIO DBG.
4144
*/
4245

4346
#define DPPI_CH_TIMER0_EVENTS_COMPARE_0 0
@@ -82,6 +85,39 @@
8285
#define DPPI_SUBSCRIBE_CCM_TASKS_CRYPT(_enable) ((DPPI_CH_RADIO_EVENTS_ADDRESS << CCM_SUBSCRIBE_CRYPT_CHIDX_Pos) | \
8386
((_enable) << CCM_SUBSCRIBE_CRYPT_EN_Pos))
8487

88+
/* used for GPIO DBG */
89+
#define DPPI_CH_RADIO_EVENTS_READY 6
90+
#define DPPI_CH_RADIO_EVENTS_RXREADY 7
91+
#define DPPI_CH_RADIO_EVENTS_DISABLED 8
92+
93+
#define DPPI_CH_ENABLE_RADIO_EVENTS_READY DPPIC_CHEN_CH6_Msk
94+
#define DPPI_CH_ENABLE_RADIO_EVENTS_RXREADY DPPIC_CHEN_CH7_Msk
95+
#define DPPI_CH_ENABLE_RADIO_EVENTS_DISABLED DPPIC_CHEN_CH8_Msk
96+
97+
#define DPPI_PUBLISH_RADIO_EVENTS_READY ((DPPI_CH_RADIO_EVENTS_READY << RADIO_PUBLISH_READY_CHIDX_Pos) | \
98+
(RADIO_PUBLISH_READY_EN_Enabled << RADIO_PUBLISH_READY_EN_Pos))
99+
#define DPPI_PUBLISH_RADIO_EVENTS_RXREADY ((DPPI_CH_RADIO_EVENTS_RXREADY << RADIO_PUBLISH_RXREADY_CHIDX_Pos) | \
100+
(RADIO_PUBLISH_RXREADY_EN_Enabled << RADIO_PUBLISH_RXREADY_EN_Pos))
101+
#define DPPI_PUBLISH_RADIO_EVENTS_DISABLED ((DPPI_CH_RADIO_EVENTS_DISABLED << RADIO_PUBLISH_DISABLED_CHIDX_Pos) | \
102+
(RADIO_PUBLISH_DISABLED_EN_Enabled << RADIO_PUBLISH_DISABLED_EN_Pos))
103+
104+
#define DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_TXRXEN ((DPPI_CH_TIMER0_EVENTS_COMPARE_0 << GPIOTE_SUBSCRIBE_SET_CHIDX_Pos) | \
105+
(1 << GPIOTE_SUBSCRIBE_SET_EN_Pos))
106+
#define DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_ADDRESS ((DPPI_CH_RADIO_EVENTS_ADDRESS << GPIOTE_SUBSCRIBE_SET_CHIDX_Pos) | \
107+
(1 << GPIOTE_SUBSCRIBE_SET_EN_Pos))
108+
#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_END ((DPPI_CH_RADIO_EVENTS_END << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \
109+
(1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos))
110+
#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_READY ((DPPI_CH_RADIO_EVENTS_READY << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \
111+
(1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos))
112+
#define DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_RXREADY ((DPPI_CH_RADIO_EVENTS_RXREADY << GPIOTE_SUBSCRIBE_SET_CHIDX_Pos) | \
113+
(1 << GPIOTE_SUBSCRIBE_SET_EN_Pos))
114+
#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_DISABLED ((DPPI_CH_RADIO_EVENTS_DISABLED << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \
115+
(1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos))
116+
#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_CAPTURE3 ((DPPI_CH_TIMER0_EVENTS_COMPARE_3 << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \
117+
(1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos))
118+
#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_ADDRESS ((DPPI_CH_RADIO_EVENTS_ADDRESS << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \
119+
(1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos))
120+
85121
extern uint8_t g_nrf_num_irks;
86122
extern uint32_t g_nrf_irk_list[];
87123

@@ -1179,6 +1215,84 @@ ble_phy_isr(void)
11791215
os_trace_isr_exit();
11801216
}
11811217

1218+
#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \
1219+
MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \
1220+
MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0
1221+
static inline void
1222+
ble_phy_dbg_time_setup_gpiote(int index, int pin)
1223+
{
1224+
NRF_GPIO_Type *port;
1225+
1226+
port = pin > 31 ? NRF_P1_NS : NRF_P0_NS;
1227+
pin &= 0x1f;
1228+
1229+
/* Configure GPIO directly to avoid dependency to hal_gpio (for porting) */
1230+
port->DIRSET = (1 << pin);
1231+
port->OUTCLR = (1 << pin);
1232+
1233+
NRF_GPIOTE_NS->CONFIG[index] =
1234+
(GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
1235+
((pin & 0x1F) << GPIOTE_CONFIG_PSEL_Pos) |
1236+
((port == NRF_P1_NS) << GPIOTE_CONFIG_PORT_Pos);
1237+
}
1238+
#endif
1239+
1240+
static void
1241+
ble_phy_dbg_time_setup(void)
1242+
{
1243+
int gpiote_idx __attribute__((unused)) = 8;
1244+
1245+
/*
1246+
* We setup GPIOTE starting from last configuration index to minimize risk
1247+
* of conflict with GPIO setup via hal. It's not great solution, but since
1248+
* this is just debugging code we can live with this.
1249+
*/
1250+
1251+
#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0
1252+
ble_phy_dbg_time_setup_gpiote(--gpiote_idx,
1253+
MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN));
1254+
1255+
NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_TXRXEN;
1256+
NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_READY;
1257+
1258+
/* Publish RADIO->EVENTS_READY */
1259+
NRF_RADIO_NS->PUBLISH_READY = DPPI_PUBLISH_RADIO_EVENTS_READY;
1260+
NRF_DPPIC_NS->CHENSET = DPPI_CH_ENABLE_RADIO_EVENTS_READY;
1261+
1262+
#endif
1263+
1264+
#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0
1265+
ble_phy_dbg_time_setup_gpiote(--gpiote_idx,
1266+
MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN));
1267+
1268+
NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_ADDRESS;
1269+
NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_END;
1270+
#endif
1271+
1272+
#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0
1273+
ble_phy_dbg_time_setup_gpiote(--gpiote_idx,
1274+
MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN));
1275+
1276+
NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_RXREADY;
1277+
1278+
/* TODO figure out how (if?) to subscribe task to multiple DPPI channels
1279+
* Currently only last one is working. Also using multiple GPIOTE for same
1280+
* PIN doesn't work...
1281+
*/
1282+
NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_DISABLED;
1283+
NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_ADDRESS;
1284+
NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_CAPTURE3;
1285+
1286+
/* Publish RADIO->EVENTS_RXREADY */
1287+
NRF_RADIO_NS->PUBLISH_RXREADY = DPPI_PUBLISH_RADIO_EVENTS_RXREADY;
1288+
NRF_DPPIC_NS->CHENSET = DPPI_CH_ENABLE_RADIO_EVENTS_RXREADY;
1289+
1290+
/* Publish RADIO->EVENTS_DISABLED */
1291+
NRF_RADIO_NS->PUBLISH_DISABLED = DPPI_CH_ENABLE_RADIO_EVENTS_DISABLED;
1292+
NRF_DPPIC_NS->CHENSET = DPPI_CH_ENABLE_RADIO_EVENTS_DISABLED;
1293+
#endif
1294+
}
1295+
11821296
int
11831297
ble_phy_init(void)
11841298
{
@@ -1296,6 +1410,8 @@ ble_phy_init(void)
12961410
g_ble_phy_data.phy_stats_initialized = 1;
12971411
}
12981412

1413+
ble_phy_dbg_time_setup();
1414+
12991415
return 0;
13001416
}
13011417

@@ -1725,13 +1841,50 @@ ble_phy_restart_rx(void)
17251841
ble_phy_rx();
17261842
}
17271843

1844+
static void
1845+
ble_phy_dbg_clear_pins(void)
1846+
{
1847+
#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \
1848+
MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \
1849+
MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0
1850+
NRF_GPIO_Type *port;
1851+
int pin;
1852+
1853+
#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0
1854+
pin = MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN);
1855+
port = pin > 31 ? NRF_P1_NS : NRF_P0_NS;
1856+
pin &= 0x1f;
1857+
1858+
port->OUTCLR = (1 << pin);
1859+
#endif
1860+
1861+
#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0
1862+
pin = MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN);
1863+
port = pin > 31 ? NRF_P1_NS : NRF_P0_NS;
1864+
pin &= 0x1f;
1865+
1866+
port->OUTCLR = (1 << pin);
1867+
#endif
1868+
1869+
#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0
1870+
pin = MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN);
1871+
port = pin > 31 ? NRF_P1_NS : NRF_P0_NS;
1872+
pin &= 0x1f;
1873+
1874+
port->OUTCLR = (1 << pin);
1875+
#endif
1876+
#endif
1877+
}
1878+
17281879
void
17291880
ble_phy_disable(void)
17301881
{
17311882
ble_phy_trace_void(BLE_PHY_TRACE_ID_DISABLE);
17321883

17331884
ble_phy_stop_usec_timer();
17341885
ble_phy_disable_irq_and_ppi();
1886+
1887+
ble_phy_dbg_clear_pins();
17351888
}
17361889

17371890
uint32_t

nimble/drivers/nrf5340/syscfg.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,42 @@ syscfg.defs:
2121
description: >
2222
Enable SystemView tracing module for radio driver.
2323
value: 0
24+
25+
BLE_PHY_DBG_TIME_TXRXEN_READY_PIN:
26+
description: >
27+
When set to proper GPIO pin number, this pin will be set
28+
to high state when radio is enabled (TASKS_TXEN or TASKS_RXEN)
29+
and back to low state on radio EVENTS_READY.
30+
This can be used to measure radio ram-up time.
31+
32+
Note:
33+
GPIO control for selected pin needs to be assigned to Network
34+
Core, configure IPC_NRF5340_NET_GPIO in ipc_nrf5340 driver on
35+
Application Core.
36+
value: -1
37+
38+
BLE_PHY_DBG_TIME_ADDRESS_END_PIN:
39+
description: >
40+
When set to proper GPIO pin number, this pin will be set
41+
to high state on radio EVENTS_ADDRESS and back to low state
42+
on radio EVENTS_END.
43+
This can be used to measure radio pipeline delays.
44+
45+
Note:
46+
GPIO control for selected pin needs to be assigned to Network
47+
Core, configure IPC_NRF5340_NET_GPIO in ipc_nrf5340 driver on
48+
Application Core.
49+
value: -1
50+
51+
BLE_PHY_DBG_TIME_WFR_PIN:
52+
description: >
53+
When set to proper GPIO pin number, this pin will be set
54+
to high state on radio EVENTS_RXREADY and back to low
55+
state when wfr timer expires.
56+
This can be used to check if wfr is calculated properly.
57+
58+
Note:
59+
GPIO control for selected pin needs to be assigned to Network
60+
Core, configure IPC_NRF5340_NET_GPIO in ipc_nrf5340 driver on
61+
Application Core.
62+
value: -1

0 commit comments

Comments
 (0)