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

set the PHY LE CODED and sd_ble_gap_tx_power_set give ERROR with the new S140 V6.0.0

Hello everyone,

I'm trying to use the new SDK 15.0.0 and the S140 soft device V6.0.0. I would like to use the LE CODED physical layer and set my TX output power, but when I try to setup my advertisment like this :

static void advertising_init(void)
{
    uint32_t      err_code;
    ble_advdata_t advdata;
    ble_advdata_manuf_data_t manuf_specific_data;
    ble_gap_conn_sec_mode_t sec_mode;
    int8_t tx_power = 0;
    uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;

    //err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV,m_adv_handle, tx_power);
    //APP_ERROR_CHECK(err_code);

    //sd_power_dcdc_mode_set(1);
    
    memset(&manuf_specific_data, 0, sizeof(manuf_specific_data));

    manuf_specific_data.data.p_data = (uint8_t *)BLE_data;
    manuf_specific_data.data.size   = sizeof(BLE_data);
    manuf_specific_data.company_identifier = Compagny_identifier;
    
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    err_code = sd_ble_gap_device_name_set(&sec_mode,
                                          (const uint8_t *) DEVICE_NAME,
                                          strlen(DEVICE_NAME));
    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type             = BLE_ADVDATA_SHORT_NAME;
    advdata.short_name_len        = strlen(DEVICE_NAME);
    advdata.flags                 = flags;
    advdata.p_manuf_specific_data = &manuf_specific_data;

    // Initialize advertising parameters (used when starting advertising).
    memset(&m_adv_params, 0, sizeof(m_adv_params));

    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
    m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
    m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
    m_adv_params.duration        = 0;       // Never time out.
    m_adv_params.primary_phy     = BLE_GAP_PHY_CODED; //Long Range
    m_adv_params.secondary_phy   = BLE_GAP_PHY_CODED; //Long Range

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
    APP_ERROR_CHECK(err_code);
}

I get an app_error_fault_handler . I don't understand why ... The LE CODED isn't yet supported for broadcasting ? and why the TX POWER set doesn't work as I implemented it?

Sincerely,
Sylvain.

Parents
  • Hello Sylvain,

    Can you please try to set define "DEBUG" in your preprocessor defines, and then turn off optimization. Then you can set a breakpoint on line 90 in app_error_weak.c, and see if it stops there during debugging. If it does, add p_info to "watch" and see which APP_ERROR_CHECK(err_code) that got an err_code != 0 (NRF_SUCCESS) and what the err_code was.

    There are too many unknown variables for me to test it here.

     

    Best regards,

    Edvin

  • Hello Edvin,

    The first error is generated for this function :

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);

    And the error code reported is : 0x00000007 (I don't know where I can see what is this error. But I think it is this one : * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied.) I can't access the svcall function to see the C code ...

    Is it normal ?

    If the error's what I think, I configured my flag to : BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED

    The second error is generated for this function :

    err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV,m_adv_handle, tx_power);

    The error code reported is : 0x00003004 ... I don't know where I can see what is this error .

    Kind regards,
    Sylvain.

  • Hello,

    If you open ble_gap.h in SDK15, you will see the possible return values for sd_ble_gap_adv_set_configure(). Then, if you see the definition of one of the return values, you will see the list all the return values, and their numerical (decimal) value. 

    err_code = 0x07 is not NRF_ERROR_INVALID_FLAGS, but NRF_ERROR_INVALID_PARAM.

     

    The explanation from this is:

    NRF_ERROR_INVALID_PARAM:

    Invalid parameter(s) supplied:
    * - Invalid advertising data configuration specified. See @ref ble_gap_adv_data_t.
    * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t.
    * - Use of whitelist requested but whitelist has not been set,
    * see @ref sd_ble_gap_whitelist_set.

     I do not know exactly what parameters that are invalid, but again, I can't see your BLE_data pointer. 

     

    The second value is BLE_ERROR_INVALID_ADV_HANDLE, Advertising handle not found

    Did you pass the correct advertising handle into sd_ble_gap_tx_power_set()?

     

    Best regards,

    Edvin

  • 1) I don't understand this error because when I set the physical layer to 1MBPS there's no error ... BLE_DATA is a vector with a length of 2, nothing else ... I have posted all my main, maybe it'll be more clear

    2) Here's the advertising Handle that I pass through the function : static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;

    I don't know if there hare other handle possible for the advertising data ..

    Here's my complete main program:

    /**
     * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA
     * 
     * All rights reserved.
     * 
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     * 
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     * 
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     * 
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     * 
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     * 
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     * 
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * 
     */
    #include "sdk_config.h"
    #include "nrf_drv_spis.h"
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "app_error.h"
    #include <string.h>
    
    #include "nrf_soc.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_ble.h"
    #include "ble_advdata.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include <stdint.h>
    #include "nordic_common.h"
    #include "nrf.h"
    #include "ble.h"
    #include "ble_err.h"
    #include "ble_hci.h"
    #include "ble_srv_common.h"
    #include "ble_advertising.h"
    #include "ble_bas.h"
    #include "ble_hts.h"
    #include "ble_dis.h"
    #include "ble_conn_params.h"
    #include "sensorsim.h"
    #include "nrf_sdh_soc.h"
    #include "app_timer.h"
    #include "peer_manager.h"
    #include "bsp_btn_ble.h"
    #include "fds.h"
    #include "ble_conn_state.h"
    #include "nrf_ble_gatt.h"
    #include "nrf_ble_qwr.h"
    #include "nrf_pwr_mgmt.h"
    
    #define DEVICE_NAME "VOCSens#01"
    #define Compagny_identifier 0x0059 //Nordic Semiconductor ASA
    
    #define TEST_STRING "Nordic"
    static uint8_t       m_rx_buf[sizeof(TEST_STRING) + 1];    /**< RX buffer. */
    
    static uint8_t BLE_data[2] = {0x01,0x02};
    
    #define APP_BLE_CONN_CFG_TAG            1                                 /**< A tag identifying the SoftDevice BLE configuration. */
    #define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(1000, UNIT_0_625_MS) /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100ms to 10.24s). */
    #define DEAD_BEEF                       0xDEADBEEF                        /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
    #define BLE_data_LENGTH                 0x1F                             /**< 31 bytes is the maximum size for adv data. */ 
    
    static ble_gap_adv_params_t m_adv_params;                                  /**< Parameters to be passed to the stack when starting advertising. */
    static uint8_t              m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
    static uint8_t              m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];  /**< Buffer for storing an encoded advertising set. */
    
    /**@brief Callback function for asserts in the SoftDevice.
     *
     * @details This function will be called in case of an assert in the SoftDevice.
     *
     * @warning This handler is an example only and does not fit a final product. You need to analyze
     *          how your product is supposed to react in case of Assert.
     * @warning On assert from the SoftDevice, the system can only recover on reset.
     *
     * @param[in]   line_num   Line number of the failing ASSERT call.
     * @param[in]   file_name  File name of the failing ASSERT call.
     */
    void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    {
        app_error_handler(DEAD_BEEF, line_num, p_file_name);
    }
    
    /**@brief Struct that contains pointers to the encoded advertising data. */
    static ble_gap_adv_data_t m_adv_data =
    {
        .adv_data =
        {
            .p_data = m_enc_advdata,
            .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
        },
        .scan_rsp_data =
        {
            .p_data = NULL,
            .len    = 0
    
        }
    };
    
    /**@brief Function for initializing the Advertising functionality.
     *
     * @details Encodes the required advertising data and passes it to the stack.
     *          Also builds a structure to be passed to the stack when starting advertising.
     */
    static void advertising_init(void)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
        ble_advdata_manuf_data_t manuf_specific_data;
        ble_gap_conn_sec_mode_t sec_mode;
        int8_t tx_power = 0;
        uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
    
        err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV,m_adv_handle, tx_power);
        APP_ERROR_CHECK(err_code);
    
        //sd_power_dcdc_mode_set(1);
        
        memset(&manuf_specific_data, 0, sizeof(manuf_specific_data));
    
        manuf_specific_data.data.p_data = (uint8_t *)BLE_data;
        manuf_specific_data.data.size   = sizeof(BLE_data);
        manuf_specific_data.company_identifier = Compagny_identifier;
        
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
        err_code = sd_ble_gap_device_name_set(&sec_mode,
                                              (const uint8_t *) DEVICE_NAME,
                                              strlen(DEVICE_NAME));
        // Build and set advertising data.
        memset(&advdata, 0, sizeof(advdata));
    
        advdata.name_type             = BLE_ADVDATA_SHORT_NAME;
        advdata.short_name_len        = strlen(DEVICE_NAME);
        advdata.flags                 = flags;
        advdata.p_manuf_specific_data = &manuf_specific_data;
    
        // Initialize advertising parameters (used when starting advertising).
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
        m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
        m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = 0;       // Never time out.
        m_adv_params.primary_phy     = BLE_GAP_PHY_CODED;//BLE_GAP_PHY_CODED; //Long Range
        m_adv_params.secondary_phy   = BLE_GAP_PHY_CODED; //Long Range
    
        err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for starting advertising.
     */
    static void advertising_start(void)
    {
        ret_code_t err_code;
        
        err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
        APP_ERROR_CHECK(err_code);
    
    }
    static void update_Payload(char * data, uint8_t length)
    {
        uint32_t  err_code;
        
        err_code = sd_ble_gap_adv_data_set(data,sizeof(BLE_data),NULL,0);
    }
    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for initializing logging. */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    /**@brief Function for initializing timers. */
    static void timers_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for doing power management. */
    static void power_manage(void)
    {
        ret_code_t err_code = sd_app_evt_wait();
        APP_ERROR_CHECK(err_code);
    }
    
    
    int main(void)
    {
        // Enable the constant latency sub power mode to minimize the time it takes
        // for the SPIS peripheral to become active after the CSN line is asserted
        // (when the CPU is in sleep mode).
        NRF_POWER->TASKS_CONSTLAT = 1;
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        ble_stack_init();
        advertising_init();
        advertising_start();
        
    while (1)
        {
        }
    }
    

    Kind regards,
    Sylvain.

  • Hello Sylvain,

    I am confused. When I try to compile your main.c with a project in SDK15 and SoftDevice S140, I get the error that sd_ble_gap_adv_data_set() is not defined. 

    I see that you do not use it, as it is used in earlier SDKs, but not SDK15.0.0 (S140 v6).

     

    As for your errors.

    I looked up the functions that returned these errors on infocenter, but the same information is also located in the SDK, 

    sd_ble_gap_adv_set_configure() is described on line 1759 in ble_gap.h.

    sd_ble_gap_tx_power_set() is described on line 1927 in ble_gap.h.

    (links to infocenter)

     

    As for the sd_ble_gap_tx_power_set(), it returned 0x3004, which as you know means "invalid conn handle". In the description, it also says that if the role is BLE_GAP_TX_POWER_ROLE_ADV, it will use the specified transmit power, and include it in the advertising packet header if ble_gap_adv_properties_t::include_tx_power is set.

     

    So the problem is that BLE_GAP_ADV_SET_HANDLE_NOT_SET is not a valid input. You have to call it after sd_ble_gap_adv_set_configure(), which changes the m_adv_handle.

     

    For the sd_ble_gap_adv_set_configure, it says that if it returns NRF_ERROR_INVALID_PARAM, one of the three points (that I mentioned in the previous post) have wrong settings. In this case, it is the ble_gap_adv_params_t variable. If you look at the description of ble_gap_adv_params_t::primary phy, it says:

      uint8_t                  primary_phy;             /**< Indicates the PHY on which the primary advertising channel packets
                                                             are transmitted. If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS
                                                             will be used.
                                                             Valid values are @ref BLE_GAP_PHY_1MBPS and @ref BLE_GAP_PHY_CODED.
                                                             @note The primary_phy shall indicate @ref BLE_GAP_PHY_1MBPS if
                                                                   @ref ble_gap_adv_properties_t::type is not an extended advertising type. */

    So in main.c, in your advertising_init() function, if you change:

    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;

    to

    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;

    you will be allowed to use the BLE_GAP_PHY_CODED for advertising.

     

    Try it out, and let me know if it does not work.

     

    Attached is the modified main.c file.

    /**
     * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA
     * 
     * All rights reserved.
     * 
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     * 
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     * 
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     * 
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     * 
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     * 
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     * 
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * 
     */
    #include "sdk_config.h"
    #include "nrf_drv_spis.h"
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "app_error.h"
    #include <string.h>
    
    #include "nrf_soc.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_ble.h"
    #include "ble_advdata.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include <stdint.h>
    #include "nordic_common.h"
    #include "nrf.h"
    #include "ble.h"
    #include "ble_err.h"
    #include "ble_hci.h"
    #include "ble_srv_common.h"
    #include "ble_advertising.h"
    #include "ble_bas.h"
    #include "ble_hts.h"
    #include "ble_dis.h"
    #include "ble_conn_params.h"
    #include "sensorsim.h"
    #include "nrf_sdh_soc.h"
    #include "app_timer.h"
    #include "peer_manager.h"
    #include "bsp_btn_ble.h"
    #include "fds.h"
    #include "ble_conn_state.h"
    #include "nrf_ble_gatt.h"
    #include "nrf_ble_qwr.h"
    #include "nrf_pwr_mgmt.h"
    
    #define DEVICE_NAME "VOCSens#01"
    #define Compagny_identifier 0x0059 //Nordic Semiconductor ASA
    
    #define TEST_STRING "Nordic"
    static uint8_t       m_rx_buf[sizeof(TEST_STRING) + 1];    /**< RX buffer. */
    
    static uint8_t BLE_data[2] = {0x01,0x02};
    
    #define APP_BLE_CONN_CFG_TAG            1                                 /**< A tag identifying the SoftDevice BLE configuration. */
    #define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(1000, UNIT_0_625_MS) /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100ms to 10.24s). */
    #define DEAD_BEEF                       0xDEADBEEF                        /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
    #define BLE_data_LENGTH                 0x1F                             /**< 31 bytes is the maximum size for adv data. */ 
    
    static ble_gap_adv_params_t m_adv_params;                                  /**< Parameters to be passed to the stack when starting advertising. */
    static uint8_t              m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
    static uint8_t              m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];  /**< Buffer for storing an encoded advertising set. */
    
    /**@brief Callback function for asserts in the SoftDevice.
     *
     * @details This function will be called in case of an assert in the SoftDevice.
     *
     * @warning This handler is an example only and does not fit a final product. You need to analyze
     *          how your product is supposed to react in case of Assert.
     * @warning On assert from the SoftDevice, the system can only recover on reset.
     *
     * @param[in]   line_num   Line number of the failing ASSERT call.
     * @param[in]   file_name  File name of the failing ASSERT call.
     */
    void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    {
        app_error_handler(DEAD_BEEF, line_num, p_file_name);
    }
    
    /**@brief Struct that contains pointers to the encoded advertising data. */
    static ble_gap_adv_data_t m_adv_data =
    {
        .adv_data =
        {
            .p_data = m_enc_advdata,
            .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
        },
        .scan_rsp_data =
        {
            .p_data = NULL,
            .len    = 0
    
        }
    };
    
    /**@brief Function for initializing the Advertising functionality.
     *
     * @details Encodes the required advertising data and passes it to the stack.
     *          Also builds a structure to be passed to the stack when starting advertising.
     */
    static void advertising_init(void)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
        ble_advdata_manuf_data_t manuf_specific_data;
        ble_gap_conn_sec_mode_t sec_mode;
        int8_t tx_power = 0;
        uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
    
    //    err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV,m_adv_handle, tx_power);
    //    APP_ERROR_CHECK(err_code);
    
        //sd_power_dcdc_mode_set(1);
        
        memset(&manuf_specific_data, 0, sizeof(manuf_specific_data));
    
        manuf_specific_data.data.p_data = (uint8_t *)BLE_data;
        manuf_specific_data.data.size   = sizeof(BLE_data);
        manuf_specific_data.company_identifier = Compagny_identifier;
        
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
        err_code = sd_ble_gap_device_name_set(&sec_mode,
                                              (const uint8_t *) DEVICE_NAME,
                                              strlen(DEVICE_NAME));
        // Build and set advertising data.
        memset(&advdata, 0, sizeof(advdata));
    
        advdata.name_type             = BLE_ADVDATA_SHORT_NAME;
        advdata.short_name_len        = strlen(DEVICE_NAME);
        advdata.flags                 = flags;
        advdata.p_manuf_specific_data = &manuf_specific_data;
    
        // Initialize advertising parameters (used when starting advertising).
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
        m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
        m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = 0;       // Never time out.
        m_adv_params.primary_phy     = BLE_GAP_PHY_CODED;//BLE_GAP_PHY_CODED; //Long Range
        m_adv_params.secondary_phy   = BLE_GAP_PHY_CODED; //Long Range
    
        err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
        APP_ERROR_CHECK(err_code);
        
        err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV,m_adv_handle, tx_power);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for starting advertising.
     */
    static void advertising_start(void)
    {
        ret_code_t err_code;
        
        err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
        APP_ERROR_CHECK(err_code);
    
    }
    /*static void update_Payload(char * data, uint8_t length)
    {
        uint32_t  err_code;
        
        err_code = sd_ble_gap_adv_data_set(data,sizeof(BLE_data),NULL,0);
    }*/
    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for initializing logging. */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    /**@brief Function for initializing timers. */
    static void timers_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for doing power management. */
    static void power_manage(void)
    {
        ret_code_t err_code = sd_app_evt_wait();
        APP_ERROR_CHECK(err_code);
    }
    
    
    int main(void)
    {
        // Enable the constant latency sub power mode to minimize the time it takes
        // for the SPIS peripheral to become active after the CSN line is asserted
        // (when the CPU is in sleep mode).
        NRF_POWER->TASKS_CONSTLAT = 1;
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
        
        NRF_LOG_INFO("started");    // I added this to check that it was running after advertising_init() did not return any errors.
    
        ble_stack_init();
        advertising_init();
        advertising_start();
        
    while (1)
        {
            while (NRF_LOG_PROCESS() == false){};   // added this to see the log print.
            //do nothing
        }
    }
    

     

    Best regards,

    Edvin

Reply
  • Hello Sylvain,

    I am confused. When I try to compile your main.c with a project in SDK15 and SoftDevice S140, I get the error that sd_ble_gap_adv_data_set() is not defined. 

    I see that you do not use it, as it is used in earlier SDKs, but not SDK15.0.0 (S140 v6).

     

    As for your errors.

    I looked up the functions that returned these errors on infocenter, but the same information is also located in the SDK, 

    sd_ble_gap_adv_set_configure() is described on line 1759 in ble_gap.h.

    sd_ble_gap_tx_power_set() is described on line 1927 in ble_gap.h.

    (links to infocenter)

     

    As for the sd_ble_gap_tx_power_set(), it returned 0x3004, which as you know means "invalid conn handle". In the description, it also says that if the role is BLE_GAP_TX_POWER_ROLE_ADV, it will use the specified transmit power, and include it in the advertising packet header if ble_gap_adv_properties_t::include_tx_power is set.

     

    So the problem is that BLE_GAP_ADV_SET_HANDLE_NOT_SET is not a valid input. You have to call it after sd_ble_gap_adv_set_configure(), which changes the m_adv_handle.

     

    For the sd_ble_gap_adv_set_configure, it says that if it returns NRF_ERROR_INVALID_PARAM, one of the three points (that I mentioned in the previous post) have wrong settings. In this case, it is the ble_gap_adv_params_t variable. If you look at the description of ble_gap_adv_params_t::primary phy, it says:

      uint8_t                  primary_phy;             /**< Indicates the PHY on which the primary advertising channel packets
                                                             are transmitted. If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS
                                                             will be used.
                                                             Valid values are @ref BLE_GAP_PHY_1MBPS and @ref BLE_GAP_PHY_CODED.
                                                             @note The primary_phy shall indicate @ref BLE_GAP_PHY_1MBPS if
                                                                   @ref ble_gap_adv_properties_t::type is not an extended advertising type. */

    So in main.c, in your advertising_init() function, if you change:

    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;

    to

    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;

    you will be allowed to use the BLE_GAP_PHY_CODED for advertising.

     

    Try it out, and let me know if it does not work.

     

    Attached is the modified main.c file.

    /**
     * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA
     * 
     * All rights reserved.
     * 
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     * 
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     * 
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     * 
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     * 
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     * 
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     * 
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * 
     */
    #include "sdk_config.h"
    #include "nrf_drv_spis.h"
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "app_error.h"
    #include <string.h>
    
    #include "nrf_soc.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_ble.h"
    #include "ble_advdata.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include <stdint.h>
    #include "nordic_common.h"
    #include "nrf.h"
    #include "ble.h"
    #include "ble_err.h"
    #include "ble_hci.h"
    #include "ble_srv_common.h"
    #include "ble_advertising.h"
    #include "ble_bas.h"
    #include "ble_hts.h"
    #include "ble_dis.h"
    #include "ble_conn_params.h"
    #include "sensorsim.h"
    #include "nrf_sdh_soc.h"
    #include "app_timer.h"
    #include "peer_manager.h"
    #include "bsp_btn_ble.h"
    #include "fds.h"
    #include "ble_conn_state.h"
    #include "nrf_ble_gatt.h"
    #include "nrf_ble_qwr.h"
    #include "nrf_pwr_mgmt.h"
    
    #define DEVICE_NAME "VOCSens#01"
    #define Compagny_identifier 0x0059 //Nordic Semiconductor ASA
    
    #define TEST_STRING "Nordic"
    static uint8_t       m_rx_buf[sizeof(TEST_STRING) + 1];    /**< RX buffer. */
    
    static uint8_t BLE_data[2] = {0x01,0x02};
    
    #define APP_BLE_CONN_CFG_TAG            1                                 /**< A tag identifying the SoftDevice BLE configuration. */
    #define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(1000, UNIT_0_625_MS) /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100ms to 10.24s). */
    #define DEAD_BEEF                       0xDEADBEEF                        /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
    #define BLE_data_LENGTH                 0x1F                             /**< 31 bytes is the maximum size for adv data. */ 
    
    static ble_gap_adv_params_t m_adv_params;                                  /**< Parameters to be passed to the stack when starting advertising. */
    static uint8_t              m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
    static uint8_t              m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];  /**< Buffer for storing an encoded advertising set. */
    
    /**@brief Callback function for asserts in the SoftDevice.
     *
     * @details This function will be called in case of an assert in the SoftDevice.
     *
     * @warning This handler is an example only and does not fit a final product. You need to analyze
     *          how your product is supposed to react in case of Assert.
     * @warning On assert from the SoftDevice, the system can only recover on reset.
     *
     * @param[in]   line_num   Line number of the failing ASSERT call.
     * @param[in]   file_name  File name of the failing ASSERT call.
     */
    void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    {
        app_error_handler(DEAD_BEEF, line_num, p_file_name);
    }
    
    /**@brief Struct that contains pointers to the encoded advertising data. */
    static ble_gap_adv_data_t m_adv_data =
    {
        .adv_data =
        {
            .p_data = m_enc_advdata,
            .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
        },
        .scan_rsp_data =
        {
            .p_data = NULL,
            .len    = 0
    
        }
    };
    
    /**@brief Function for initializing the Advertising functionality.
     *
     * @details Encodes the required advertising data and passes it to the stack.
     *          Also builds a structure to be passed to the stack when starting advertising.
     */
    static void advertising_init(void)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
        ble_advdata_manuf_data_t manuf_specific_data;
        ble_gap_conn_sec_mode_t sec_mode;
        int8_t tx_power = 0;
        uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
    
    //    err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV,m_adv_handle, tx_power);
    //    APP_ERROR_CHECK(err_code);
    
        //sd_power_dcdc_mode_set(1);
        
        memset(&manuf_specific_data, 0, sizeof(manuf_specific_data));
    
        manuf_specific_data.data.p_data = (uint8_t *)BLE_data;
        manuf_specific_data.data.size   = sizeof(BLE_data);
        manuf_specific_data.company_identifier = Compagny_identifier;
        
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
        err_code = sd_ble_gap_device_name_set(&sec_mode,
                                              (const uint8_t *) DEVICE_NAME,
                                              strlen(DEVICE_NAME));
        // Build and set advertising data.
        memset(&advdata, 0, sizeof(advdata));
    
        advdata.name_type             = BLE_ADVDATA_SHORT_NAME;
        advdata.short_name_len        = strlen(DEVICE_NAME);
        advdata.flags                 = flags;
        advdata.p_manuf_specific_data = &manuf_specific_data;
    
        // Initialize advertising parameters (used when starting advertising).
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
        m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
        m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = 0;       // Never time out.
        m_adv_params.primary_phy     = BLE_GAP_PHY_CODED;//BLE_GAP_PHY_CODED; //Long Range
        m_adv_params.secondary_phy   = BLE_GAP_PHY_CODED; //Long Range
    
        err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
        APP_ERROR_CHECK(err_code);
        
        err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV,m_adv_handle, tx_power);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for starting advertising.
     */
    static void advertising_start(void)
    {
        ret_code_t err_code;
        
        err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
        APP_ERROR_CHECK(err_code);
    
    }
    /*static void update_Payload(char * data, uint8_t length)
    {
        uint32_t  err_code;
        
        err_code = sd_ble_gap_adv_data_set(data,sizeof(BLE_data),NULL,0);
    }*/
    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for initializing logging. */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    /**@brief Function for initializing timers. */
    static void timers_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for doing power management. */
    static void power_manage(void)
    {
        ret_code_t err_code = sd_app_evt_wait();
        APP_ERROR_CHECK(err_code);
    }
    
    
    int main(void)
    {
        // Enable the constant latency sub power mode to minimize the time it takes
        // for the SPIS peripheral to become active after the CSN line is asserted
        // (when the CPU is in sleep mode).
        NRF_POWER->TASKS_CONSTLAT = 1;
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
        
        NRF_LOG_INFO("started");    // I added this to check that it was running after advertising_init() did not return any errors.
    
        ble_stack_init();
        advertising_init();
        advertising_start();
        
    while (1)
        {
            while (NRF_LOG_PROCESS() == false){};   // added this to see the log print.
            //do nothing
        }
    }
    

     

    Best regards,

    Edvin

Children
No Data
Related