This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Mesh PA / LNA problems

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.

  • Hei Ferdi, 

    Could you check the log on the device under test to see if there is any assertion ?
    I suspect that the device crashed after it disable and enable softdevice again after provisioning (before configuration)

    Also please try testing provisioning using ADV bearer  (using the provisioner example or use PyACI) instead of using a phone. In addition please check the signal strength when you do ADV mesh bearer. 

    Note that we have 2 systems that we need to enable PA/LNA, one is for the softdevice (GATT bearer) when you call sd_ble_opt_set() and one is for the mesh stack (ADV bearer) when you call mesh_pa_lna_gpiote_enable(). 

  • Hi,

    There are no asserts when trying to provision/configure with the nRF Mesh app (iOS). Sequence during provisioning goes like this (I am only showing relevant prints). While the app is requesting the composition data, it doesn't print out anything relevant. The DUT is still running and I can still see it advertise using nRF Connect. I also have a WDT timer that does not get invoked.

    <00> t:     147444>, ble_softdevice_support.c,  106, Successfully updated connection parameters
    <00> t:     281391>, mesh_gatt.c,  576, New MTU: 66
    <00> t:     714815>, main.c, 1585, Successfully provisioned
    <00> t:     714820>, main.c, 1580, Node Address: 0x0003

    When using the provisioner example the DUT doesn't print out anything during the provisioning and asserts after the provisioner prints "Provisioning link established"

    <00> t:    2570220>, app_error_weak.c,   96, Softdevice assert: 88972:0

    After the assert DUT's watchdog kicks in and restarts it.

    Here is the provisioner log:

    <00> t:      10227>, main.c,  483, Starting application ...
    <00> t:      10230>, main.c,  484, Provisioned Nodes: 0, Configured Nodes: 0
    <00> t:      10233>, main.c,  486, Dev key : 534A368958599EBF4A6AA9272673D9F5
    <00> t:      10236>, main.c,  487, Net key : FB9BC9BC9EE49A67E8EE781808B8A4C7
    <00> t:      10239>, main.c,  488, App key : 0BA8A8B7869DF5B3AFB6DC4D1A8F1E1C
    <00> t:      10242>, main.c,  489, Press Button 1 to start provisioning and configuration process. 
    <00> t:     604590>, main.c,  351, Button 1 pressed
    <00> t:     604593>, main.c,  274, Start provisioning procedure ...
    <00> t:     604595>, provisioner_helper.c,  326, Scanning For Unprovisioned Devices
    <00> t:     769005>, provisioner_helper.c,  168, UUID : D1E9C823620448C8BA0698129CC4AC23
    <00> t:     769008>, provisioner_helper.c,  171, ^RSSI: -87
    <00> t:     769010>, provisioner_helper.c,  177, ^URI Hash: 74F97940
    <00> t:     769024>, provisioner_helper.c,  332, Stop Scanning For Unprovisioned Devices
    <00> t:     769027>, provisioner_helper.c,  183, URI hash matched to ¹URI for LS Server example. Provisioning ...
    <00> t:    1580059>, provisioner_helper.c,  300, Provisioning link established
    <00> t:    2579259>, provisioner_helper.c,  192, Local provisioning link closed: prov_state: 3  remaining retries: 2
    <00> t:    2579263>, provisioner_helper.c,  197, Provisioning failed. Retrying...
    <00> t:    2579266>, provisioner_helper.c,  326, Scanning For Unprovisioned Devices
    <00> t:    2698276>, provisioner_helper.c,  168, UUID : D1E9C823620448C8BA0698129CC4AC23
    <00> t:    2698280>, provisioner_helper.c,  171, ^RSSI: -87
    <00> t:    2698282>, provisioner_helper.c,  177, ^URI Hash: 74F97940
    <00> t:    2698295>, provisioner_helper.c,  332, Stop Scanning For Unprovisioned Devices
    <00> t:    2698299>, provisioner_helper.c,  183, URI hash matched to ¹URI for LS Server example. Provisioning ...
    <00> t:    2723087>, provisioner_helper.c,  300, Provisioning link established
    <00> t:    4894334>, provisioner_helper.c,  192, Local provisioning link closed: prov_state: 3  remaining retries: 1
    <00> t:    4894338>, provisioner_helper.c,  197, Provisioning failed. Retrying...
    <00> t:    4894341>, provisioner_helper.c,  326, Scanning For Unprovisioned Devices
    <00> t:    4902933>, provisioner_helper.c,  168, UUID : D1E9C823620448C8BA0698129CC4AC23
    <00> t:    4902936>, provisioner_helper.c,  171, ^RSSI: -86
    <00> t:    4902939>, provisioner_helper.c,  177, ^URI Hash: 74F97940
    <00> t:    4902952>, provisioner_helper.c,  332, Stop Scanning For Unprovisioned Devices
    <00> t:    4902955>, provisioner_helper.c,  183, URI hash matched to ¹URI for LS Server example. Provisioning ...
    <00> t:    4911971>, provisioner_helper.c,  300, Provisioning link established
    <00> t:    5910204>, provisioner_helper.c,  192, Local provisioning link closed: prov_state: 3  remaining retries: 0
    <00> t:    5910208>, provisioner_helper.c,  204, Provisioning Failed. Code: 1, Could not assign node addr: 0x0203
    <00> t:    5910213>, main.c,  204, Provisioning failed. Press Button 1 to retry.
    <00> t:    7142802>, main.c,  351, Button 1 pressed
    <00> t:    7142804>, main.c,  274, Start provisioning procedure ...
    <00> t:    7142807>, provisioner_helper.c,  326, Scanning For Unprovisioned Devices
    <00> t:    7430260>, provisioner_helper.c,  168, UUID : D1E9C823620448C8BA0698129CC4AC23
    <00> t:    7430263>, provisioner_helper.c,  171, ^RSSI: -85
    <00> t:    7430265>, provisioner_helper.c,  177, ^URI Hash: 74F97940
    <00> t:    7430279>, provisioner_helper.c,  332, Stop Scanning For Unprovisioned Devices
    <00> t:    7430282>, provisioner_helper.c,  183, URI hash matched to ¹URI for LS Server example. Provisioning ...
    <00> t:    8232869>, provisioner_helper.c,  300, Provisioning link established

    They are about 25cm apart, but the log only shows RSSI around -85. nRF Connect shows -30.

    As a hunch, I brought them closer together, about 10cm and it was able to provision successfully.

    <00> t:     544973>, main.c,  351, Button 1 pressed
    <00> t:     544976>, main.c,  274, Start provisioning procedure ...
    <00> t:     544978>, provisioner_helper.c,  326, Scanning For Unprovisioned Devices
    <00> t:     561570>, provisioner_helper.c,  168, UUID : D1E9C823620448C8BA0698129CC4AC23
    <00> t:     561573>, provisioner_helper.c,  171, ^RSSI: -80
    <00> t:     561575>, provisioner_helper.c,  177, ^URI Hash: 74F97940
    <00> t:     561589>, provisioner_helper.c,  332, Stop Scanning For Unprovisioned Devices
    <00> t:     561592>, provisioner_helper.c,  183, URI hash matched to ¹URI for LS Server example. Provisioning ...
    <00> t:     568232>, provisioner_helper.c,  300, Provisioning link established
    <00> t:     582557>, provisioner_helper.c,  295, Static authentication data provided
    <00> t:     596571>, provisioner_helper.c,  233, Provisioning completed received
    <00> t:     596574>, provisioner_helper.c,  238, Adding device address, and device keys
    <00> t:     596596>, provisioner_helper.c,  251, Addr: 0x0201 addr_handle: 0 netkey_handle: 0 devkey_handle: 2
    <00> t:     602534>, provisioner_helper.c,  192, Local provisioning link closed: prov_state: 2  remaining retries: 2
    <00> t:     602542>, main.c,  194, Provisioning successful
    <00> t:     602547>, provisioner_helper.c,  216, Provisioning complete. ¹URI for LS Server example - address: 0x0201 elements: 1
    <00> t:     602552>, node_setup.c,  736, Configuring Node: 0x0201
    <00> t:     602555>, node_setup.c,  632, Config client setup: devkey_handle:2 addr_handle:0
    <00> t:     602559>, node_setup.c,  412, Getting composition data
    <00> t:     737053>, main.c,  247, Config client event
    <00> t:     737056>, node_setup.c,  421, Updating network transmit: count: 2 steps: 1
    <00> t:     739830>, main.c,  247, Config client event
    <00> t:     739833>, node_setup.c,  432, Adding appkey
    <00> t:     765202>, main.c,  247, Config client event
    <00> t:     765204>, node_setup.c,  272, opcode status field: 0 
    <00> t:     765207>, node_setup.c,  470, App key bind: Health server on element address 0x0201
    <00> t:     768206>, main.c,  247, Config client event
    <00> t:     768208>, node_setup.c,  272, opcode status field: 0 
    <00> t:     768224>, node_setup.c,  489, Setting publication address for Health server to 0x0001
    <00> t:     775804>, main.c,  247, Config client event
    <00> t:     775806>, node_setup.c,  272, opcode status field: 0 
    <00> t:     775809>, node_setup.c,  470, App key bind: Generic OnOff server on element address 0x0201
    <00> t:     778107>, main.c,  247, Config client event
    <00> t:     778110>, node_setup.c,  272, opcode status field: 0 
    <00> t:     778126>, node_setup.c,  523, Setting publication address to 0xC005 for Generic OnOff server on element address 0x0201
    <00> t:     785558>, main.c,  247, Config client event
    <00> t:     785560>, node_setup.c,  272, opcode status field: 0 
    <00> t:     785570>, node_setup.c,  572, Adding subscription to address 0xC003 for Generic OnOff server on element address 0x0201
    <00> t:     787815>, main.c,  247, Config client event
    <00> t:     787817>, node_setup.c,  272, opcode status field: 0 
    <00> t:     787820>, main.c,  174, Configuration of device 0 successful
    <00> t:     787826>, provisioner_helper.c,  326, Scanning For Unprovisioned Devices
    <00> t:    1100798>, main.c,  219, Node 0x0201 alive with 0 active fault(s), RSSI: -89

    From 50cm, the provisioner doesn't see the DUT at all.

    So I tried disabling the PA/LNA and from 25cm, it was able to provision fine and the signal strength shows much stronger at -42.

    <00> t:     779434>, main.c,  351, Button 1 pressed
    <00> t:     779437>, main.c,  274, Start provisioning procedure ...
    <00> t:     779439>, provisioner_helper.c,  326, Scanning For Unprovisioned Devices
    <00> t:     831083>, provisioner_helper.c,  168, UUID : D1E9C823620448C8BA0698129CC4AC23
    <00> t:     831086>, provisioner_helper.c,  171, ^RSSI: -42
    <00> t:     831088>, provisioner_helper.c,  177, ^URI Hash: 74F97940
    <00> t:     831102>, provisioner_helper.c,  332, Stop Scanning For Unprovisioned Devices
    <00> t:     831105>, provisioner_helper.c,  183, URI hash matched to ¹URI for LS Server example. Provisioning ...
    <00> t:     838232>, provisioner_helper.c,  300, Provisioning link established
    <00> t:     852880>, provisioner_helper.c,  295, Static authentication data provided
    <00> t:     866656>, provisioner_helper.c,  233, Provisioning completed received
    <00> t:     866659>, provisioner_helper.c,  238, Adding device address, and device keys
    <00> t:     866682>, provisioner_helper.c,  251, Addr: 0x0201 addr_handle: 0 netkey_handle: 0 devkey_handle: 2
    <00> t:     872229>, provisioner_helper.c,  192, Local provisioning link closed: prov_state: 2  remaining retries: 2
    <00> t:     872237>, main.c,  194, Provisioning successful
    <00> t:     872242>, provisioner_helper.c,  216, Provisioning complete. ¹URI for LS Server example - address: 0x0201 elements: 1
    <00> t:     872247>, node_setup.c,  736, Configuring Node: 0x0201
    <00> t:     872250>, node_setup.c,  632, Config client setup: devkey_handle:2 addr_handle:0
    <00> t:     872254>, node_setup.c,  412, Getting composition data
    <00> t:     894980>, main.c,  247, Config client event
    <00> t:     894983>, node_setup.c,  421, Updating network transmit: count: 2 steps: 1
    <00> t:     897226>, main.c,  247, Config client event
    <00> t:     897228>, node_setup.c,  432, Adding appkey
    <00> t:     902057>, main.c,  247, Config client event
    <00> t:     902059>, node_setup.c,  272, opcode status field: 0 
    <00> t:     902062>, node_setup.c,  470, App key bind: Health server on element address 0x0201
    <00> t:     904382>, main.c,  247, Config client event
    <00> t:     904384>, node_setup.c,  272, opcode status field: 0 
    <00> t:     904401>, node_setup.c,  489, Setting publication address for Health server to 0x0001
    <00> t:     911714>, main.c,  247, Config client event
    <00> t:     911716>, node_setup.c,  272, opcode status field: 0 
    <00> t:     911719>, node_setup.c,  470, App key bind: Generic OnOff server on element address 0x0201
    <00> t:     914114>, main.c,  247, Config client event
    <00> t:     914116>, node_setup.c,  272, opcode status field: 0 
    <00> t:     914132>, node_setup.c,  523, Setting publication address to 0xC005 for Generic OnOff server on element address 0x0201
    <00> t:     921732>, main.c,  247, Config client event
    <00> t:     921734>, node_setup.c,  272, opcode status field: 0 
    <00> t:     921744>, node_setup.c,  572, Adding subscription to address 0xC003 for Generic OnOff server on element address 0x0201
    <00> t:     925241>, main.c,  247, Config client event
    <00> t:     925244>, node_setup.c,  272, opcode status field: 0 
    <00> t:     925246>, main.c,  174, Configuration of device 0 successful
    <00> t:     925253>, provisioner_helper.c,  326, Scanning For Unprovisioned Devices
    <00> t:    1234421>, main.c,  219, Node 0x0201 alive with 0 active fault(s), RSSI: -42

    At 50cm, it also worked. I am not 100% sure, but I think the DUT still asserted one time without the PA/LNA.

    I did try the nRF Mesh app again with the phone very close and it still did not work.

    Thanks.

  • Hmm, it doesn't sound to me like PA/LNA actually works. 
    Please try testing again with Android phone without PA/LNA.

    And then try to test PA/LNA without mesh or softdevice. There is a customer made an example for the exact same module you have: https://devzone.nordicsemi.com/f/nordic-q-a/31050/controlling-a-pa-lna-sky66112-11-with-the-nrf52832-and-proprietary-protocols
    Next step is to test it with the softdevice, without mesh. 

  • What makes you say that the PA/LNA isn't working? I see about a 30dBm increase in signal strength when scanning with nRF Connect.

    And why test on Android without PA/LNA? Everything seems to work fine without it.

    Ok, testing on Android without PA/LNA worked, as I expected. But with PA/LNA it worked too! I feel like it takes longer and I see a couple of disconnect/reconnects, but I was able to configure the app key, and publish/subscribe groups.

    Android seems to behave similar to the Provisioner example, requiring a couple of retries.

    On a hunch I re-installed nRF Mesh on iOS and it was able to provision and configure with PA/LNA, but again, it didn't feel as smooth as without PA/LNA.

    This will definitely require a lot more testing before I feel comfortable with it.

    Could it be that the signal is too strong and it's over-saturating the receiver? -25dBm should be fine though.

    How do I set the TX power? Do I also have to set this in two places, BLE and Mesh?

    I guess my next question is, how can I determine if it's working 100% correctly?

    Thanks.

  • I think the best way to test PA/LNA is to test with actual longer range. Testing high power output indoor you will get a lot of reflections of the signal and can cause interference issue and as you mentioned, over-saturating. 


    Another option is to reduce the output power from the nRF52 to test. To change the output power, have a look at the answer by Rick Chung here: https://devzone.nordicsemi.com/f/nordic-q-a/56139/how-to-modify-tx-power-in-mesh-sdk-4-0-lpn-example

Related