On SDK16.0.0 + Mesh SDK 4.1.0
I am using a Fanstel BT840X module that has an onboard Skyworks SKY66112 PA/LNA.
I followed the Infocenter guide along with an old example (to automatically assign unused PPI and GPIOTE channels). I can see the stronger RSSI and I can provision it fine (nRF Mesh app), but then it times out on 'Requesting Composition Data'.
static ble_opt_t ble_pa_lna_opts; static mesh_pa_lna_gpiote_params_t m_pa_lna_params; static void pa_lna_init(uint8_t gpio_pa_pin, uint8_t gpio_lna_pin) { nrf_ppi_channel_t m_pa_lna_set_ppi_channel; nrf_ppi_channel_t m_pa_lna_clr_ppi_channel; uint8_t pa_lna_gpiote_ch = NULL; memset(&ble_pa_lna_opts, 0, sizeof(ble_opt_t)); memset(&m_pa_lna_params, 0, sizeof(mesh_pa_lna_gpiote_params_t)); // Enable BT840X SKY66112 PA/LNA nrf_gpio_cfg_output(BT840X_CPS); nrf_gpio_cfg_output(BT840X_CHL); nrf_gpio_pin_set(BT840X_CHL); nrf_gpio_pin_clear(BT840X_CPS); //low=enable, high=bypass //Already initialized by buttons_init() //ERROR_CHECK(nrf_drv_gpiote_init()); //Already initialized by saadc_init() //ERROR_CHECK(nrf_drv_ppi_init()); ERROR_CHECK(nrf_drv_ppi_channel_alloc(&m_pa_lna_set_ppi_channel)); ERROR_CHECK(nrf_drv_ppi_channel_alloc(&m_pa_lna_clr_ppi_channel)); nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false); if((gpio_pa_pin == NULL) && (gpio_lna_pin == NULL)) { ERROR_CHECK(NRF_ERROR_INVALID_PARAM); } if(gpio_pa_pin != NULL) { if(pa_lna_gpiote_ch == NULL) { ERROR_CHECK(nrf_drv_gpiote_out_init(gpio_pa_pin, &config)); pa_lna_gpiote_ch = nrf_drv_gpiote_out_task_addr_get(gpio_pa_pin); } // BLE PA config ble_pa_lna_opts.common_opt.pa_lna.pa_cfg.enable = 1; ble_pa_lna_opts.common_opt.pa_lna.pa_cfg.active_high = 1; ble_pa_lna_opts.common_opt.pa_lna.pa_cfg.gpio_pin = gpio_pa_pin; // MESH PA config m_pa_lna_params.pa_cfg.enable = 1; m_pa_lna_params.pa_cfg.active_high = 1; m_pa_lna_params.pa_cfg.gpio_pin = gpio_pa_pin; } if(gpio_lna_pin != NULL) { if(pa_lna_gpiote_ch == NULL) { ERROR_CHECK(nrf_drv_gpiote_out_init(gpio_lna_pin, &config)); pa_lna_gpiote_ch = nrf_drv_gpiote_out_task_addr_get(gpio_lna_pin); } // LNA config ble_pa_lna_opts.common_opt.pa_lna.lna_cfg.enable = 1; ble_pa_lna_opts.common_opt.pa_lna.lna_cfg.active_high = 1; ble_pa_lna_opts.common_opt.pa_lna.lna_cfg.gpio_pin = gpio_lna_pin; // MESH LNA config m_pa_lna_params.pa_cfg.enable = 1; m_pa_lna_params.pa_cfg.active_high = 1; m_pa_lna_params.pa_cfg.gpio_pin = gpio_lna_pin; } // Common BLE PA/LNA config ble_pa_lna_opts.common_opt.pa_lna.ppi_ch_id_set = m_pa_lna_set_ppi_channel; // PPI channel used for radio pin setting ble_pa_lna_opts.common_opt.pa_lna.ppi_ch_id_clr = m_pa_lna_clr_ppi_channel; // PPI channel used for radio pin clearing ble_pa_lna_opts.common_opt.pa_lna.gpiote_ch_id = (pa_lna_gpiote_ch - NRF_GPIOTE_BASE) >> 2; // GPIOTE channel used for radio pin toggling // Common MESH PA/LNA config, can use same channels as for BLE m_pa_lna_params.ppi_ch_id_set = ble_pa_lna_opts.common_opt.pa_lna.ppi_ch_id_set; m_pa_lna_params.ppi_ch_id_clr = ble_pa_lna_opts.common_opt.pa_lna.ppi_ch_id_clr; m_pa_lna_params.gpiote_ch_id = ble_pa_lna_opts.common_opt.pa_lna.gpiote_ch_id; __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "PA/LNA PPI_SET: %u, PPI_CLR: %u, GPIOTE: %u\n", ble_pa_lna_opts.common_opt.pa_lna.ppi_ch_id_set, ble_pa_lna_opts.common_opt.pa_lna.ppi_ch_id_clr, ble_pa_lna_opts.common_opt.pa_lna.gpiote_ch_id); //ERROR_CHECK(sd_ble_opt_set(BLE_COMMON_OPT_PA_LNA, &ble_pa_lna_opts)); }
This ends up assigning PPI channels 2 & 3 and GPIOTE channel 1. I believe this makes sense since I am using 2 PPI channels for SAADC and 1 GPIOTE channel for app_button.
I added the provisioning_sd_ble_opt_cb() callback and modified prov_start_params in start() for it.
static void provisioning_sd_ble_opt_cb(void) { ERROR_CHECK(sd_ble_opt_set(BLE_COMMON_OPT_PA_LNA, &ble_pa_lna_opts)); } static void start(void) { //rtt_input_enable(app_rtt_input_handler, RTT_INPUT_POLL_PERIOD_MS); if(!m_device_provisioned) { static const uint8_t static_auth_data[NRF_MESH_KEY_SIZE] = STATIC_AUTH_DATA; mesh_provisionee_start_params_t prov_start_params = { .p_static_data = static_auth_data, #if ENABLE_PA_LNA .prov_sd_ble_opt_set_cb = provisioning_sd_ble_opt_cb, #else .prov_sd_ble_opt_set_cb = NULL, #endif .prov_complete_cb = provisioning_complete_cb, .prov_device_identification_start_cb = device_identification_start_cb, .prov_device_identification_stop_cb = NULL, .prov_abort_cb = provisioning_aborted_cb, .p_device_uri = EX_URI_LS_SERVER }; ERROR_CHECK(mesh_provisionee_prov_start(&prov_start_params)); } else { unicast_address_print(); } ERROR_CHECK(mesh_stack_start()); }
Finally, I modified initialize() to add the calls before and after mesh_init() as per the guide.
static void initialize(void) { __LOG_INIT(LOG_SRC_APP | LOG_SRC_FRIEND, LOG_LEVEL_DBG1, LOG_CALLBACK_DEFAULT); uint32_t icRevision = NRF_FICR->INFO.VARIANT; __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "IC Revision: %08X (%c%c%c%c)\n", icRevision, (icRevision>>24)&0xFF, (icRevision>>16)&0xFF, (icRevision>>8)&0xFF, icRevision&0xFF); ERROR_CHECK(app_timer_init()); hal_leds_init(); #if BUTTON_BOARD //ERROR_CHECK(hal_buttons_init(button_event_handler)); buttons_init(); //using app_button.c #endif //SAADC saadc_init(); saadc_sampling_event_init(); saadc_sampling_event_enable(); #if ENABLE_PA_LNA pa_lna_init(BT840X_CTX, BT840X_CRX); #endif ble_stack_init(); #if MESH_FEATURE_GATT_ENABLED gap_params_init(); conn_params_init(); #endif #if ENABLE_PA_LNA ERROR_CHECK(sd_ble_opt_set(BLE_COMMON_OPT_PA_LNA, &ble_pa_lna_opts)); #endif mesh_init(); #if ENABLE_PA_LNA mesh_pa_lna_gpiote_enable(&m_pa_lna_params); #endif }
After all this, it provisions fine, but times out on the next step where it's requesting the composition data.
Thanks.