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

app_error_fault_handler id=0x00004001, pc=0x0003290b & app_error_handler / SDK v17 / nrf2840 PDK

Hello,

 I am developing using nrf2840 PDK, SDK v17.0.0, S140

I have made two services, one is to control the led blinking rate via nrf connect android app and the other is to display battery level on the nrf connect android app, i have attached all the code files below

main.c file:

/**
 * Copyright (c) 2014 - 2018, 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 <stdbool.h>
#include <stdint.h>
#include <string.h>

#include "nordic_common.h"
#include "nrf.h"
#include "app_error.h"
#include "ble.h"
#include "ble_hci.h"
#include "ble_srv_common.h"
#include "ble_advdata.h"
#include "ble_advertising.h"
#include "ble_conn_params.h"
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h"
#include "nrf_sdh_ble.h"
#include "app_timer.h"
#include "fds.h"
#include "peer_manager.h"
#include "bsp_btn_ble.h"
#include "sensorsim.h"
#include "ble_conn_state.h"
#include "nrf_ble_gatt.h"
#include "nrf_ble_qwr.h"
#include "nrf_pwr_mgmt.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#include "ble_bas.h"
#include "services/led_service.h"

#include "Battery Level/battery_voltage.h"


#define DEVICE_NAME                     "BLE_Lightbulb"                       /**< Name of device. Will be included in the advertising data. */
#define MANUFACTURER_NAME               "NordicSemiconductor"                   /**< Manufacturer. Will be passed to Device Information Service. */
#define APP_ADV_INTERVAL                300                                     /**< The advertising interval (in units of 0.625 ms. This value corresponds to 187.5 ms). */

// Corresponds to LED2 on the development kit
#define LIGHTBULB_LED                   BSP_BOARD_LED_1                         /**< LED to be toggled with the help of the LED Button Service. */

#define APP_ADV_DURATION                18000                                   /**< The advertising duration (180 seconds) in units of 10 milliseconds. */
#define APP_BLE_OBSERVER_PRIO           3                                       /**< Application's BLE observer priority. You shouldn't need to modify this value. */
#define APP_BLE_CONN_CFG_TAG            1                                       /**< A tag identifying the SoftDevice BLE configuration. */

#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(100, UNIT_1_25_MS)        /**< Minimum acceptable connection interval (0.1 seconds). */
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(200, UNIT_1_25_MS)        /**< Maximum acceptable connection interval (0.2 second). */
#define SLAVE_LATENCY                   0                                       /**< Slave latency. */
#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)         /**< Connection supervisory timeout (4 seconds). */

#define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                   /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                  /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT    3                                       /**< Number of attempts before giving up the connection parameter negotiation. */

#define SEC_PARAM_BOND                  1                                       /**< Perform bonding. */
#define SEC_PARAM_MITM                  0                                       /**< Man In The Middle protection not required. */
#define SEC_PARAM_LESC                  0                                       /**< LE Secure Connections not enabled. */
#define SEC_PARAM_KEYPRESS              0                                       /**< Keypress notifications not enabled. */
#define SEC_PARAM_IO_CAPABILITIES       BLE_GAP_IO_CAPS_NONE                    /**< No I/O capabilities. */
#define SEC_PARAM_OOB                   0                                       /**< Out Of Band data not available. */
#define SEC_PARAM_MIN_KEY_SIZE          7                                       /**< Minimum encryption key size. */
#define SEC_PARAM_MAX_KEY_SIZE          16                                      /**< Maximum encryption key size. */

#define DEAD_BEEF                       0xDEADBEEF                              /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */

/**< Battery timer. */
APP_TIMER_DEF(m_battery_timer_id);

#define BATTERY_LEVEL_MEAS_INTERVAL     APP_TIMER_TICKS(30000)                 /**< Battery level measurement interval (ticks). */

NRF_BLE_GATT_DEF(m_gatt);                                                       /**< GATT module instance. */
NRF_BLE_QWR_DEF(m_qwr);                                                         /**< Context for the Queued Write module.*/
BLE_ADVERTISING_DEF(m_advertising);                                             /**< Advertising module instance. */

static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID;                        /**< Handle of the current connection. */

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. */
static uint8_t m_enc_scan_response_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX];         /**< Buffer for storing an encoded scan data. */

/**@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 = m_enc_scan_response_data,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX

    }
};

/**< Structure used to identify the battery service. */
BLE_BAS_DEF(m_bas);

/**< Structure used to identify the LED service. */
BLE_LED_SERVICE_DEF(m_led_service);
static void led_write_handler(uint16_t conn_handle, ble_led_service_t * p_led_service, uint8_t led_state);

static void battery_level_meas_timeout_handler(void * p_context);
static void battery_level_update(void);

static ble_uuid_t m_adv_uuids[] =                                               /**< Universally unique service identifiers. */
{
    {BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_TYPE_BLE}
};

static void advertising_start(bool erase_bonds);


/**@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 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_battery_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                battery_level_meas_timeout_handler);
    APP_ERROR_CHECK(err_code);
}

/**@brief Function for starting application timers.
 */
static void application_timers_start(void)
{
    uint32_t err_code;

    // Start application timers.
    err_code = app_timer_start(m_battery_timer_id, BATTERY_LEVEL_MEAS_INTERVAL, 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.
 */
static void gap_params_init(void)
{
    ret_code_t              err_code;
    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);

    err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_UNKNOWN);
    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 initializing the GATT module.
 */
static void gatt_init(void)
{
    ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, NULL);
    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.
 */
static void nrf_qwr_error_handler(uint32_t nrf_error)
{
    APP_ERROR_HANDLER(nrf_error);
}

/**@brief Function for initializing services that will be used by the application.
 */
static void services_init(void)
{
    uint32_t       err_code;
    ble_bas_init_t bas_init;
    ble_led_service_init_t led_init;

    nrf_ble_qwr_init_t qwr_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);

    // 1. Initialize the LED service
    led_init.led_write_handler = led_write_handler;

    err_code = ble_led_service_init(&m_led_service, &led_init);
    APP_ERROR_CHECK(err_code);

    // 2. Initialize Battery Service.
   // ble_bas_init_t bas_init;
    memset(&bas_init, 0, sizeof(bas_init));

    // Here the sec level for the Battery Service can be changed/increased.
    /*BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&bas_init.battery_level_char_attr_md.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_report_read_perm);*/

    bas_init.bl_rd_sec = SEC_OPEN;
    bas_init.bl_cccd_wr_sec = SEC_OPEN;
    bas_init.bl_report_rd_sec = SEC_OPEN;

    //bas_init.evt_handler =  on_bat_evt; 
    bas_init.evt_handler          = NULL;
    bas_init.support_notification = true;
    bas_init.p_report_ref         = NULL;
    bas_init.initial_batt_level   = 100;

    err_code = ble_bas_init(&m_bas, &bas_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.
 */
static 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.
 */
static void conn_params_error_handler(uint32_t nrf_error)
{
    APP_ERROR_HANDLER(nrf_error);
}


/**@brief Function for initializing the Connection Parameters module.
 */
static 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 putting the chip into sleep mode.
 *
 * @note This function will not return.
 */
static void sleep_mode_enter(void)
{
    ret_code_t err_code;

    err_code = bsp_indication_set(BSP_INDICATE_IDLE);
    APP_ERROR_CHECK(err_code);

    // Prepare wakeup buttons.
    err_code = bsp_btn_ble_sleep_mode_prepare();
    APP_ERROR_CHECK(err_code);

    // Go to system-off mode (this function will not return; wakeup will cause a reset).
    err_code = sd_power_system_off();
    APP_ERROR_CHECK(err_code);
}

/**@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.
 */
static 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.");
            err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_ADV_EVT_IDLE:
            sleep_mode_enter();
            break;

        default:
            break;
    }
}

/**@brief Function for handling BLE events.
 *
 * @param[in]   p_ble_evt   Bluetooth stack event.
 * @param[in]   p_context   Unused.
 */
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    ret_code_t err_code = NRF_SUCCESS;

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_DISCONNECTED:
            NRF_LOG_INFO("Disconnected.");
            // LED indication will be changed when advertising starts.
            break;

        case BLE_GAP_EVT_CONNECTED:
            NRF_LOG_INFO("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:
        {
            NRF_LOG_DEBUG("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.
            NRF_LOG_DEBUG("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.
            NRF_LOG_DEBUG("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 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);

    // 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 write events to the LED characteristic.
 *
 * @param[in] p_led_service  Instance of LED Service to which the write applies.
 * @param[in] led_state      Written/desired state of the LED.
 */
static void led_write_handler(uint16_t conn_handle, ble_led_service_t * p_led_service, uint8_t led_state)
{
    if (led_state)
    {
        bsp_board_led_on(LIGHTBULB_LED);
        NRF_LOG_INFO("Received LED ON!");
    }
    else
    {
        bsp_board_led_off(LIGHTBULB_LED);
        NRF_LOG_INFO("Received LED OFF!");
    }
}

/**@brief Function for initializing the Advertising functionality.
 */
static void advertising_init(void)
{
    ret_code_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;
    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 Clear bond information from persistent storage.
.2 */
static 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 handling events from the BSP module.
 *
 * @param[in]   event   Event generated when button is pressed.
 */
static void bsp_event_handler(bsp_event_t event)
{
    ret_code_t err_code;

    switch (event)
    {
        case BSP_EVENT_SLEEP:
            sleep_mode_enter();
            break; // BSP_EVENT_SLEEP

        case BSP_EVENT_DISCONNECT:
            err_code = sd_ble_gap_disconnect(m_conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            if (err_code != NRF_ERROR_INVALID_STATE)
            {
                APP_ERROR_CHECK(err_code);
            }
            break; // BSP_EVENT_DISCONNECT

        case BSP_EVENT_WHITELIST_OFF:
            if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
            {
                err_code = ble_advertising_restart_without_whitelist(&m_advertising);
                if (err_code != NRF_ERROR_INVALID_STATE)
                {
                    APP_ERROR_CHECK(err_code);
                }
            }
            break; // BSP_EVENT_KEY_0

        default:
            break;
    }
}


/**@brief Function for initializing leds.
 *
 * @details Initializes all LEDs used by the application.
 */
static void leds_init()
{
    ret_code_t err_code;
    
    err_code = bsp_init(BSP_INIT_LEDS, bsp_event_handler);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing the nrf log module.
 */
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 power management.
 */
static void power_management_init(void)
{
    ret_code_t err_code;
    err_code = nrf_pwr_mgmt_init();
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for handling the idle state (main loop).
 *
 * @details If there is no pending log operation, then sleep until next the next event occurs.
 */
static void idle_state_handle(void)
{
    if (NRF_LOG_PROCESS() == false)
    {
        nrf_pwr_mgmt_run();
    }
}

/**@brief Function for handling the Battery measurement timer timeout.
 *
 * @details This function will be called each time the battery level measurement timer expires.
 *
 * @param[in] p_context  Pointer used for passing some arbitrary information (context) from the
 *                       app_start_timer() call to the timeout handler.
 */
static void battery_level_meas_timeout_handler(void * p_context)
{
    UNUSED_PARAMETER(p_context);
    NRF_LOG_INFO("Battery Level timeout event");

    // Only send the battery level update if we are connected
    if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
    {
        battery_level_update();
    }
}
/**@brief Function for updating the Battery Level measurement*/
static void battery_level_update(void)
{
    ret_code_t err_code;

    uint8_t  battery_level;
    uint16_t vbatt;              // Variable to hold voltage reading
    battery_voltage_get(&vbatt); // Get new battery voltage

    battery_level = battery_level_in_percent(vbatt);          //Transform the millivolts value into battery level percent.
    printf("ADC result in percent: %d\r\n", battery_level);

    err_code = ble_bas_battery_level_update(&m_bas, battery_level, m_conn_handle);
    if ((err_code != NRF_SUCCESS) &&
        (err_code != NRF_ERROR_INVALID_STATE) &&
        (err_code != NRF_ERROR_RESOURCES) &&
        (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
       )
    {
        APP_ERROR_HANDLER(err_code);
    }
}

/**@brief Function for starting advertising.
 
static void advertising_start()
{
    ret_code_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);
}*/

/**@brief Function for starting advertising.
 */
static 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_start(&m_advertising, BLE_ADV_MODE_FAST);

        APP_ERROR_CHECK(err_code);
    }
}

/**@brief Function for application main entry.
 */
int main(void)
{
    bool erase_bonds;

    // Initialize.
    log_init();
    timers_init();
    battery_voltage_init();
    leds_init();
    power_management_init();
    ble_stack_init();
    gap_params_init();
    gatt_init();
    advertising_init();
    services_init();
    conn_params_init();
   

    // Start execution.
    NRF_LOG_INFO("BLE Lightbulb example started.");
    application_timers_start();
  
    advertising_start(erase_bonds);

    // Enter main loop.
    for (;;)
    {
        idle_state_handle();
    }
}
 

led_service.h file:

/*
 * The MIT License (MIT)
 * Copyright (c) 2018 Novel Bits
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 */
 
#ifndef LED_SERVICE_H
#define LED_SERVICE_H
 
#include <stdint.h>
#include "boards.h"
#include "ble.h"
#include "ble_srv_common.h"
#include "nrf_sdh_ble.h"
 
/**@brief   Macro for defining a ble_led_service instance.
 *
 * @param   _name   Name of the instance.
 * @hideinitializer
 */
 
#define BLE_LED_SERVICE_BLE_OBSERVER_PRIO 2
 
#define BLE_LED_SERVICE_DEF(_name)                                                                          \
static ble_led_service_t _name;                                                                             \
NRF_SDH_BLE_OBSERVER(_name ## _obs,                                                                         \
                     BLE_LED_SERVICE_BLE_OBSERVER_PRIO,                                                     \
                     ble_led_service_on_ble_evt, &_name)
 
// LED service:                     E54B0001-67F5-479E-8711-B3B99198CE6C
//   LED 2 characteristic:   E54B0002-67F5-479E-8711-B3B99198CE6C
 
// The bytes are stored in little-endian format, meaning the
// Least Significant Byte is stored first
// (reversed from the order they're displayed as)
 
// Base UUID: E54B0000-67F5-479E-8711-B3B99198CE6C
#define BLE_UUID_LED_SERVICE_BASE_UUID  {0x6C, 0xCE, 0x98, 0x91, 0xB9, 0xB3, 0x11, 0x87, 0x9E, 0x47, 0xF5, 0x67, 0x00, 0x00, 0x4B, 0xE5}
 
// Service & characteristics UUIDs
#define BLE_UUID_LED_SERVICE_UUID  0x0001
#define BLE_UUID_LED_2_CHAR_UUID   0x0002
 
// Forward declaration of the custom_service_t type.
typedef struct ble_led_service_s ble_led_service_t;
 
typedef void (*ble_led_service_led_write_handler_t) (uint16_t conn_handle, ble_led_service_t * p_led_service, uint8_t new_state);
 
/** @brief LED Service init structure. This structure contains all options and data needed for
 *        initialization of the service.*/
typedef struct
{
    ble_led_service_led_write_handler_t led_write_handler; /**< Event handler to be called when the LED Characteristic is written. */
} ble_led_service_init_t;
 
/**@brief LED Service structure.
 *        This contains various status information
 *        for the service.
 */
typedef struct ble_led_service_s
{
    uint16_t                            conn_handle;
    uint16_t                            service_handle;
    uint8_t                             uuid_type;
    ble_gatts_char_handles_t            led_2_char_handles;
    ble_led_service_led_write_handler_t led_write_handler;
 
} ble_led_service_t;
 
// Function Declarations
 
/**@brief Function for initializing the LED Service.
 *
 * @param[out]  p_led_service  LED Service structure. This structure will have to be supplied by
 *                                the application. It will be initialized by this function, and will later
 *                                be used to identify this particular service instance.
 *
 * @return      NRF_SUCCESS on successful initialization of service, otherwise an error code.
 */
uint32_t ble_led_service_init(ble_led_service_t * p_led_service, const ble_led_service_init_t * p_led_service_init);
 
/**@brief Function for handling the application's BLE stack events.
 *
 * @details This function handles all events from the BLE stack that are of interest to the LED Service.
 *
 * @param[in] p_ble_evt  Event received from the BLE stack.
 * @param[in] p_context  LED Service structure.
 */
void ble_led_service_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
 
#endif /* LED_SERVICE_H */

led_service.c file:

/*
 * The MIT License (MIT)
 * Copyright (c) 2018 Novel Bits
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 */
 
#include <string.h>
 
#include "nrf_log.h"
#include "led_service.h"
 
static const uint8_t LED2CharName[] = "LED 2";
 
/**@brief Function for handling the Connect event.
 *
 * @param[in]   p_led_service  LED service structure.
 * @param[in]   p_ble_evt      Event received from the BLE stack.
 */
static void on_connect(ble_led_service_t * p_led_service, ble_evt_t const * p_ble_evt)
{
    p_led_service->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
}
 
/**@brief Function for handling the Disconnect event.
 *
 * @param[in]   p_bas       LED service structure.
 * @param[in]   p_ble_evt   Event received from the BLE stack.
 */
static void on_disconnect(ble_led_service_t * p_led_service, ble_evt_t const * p_ble_evt)
{
    UNUSED_PARAMETER(p_ble_evt);
    p_led_service->conn_handle = BLE_CONN_HANDLE_INVALID;
}
 
/**@brief Function for handling the Write event.
 *
 * @param[in] p_led_service   LED Service structure.
 * @param[in] p_ble_evt       Event received from the BLE stack.
 */
static void on_write(ble_led_service_t * p_led_service, ble_evt_t const * p_ble_evt)
{
    ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
 
    if (   (p_evt_write->handle == p_led_service->led_2_char_handles.value_handle)
        && (p_evt_write->len == 1)
        && (p_led_service->led_write_handler != NULL))
    {
        p_led_service->led_write_handler(p_ble_evt->evt.gap_evt.conn_handle, p_led_service, p_evt_write->data[0]);
    }
}
 
/**@brief Function for adding the LED 2 characteristic.
 *
 */
static uint32_t led_2_char_add(ble_led_service_t * p_led_service)
{
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_t    attr_char_value;
    ble_gatts_attr_md_t attr_md;
    ble_uuid_t          ble_uuid;
 
    memset(&char_md, 0, sizeof(char_md));
    memset(&attr_md, 0, sizeof(attr_md));
    memset(&attr_char_value, 0, sizeof(attr_char_value));
 
    char_md.char_props.read          = 1;
    char_md.char_props.write         = 1;
    char_md.p_char_user_desc         = LED2CharName;
    char_md.char_user_desc_size      = sizeof(LED2CharName);
    char_md.char_user_desc_max_size  = sizeof(LED2CharName);
    char_md.p_char_pf                = NULL;
    char_md.p_user_desc_md           = NULL;
    char_md.p_cccd_md                = NULL;
    char_md.p_sccd_md                = NULL;
 
    // Define the LED 2 Characteristic UUID
    ble_uuid.type = p_led_service->uuid_type;
    ble_uuid.uuid = BLE_UUID_LED_2_CHAR_UUID;
 
    // Set permissions on the Characteristic value
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
 
    // Attribute Metadata settings
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 0;
    attr_md.vlen       = 0;
 
    // Attribute Value settings
    attr_char_value.p_uuid       = &ble_uuid;
    attr_char_value.p_attr_md    = &attr_md;
    attr_char_value.init_len     = sizeof(uint8_t);
    attr_char_value.init_offs    = 0;
    attr_char_value.max_len      = sizeof(uint8_t);
    attr_char_value.p_value      = NULL;
 
    return sd_ble_gatts_characteristic_add(p_led_service->service_handle, &char_md,
                                           &attr_char_value,
                                           &p_led_service->led_2_char_handles);
}
 
uint32_t ble_led_service_init(ble_led_service_t * p_led_service, const ble_led_service_init_t * p_led_service_init)
{
    uint32_t   err_code;
    ble_uuid_t ble_uuid;
 
    // Initialize service structure
    p_led_service->conn_handle = BLE_CONN_HANDLE_INVALID;
 
    // Initialize service structure.
    p_led_service->led_write_handler = p_led_service_init->led_write_handler;
 
    // Add service UUID
    ble_uuid128_t base_uuid = {BLE_UUID_LED_SERVICE_BASE_UUID};
    err_code = sd_ble_uuid_vs_add(&base_uuid, &p_led_service->uuid_type);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
 
    // Set up the UUID for the service (base + service-specific)
    ble_uuid.type = p_led_service->uuid_type;
    ble_uuid.uuid = BLE_UUID_LED_SERVICE_UUID;
 
    // Set up and add the service
    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_led_service->service_handle);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
 
    // Add the different characteristics in the service:
    //   Button press characteristic:   E54B0002-67F5-479E-8711-B3B99198CE6C
    err_code = led_2_char_add(p_led_service);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
 
    return NRF_SUCCESS;
}
 
void ble_led_service_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
    ble_led_service_t * p_led_service = (ble_led_service_t *)p_context;
 
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            on_connect(p_led_service, p_ble_evt);
            break;
 
        case BLE_GATTS_EVT_WRITE:
            on_write(p_led_service, p_ble_evt);
            break;
 
        case BLE_GAP_EVT_DISCONNECTED:
            on_disconnect(p_led_service, p_ble_evt);
            break;
 
        default:
            // No implementation needed.
            break;
    }
}

battery_voltage.h file:

/*
 * The MIT License (MIT)
 * Copyright (c) 2018 Novel Bits
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 */

#ifndef BATTERY_VOLTAGE_H__
#define BATTERY_VOLTAGE_H__

#include <stdint.h>

/**@brief Function for initializing the battery voltage module.
 */
void battery_voltage_init(void);

/**@brief Function for reading the battery voltage.
 *
 * @param[out]   p_vbatt       Pointer to the battery voltage value.
 */
void battery_voltage_get(uint16_t * p_vbatt);

#endif // BATTERY_VOLTAGE_H__

battery_voltage.c file:

/**
 * Copyright (c) 2016 - 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 "battery_voltage.h"
#include "nrf_drv_saadc.h"
#include "sdk_macros.h"
#include "nrf_log.h"

#define ADC_REF_VOLTAGE_IN_MILLIVOLTS  600  //!< Reference voltage (in milli volts) used by ADC while doing conversion.
#define DIODE_FWD_VOLT_DROP_MILLIVOLTS 270  //!< Typical forward voltage drop of the diode (Part no: SD103ATW-7-F) that is connected in series with the voltage supply. This is the voltage drop when the forward current is 1mA. Source: Data sheet of 'SURFACE MOUNT SCHOTTKY BARRIER DIODE ARRAY' available at www.diodes.com.
#define ADC_RES_10BIT                  1024 //!< Maximum digital value for 10-bit ADC conversion.
#define ADC_PRE_SCALING_COMPENSATION   6    //!< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage.
#define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE) \
    ((((ADC_VALUE) *ADC_REF_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_PRE_SCALING_COMPENSATION)

static nrf_saadc_value_t adc_buf;                   //!< Buffer used for storing ADC value.
static uint16_t          m_batt_lvl_in_milli_volts; //!< Current battery level.

/**@brief Function handling events from 'nrf_drv_saadc.c'.
 *
 * @param[in] p_evt SAADC event.
 */
static void saadc_event_handler(nrf_drv_saadc_evt_t const * p_evt)
{
    if (p_evt->type == NRF_DRV_SAADC_EVT_DONE)
    {
        nrf_saadc_value_t adc_result;

        adc_result = p_evt->data.done.p_buffer[0];

        m_batt_lvl_in_milli_volts = ADC_RESULT_IN_MILLI_VOLTS(adc_result) + DIODE_FWD_VOLT_DROP_MILLIVOLTS;

        NRF_LOG_INFO("ADC reading - ADC:%d,  In Millivolts: %d\r\n", adc_result, m_batt_lvl_in_milli_volts);
    }
}

void battery_voltage_init(void)
{
    ret_code_t err_code = nrf_drv_saadc_init(NULL, saadc_event_handler);

    APP_ERROR_CHECK(err_code);

    nrf_saadc_channel_config_t config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD);
    err_code = nrf_drv_saadc_channel_init(0, &config);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(&adc_buf, 1);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_sample();
    APP_ERROR_CHECK(err_code);
}

void battery_voltage_get(uint16_t * p_vbatt)
{
    VERIFY_PARAM_NOT_NULL_VOID(p_vbatt);

    *p_vbatt = m_batt_lvl_in_milli_volts;
    if (!nrf_drv_saadc_is_busy())
    {
        ret_code_t err_code = nrf_drv_saadc_buffer_convert(&adc_buf, 1);
        APP_ERROR_CHECK(err_code);

        err_code = nrf_drv_saadc_sample();
        APP_ERROR_CHECK(err_code);
    }
}

The code builds without any error, but while debugging i get the following errors:

void app_error_fault_handler(unsigned int id=0x00004001, unsigned int pc=0x0003290b, unsigned int info=0x2003ffc0)

void app_error_handler(unsigned int error_code=0x00000000, unsigned int line_num=0x200023b4, const uint8_t* p_file_name=0x0000001b)

Below I have also attached the output that is being displayed on disassembly window :

  B083        sub sp, sp, #12
--- app_button.c -- 305 ------------------------------------
}
uint32_t app_button_enable(void)
{
ASSERT(mp_buttons);
    4B11        ldr r3, =0x2000291C <mp_buttons>
    681B        ldr r3, [r3]
    2B00        cmp r3, #0
    D104        bne 0x00028D6A
    4910        ldr r1, =0x0003C6FC
    F2401035    movw r0, #0x135
    F009FAA7    bl 0x000322B8 <assert_nrf_callback>
--- app_button.c -- 310 ------------------------------------
uint32_t i;
for (i = 0; i < m_button_count; i++)
    2300        movs r3, #0
    9301        str r3, [sp, #4]
    E00C        b 0x00028D8A
--- app_button.c -- 313 ------------------------------------
{
nrf_drv_gpiote_in_event_enable(mp_buttons[i].pin_no, true);
    4B0B        ldr r3, =0x2000291C <mp_buttons>
    681A        ldr r2, [r3]
    9B01        ldr r3, [sp, #4]
    00DB        lsls r3, r3, #3
    4413        add r3, r2
    781B        ldrb r3, [r3]
    2101        movs r1, #1
    4618        mov r0, r3
    F006F928    bl 0x0002EFD4 <nrfx_gpiote_in_event_enable>
--- app_button.c -- 312 ------------------------------------
for (i = 0; i < m_button_count; i++)
    9B01        ldr r3, [sp, #4]
    3301        adds r3, #1
    9301        str r3, [sp, #4]
    4B07        ldr r3, =0x20002920 <m_button_count>
    781B        ldrb r3, [r3]
    461A        mov r2, r3
    9B01        ldr r3, [sp, #4]
    4293        cmp r3, r2
    D3EC        bcc 0x00028D70
--- app_button.c -- 313 ------------------------------------
{
nrf_drv_gpiote_in_event_enable(mp_buttons[i].pin_no, true);
}
return NRF_SUCCESS;
    2300        movs r3, #0
--- app_button.c -- 318 ------------------------------------
}
    4618        mov r0, r3
    B003        add sp, sp, #12
    F85DFB04    pop.w {pc}
    2000291C    .word 0x2000291C
    0003C6FC    .word 0x0003C6FC
    20002920    .word 0x20002920
--- app_error.c -- 75 --------------------------------------
UNUSED_VARIABLE(error_info);
}
void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info)
{
    B086        sub sp, sp, #24
    9003        str r0, [sp, #12]
    9102        str r1, [sp, #8]
    9201        str r2, [sp, #4]
--- app_error.c -- 91 --------------------------------------
} m_error_data = {0};
// The following variable helps Keil keep the call stack visible, in addition, it can be set to
// 0 in the debugger to continue executing code after the error check.
volatile bool loop = true;
    2301        movs r3, #1
    F88D3017    strb.w r3, [sp, #23]
--- app_error.c -- 96 --------------------------------------
UNUSED_VARIABLE(loop);
    F89D3017    ldrb.w r3, [sp, #23]
--- app_error.c -- 97 --------------------------------------
m_error_data.fault_id = id;
    4A20        ldr r2, =0x20002970 <m_error_data.7809>
    9B03        ldr r3, [sp, #12]
    6013        str r3, [r2]
--- app_error.c -- 99 --------------------------------------
m_error_data.pc = pc;
    4A1E        ldr r2, =0x20002970 <m_error_data.7809>
    9B02        ldr r3, [sp, #8]
    6053        str r3, [r2, #4]
--- app_error.c -- 100 -------------------------------------
m_error_data.error_info = info;
    4A1D        ldr r2, =0x20002970 <m_error_data.7809>
    9B01        ldr r3, [sp, #4]
    6093        str r3, [r2, #8]
--- app_error.c -- 101 -------------------------------------
switch (id)
    9B03        ldr r3, [sp, #12]
    F2440201    movw r2, #0x4001
    4293        cmp r3, r2
    D012        beq 0x00028E00
    9B03        ldr r3, [sp, #12]
    F2440202    movw r2, #0x4002
    4293        cmp r3, r2
    D120        bne 0x00028E26
--- app_error.c -- 103 -------------------------------------
{
case NRF_FAULT_ID_SDK_ASSERT:
m_error_data.p_assert_info = (assert_info_t *)info;
    9B01        ldr r3, [sp, #4]
    4A16        ldr r2, =0x20002970 <m_error_data.7809>
    60D3        str r3, [r2, #12]
--- app_error.c -- 106 -------------------------------------
m_error_data.line_num = m_error_data.p_assert_info->line_num;
    4B15        ldr r3, =0x20002970 <m_error_data.7809>
    68DB        ldr r3, [r3, #12]
    681B        ldr r3, [r3]
    4A13        ldr r2, =0x20002970 <m_error_data.7809>
    6193        str r3, [r2, #24]
--- app_error.c -- 107 -------------------------------------
m_error_data.p_file_name = m_error_data.p_assert_info->p_file_name;
    4B12        ldr r3, =0x20002970 <m_error_data.7809>
    68DB        ldr r3, [r3, #12]
    685B        ldr r3, [r3, #4]
    4A11        ldr r2, =0x20002970 <m_error_data.7809>
    61D3        str r3, [r2, #28]
--- app_error.c -- 108 -------------------------------------
break;
    E012        b 0x00028E26
--- app_error.c -- 109 -------------------------------------
case NRF_FAULT_ID_SDK_ERROR:
m_error_data.p_error_info = (error_info_t *)info;
    9B01        ldr r3, [sp, #4]
    4A0F        ldr r2, =0x20002970 <m_error_data.7809>
    6113        str r3, [r2, #16]
--- app_error.c -- 112 -------------------------------------
m_error_data.err_code = m_error_data.p_error_info->err_code;
    4B0E        ldr r3, =0x20002970 <m_error_data.7809>
    691B        ldr r3, [r3, #16]
    689B        ldr r3, [r3, #8]
    4A0C        ldr r2, =0x20002970 <m_error_data.7809>
    6153        str r3, [r2, #20]
--- app_error.c -- 113 -------------------------------------
m_error_data.line_num = m_error_data.p_error_info->line_num;
    4B0B        ldr r3, =0x20002970 <m_error_data.7809>
    691B        ldr r3, [r3, #16]
    681B        ldr r3, [r3]
    4A0A        ldr r2, =0x20002970 <m_error_data.7809>
    6193        str r3, [r2, #24]
--- app_error.c -- 114 -------------------------------------
m_error_data.p_file_name = m_error_data.p_error_info->p_file_name;
    4B09        ldr r3, =0x20002970 <m_error_data.7809>
    691B        ldr r3, [r3, #16]
    685B        ldr r3, [r3, #4]
    4A07        ldr r2, =0x20002970 <m_error_data.7809>
    61D3        str r3, [r2, #28]
--- app_error.c -- 115 -------------------------------------
break;
    BF00        nop
--- cmsis_gcc.h -- 205 -------------------------------------
Can only be executed in Privileged modes.
*/
__STATIC_FORCEINLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i" : : : "memory");
    B672        cpsid i
--- cmsis_gcc.h -- 210 -------------------------------------
}
    BF00        nop
--- app_error.c -- 118 -------------------------------------
UNUSED_VARIABLE(m_error_data);
// If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger.
__disable_irq();
while (loop);
    BF00        nop
    F89D3017    ldrb.w r3, [sp, #23]
    B2DB        uxtb r3, r3
    2B00        cmp r3, #0
    D1FA        bne 0x00028E2C
--- cmsis_gcc.h -- 194 -------------------------------------
Can only be executed in Privileged modes.
*/
__STATIC_FORCEINLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i" : : : "memory");
    B662        cpsie i
--- cmsis_gcc.h -- 199 -------------------------------------
}
    BF00        nop
--- app_error.c -- 121 -------------------------------------
__disable_irq();
while (loop);
__enable_irq();
}
    BF00        nop
    B006        add sp, sp, #24
    4770        bx lr
    20002970    .word 0x20002970
--- app_error_handler_gcc.c -- 45 --------------------------
void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name) __attribute__(( naked ));
void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
{
__ASM volatile(
    B500        push {lr}
    B083        sub sp, sp, #12
    9002        str r0, [sp, #8]
    9100        str r1, [sp]
    9201        str r2, [sp, #4]
    F2440001    movw r0, #0x4001
    4671        mov r1, lr
    466A        mov r2, sp
    F000F803    bl 0x00028E60 <app_error_fault_handler> (fault point for app_error_handler) (00028E56)
    B003        add sp, sp, #12
    BD00        pop {pc}
--- app_error_handler_gcc.c -- 80 --------------------------
"X" (app_error_fault_handler)
: /* Clobbers */
"r0", "r1", "r2"
);
}
    BF00        nop
--- app_error_weak.c -- 53 ---------------------------------
* Function is implemented as weak so that it can be overwritten by custom application error handler
* when needed.
*/
__WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
{
    B530        push {r4-r5, lr}
    B08B        sub sp, sp, #0x2C
    9007        str r0, [sp, #28]
    9106        str r1, [sp, #24]
    9205        str r2, [sp, #20]
--- cmsis_gcc.h -- 205 -------------------------------------
Can only be executed in Privileged modes.
*/
__STATIC_FORCEINLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i" : : : "memory");
    B672        cpsid i
--- cmsis_gcc.h -- 210 -------------------------------------
}
    BF00        nop
--- app_error_weak.c -- 55 ---------------------------------
*/
__WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
{
__disable_irq();
NRF_LOG_FINAL_FLUSH();
    F7FFFAF5    bl 0x0002845C <nrf_log_panic>
    BF00        nop
    F7FFF8B0    bl 0x00027FD8 <nrf_log_frontend_dequeue>
    4603        mov r3, r0
    2B00        cmp r3, #0
    D1FA        bne 0x00028E74
--- app_error_weak.c -- 60 ---------------------------------
#ifndef DEBUG
NRF_LOG_ERROR("Fatal error");
#else
switch (id)
    9B07        ldr r3, [sp, #28]
    F2440202    movw r2, #0x4002
    4293        cmp r3, r2
    D02F        beq 0x00028EE8
    9B07        ldr r3, [sp, #28]
    F2440202    movw r2, #0x4002
    4293        cmp r3, r2
    D869        bhi 0x00028F66
    9B07        ldr r3, [sp, #28]
    F2440201    movw r2, #0x4001
    4293        cmp r3, r2
    D037        beq 0x00028F0C
    9B07        ldr r3, [sp, #28]
    F2440201    movw r2, #0x4001
    4293        cmp r3, r2
    D85F        bhi 0x00028F66
    9B07        ldr r3, [sp, #28]
    2B01        cmp r3, #1
    D005        beq 0x00028EB8
    9B07        ldr r3, [sp, #28]
    F2410201    movw r2, #0x1001
    4293        cmp r3, r2
    D00C        beq 0x00028ED0
    E056        b 0x00028F66
--- app_error_weak.c -- 65 ---------------------------------
{
#if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
case NRF_FAULT_ID_SD_ASSERT:
NRF_LOG_ERROR("SOFTDEVICE: ASSERTION FAILED");
    4A39        ldr r2, =0x0003C3CC <m_nrf_log_app_logs_data_const>
    4B3A        ldr r3, =0x0003C39C <__cli_command_load_end__>
    1AD3        subs r3, r2, r3
    08DB        lsrs r3, r3, #3
    041B        lsls r3, r3, #16
    F0430301    orr r3, r3, #1
    4938        ldr r1, =0x0003C750
    4618        mov r0, r3
    F7FFF813    bl 0x00027EF4 <nrf_log_frontend_std_0>
--- app_error_weak.c -- 69 ---------------------------------
break;
    E057        b 0x00028F80
--- app_error_weak.c -- 70 ---------------------------------
case NRF_FAULT_ID_APP_MEMACC:
NRF_LOG_ERROR("SOFTDEVICE: INVALID MEMORY ACCESS");
    4A33        ldr r2, =0x0003C3CC <m_nrf_log_app_logs_data_const>
    4B34        ldr r3, =0x0003C39C <__cli_command_load_end__>
    1AD3        subs r3, r2, r3
    08DB        lsrs r3, r3, #3
    041B        lsls r3, r3, #16
    F0430301    orr r3, r3, #1
    4933        ldr r1, =0x0003C770
    4618        mov r0, r3
    F7FFF807    bl 0x00027EF4 <nrf_log_frontend_std_0>
--- app_error_weak.c -- 72 ---------------------------------
break;
    E04B        b 0x00028F80
--- app_error_weak.c -- 73 ---------------------------------
#endif
case NRF_FAULT_ID_SDK_ASSERT:
{
assert_info_t * p_info = (assert_info_t *)info;
    9B05        ldr r3, [sp, #20]
    9309        str r3, [sp, #0x24]
--- app_error_weak.c -- 77 ---------------------------------
NRF_LOG_ERROR("ASSERTION FAILED at %s:%u",
    4A2C        ldr r2, =0x0003C3CC <m_nrf_log_app_logs_data_const>
    4B2D        ldr r3, =0x0003C39C <__cli_command_load_end__>
    1AD3        subs r3, r2, r3
    08DB        lsrs r3, r3, #3
    041B        lsls r3, r3, #16
    F0430001    orr r0, r3, #1
    9B09        ldr r3, [sp, #0x24]
    685B        ldr r3, [r3, #4]
    461A        mov r2, r3
    9B09        ldr r3, [sp, #0x24]
    681B        ldr r3, [r3]
    492A        ldr r1, =0x0003C794
    F7FFF814    bl 0x00027F32 <nrf_log_frontend_std_2>
--- app_error_weak.c -- 78 ---------------------------------
p_info->p_file_name,
p_info->line_num);
break;
    E039        b 0x00028F80
--- app_error_weak.c -- 81 ---------------------------------
}
case NRF_FAULT_ID_SDK_ERROR:
{
error_info_t * p_info = (error_info_t *)info;
    9B05        ldr r3, [sp, #20]
    9308        str r3, [sp, #32]
--- app_error_weak.c -- 85 ---------------------------------
NRF_LOG_ERROR("ERROR %u [%s] at %s:%u\r\nPC at: 0x%08x",
    4A23        ldr r2, =0x0003C3CC <m_nrf_log_app_logs_data_const>
    4B24        ldr r3, =0x0003C39C <__cli_command_load_end__>
    1AD3        subs r3, r2, r3
    08DB        lsrs r3, r3, #3
    041B        lsls r3, r3, #16
    F0430401    orr r4, r3, #1
    9B08        ldr r3, [sp, #32]
    689D        ldr r5, [r3, #8]
    9B08        ldr r3, [sp, #32]
    689B        ldr r3, [r3, #8]
    4618        mov r0, r3
    F004FA50    bl 0x0002D3CC <nrf_strerror_get>
    4603        mov r3, r0
    4618        mov r0, r3
    9B08        ldr r3, [sp, #32]
    685B        ldr r3, [r3, #4]
    4619        mov r1, r3
    9B08        ldr r3, [sp, #32]
    681B        ldr r3, [r3]
    9A06        ldr r2, [sp, #24]
    9202        str r2, [sp, #8]
    9301        str r3, [sp, #4]
    9100        str r1, [sp]
    4603        mov r3, r0
    462A        mov r2, r5
    491B        ldr r1, =0x0003C7B0
    4620        mov r0, r4
    F7FFF81C    bl 0x00027F86 <nrf_log_frontend_std_5>
--- app_error_weak.c -- 87 ---------------------------------
nrf_strerror_get(p_info->err_code),
p_info->p_file_name,
p_info->line_num,
pc);
NRF_LOG_ERROR("End of error report");
    4A14        ldr r2, =0x0003C3CC <m_nrf_log_app_logs_data_const>
    4B14        ldr r3, =0x0003C39C <__cli_command_load_end__>
    1AD3        subs r3, r2, r3
    08DB        lsrs r3, r3, #3
    041B        lsls r3, r3, #16
    F0430301    orr r3, r3, #1
    4916        ldr r1, =0x0003C7D8
    4618        mov r0, r3
    F7FEFFC8    bl 0x00027EF4 <nrf_log_frontend_std_0>
--- app_error_weak.c -- 92 ---------------------------------
break;
    E00C        b 0x00028F80
--- app_error_weak.c -- 93 ---------------------------------
}
default:
NRF_LOG_ERROR("UNKNOWN FAULT at 0x%08X", pc);
    4A0E        ldr r2, =0x0003C3CC <m_nrf_log_app_logs_data_const>
    4B0E        ldr r3, =0x0003C39C <__cli_command_load_end__>
    1AD3        subs r3, r2, r3
    08DB        lsrs r3, r3, #3
    041B        lsls r3, r3, #16
    F0430301    orr r3, r3, #1
    9A06        ldr r2, [sp, #24]
    4911        ldr r1, =0x0003C7EC
    4618        mov r0, r3
    F7FEFFC9    bl 0x00027F10 <nrf_log_frontend_std_1>
--- app_error_weak.c -- 96 ---------------------------------
break;
    BF00        nop
--- app_error_weak.c -- 97 ---------------------------------
}
#endif
NRF_BREAKPOINT_COND;
    4B0F        ldr r3, =0xE000EDF0
    681B        ldr r3, [r3]
    F0030301    and r3, r3, #1
    2B00        cmp r3, #0
    D000        beq 0x00028F8E
    BE00        bkpt #0         (fault point for app_error_fault_handler)(00028F8C)
--- app_error_weak.c -- 103 --------------------------------
#ifndef DEBUG
NRF_LOG_WARNING("System reset");
NVIC_SystemReset();
#else
app_error_save_and_stop(id, pc, info);
    9A05        ldr r2, [sp, #20]
    9906        ldr r1, [sp, #24]
    9807        ldr r0, [sp, #28]
    F7FFFF0A    bl 0x00028DAC <app_error_save_and_stop>
--- app_error_weak.c -- 108 --------------------------------
#endif // DEBUG
}
    BF00        nop
    B00B        add sp, sp, #0x2C
    BD30        pop {r4-r5, pc}
    BF00        nop
    0003C3CC    .word 0x0003C3CC
    0003C39C    .word 0x0003C39C
    0003C750    .word 0x0003C750
    0003C770    .word 0x0003C770
    0003C794    .word 0x0003C794
    0003C7B0    .word 0x0003C7B0
    0003C7D8    .word 0x0003C7D8
    0003C7EC    .word 0x0003C7EC
    E000EDF0    .word 0xE000EDF0
--- app_timer2.c -- 110 ------------------------------------
/**
* @brief Return current 64 bit timestamp
*/
static uint64_t get_now(void)
{
    B5F0        push {r4-r7, lr}
    B083        sub sp, sp, #12
--- app_timer2.c -- 115 ------------------------------------
uint64_t now = m_base_counter + drv_rtc_counter_get(&m_rtc_inst);
    4812        ldr r0, =0x200022D4 <m_rtc_inst>
    F001F804    bl 0x00029FD6 <drv_rtc_counter_get>
    4603        mov r3, r0
    4618        mov r0, r3
    F04F0100    mov.w r1, #0
    4B10        ldr r3, =0x20002998 <m_base_counter>
    E9D32300    ldrd r2, r3, [r3, #0]
    1886        adds r6, r0, r2
    EB410703    adc.w r7, r1, r3
    E9CD6700    strd r6, r7, [sp, #0]
--- app_timer2.c -- 117 ------------------------------------
/* it is possible that base was not updated and overflow occured, in that case 'now' will be
* 24bit value behind. Additional timestamp updated on every 24 bit period is used to detect
* that case. Apart from that 'now' should never be behind previously read timestamp.
*/
if (now < m_stamp64) {
    4B0D        ldr r3, =0x200029A0 <m_stamp64>
    E9D32300    ldrd r2, r3, [r3, #0]
    E9DD0100    ldrd r0, r1, [sp, #0]
    4299        cmp r1, r3
    BF08        it eq
    4290        cmpeq r0, r2
    D207        bcs 0x00029008
--- app_timer2.c -- 122 ------------------------------------
now += (DRV_RTC_MAX_CNT + 1);
    E9DD2300    ldrd r2, r3, [sp, #0]
    F1127480    adds.w r4, r2, #0x1000000
    F1430500    adc r5, r3, #0
    E9CD4500    strd r4, r5, [sp, #0]
--- app_timer2.c -- 123 ------------------------------------
}
return now;
    E9DD2300    ldrd r2, r3, [sp, #0]
--- app_timer2.c -- 126 ------------------------------------
}
    4610        mov r0, r2
    4619        mov r1, r3
    B003        add sp, sp, #12
    BDF0        pop {r4-r7, pc}
    200022D4    .word 0x200022D4
    20002998    .word 0x20002998
    200029A0    .word 0x200029A0
--- app_timer2.c -- 127 ------------------------------------
/**
* @brief Function used for comparing items in sorted list.
*/
static inline bool compare_func(nrf_sortlist_item_t * p_item0, nrf_sortlist_item_t *p_item1)
{
    B088        sub sp, sp, #32
    9001        str r0, [sp, #4]
    9100        str r1, [sp]
--- app_timer2.c -- 132 ------------------------------------
app_timer_t * p0 = CONTAINER_OF(p_item0, app_timer_t, list_item);
    9B01        ldr r3, [sp, #4]
    9307        str r3, [sp, #28]
--- app_timer2.c -- 133 ------------------------------------
app_timer_t * p1 = CONTAINER_OF(p_item1, app_timer_t, list_item);
    9B00        ldr r3, [sp]
    9306        str r3, [sp, #24]
--- app_timer2.c -- 134 ------------------------------------
uint64_t p0_end = p0->end_val;
    9B07        ldr r3, [sp, #28]
    E9D32302    ldrd r2, r3, [r3, #8]
    E9CD2304    strd r2, r3, [sp, #16]
--- app_timer2.c -- 136 ------------------------------------
uint64_t p1_end = p1->end_val;
    9B06        ldr r3, [sp, #24]
    E9D32302    ldrd r2, r3, [r3, #8]
    E9CD2302    strd r2, r3, [sp, #8]
--- app_timer2.c -- 137 ------------------------------------
return (p0_end <= p1_end) ? true : false;
    E9DD2304    ldrd r2, r3, [sp, #16]
    E9DD0102    ldrd r0, r1, [sp, #8]
    4299        cmp r1, r3
    BF08        it eq
    4290        cmpeq r0, r2
    BF2C        ite cs
    2301        movcs r3, #1
    2300        movcc r3, #0

Can you explain me in detail and preferably step by step, how do i go about solving this problem? 

Thank You!

Parents
  • I can't see what the issue is based on the disassembly window, but have you checked the log from the nRF? I don't know whether you have enabled the log in sdk_config.h. What does it look like?

    The 

    app_error_fault_handler(unsigned int id=0x00004001, unsigned int pc=0x0003290b, unsigned int info=0x2003ffc0)

    information doesn't say much without actually debugging myself, but here is what I would do:

    1. Find your preprocessor definitions (in your project settings) and add "DEBUG" to them. Let me know what IDE you use if you are not sure how to do this.

    2. Enable logging if it is not already enabled in sdk_config.h. You need to set NRF_LOG_ENABLED to 1, and have at least one of the backends set to 1 (RTT or UART). If you can't see the log, let me know what IDE you use, and what your preferred backend is. (If you use Segger Embedded Studio, set NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED to 0 and NRF_LOG_BACKEND_RTT_ENABLED to 1, and the log should pop up when you start a debug session.

    3. See what the log says. It should say something about an error, and point to a line number in one of your files. If you look at that place, you should see something similar to "APP_ERROR_CHECK(err_code);" What function returned that err_code? On top of that, see if you can find out why it returned that err_code. If you can't find out why, let me know.

    4. Fix that function

    If you for some reason have difficulties accessing the log, you can define DEBUG in the preprocessor definitions, set a breakpoint on line 91 in app_error_weak.c, and check what the err_code, p_file_name, and line num is pointing to in order to locate the issue.

    Best regards,

    Edvin

  • Thank You, I was able to solve the problem, by following point 1 & 2, it was a RAM size issue and after following points 1&2 the debug terminal let me knew about the actual ram size I should keep and the starting address. 

Reply Children
No Data
Related