<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Problem with merging calendar and ble</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/57041/problem-with-merging-calendar-and-ble</link><description>I tried to merge ble and calendar example but when i call &amp;quot;nrf_cal_init();&amp;quot; I&amp;#39;ve got error &amp;quot;app: SOFTDEVICE: INVALID MEMORY ACCESS&amp;quot; i tried to use RTC2 in Calendar.h but nothing chenged</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 28 Jan 2020 08:39:51 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/57041/problem-with-merging-calendar-and-ble" /><item><title>RE: Problem with merging calendar and ble</title><link>https://devzone.nordicsemi.com/thread/231317?ContentTypeID=1</link><pubDate>Tue, 28 Jan 2020 08:39:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:de143248-13f3-492b-9f6a-378e502cc191</guid><dc:creator>J&amp;#248;rgen Holmefjord</dc:creator><description>&lt;p&gt;If you are using the softdevice, it should be sufficient to comment out lines 25-28 in the file I linked on GitHub above.&lt;/p&gt;
&lt;p&gt;You also need to use RTC2 like you suggested in your initial post.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Problem with merging calendar and ble</title><link>https://devzone.nordicsemi.com/thread/231308?ContentTypeID=1</link><pubDate>Tue, 28 Jan 2020 08:15:25 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f6bc057e-0268-4019-be3f-1c0cad788969</guid><dc:creator>OLEG_T</dc:creator><description>&lt;p&gt;Thanks for your answer! It is my first experience of using nordic and ble. If I understand you correctly i need to change nrf_cal_init function. I will be very grateful if you give me an example of how to fix it&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Problem with merging calendar and ble</title><link>https://devzone.nordicsemi.com/thread/231244?ContentTypeID=1</link><pubDate>Mon, 27 Jan 2020 16:26:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:951211b0-0c71-4e45-90e2-c67c48e31ca8</guid><dc:creator>J&amp;#248;rgen Holmefjord</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://github.com/NordicPlayground/nrf5-calendar-example/blob/master/nrf_calendar.c#L25"&gt;nrf_cal_init function will access the CLOCK peripheral&lt;/a&gt;, which has &lt;a href="https://infocenter.nordicsemi.com/topic/sds_s140/SDS/s1xx/sd_resource_reqs/hw_block_interrupt_vector.html"&gt;restricted access&lt;/a&gt; when the softdevice is enabled (the softdevice controls the clocks).&lt;/p&gt;
&lt;p&gt;The LFCLK will always be running with the softdevice enabled. You can use the&amp;nbsp;&lt;a title="Clock" href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v16.0.0/hardware_driver_clock.html?cp=7_1_2_0_0"&gt;Clock&lt;/a&gt;&amp;nbsp;driver to control the clock if you are switching between having the softdevice enabled and disabled.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;br /&gt;Jørgen&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Problem with merging calendar and ble</title><link>https://devzone.nordicsemi.com/thread/231242?ContentTypeID=1</link><pubDate>Mon, 27 Jan 2020 16:21:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f966b282-41f0-41d9-9546-4031e4443b6d</guid><dc:creator>OLEG_T</dc:creator><description>&lt;p&gt;#ifndef __NRF_CALENDAR_H__&lt;br /&gt;#define __NRF_CALENDAR_H__&lt;/p&gt;
&lt;p&gt;#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdbool.h&amp;gt;&lt;br /&gt;#include &amp;quot;time.h&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;#include &amp;quot;nrf_log.h&amp;quot;&lt;br /&gt;#include &amp;quot;nrf_log_ctrl.h&amp;quot;&lt;br /&gt;#include &amp;quot;nrf_log_default_backends.h&amp;quot;&lt;/p&gt;
&lt;p&gt;// Change the following defines to change the RTC timer used or the interrupt priority&lt;br /&gt;#define CAL_RTC NRF_RTC2&lt;br /&gt;#define CAL_RTC_IRQn RTC2_IRQn&lt;br /&gt;#define CAL_RTC_IRQHandler RTC2_IRQHandler&lt;br /&gt;#define CAL_RTC_IRQ_Priority 3&lt;/p&gt;
&lt;p&gt;// Initializes the calendar library. Run this before calling any other functions. &lt;br /&gt;void nrf_cal_init(void);&lt;/p&gt;
&lt;p&gt;// Enables a callback feature in the calendar library that can call a function automatically at the specified interval (seconds).&lt;br /&gt;void nrf_cal_set_callback(void (*callback)(void), uint32_t interval);&lt;/p&gt;
&lt;p&gt;// Sets the date and time stored in the calendar library. &lt;br /&gt;// When this function is called a second time calibration data will be automatically generated based on the error in time since the&lt;br /&gt;// last call to the set time function. To ensure good calibration this function should not be called too often &lt;br /&gt;// (depending on the accuracy of the 32 kHz clock it should be sufficient to call it between once a week and once a month). &lt;br /&gt;void nrf_cal_set_time(uint32_t year, uint32_t month, uint32_t day, uint32_t hour, uint32_t minute, uint32_t second);&lt;/p&gt;
&lt;p&gt;// Returns the uncalibrated time as a tm struct. For more information about the tm struct and the time.h library in general please refer to:&lt;br /&gt;// &lt;a href="http://www.tutorialspoint.com/c_standard_library/time_h.htm"&gt;www.tutorialspoint.com/.../time_h.htm&lt;/a&gt;&lt;br /&gt;struct tm *nrf_cal_get_time(void);&lt;/p&gt;
&lt;p&gt;// Returns the calibrated time as a tm struct. If no calibration data is available it will return the uncalibrated time.&lt;br /&gt;struct tm *nrf_cal_get_time_calibrated(void);&lt;/p&gt;
&lt;p&gt;// Returns a string for printing the date and time. Turn the calibration on/off by setting the calibrate parameter. &lt;br /&gt;char *nrf_cal_get_time_string(bool calibrated);&lt;/p&gt;
&lt;p&gt;#endif&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Problem with merging calendar and ble</title><link>https://devzone.nordicsemi.com/thread/231241?ContentTypeID=1</link><pubDate>Mon, 27 Jan 2020 16:20:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7da2ce73-121f-43d6-ac83-186a9312bb0e</guid><dc:creator>OLEG_T</dc:creator><description>&lt;p&gt;#include &amp;lt;stdbool.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;#include &amp;lt;string.h&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;quot;nordic_common.h&amp;quot;&lt;br /&gt;#include &amp;quot;nrf.h&amp;quot;&lt;br /&gt;#include &amp;quot;app_error.h&amp;quot;&lt;br /&gt;#include &amp;quot;ble.h&amp;quot;&lt;br /&gt;#include &amp;quot;ble_hci.h&amp;quot;&lt;br /&gt;#include &amp;quot;ble_srv_common.h&amp;quot;&lt;br /&gt;#include &amp;quot;ble_advdata.h&amp;quot;&lt;br /&gt;#include &amp;quot;ble_advertising.h&amp;quot;&lt;br /&gt;#include &amp;quot;ble_conn_params.h&amp;quot;&lt;br /&gt;#include &amp;quot;nrf_sdh.h&amp;quot;&lt;br /&gt;#include &amp;quot;nrf_sdh_soc.h&amp;quot;&lt;br /&gt;#include &amp;quot;nrf_sdh_ble.h&amp;quot;&lt;br /&gt;#include &amp;quot;app_timer.h&amp;quot;&lt;br /&gt;#include &amp;quot;fds.h&amp;quot;&lt;br /&gt;#include &amp;quot;peer_manager.h&amp;quot;&lt;br /&gt;#include &amp;quot;bsp_btn_ble.h&amp;quot;&lt;br /&gt;#include &amp;quot;sensorsim.h&amp;quot;&lt;br /&gt;#include &amp;quot;ble_conn_state.h&amp;quot;&lt;br /&gt;#include &amp;quot;nrf_ble_gatt.h&amp;quot;&lt;br /&gt;#include &amp;quot;nrf_ble_qwr.h&amp;quot;&lt;br /&gt;#include &amp;quot;nrf_pwr_mgmt.h&amp;quot;&lt;/p&gt;
&lt;p&gt;#include &amp;quot;nrf_log.h&amp;quot;&lt;br /&gt;#include &amp;quot;nrf_log_ctrl.h&amp;quot;&lt;br /&gt;#include &amp;quot;nrf_log_default_backends.h&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;#include &amp;quot;ble_bas.h&amp;quot;&lt;br /&gt;#include &amp;quot;services/led_service.h&amp;quot;&lt;/p&gt;
&lt;p&gt;#include &amp;quot;Battery Level/battery_voltage.h&amp;quot;&lt;br /&gt;#include &amp;quot;services/button_service.h&amp;quot;&lt;br /&gt;#include &amp;quot;Calendar.h&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;//#include &amp;quot;nrf_drv_qspi.h&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;#define DEVICE_NAME &amp;quot;BLE_Test&amp;quot; /**&amp;lt; Name of device. Will be included in the advertising data. */&lt;br /&gt;#define MANUFACTURER_NAME &amp;quot;NordicSemiconductor&amp;quot; /**&amp;lt; Manufacturer. Will be passed to Device Information Service. */&lt;br /&gt;#define APP_ADV_INTERVAL 300 /**&amp;lt; The advertising interval (in units of 0.625 ms. This value corresponds to 187.5 ms). */&lt;/p&gt;
&lt;p&gt;// Corresponds to LED2 on the development kit&lt;br /&gt;#define LIGHTBULB_LED BSP_BOARD_LED_1 &lt;br /&gt;#define LED3 BSP_BOARD_LED_2 /**&amp;lt; LED to be toggled with the help of the LED Button Service. */&lt;/p&gt;
&lt;p&gt;#define APP_ADV_DURATION 18000 /**&amp;lt; The advertising duration (180 seconds) in units of 10 milliseconds. */&lt;br /&gt;#define APP_BLE_OBSERVER_PRIO 3 /**&amp;lt; Application&amp;#39;s BLE observer priority. You shouldn&amp;#39;t need to modify this value. */&lt;br /&gt;#define APP_BLE_CONN_CFG_TAG 1 /**&amp;lt; A tag identifying the SoftDevice BLE configuration. */&lt;/p&gt;
&lt;p&gt;#define MIN_CONN_INTERVAL MSEC_TO_UNITS(100, UNIT_1_25_MS) /**&amp;lt; Minimum acceptable connection interval (0.1 seconds). */&lt;br /&gt;#define MAX_CONN_INTERVAL MSEC_TO_UNITS(200, UNIT_1_25_MS) /**&amp;lt; Maximum acceptable connection interval (0.2 second). */&lt;br /&gt;#define SLAVE_LATENCY 0 /**&amp;lt; Slave latency. */&lt;br /&gt;#define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**&amp;lt; Connection supervisory timeout (4 seconds). */&lt;/p&gt;
&lt;p&gt;#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000) /**&amp;lt; Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */&lt;br /&gt;#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(30000) /**&amp;lt; Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */&lt;br /&gt;#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**&amp;lt; Number of attempts before giving up the connection parameter negotiation. */&lt;/p&gt;
&lt;p&gt;#define SEC_PARAM_BOND 1 /**&amp;lt; Perform bonding. */&lt;br /&gt;#define SEC_PARAM_MITM 0 /**&amp;lt; Man In The Middle protection not required. */&lt;br /&gt;#define SEC_PARAM_LESC 0 /**&amp;lt; LE Secure Connections not enabled. */&lt;br /&gt;#define SEC_PARAM_KEYPRESS 0 /**&amp;lt; Keypress notifications not enabled. */&lt;br /&gt;#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_NONE /**&amp;lt; No I/O capabilities. */&lt;br /&gt;#define SEC_PARAM_OOB 0 /**&amp;lt; Out Of Band data not available. */&lt;br /&gt;#define SEC_PARAM_MIN_KEY_SIZE 7 /**&amp;lt; Minimum encryption key size. */&lt;br /&gt;#define SEC_PARAM_MAX_KEY_SIZE 16 /**&amp;lt; Maximum encryption key size. */&lt;/p&gt;
&lt;p&gt;#define DEAD_BEEF 0xDEADBEEF /**&amp;lt; Value used as error code on stack dump, can be used to identify stack location on stack unwind. */&lt;/p&gt;
&lt;p&gt;#define BUTTON_DETECTION_DELAY APP_TIMER_TICKS(50)&lt;br /&gt;/**&amp;lt; Battery timer. */&lt;br /&gt;APP_TIMER_DEF(m_battery_timer_id);&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;#define BATTERY_LEVEL_MEAS_INTERVAL APP_TIMER_TICKS(1000) /**&amp;lt; Battery level measurement interval (ticks). */&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;// FROM_SERVICE_TUTORIAL: Declare a service structure for our application&lt;br /&gt;ble_os_t m_our_service;&lt;/p&gt;
&lt;p&gt;static bool run_time_updates = false;&lt;/p&gt;
&lt;p&gt;// OUR_JOB: Step 3.G, Declare an app_timer id variable and define our timer interval and define a timer interval&lt;br /&gt;APP_TIMER_DEF(m_our_char_timer_id);&lt;br /&gt;#define OUR_CHAR_TIMER_INTERVAL APP_TIMER_TICKS(1000) //1000 ms intervals&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;NRF_BLE_GATT_DEF(m_gatt); /**&amp;lt; GATT module instance. */&lt;br /&gt;NRF_BLE_QWR_DEF(m_qwr); /**&amp;lt; Context for the Queued Write module.*/&lt;br /&gt;BLE_ADVERTISING_DEF(m_advertising); /**&amp;lt; Advertising module instance. */&lt;/p&gt;
&lt;p&gt;static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**&amp;lt; Handle of the current connection. */&lt;/p&gt;
&lt;p&gt;static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**&amp;lt; Advertising handle used to identify an advertising set. */&lt;br /&gt;static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**&amp;lt; Buffer for storing an encoded advertising set. */&lt;br /&gt;static uint8_t m_enc_scan_response_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**&amp;lt; Buffer for storing an encoded scan data. */&lt;/p&gt;
&lt;p&gt;/**@brief Struct that contains pointers to the encoded advertising data. */&lt;br /&gt;static ble_gap_adv_data_t m_adv_data =&lt;br /&gt;{&lt;br /&gt; .adv_data =&lt;br /&gt; {&lt;br /&gt; .p_data = m_enc_advdata,&lt;br /&gt; .len = BLE_GAP_ADV_SET_DATA_SIZE_MAX&lt;br /&gt; },&lt;br /&gt; .scan_rsp_data =&lt;br /&gt; {&lt;br /&gt; .p_data = m_enc_scan_response_data,&lt;br /&gt; .len = BLE_GAP_ADV_SET_DATA_SIZE_MAX&lt;/p&gt;
&lt;p&gt;}&lt;br /&gt;};&lt;/p&gt;
&lt;p&gt;/**&amp;lt; Structure used to identify the battery service. */&lt;br /&gt;BLE_BAS_DEF(m_bas);&lt;/p&gt;
&lt;p&gt;/**&amp;lt; Structure used to identify the LED service. */&lt;br /&gt;BLE_LED_SERVICE_DEF(m_led_service);&lt;br /&gt;static void led_write_handler(uint16_t conn_handle, ble_led_service_t * p_led_service, uint8_t led_state);&lt;/p&gt;
&lt;p&gt;static void battery_level_meas_timeout_handler(void * p_context);&lt;br /&gt;static void battery_level_update(void);&lt;/p&gt;
&lt;p&gt;static ble_uuid_t m_adv_uuids[] = /**&amp;lt; Universally unique service identifiers. */&lt;br /&gt;{&lt;br /&gt; {BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_TYPE_BLE}&lt;br /&gt;};&lt;/p&gt;
&lt;p&gt;static void advertising_start();&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/**@brief Callback function for asserts in the SoftDevice.&lt;br /&gt; *&lt;br /&gt; * @details This function will be called in case of an assert in the SoftDevice.&lt;br /&gt; *&lt;br /&gt; * @warning This handler is an example only and does not fit a final product. You need to analyze&lt;br /&gt; * how your product is supposed to react in case of Assert.&lt;br /&gt; * @warning On assert from the SoftDevice, the system can only recover on reset.&lt;br /&gt; *&lt;br /&gt; * @param[in] line_num Line number of the failing ASSERT call.&lt;br /&gt; * @param[in] file_name File name of the failing ASSERT call.&lt;br /&gt; */&lt;br /&gt;void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)&lt;br /&gt;{&lt;br /&gt; app_error_handler(DEAD_BEEF, line_num, p_file_name);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for the Timer initialization.&lt;br /&gt; *&lt;br /&gt; * @details Initializes the timer module. This creates and starts application timers.&lt;br /&gt; */&lt;br /&gt;static void timers_init(void)&lt;br /&gt;{&lt;br /&gt; // Initialize timer module.&lt;br /&gt; ret_code_t err_code = app_timer_init();&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt; &lt;br /&gt; // Create timers.&lt;br /&gt; err_code = app_timer_create(&amp;amp;m_battery_timer_id,&lt;br /&gt; APP_TIMER_MODE_REPEATED,&lt;br /&gt; battery_level_meas_timeout_handler);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for starting application timers.&lt;br /&gt; */&lt;br /&gt;static void application_timers_start(void)&lt;br /&gt;{&lt;br /&gt; uint32_t err_code;&lt;/p&gt;
&lt;p&gt;// Start application timers.&lt;br /&gt; err_code = app_timer_start(m_battery_timer_id, BATTERY_LEVEL_MEAS_INTERVAL, NULL);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for the GAP initialization.&lt;br /&gt; *&lt;br /&gt; * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the&lt;br /&gt; * device including the device name, appearance, and the preferred connection parameters.&lt;br /&gt; */&lt;br /&gt;static void gap_params_init(void)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code;&lt;br /&gt; ble_gap_conn_params_t gap_conn_params;&lt;br /&gt; ble_gap_conn_sec_mode_t sec_mode;&lt;/p&gt;
&lt;p&gt;BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;sec_mode);&lt;/p&gt;
&lt;p&gt;err_code = sd_ble_gap_device_name_set(&amp;amp;sec_mode,&lt;br /&gt; (const uint8_t *)DEVICE_NAME,&lt;br /&gt; strlen(DEVICE_NAME));&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;/p&gt;
&lt;p&gt;err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_UNKNOWN);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;/p&gt;
&lt;p&gt;memset(&amp;amp;gap_conn_params, 0, sizeof(gap_conn_params));&lt;/p&gt;
&lt;p&gt;gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;&lt;br /&gt; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;&lt;br /&gt; gap_conn_params.slave_latency = SLAVE_LATENCY;&lt;br /&gt; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;&lt;/p&gt;
&lt;p&gt;err_code = sd_ble_gap_ppcp_set(&amp;amp;gap_conn_params);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/**@brief Function for initializing the GATT module.&lt;br /&gt; */&lt;br /&gt;static void gatt_init(void)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code = nrf_ble_gatt_init(&amp;amp;m_gatt, NULL);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/**@brief Function for handling Queued Write Module errors.&lt;br /&gt; *&lt;br /&gt; * @details A pointer to this function will be passed to each service which may need to inform the&lt;br /&gt; * application about an error.&lt;br /&gt; *&lt;br /&gt; * @param[in] nrf_error Error code containing information about what went wrong.&lt;br /&gt; */&lt;br /&gt;static void nrf_qwr_error_handler(uint32_t nrf_error)&lt;br /&gt;{&lt;br /&gt; APP_ERROR_HANDLER(nrf_error);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for initializing services that will be used by the application.&lt;br /&gt; */&lt;br /&gt;static void services_init(void)&lt;br /&gt;{&lt;br /&gt; uint32_t err_code;&lt;br /&gt; ble_bas_init_t bas_init;&lt;br /&gt; ble_led_service_init_t led_init;&lt;/p&gt;
&lt;p&gt;nrf_ble_qwr_init_t qwr_init = {0};&lt;/p&gt;
&lt;p&gt;// Initialize Queued Write Module.&lt;br /&gt; qwr_init.error_handler = nrf_qwr_error_handler;&lt;/p&gt;
&lt;p&gt;err_code = nrf_ble_qwr_init(&amp;amp;m_qwr, &amp;amp;qwr_init);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;/p&gt;
&lt;p&gt;// 1. Initialize the LED service&lt;br /&gt; led_init.led_write_handler = led_write_handler;&lt;/p&gt;
&lt;p&gt;err_code = ble_led_service_init(&amp;amp;m_led_service, &amp;amp;led_init);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;/p&gt;
&lt;p&gt;// 2. Initialize Battery Service.&lt;br /&gt; memset(&amp;amp;bas_init, 0, sizeof(bas_init));&lt;/p&gt;
&lt;p&gt;// Here the sec level for the Battery Service can be changed/increased.&lt;br /&gt; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;bas_init.battery_level_char_attr_md.cccd_write_perm);&lt;br /&gt; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;bas_init.battery_level_char_attr_md.read_perm);&lt;br /&gt; BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&amp;amp;bas_init.battery_level_char_attr_md.write_perm);&lt;/p&gt;
&lt;p&gt;BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;bas_init.battery_level_report_read_perm);&lt;/p&gt;
&lt;p&gt;bas_init.evt_handler = NULL;&lt;br /&gt; bas_init.support_notification = true;&lt;br /&gt; bas_init.p_report_ref = NULL;&lt;br /&gt; bas_init.initial_batt_level = 100;&lt;/p&gt;
&lt;p&gt;err_code = ble_bas_init(&amp;amp;m_bas, &amp;amp;bas_init);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/**@brief Function for handling the Connection Parameters Module.&lt;br /&gt; *&lt;br /&gt; * @details This function will be called for all events in the Connection Parameters Module which&lt;br /&gt; * are passed to the application.&lt;br /&gt; * @note All this function does is to disconnect. This could have been done by simply&lt;br /&gt; * setting the disconnect_on_fail config parameter, but instead we use the event&lt;br /&gt; * handler mechanism to demonstrate its use.&lt;br /&gt; *&lt;br /&gt; * @param[in] p_evt Event received from the Connection Parameters Module.&lt;br /&gt; */&lt;br /&gt;static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code;&lt;/p&gt;
&lt;p&gt;if (p_evt-&amp;gt;evt_type == BLE_CONN_PARAMS_EVT_FAILED)&lt;br /&gt; {&lt;br /&gt; err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/**@brief Function for handling a Connection Parameters error.&lt;br /&gt; *&lt;br /&gt; * @param[in] nrf_error Error code containing information about what went wrong.&lt;br /&gt; */&lt;br /&gt;static void conn_params_error_handler(uint32_t nrf_error)&lt;br /&gt;{&lt;br /&gt; APP_ERROR_HANDLER(nrf_error);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/**@brief Function for initializing the Connection Parameters module.&lt;br /&gt; */&lt;br /&gt;static void conn_params_init(void)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code;&lt;br /&gt; ble_conn_params_init_t cp_init;&lt;/p&gt;
&lt;p&gt;memset(&amp;amp;cp_init, 0, sizeof(cp_init));&lt;/p&gt;
&lt;p&gt;cp_init.p_conn_params = NULL;&lt;br /&gt; cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;&lt;br /&gt; cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;&lt;br /&gt; cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;&lt;br /&gt; cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;&lt;br /&gt; cp_init.disconnect_on_fail = false;&lt;br /&gt; cp_init.evt_handler = on_conn_params_evt;&lt;br /&gt; cp_init.error_handler = conn_params_error_handler;&lt;/p&gt;
&lt;p&gt;err_code = ble_conn_params_init(&amp;amp;cp_init);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for putting the chip into sleep mode.&lt;br /&gt; *&lt;br /&gt; * @note This function will not return.&lt;br /&gt; */&lt;br /&gt;static void sleep_mode_enter(void)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code;&lt;/p&gt;
&lt;p&gt;err_code = bsp_indication_set(BSP_INDICATE_IDLE);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;/p&gt;
&lt;p&gt;// Prepare wakeup buttons.&lt;br /&gt; err_code = bsp_btn_ble_sleep_mode_prepare();&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;/p&gt;
&lt;p&gt;// Go to system-off mode (this function will not return; wakeup will cause a reset).&lt;br /&gt; err_code = sd_power_system_off();&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for handling BLE events.&lt;br /&gt; *&lt;br /&gt; * @param[in] p_ble_evt Bluetooth stack event.&lt;br /&gt; * @param[in] p_context Unused.&lt;br /&gt; */&lt;br /&gt;static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code = NRF_SUCCESS;&lt;/p&gt;
&lt;p&gt;switch (p_ble_evt-&amp;gt;header.evt_id)&lt;br /&gt; {&lt;br /&gt; case BLE_GAP_EVT_DISCONNECTED:&lt;br /&gt; NRF_LOG_INFO(&amp;quot;Disconnected.&amp;quot;);&lt;br /&gt; // LED indication will be changed when advertising starts.&lt;br /&gt; break;&lt;/p&gt;
&lt;p&gt;case BLE_GAP_EVT_CONNECTED:&lt;br /&gt; NRF_LOG_INFO(&amp;quot;Connected.&amp;quot;);&lt;br /&gt; err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt; m_conn_handle = p_ble_evt-&amp;gt;evt.gap_evt.conn_handle;&lt;br /&gt; err_code = nrf_ble_qwr_conn_handle_assign(&amp;amp;m_qwr, m_conn_handle);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt; break;&lt;/p&gt;
&lt;p&gt;case BLE_GAP_EVT_SEC_PARAMS_REQUEST:&lt;br /&gt; // Pairing not supported&lt;br /&gt; err_code = sd_ble_gap_sec_params_reply(m_conn_handle,&lt;br /&gt; BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,&lt;br /&gt; NULL,&lt;br /&gt; NULL);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt; break;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt; case BLE_GAP_EVT_PHY_UPDATE_REQUEST:&lt;br /&gt; {&lt;br /&gt; NRF_LOG_DEBUG(&amp;quot;PHY update request.&amp;quot;);&lt;br /&gt; ble_gap_phys_t const phys =&lt;br /&gt; {&lt;br /&gt; .rx_phys = BLE_GAP_PHY_AUTO,&lt;br /&gt; .tx_phys = BLE_GAP_PHY_AUTO,&lt;br /&gt; };&lt;br /&gt; err_code = sd_ble_gap_phy_update(p_ble_evt-&amp;gt;evt.gap_evt.conn_handle, &amp;amp;phys);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt; } break;&lt;/p&gt;
&lt;p&gt;case BLE_GATTS_EVT_SYS_ATTR_MISSING:&lt;br /&gt; // No system attributes have been stored.&lt;br /&gt; err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt; break;&lt;/p&gt;
&lt;p&gt;case BLE_GATTC_EVT_TIMEOUT:&lt;br /&gt; // Disconnect on GATT Client timeout event.&lt;br /&gt; NRF_LOG_DEBUG(&amp;quot;GATT Client Timeout.&amp;quot;);&lt;br /&gt; err_code = sd_ble_gap_disconnect(p_ble_evt-&amp;gt;evt.gattc_evt.conn_handle,&lt;br /&gt; BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt; break;&lt;/p&gt;
&lt;p&gt;case BLE_GATTS_EVT_TIMEOUT:&lt;br /&gt; // Disconnect on GATT Server timeout event.&lt;br /&gt; NRF_LOG_DEBUG(&amp;quot;GATT Server Timeout.&amp;quot;);&lt;br /&gt; err_code = sd_ble_gap_disconnect(p_ble_evt-&amp;gt;evt.gatts_evt.conn_handle,&lt;br /&gt; BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt; break;&lt;/p&gt;
&lt;p&gt;default:&lt;br /&gt; // No implementation needed.&lt;br /&gt; break;&lt;br /&gt; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for initializing the BLE stack.&lt;br /&gt; *&lt;br /&gt; * @details Initializes the SoftDevice and the BLE event interrupt.&lt;br /&gt; */&lt;br /&gt;static void ble_stack_init(void)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code;&lt;/p&gt;
&lt;p&gt;err_code = nrf_sdh_enable_request();&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;/p&gt;
&lt;p&gt;// Configure the BLE stack using the default settings.&lt;br /&gt; // Fetch the start address of the application RAM.&lt;br /&gt; uint32_t ram_start = 0;&lt;br /&gt; err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &amp;amp;ram_start);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;/p&gt;
&lt;p&gt;// Enable BLE stack.&lt;br /&gt; err_code = nrf_sdh_ble_enable(&amp;amp;ram_start);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;/p&gt;
&lt;p&gt;// Register a handler for BLE events.&lt;br /&gt; NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);&lt;br /&gt; //OUR_JOB: Step 3.C Set up a BLE event observer to call ble_our_service_on_ble_evt() to do housekeeping of ble connections related to our service and characteristics.&lt;br /&gt; NRF_SDH_BLE_OBSERVER(m_our_service_observer, APP_BLE_OBSERVER_PRIO, ble_our_service_on_ble_evt, (void*) &amp;amp;m_our_service);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for handling write events to the LED characteristic.&lt;br /&gt; *&lt;br /&gt; * @param[in] p_led_service Instance of LED Service to which the write applies.&lt;br /&gt; * @param[in] led_state Written/desired state of the LED.&lt;br /&gt; */&lt;br /&gt;static void led_write_handler(uint16_t conn_handle, ble_led_service_t * p_led_service, uint8_t led_state)&lt;br /&gt;{&lt;br /&gt; if (led_state == 0x01)&lt;br /&gt; {&lt;br /&gt; bsp_board_led_on(LIGHTBULB_LED);&lt;br /&gt; NRF_LOG_INFO(&amp;quot;Received LED ON!&amp;quot;);&lt;br /&gt; &lt;br /&gt; }&lt;br /&gt; else if(led_state == 0x02)&lt;br /&gt; {&lt;br /&gt; bsp_board_led_on(LED3);&lt;br /&gt; NRF_LOG_INFO(&amp;quot;Received LED2 ON!&amp;quot;);&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt; bsp_board_led_off(LIGHTBULB_LED);&lt;br /&gt; bsp_board_led_off(LED3);&lt;br /&gt; NRF_LOG_INFO(&amp;quot;Received LED OFF!&amp;quot;);&lt;br /&gt; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for handling advertising events.&lt;br /&gt; *&lt;br /&gt; * @details This function will be called for advertising events which are passed to the application.&lt;br /&gt; *&lt;br /&gt; * @param[in] ble_adv_evt Advertising event.&lt;br /&gt; */&lt;br /&gt;static void on_adv_evt(ble_adv_evt_t ble_adv_evt)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code;&lt;/p&gt;
&lt;p&gt;switch (ble_adv_evt)&lt;br /&gt; {&lt;br /&gt; case BLE_ADV_EVT_FAST:&lt;br /&gt; NRF_LOG_INFO(&amp;quot;Fast advertising.&amp;quot;);&lt;br /&gt; err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt; break;&lt;/p&gt;
&lt;p&gt;case BLE_ADV_EVT_IDLE:&lt;br /&gt; sleep_mode_enter();&lt;br /&gt; break;&lt;/p&gt;
&lt;p&gt;default:&lt;br /&gt; break;&lt;br /&gt; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/**@brief Function for initializing the Advertising functionality.&lt;br /&gt; */&lt;br /&gt;static void advertising_init(void)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code;&lt;br /&gt; ble_advertising_init_t init;&lt;/p&gt;
&lt;p&gt;memset(&amp;amp;init, 0, sizeof(init));&lt;/p&gt;
&lt;p&gt;init.advdata.name_type = BLE_ADVDATA_FULL_NAME;&lt;br /&gt; init.advdata.include_appearance = true;&lt;br /&gt; init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;&lt;br /&gt; init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);&lt;br /&gt; init.advdata.uuids_complete.p_uuids = m_adv_uuids;&lt;/p&gt;
&lt;p&gt;init.config.ble_adv_fast_enabled = true;&lt;br /&gt; init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;&lt;br /&gt; init.config.ble_adv_fast_timeout = APP_ADV_DURATION;&lt;/p&gt;
&lt;p&gt;init.evt_handler = on_adv_evt;&lt;/p&gt;
&lt;p&gt;err_code = ble_advertising_init(&amp;amp;m_advertising, &amp;amp;init);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;/p&gt;
&lt;p&gt;ble_advertising_conn_cfg_tag_set(&amp;amp;m_advertising, APP_BLE_CONN_CFG_TAG);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for handling events from the BSP module.&lt;br /&gt; *&lt;br /&gt; * @param[in] event Event generated when button is pressed.&lt;br /&gt; */&lt;br /&gt; &lt;br /&gt;static void bsp_event_handler(bsp_event_t event)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code;&lt;br /&gt; int32_t temperature = 0;&lt;/p&gt;
&lt;p&gt;switch (event)&lt;br /&gt; {&lt;br /&gt; case BSP_EVENT_SLEEP:&lt;br /&gt; sleep_mode_enter();&lt;br /&gt; break; // BSP_EVENT_SLEEP&lt;/p&gt;
&lt;p&gt;case BSP_EVENT_DISCONNECT:&lt;br /&gt; err_code = sd_ble_gap_disconnect(m_conn_handle,&lt;br /&gt; BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);&lt;br /&gt; if (err_code != NRF_ERROR_INVALID_STATE)&lt;br /&gt; {&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt; }&lt;br /&gt; break; // BSP_EVENT_DISCONNECT&lt;/p&gt;
&lt;p&gt;case BSP_EVENT_WHITELIST_OFF:&lt;br /&gt; if (m_conn_handle == BLE_CONN_HANDLE_INVALID)&lt;br /&gt; {&lt;br /&gt; err_code = ble_advertising_restart_without_whitelist(&amp;amp;m_advertising);&lt;br /&gt; if (err_code != NRF_ERROR_INVALID_STATE)&lt;br /&gt; {&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; break; // BSP_EVENT_KEY_0&lt;/p&gt;
&lt;p&gt;case BSP_EVENT_KEY_0:&lt;br /&gt; if (m_conn_handle != BLE_CONN_HANDLE_INVALID)&lt;br /&gt; {&lt;br /&gt; temperature = 1;&lt;br /&gt; NRF_LOG_INFO(&amp;quot;Button1 Pressed&amp;quot;);&lt;br /&gt; our_temperature_characteristic_update(&amp;amp;m_our_service, &amp;amp;temperature);&lt;br /&gt; }&lt;br /&gt; break;&lt;/p&gt;
&lt;p&gt;case BSP_EVENT_KEY_1:&lt;br /&gt; if (m_conn_handle != BLE_CONN_HANDLE_INVALID)&lt;br /&gt; {&lt;br /&gt; temperature = 2;&lt;br /&gt; NRF_LOG_INFO(&amp;quot;Button1 Pressed&amp;quot;);&lt;br /&gt; our_temperature_characteristic_update(&amp;amp;m_our_service, &amp;amp;temperature);&lt;br /&gt; }&lt;br /&gt; break;&lt;/p&gt;
&lt;p&gt;case BSP_EVENT_KEY_2:&lt;br /&gt; if (m_conn_handle != BLE_CONN_HANDLE_INVALID)&lt;br /&gt; {&lt;br /&gt; temperature = 4;&lt;br /&gt; NRF_LOG_INFO(&amp;quot;Button1 Pressed&amp;quot;);&lt;br /&gt; our_temperature_characteristic_update(&amp;amp;m_our_service, &amp;amp;temperature);&lt;br /&gt; }&lt;br /&gt; break;&lt;/p&gt;
&lt;p&gt;case BSP_EVENT_KEY_3:&lt;br /&gt; if (m_conn_handle != BLE_CONN_HANDLE_INVALID)&lt;br /&gt; {&lt;br /&gt; temperature = 8;&lt;br /&gt; NRF_LOG_INFO(&amp;quot;Button1 Pressed&amp;quot;);&lt;br /&gt; our_temperature_characteristic_update(&amp;amp;m_our_service, &amp;amp;temperature);&lt;br /&gt; }&lt;br /&gt; break;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt; default:&lt;br /&gt; break;&lt;br /&gt; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for initializing leds.&lt;br /&gt; *&lt;br /&gt; * @details Initializes all LEDs used by the application.&lt;br /&gt; */&lt;br /&gt;static void leds_init()&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code;&lt;br /&gt; &lt;br /&gt; err_code = bsp_init(BSP_INIT_LEDS| BSP_INIT_BUTTONS, bsp_event_handler);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/**@brief Function for initializing the nrf log module.&lt;br /&gt; */&lt;br /&gt;static void log_init(void)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code = NRF_LOG_INIT(NULL);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;/p&gt;
&lt;p&gt;NRF_LOG_DEFAULT_BACKENDS_INIT();&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/**@brief Function for initializing power management.&lt;br /&gt; */&lt;br /&gt;static void power_management_init(void)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code;&lt;br /&gt; err_code = nrf_pwr_mgmt_init();&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/**@brief Function for handling the idle state (main loop).&lt;br /&gt; *&lt;br /&gt; * @details If there is no pending log operation, then sleep until next the next event occurs.&lt;br /&gt; */&lt;br /&gt;static void idle_state_handle(void)&lt;br /&gt;{&lt;br /&gt; if (NRF_LOG_PROCESS() == false)&lt;br /&gt; {&lt;br /&gt; nrf_pwr_mgmt_run();&lt;br /&gt; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/**@brief Function for starting advertising.&lt;br /&gt; */&lt;br /&gt;static void advertising_start()&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code = ble_advertising_start(&amp;amp;m_advertising, BLE_ADV_MODE_FAST);&lt;br /&gt; APP_ERROR_CHECK(err_code);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for handling the Battery measurement timer timeout.&lt;br /&gt; *&lt;br /&gt; * @details This function will be called each time the battery level measurement timer expires.&lt;br /&gt; *&lt;br /&gt; * @param[in] p_context Pointer used for passing some arbitrary information (context) from the&lt;br /&gt; * app_start_timer() call to the timeout handler.&lt;br /&gt; */&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;static void battery_level_meas_timeout_handler(void * p_context)&lt;br /&gt;{&lt;br /&gt; UNUSED_PARAMETER(p_context);&lt;br /&gt; NRF_LOG_INFO(&amp;quot;Battery Level timeout event&amp;quot;);&lt;br /&gt; &lt;/p&gt;
&lt;p&gt;// Only send the battery level update if we are connected&lt;br /&gt; if (m_conn_handle != BLE_CONN_HANDLE_INVALID)&lt;br /&gt; {&lt;br /&gt; battery_level_update();&lt;br /&gt; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;/**@brief Function for updating the Battery Level measurement*/&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;static void battery_level_update(void)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code;&lt;/p&gt;
&lt;p&gt;uint8_t battery_level;&lt;br /&gt; uint16_t vbatt; // Variable to hold voltage reading&lt;br /&gt; battery_voltage_get(&amp;amp;vbatt); // Get new battery voltage&lt;/p&gt;
&lt;p&gt;battery_level = battery_level_in_percent(vbatt); //Transform the millivolts value into battery level percent.&lt;br /&gt; NRF_LOG_INFO(&amp;quot;ADC result in percent: %d\r\n&amp;quot;, battery_level);&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; err_code = ble_bas_battery_level_update(&amp;amp;m_bas, battery_level, m_conn_handle);&lt;br /&gt; NRF_LOG_INFO(&amp;quot;err_code %d\r\n&amp;quot;, err_code);&lt;br /&gt; if ((err_code != NRF_SUCCESS) &amp;amp;&amp;amp;&lt;br /&gt; (err_code != NRF_ERROR_INVALID_STATE) &amp;amp;&amp;amp;&lt;br /&gt; (err_code != NRF_ERROR_RESOURCES) &amp;amp;&amp;amp;&lt;br /&gt; (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)&lt;br /&gt; )&lt;br /&gt; {&lt;br /&gt; APP_ERROR_HANDLER(err_code);&lt;br /&gt; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;void print_current_time()&lt;br /&gt;{&lt;br /&gt; printf(&amp;quot;Uncalibrated time:\t%s\r\n&amp;quot;, nrf_cal_get_time_string(false));&lt;br /&gt; printf(&amp;quot;Calibrated time:\t%s\r\n&amp;quot;, nrf_cal_get_time_string(true));&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;void calendar_updated()&lt;br /&gt;{&lt;br /&gt; if(run_time_updates)&lt;br /&gt; {&lt;br /&gt; print_current_time();&lt;br /&gt; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;/**@brief Function for application main entry.&lt;br /&gt;*/&lt;br /&gt; &lt;br /&gt;int main(void)&lt;br /&gt;{&lt;/p&gt;
&lt;p&gt;bool erase_bonds;&lt;br /&gt; &lt;br /&gt; // Initialize.&lt;br /&gt; log_init();&lt;br /&gt; timers_init();&lt;br /&gt; battery_voltage_init();&lt;br /&gt; leds_init();&lt;br /&gt; power_management_init();&lt;br /&gt; ble_stack_init();&lt;br /&gt; gap_params_init();&lt;br /&gt; gatt_init();&lt;br /&gt; services_init();&lt;br /&gt; advertising_init();&lt;br /&gt; conn_params_init();&lt;br /&gt; application_timers_start();&lt;/p&gt;
&lt;p&gt;our_service_init(&amp;amp;m_our_service);&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;uint32_t year = 2020, month = 1, day = 27, hour = 15, minute = 40, second = 0;&lt;br /&gt; NRF_CLOCK-&amp;gt;EVENTS_HFCLKSTARTED = 0;&lt;br /&gt; NRF_CLOCK-&amp;gt;TASKS_HFCLKSTART = 1;&lt;br /&gt; while(NRF_CLOCK-&amp;gt;EVENTS_HFCLKSTARTED == 0);&lt;/p&gt;
&lt;p&gt;nrf_cal_init();&lt;br /&gt; nrf_cal_set_callback(calendar_updated, 4);&lt;/p&gt;
&lt;p&gt;// Start execution.&lt;br /&gt; NRF_LOG_INFO(&amp;quot;BLE started.&amp;quot;);&lt;br /&gt; &lt;br /&gt; advertising_start();&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;// Enter main loop.&lt;br /&gt; for (;;)&lt;br /&gt; {&lt;br /&gt; idle_state_handle();&lt;br /&gt; }&lt;br /&gt;}&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>