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

Firmware Crash on ble_stack_init()

The firmware crashes when passing the ble_stack_init() when the firmware is download but in debug mode it works fine. The screen shots below shows this event.

We are using S132 and nRF5_SDK_17.0.2_d674dde

Code Snippet

On this scope shots we can see that on debug mode the test point would go low after around 2 seconds but on downloaded it didn't go low even after 3 seconds and more.

Debug Mode

Downloaded

Any thoughts on what is causing this issue?

Parents
  • Hi

    Could you upload the main.c file here for me so I could take a look at it in its entirety, as I'm not able to spot what's wrong by the snippets you have provided.

    Do you by chance have DEBUG enabled in your preprocessor definitions in your SES project?

    Best regards,

    Simon

  • Hello Simon, as of now the the preprocessor definitions in the Segger Embedded Studio includes the following :

    APP_TIMER_V2

    APP_TIMER_V2_RTC1_ENABLED

    BOARD_CUSTOM

    CONFIG_GPIO_AS_PINRESET

    CONFIG_NFCT_PINS_AS_GPIOS

    FLOAT_ABI_HARD

    INITIALIZE_USER_SECTIONS

    NO_VTOR_CONFIG

    NRF52

    NRF52832_XXAA

    NRF52_PAN_74

    NRF_SD_BLE_API_VERSION=7

    S132

    SOFTDEVICE_PRESENT

    We did not specify the DEBUG keyword.

    I am not sure why I cannot upload our ble_module.c file here. I am trying to embed it here as code.

    #include "ble_module.h"
    BLE_CUS_DEF(m_cus);
    
    BLE_SERVICE_1_DEF(m_service_1);
    
    BLE_SERVICE_2_DEF(m_service_2);
    
    BLE_SERVICE_3_DEF(m_service_3);
    
    BLE_SERVICE_4_DEF(m_service_4);
    /**< Context for the Queued Write module.*/
    NRF_BLE_QWR_DEF(m_qwr);
    /**< GATT module instance. */
    NRF_BLE_GATT_DEF(m_gatt);
    /**< Advertising module instance. */
    BLE_ADVERTISING_DEF(m_advertising);
    APP_TIMER_DEF(m_service_4_char_1_notification_timer_id);
    APP_TIMER_DEF(m_service_4_char_2_notification_timer_id);
    APP_TIMER_DEF(m_service_4_char_3_notification_timer_id);
    
    
    static uint16_t m_conn_handle         = BLE_CONN_HANDLE_INVALID;    /**< Handle of the current connection. */
    static ble_uuid_t m_adv_uuids[] =                                   /**< Universally unique service identifiers. */
    {
        {SERVICE_3_UUID, BLE_UUID_TYPE_VENDOR_BEGIN}
    };
    
    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     * @note: Controller board doesn't have XTAL see NRF_SDH_CLOCK_LF_SRC of
     *        sdk_config.h
     */
    void ble_stack_init(void)
    {
        uint32_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);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }
    
    /**@brief Function for handling BLE events.
     *
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        uint32_t err_code = NRF_SUCCESS;
        uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID;
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_DISCONNECTED:
                printf("Disconnected.");
                break;
    
            case BLE_GAP_EVT_CONNECTED:
                printf("Connected.");
                //err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                //APP_ERROR_CHECK(err_code);
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
            {
                printf("PHY update request.");
                ble_gap_phys_t const phys =
                {
                    .rx_phys = BLE_GAP_PHY_AUTO,
                    .tx_phys = BLE_GAP_PHY_AUTO,
                };
                err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
                APP_ERROR_CHECK(err_code);
            } break;
    
            case BLE_GATTC_EVT_TIMEOUT:
                // Disconnect on GATT Client timeout event.
                printf("GATT Client Timeout.");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GATTS_EVT_TIMEOUT:
                // Disconnect on GATT Server timeout event.
                printf("GATT Server Timeout.");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
    
            default:
                // No implementation needed.
                break;
        }
    }
    
    /**@brief Function for initializing the GATT module.
     */
    void gatt_init(void)
    {
        uint32_t err_code = nrf_ble_gatt_init(&m_gatt, NULL);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for the GAP initialization.
     *
     * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
     *          device including the device name, appearance, and the preferred connection parameters.
     */
    void gap_params_init(void)
    {
        uint32_t              err_code;
        // Note : ble_gap_conn_params_t and ble_gap_conn_sec_mode_t are structs based from the BLE 5.0 standard.
        ble_gap_conn_params_t   gap_conn_params;
        ble_gap_conn_sec_mode_t sec_mode;
    
        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));
        APP_ERROR_CHECK(err_code);
    
        memset(&gap_conn_params, 0, sizeof(gap_conn_params));
    
        gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
        gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
        gap_conn_params.slave_latency     = SLAVE_LATENCY;
        gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;
    
        err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for handling Queued Write Module errors.
     *
     * @details A pointer to this function will be passed to each service which may need to inform the
     *          application about an error.
     *
     * @param[in]   nrf_error   Error code containing information about what went wrong.
     */
    void nrf_qwr_error_handler(uint32_t nrf_error)
    {
        APP_ERROR_HANDLER(nrf_error);
    }
    
    static void on_cus_evt(ble_cus_t     * p_cus_service,
                           ble_cus_evt_t * p_evt)
    {
        ret_code_t err_code;
        
        switch(p_evt->evt_type)
        {
            case BLE_CUS_EVT_NOTIFICATION_ENABLED:
                
                 //err_code = app_timer_start(m_notification_timer_id, NOTIFICATION_INTERVAL, NULL);
                 //APP_ERROR_CHECK(err_code);
                 break;
    
            case BLE_CUS_EVT_NOTIFICATION_DISABLED:
    
                //err_code = app_timer_stop(m_notification_timer_id);
                //APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_CUS_EVT_CONNECTED:
                break;
    
            case BLE_CUS_EVT_DISCONNECTED:
                  break;
    
            default:
                  // No implementation needed.
                  break;
        }
    }
    
    
    static void on_service_4_evt(ble_service_4_t * p_service_4_service, ble_service_4_evt_t * p_evt)
    {
        uint32_t err_code;
        switch(p_evt->evt_type)
        {
            case BLE_SERVICE_4_EVT_NOTIFICATION_ENABLED:
                 err_code = app_timer_start(m_service_4_char_1_notification_timer_id, SERVICE_4_CHAR_1_MESSAGE_QUEUE_INTERVAL, NULL);
                 APP_ERROR_CHECK(err_code);
                 err_code = app_timer_start(m_service_4_char_2_notification_timer_id, SERVICE_4_CHAR_2_MESSAGE_QUEUE_INTERVAL, NULL);
                 APP_ERROR_CHECK(err_code);
                 err_code = app_timer_start(m_service_4_char_3_notification_timer_id, SERVICE_4_CHAR_3_MESSAGE_QUEUE_INTERVAL, NULL);
                 APP_ERROR_CHECK(err_code);
                 break;
    
            case BLE_SERVICE_4_EVT_NOTIFICATION_DISABLED:
                err_code = app_timer_stop(m_service_4_char_1_notification_timer_id);
                APP_ERROR_CHECK(err_code);
                err_code = app_timer_stop(m_service_4_char_2_notification_timer_id);
                APP_ERROR_CHECK(err_code);
                err_code = app_timer_stop(m_service_4_char_3_notification_timer_id);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_SERVICE_4_EVT_CONNECTED:
                break;
    
            case BLE_SERVICE_4_EVT_DISCONNECTED:
                  break;
    
            default:
                  // No implementation needed.
                  break;
        }
    }
    
    static void on_service_2_evt(ble_service_2_t * p_service_2_service, ble_service_2_evt_t * p_evt)
    {
        switch(p_evt->evt_type)
        {
            case BLE_SERVICE_2_EVT_NOTIFICATION_ENABLED:
                 break;
    
            case BLE_SERVICE_2_NOTIFICATION_DISABLED:
                break;
    
            case BLE_SERVICE_2_EVT_CONNECTED:
                break;
    
            case BLE_SERVICE_2_EVT_DISCONNECTED:
                  break;
    
            default:
                  // No implementation needed.
                  break;
        }
    }
    
    static void on_service_3_evt(ble_service_3_t * p_service_3_service, ble_service_3_evt_t * p_evt)
    {
        switch(p_evt->evt_type)
        {
            case BLE_SERVICE_3_EVT_NOTIFICATION_ENABLED:
                 break;
    
            case BLE_SERVICE_3_EVT_NOTIFICATION_DISABLED:
                break;
    
            case BLE_SERVICE_3_EVT_CONNECTED:
                break;
    
            case BLE_SERVICE_3_EVT_DISCONNECTED:
                  break;
    
            default:
                  // No implementation needed.
                  break;
        }
    }
    
    static void on_service_1_evt(ble_service_1_t * p_service_1_service, ble_service_1_evt_t * p_evt)
    {
        switch(p_evt->evt_type)
        {
            case BLE_SERVICE_1_EVT_NOTIFICATION_ENABLED:
                 break;
    
            case BLE_SERVICE_1_EVT_NOTIFICATION_DISABLED:
                break;
    
            case BLE_SERVICE_1_EVT_CONNECTED:
                break;
    
            case BLE_SERVICE_1_EVT_DISCONNECTED:
                  break;
    
            default:
                  // No implementation needed.
                  break;
        }
    }
    
    void services_init(void)
    {
            ret_code_t          err_code;
            nrf_ble_qwr_init_t  qwr_init = {0};
            ble_cus_init_t      cus_init = {0};
            ble_service_1_init_t    service_1_init = {0};
            ble_service_2_init_t      service_2_init = {0};
            ble_service_3_init_t       service_3_init = {0};
            ble_service_4_init_t       service_4_init = {0};
    
            // Initialize Queued Write Module.
            qwr_init.error_handler = nrf_qwr_error_handler;
    
            err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
            APP_ERROR_CHECK(err_code);
    
             // Initialize CUS Service init structure to zero.
            memset(&cus_init, 0, sizeof(cus_init));
            cus_init.evt_handler                = on_cus_evt;
        
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cus_init.custom_value_char_attr_md.cccd_write_perm);
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cus_init.custom_value_char_attr_md.read_perm);
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cus_init.custom_value_char_attr_md.write_perm);
        
            err_code = ble_cus_init(&m_cus, &cus_init);
            APP_ERROR_CHECK(err_code);
    
            // Initialize Service 1 init structure to zero.
            
            memset(&service_1_init, 0, sizeof(service_1_init));
            service_1_init.evt_handler = on_service_1_evt;
    
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&service_1_init.service_1_value_char_attr_md.cccd_write_perm);
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&service_1_init.service_1_value_char_attr_md.read_perm);
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&service_1_init.service_1_value_char_attr_md.write_perm);
    
            err_code = ble_service_1_init(&m_service_1, &service_1_init);
            APP_ERROR_CHECK(err_code);
            
            memset(&service_2_init, 0, sizeof(service_2_init));
            service_2_init.evt_handler = on_service_2_evt;
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&service_2_init.service_2_value_char_attr_md.cccd_write_perm);
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&service_2_init.service_2_value_char_attr_md.read_perm);
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&service_2_init.service_2_value_char_attr_md.write_perm);
    
            err_code = ble_service_2_init(&m_service_2, &service_2_init);
            APP_ERROR_CHECK(err_code);
    
    
            memset(&service_3_init, 0, sizeof(service_3_init));
            service_3_init.evt_handler = on_service_3_evt;
    
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&service_3_init.service_3_value_char_attr_md.cccd_write_perm);
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&service_3_init.service_3_value_char_attr_md.read_perm);
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&service_3_init.service_3_value_char_attr_md.write_perm);
    
            err_code = ble_service_3_init(&m_service_3, &service_3_init);
            APP_ERROR_CHECK(err_code);
    		
            memset(&service_4_init, 0, sizeof(service_4_init));
            service_4_init.evt_handler = on_service_4_evt;
    
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&service_4_init.service_4_value_char_attr_md.cccd_write_perm);
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&service_4_init.service_4_value_char_attr_md.read_perm);
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&service_4_init.service_4_value_char_attr_md.write_perm);
    
            err_code = ble_service_4_init(&m_service_4, &service_4_init);
            APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for handling the Connection Parameters Module.
     *
     * @details This function will be called for all events in the Connection Parameters Module which
     *          are passed to the application.
     *          @note All this function does is to disconnect. This could have been done by simply
     *                setting the disconnect_on_fail config parameter, but instead we use the event
     *                handler mechanism to demonstrate its use.
     *
     * @param[in] p_evt  Event received from the Connection Parameters Module.
     */
    void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
    {
        ret_code_t err_code;
    
        if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
        {
            err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
            APP_ERROR_CHECK(err_code);
        }
    }
    
    /**@brief Function for handling a Connection Parameters error.
     *
     * @param[in] nrf_error  Error code containing information about what went wrong.
     */
    void conn_params_error_handler(uint32_t nrf_error)
    {
        APP_ERROR_HANDLER(nrf_error);
    }
    
    /**@brief Function for initializing the Connection Parameters module.
     */
    void conn_params_init(void)
    {
        ret_code_t             err_code;
        ble_conn_params_init_t cp_init;
    
        memset(&cp_init, 0, sizeof(cp_init));
    
        cp_init.p_conn_params                  = NULL;
        cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
        cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
        cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
        cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
        cp_init.disconnect_on_fail             = false;
        cp_init.evt_handler                    = on_conn_params_evt;
        cp_init.error_handler                  = conn_params_error_handler;
    
        err_code = ble_conn_params_init(&cp_init);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for the Peer Manager initialization.
     */
    void peer_manager_init(void)
    {
        ble_gap_sec_params_t sec_param;
        ret_code_t           err_code;
    
        err_code = pm_init();
        APP_ERROR_CHECK(err_code);
    
        memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
    
        // Security parameters to be used for all security procedures.
        sec_param.bond           = SEC_PARAM_BOND;
        sec_param.mitm           = SEC_PARAM_MITM;
        sec_param.lesc           = SEC_PARAM_LESC;
        sec_param.keypress       = SEC_PARAM_KEYPRESS;
        sec_param.io_caps        = SEC_PARAM_IO_CAPABILITIES;
        sec_param.oob            = SEC_PARAM_OOB;
        sec_param.min_key_size   = SEC_PARAM_MIN_KEY_SIZE;
        sec_param.max_key_size   = SEC_PARAM_MAX_KEY_SIZE;
        sec_param.kdist_own.enc  = 1;
        sec_param.kdist_own.id   = 1;
        sec_param.kdist_peer.enc = 1;
        sec_param.kdist_peer.id  = 1;
    
        err_code = pm_sec_params_set(&sec_param);
        APP_ERROR_CHECK(err_code);
    
        err_code = pm_register(pm_evt_handler);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for handling Peer Manager events.
     *
     * @param[in] p_evt  Peer Manager event.
     */
    void pm_evt_handler(pm_evt_t const * p_evt)
    {
        ret_code_t err_code;
    
        switch (p_evt->evt_id)
        {
            case PM_EVT_BONDED_PEER_CONNECTED:
            {
                NRF_LOG_INFO("Connected to a previously bonded device.");
            } break;
    
            case PM_EVT_CONN_SEC_SUCCEEDED:
            {
                NRF_LOG_INFO("Connection secured: role: %d, conn_handle: 0x%x, procedure: %d.",
                             ble_conn_state_role(p_evt->conn_handle),
                             p_evt->conn_handle,
                             p_evt->params.conn_sec_succeeded.procedure);
            } break;
    
            case PM_EVT_CONN_SEC_FAILED:
            {
                /* Often, when securing fails, it shouldn't be restarted, for security reasons.
                 * Other times, it can be restarted directly.
                 * Sometimes it can be restarted, but only after changing some Security Parameters.
                 * Sometimes, it cannot be restarted until the link is disconnected and reconnected.
                 * Sometimes it is impossible, to secure the link, or the peer device does not support it.
                 * How to handle this error is highly application dependent. */
            } break;
    
            case PM_EVT_CONN_SEC_CONFIG_REQ:
            {
                // Reject pairing request from an already bonded peer.
                pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false};
                pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
            } break;
    
            case PM_EVT_STORAGE_FULL:
            {
                // Run garbage collection on the flash.
                err_code = fds_gc();
                if (err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
                {
                    // Retry.
                }
                else
                {
                    APP_ERROR_CHECK(err_code);
                }
            } break;
    
            case PM_EVT_PEERS_DELETE_SUCCEEDED:
            {
                advertising_start(false);
            } break;
    
            case PM_EVT_PEER_DATA_UPDATE_FAILED:
            {
                // Assert.
                APP_ERROR_CHECK(p_evt->params.peer_data_update_failed.error);
            } break;
    
            case PM_EVT_PEER_DELETE_FAILED:
            {
                // Assert.
                APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error);
            } break;
    
            case PM_EVT_PEERS_DELETE_FAILED:
            {
                // Log error occurrence for PM_EVT_PEERS_DELETE_FAILED
    
                NRF_LOG_INFO("PM_EVT_PEERS_DELETE_FAILED occurred. Connection handle = %d\n", p_evt->conn_handle);
    
                // Assert.
                APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error);
            } break;
    
            case PM_EVT_ERROR_UNEXPECTED:
            {
                // Assert.
                APP_ERROR_CHECK(p_evt->params.error_unexpected.error);
            } break;
    
            case PM_EVT_CONN_SEC_START:
            case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
            case PM_EVT_PEER_DELETE_SUCCEEDED:
            case PM_EVT_LOCAL_DB_CACHE_APPLIED:
            case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED:
                // This can happen when the local DB has changed.
            case PM_EVT_SERVICE_CHANGED_IND_SENT:
            case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
            default:
                break;
        }
    }
    
    /**@brief Clear bond information from persistent storage.
     */
    void delete_bonds(void)
    {
        ret_code_t err_code;
    
        NRF_LOG_INFO("Erase bonds!");
    
        err_code = pm_peers_delete();
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for starting advertising.
     */
    void advertising_start(bool erase_bonds)
    {
        if (erase_bonds == true)
        {
            delete_bonds();
            // Advertising is started by PM_EVT_PEERS_DELETED_SUCEEDED event
        }
        else
        {
            //ret_code_t err_code = ble_advertising_restart_without_whitelist(&m_advertising);
            ret_code_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
            printf("advertising_start error code = %d\n", err_code);
            APP_ERROR_CHECK(err_code);
        }
    }
    
    /**@brief Function for initializing the Advertising functionality.
     */
    void advertising_init(void)
    {
        uint32_t             err_code;
        ble_advertising_init_t init;
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance      = true;
        init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
        init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.advdata.uuids_complete.p_uuids  = m_adv_uuids;
    
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
        // Try disabling timeout
        init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
    
        init.evt_handler = on_adv_evt;
    
        err_code = ble_advertising_init(&m_advertising, &init);
        APP_ERROR_CHECK(err_code);
    
        ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    }
    
    /**@brief Function for handling advertising events.
     *
     * @details This function will be called for advertising events which are passed to the application.
     *
     * @param[in] ble_adv_evt  Advertising event.
     */
    void on_adv_evt(ble_adv_evt_t ble_adv_evt)
    {
        ret_code_t err_code;
    
        switch (ble_adv_evt)
        {
            case BLE_ADV_EVT_FAST:
                NRF_LOG_INFO("Fast advertising.");
                break;
    
            case BLE_ADV_EVT_IDLE:
                break;
    
            default:
                break;
        }
    }
    
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    static void idle_state_handle(void)
    {
        if (NRF_LOG_PROCESS() == false)
        {
            nrf_pwr_mgmt_run();
        }
    }
    
    /**@brief Function for the Timer initialization.
     *
     * @details Initializes the timer module. This creates and starts application timers.
     */
    static void timers_init(void)
    {
        // Initialize timer module.
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    
        // Create timers.
        err_code = app_timer_create(&m_service_4_char_1_notification_timer_id, APP_TIMER_MODE_REPEATED, service_4_char_1_notification_timeout_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = app_timer_create(&m_service_4_char_2_notification_timer_id, APP_TIMER_MODE_REPEATED, service_4_char_2_notification_timeout_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = app_timer_create(&m_service_4_char_3_notification_timer_id, APP_TIMER_MODE_REPEATED, service_4_char_3_notification_timeout_handler);
        APP_ERROR_CHECK(err_code);
    
        /* YOUR_JOB: Create any timers to be used by the application.
                     Below is an example of how to create a timer.
                     For every new timer needed, increase the value of the macro APP_TIMER_MAX_TIMERS by
                     one.
           ret_code_t err_code;
           err_code = app_timer_create(&m_app_timer_id, APP_TIMER_MODE_REPEATED, timer_timeout_handler);
           APP_ERROR_CHECK(err_code); */
    }
    
    /**@brief Function for initializing power management.
     */
    static void power_management_init(void)
    {
        ret_code_t err_code;
        err_code = nrf_pwr_mgmt_init();
        APP_ERROR_CHECK(err_code);
    }
    
    void service_4_char_1_notification_timeout_handler(void * p_context)
    {
        UNUSED_PARAMETER(p_context);
    
        service_4_notification_timer_update_elapsed(&m_service_4, SERVICE_4_CHAR_1_UUID);
    }
    
    void service_4_char_2_notification_timeout_handler(void * p_context)
    {
        UNUSED_PARAMETER(p_context);
    
        service_4_notification_timer_update_elapsed(&m_service_4, SERVICE_4_CHAR_2_UUID);
    }
    
    void service_4_char_3_notification_timeout_handler(void * p_context)
    {
        UNUSED_PARAMETER(p_context);
    
        service_4_notification_timer_update_elapsed(&m_service_4, SERVICE_4_CHAR_3_UUID);
    }
    
    void ble_process(void)
    {
        bool erase_bonds = false;
        log_init();
        timers_init();
        power_management_init();
        ble_stack_init();
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
        conn_params_init();
        peer_manager_init();
    
        // Start advertising for ble module. Erase_bonds is set to false to distinguish 1st advertising packet.
        // If erase_bonds is set to true, advertising will start again but it will come from
        // PM_EVT_PEERS_DELETED_SUCEEDED
        advertising_start(erase_bonds);
    
        //// Enter main loop.
        //for (;;)
        //{
        //    idle_state_handle();
        //}
    }
    

    The ble_process function is called in our main loop when other peripherals have been initialized. Also, do we have hardware restrictions when running the NRF52832 with a S132 soft device?

  • Hi Simon,

    Replying here to refer to the code snippet. We have finally resolved this concern by removing several printf and one of which is in line 577 of the code snippet above. Thanks for the quick responses.

    One question though. Is it safe to assume that printf function doesn't work with soft device or did we miss anything in the sdk_config.h?

  • Hi

    Glad you were able to find the source of the error. Normally,  if the printf doesn't work, it's caused by a missing retarget file. If you check out I.E. the ble_app_uart project you'll see that retarget.c is included and that the RETARGET_ENABLED define is set in sdk_config.h.

    // <q> RETARGET_ENABLED  - retarget - Retargeting stdio functions
     
    
    #ifndef RETARGET_ENABLED
    #define RETARGET_ENABLED 1
    #endif

    Without these the  calls to printf will do nothing at all. 

    Best regards,

    Simon

Reply
  • Hi

    Glad you were able to find the source of the error. Normally,  if the printf doesn't work, it's caused by a missing retarget file. If you check out I.E. the ble_app_uart project you'll see that retarget.c is included and that the RETARGET_ENABLED define is set in sdk_config.h.

    // <q> RETARGET_ENABLED  - retarget - Retargeting stdio functions
     
    
    #ifndef RETARGET_ENABLED
    #define RETARGET_ENABLED 1
    #endif

    Without these the  calls to printf will do nothing at all. 

    Best regards,

    Simon

Children
No Data
Related