The S132 SoftDevice for the nRF52 has support for enable/disable switching of external Power Amplifiers (PA) and Low Noise Amplifiers (LNA) using GPIO pins. This was introduced in S132 version 2.0.0-7.alpha.
In the nRF51 there was an option to use the VDD_PA pin to detect when the radio was in TX mode, but this is not an option on the nRF52, making the SoftDevice solution necessary.
The following function can be used to enable PA/LNA signal. Adapt it as required in order to change the number of pins (1 or 2), pin numbers, polarity etc.
static void pa_lna_assist(uint32_t gpio_pa_pin, uint32_t gpio_lna_pin)
static const uint32_t gpio_toggle_ch = 0;
static const uint32_t ppi_set_ch = 0;
static const uint32_t ppi_clr_ch = 1;
// Configure SoftDevice PA/LNA assist
memset(&opt, 0, sizeof(ble_opt_t));
// Common PA/LNA config
opt.common_opt.pa_lna.gpiote_ch_id = gpio_toggle_ch; // GPIOTE channel
opt.common_opt.pa_lna.ppi_ch_id_clr = ppi_clr_ch; // PPI channel for pin clearing
opt.common_opt.pa_lna.ppi_ch_id_set = ppi_set_ch; // PPI channel for pin setting
// PA config
opt.common_opt.pa_lna.pa_cfg.active_high = 1; // Set the pin to be active high
opt.common_opt.pa_lna.pa_cfg.enable = 1; // Enable toggling
opt.common_opt.pa_lna.pa_cfg.gpio_pin = gpio_pa_pin; // The GPIO pin to toggle
// LNA config
opt.common_opt.pa_lna.lna_cfg.active_high = 1; // Set the pin to be active high
opt.common_opt.pa_lna.lna_cfg.enable = 1; // Enable toggling
opt.common_opt.pa_lna.lna_cfg.gpio_pin = gpio_lna_pin; // The GPIO pin to toggle
err_code = sd_ble_opt_set(BLE_COMMON_OPT_PA_LNA, &opt);
The plot below shows a measurement using the PA/LNA signal when starting up the radio in TX mode. In the plot, M2 is the point where the analyzer triggered on the PA signal from the GPIO. This is ~7.6 us after the radio was turned on (M1) and ~5.8 us before the radio starts to modulate data (M3). The measurement was performed using S132 version 2.0.0-7.alpha.
When GPIOTE channels are allocated with nrf_drv_gpiote, how to proceed?
I do not find an API to retrieve a GPIOTE channel once it has been allocated from a nrf_drv_gpiote call, I guess here nrf_drv_gpiote_out_init(). As other part of the application may allocate channels from this API, hardcoding the GPIOTE channel to use does not seem valid. channel_port_get() would give the allocated channel, but it is not exposed to the public API of this driver.