You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

632 lines
22 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. /**
  2. * Copyright (c) 2014 - 2021, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. /** @file
  41. *
  42. * @defgroup ble_sdk_uart_over_ble_main main.c
  43. * @{
  44. * @ingroup ble_sdk_app_nus_eval
  45. * @brief UART over BLE application main file.
  46. *
  47. * This file contains the source code for a sample application that uses the Nordic UART service.
  48. * This application uses the @ref srvlib_conn_params module.
  49. */
  50. #include <stdint.h>
  51. #include <string.h>
  52. #include "app_timer.h"
  53. #include "app_uart.h"
  54. #include "app_util_platform.h"
  55. #include "ble_advdata.h"
  56. #include "ble_advertising.h"
  57. #include "ble_conn_params.h"
  58. #include "ble_hci.h"
  59. #include "ble_nus.h"
  60. #include "bsp_btn_ble.h"
  61. #include "nordic_common.h"
  62. #include "nrf.h"
  63. #include "nrf_ble_gatt.h"
  64. #include "nrf_ble_qwr.h"
  65. #include "nrf_pwr_mgmt.h"
  66. #include "nrf_sdh.h"
  67. #include "nrf_sdh_ble.h"
  68. #include "nrf_sdh_soc.h"
  69. #if defined(UART_PRESENT)
  70. #include "nrf_uart.h"
  71. #endif
  72. #if defined(UARTE_PRESENT)
  73. #include "nrf_uarte.h"
  74. #endif
  75. #include "nrf_log.h"
  76. #include "nrf_log_ctrl.h"
  77. #include "nrf_log_default_backends.h"
  78. #define APP_BLE_CONN_CFG_TAG 1 /**< A tag identifying the SoftDevice BLE configuration. */
  79. #define DEVICE_NAME "Nordic_UART" /**< Name of device. Will be included in the advertising data. */
  80. #define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */
  81. #define APP_BLE_OBSERVER_PRIO 3 /**< Application's BLE observer priority. You shouldn't need to modify this value. */
  82. #define APP_ADV_INTERVAL 64 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
  83. #define APP_ADV_DURATION 18000 /**< The advertising duration (180 seconds) in units of 10 milliseconds. */
  84. #define MIN_CONN_INTERVAL MSEC_TO_UNITS(20, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
  85. #define MAX_CONN_INTERVAL MSEC_TO_UNITS(75, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
  86. #define SLAVE_LATENCY 0 /**< Slave latency. */
  87. #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
  88. #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). */
  89. #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). */
  90. #define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */
  91. #define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
  92. #define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */
  93. #define UART_RX_BUF_SIZE 256 /**< UART RX buffer size. */
  94. BLE_NUS_DEF(m_nus, NRF_SDH_BLE_TOTAL_LINK_COUNT); /**< BLE NUS service instance. */
  95. NRF_BLE_GATT_DEF(m_gatt); /**< GATT module instance. */
  96. NRF_BLE_QWR_DEF(m_qwr); /**< Context for the Queued Write module.*/
  97. BLE_ADVERTISING_DEF(m_advertising); /**< Advertising module instance. */
  98. static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
  99. static uint16_t m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - 3; /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
  100. static ble_uuid_t m_adv_uuids[] = /**< Universally unique service identifier. */
  101. {{BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}};
  102. /**@brief Function for assert macro callback.
  103. *
  104. * @details This function will be called in case of an assert in the SoftDevice.
  105. *
  106. * @warning This handler is an example only and does not fit a final product. You need to analyse
  107. * how your product is supposed to react in case of Assert.
  108. * @warning On assert from the SoftDevice, the system can only recover on reset.
  109. *
  110. * @param[in] line_num Line number of the failing ASSERT call.
  111. * @param[in] p_file_name File name of the failing ASSERT call.
  112. */
  113. void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) { app_error_handler(DEAD_BEEF, line_num, p_file_name); }
  114. /**@brief Function for initializing the timer module.
  115. */
  116. static void timers_init(void) {
  117. ret_code_t err_code = app_timer_init();
  118. APP_ERROR_CHECK(err_code);
  119. }
  120. /**@brief Function for the GAP initialization.
  121. *
  122. * @details This function will set up all the necessary GAP (Generic Access Profile) parameters of
  123. * the device. It also sets the permissions and appearance.
  124. */
  125. static void gap_params_init(void) {
  126. uint32_t err_code;
  127. ble_gap_conn_params_t gap_conn_params;
  128. ble_gap_conn_sec_mode_t sec_mode;
  129. BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
  130. err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME));
  131. APP_ERROR_CHECK(err_code);
  132. memset(&gap_conn_params, 0, sizeof(gap_conn_params));
  133. gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
  134. gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
  135. gap_conn_params.slave_latency = SLAVE_LATENCY;
  136. gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;
  137. err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
  138. APP_ERROR_CHECK(err_code);
  139. }
  140. /**@brief Function for handling Queued Write Module errors.
  141. *
  142. * @details A pointer to this function will be passed to each service which may need to inform the
  143. * application about an error.
  144. *
  145. * @param[in] nrf_error Error code containing information about what went wrong.
  146. */
  147. static void nrf_qwr_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); }
  148. /**@brief Function for handling the data from the Nordic UART Service.
  149. *
  150. * @details This function will process the data received from the Nordic UART BLE Service and send
  151. * it to the UART module.
  152. *
  153. * @param[in] p_evt Nordic UART Service event.
  154. */
  155. /**@snippet [Handling the data received over BLE] */
  156. static void nus_data_handler(ble_nus_evt_t *p_evt) {
  157. if (p_evt->type == BLE_NUS_EVT_RX_DATA) {
  158. uint32_t err_code;
  159. NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART.");
  160. NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
  161. for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++) {
  162. do {
  163. err_code = app_uart_put(p_evt->params.rx_data.p_data[i]);
  164. if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY)) {
  165. NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code);
  166. APP_ERROR_CHECK(err_code);
  167. }
  168. } while (err_code == NRF_ERROR_BUSY);
  169. }
  170. if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length - 1] == '\r') {
  171. while (app_uart_put('\n') == NRF_ERROR_BUSY)
  172. ;
  173. }
  174. }
  175. }
  176. /**@snippet [Handling the data received over BLE] */
  177. /**@brief Function for initializing services that will be used by the application.
  178. */
  179. static void services_init(void) {
  180. uint32_t err_code;
  181. ble_nus_init_t nus_init;
  182. nrf_ble_qwr_init_t qwr_init = {0};
  183. // Initialize Queued Write Module.
  184. qwr_init.error_handler = nrf_qwr_error_handler;
  185. err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
  186. APP_ERROR_CHECK(err_code);
  187. // Initialize NUS.
  188. memset(&nus_init, 0, sizeof(nus_init));
  189. nus_init.data_handler = nus_data_handler;
  190. err_code = ble_nus_init(&m_nus, &nus_init);
  191. APP_ERROR_CHECK(err_code);
  192. }
  193. /**@brief Function for handling an event from the Connection Parameters Module.
  194. *
  195. * @details This function will be called for all events in the Connection Parameters Module
  196. * which are passed to the application.
  197. *
  198. * @note All this function does is to disconnect. This could have been done by simply setting
  199. * the disconnect_on_fail config parameter, but instead we use the event handler
  200. * mechanism to demonstrate its use.
  201. *
  202. * @param[in] p_evt Event received from the Connection Parameters Module.
  203. */
  204. static void on_conn_params_evt(ble_conn_params_evt_t *p_evt) {
  205. uint32_t err_code;
  206. if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) {
  207. err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
  208. APP_ERROR_CHECK(err_code);
  209. }
  210. }
  211. /**@brief Function for handling errors from the Connection Parameters module.
  212. *
  213. * @param[in] nrf_error Error code containing information about what went wrong.
  214. */
  215. static void conn_params_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); }
  216. /**@brief Function for initializing the Connection Parameters module.
  217. */
  218. static void conn_params_init(void) {
  219. uint32_t err_code;
  220. ble_conn_params_init_t cp_init;
  221. memset(&cp_init, 0, sizeof(cp_init));
  222. cp_init.p_conn_params = NULL;
  223. cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
  224. cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
  225. cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
  226. cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
  227. cp_init.disconnect_on_fail = false;
  228. cp_init.evt_handler = on_conn_params_evt;
  229. cp_init.error_handler = conn_params_error_handler;
  230. err_code = ble_conn_params_init(&cp_init);
  231. APP_ERROR_CHECK(err_code);
  232. }
  233. /**@brief Function for putting the chip into sleep mode.
  234. *
  235. * @note This function will not return.
  236. */
  237. static void sleep_mode_enter(void) {
  238. uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE);
  239. APP_ERROR_CHECK(err_code);
  240. // Prepare wakeup buttons.
  241. err_code = bsp_btn_ble_sleep_mode_prepare();
  242. APP_ERROR_CHECK(err_code);
  243. // Go to system-off mode (this function will not return; wakeup will cause a reset).
  244. err_code = sd_power_system_off();
  245. APP_ERROR_CHECK(err_code);
  246. }
  247. /**@brief Function for handling advertising events.
  248. *
  249. * @details This function will be called for advertising events which are passed to the application.
  250. *
  251. * @param[in] ble_adv_evt Advertising event.
  252. */
  253. static void on_adv_evt(ble_adv_evt_t ble_adv_evt) {
  254. uint32_t err_code;
  255. switch (ble_adv_evt) {
  256. case BLE_ADV_EVT_FAST:
  257. err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
  258. APP_ERROR_CHECK(err_code);
  259. break;
  260. case BLE_ADV_EVT_IDLE:
  261. sleep_mode_enter();
  262. break;
  263. default:
  264. break;
  265. }
  266. }
  267. /**@brief Function for handling BLE events.
  268. *
  269. * @param[in] p_ble_evt Bluetooth stack event.
  270. * @param[in] p_context Unused.
  271. */
  272. static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context) {
  273. uint32_t err_code;
  274. switch (p_ble_evt->header.evt_id) {
  275. case BLE_GAP_EVT_CONNECTED:
  276. NRF_LOG_INFO("Connected");
  277. err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
  278. APP_ERROR_CHECK(err_code);
  279. m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
  280. err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
  281. APP_ERROR_CHECK(err_code);
  282. break;
  283. case BLE_GAP_EVT_DISCONNECTED:
  284. NRF_LOG_INFO("Disconnected");
  285. // LED indication will be changed when advertising starts.
  286. m_conn_handle = BLE_CONN_HANDLE_INVALID;
  287. break;
  288. case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
  289. NRF_LOG_DEBUG("PHY update request.");
  290. ble_gap_phys_t const phys = {
  291. .rx_phys = BLE_GAP_PHY_AUTO,
  292. .tx_phys = BLE_GAP_PHY_AUTO,
  293. };
  294. err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
  295. APP_ERROR_CHECK(err_code);
  296. } break;
  297. case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
  298. // Pairing not supported
  299. err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
  300. APP_ERROR_CHECK(err_code);
  301. break;
  302. case BLE_GATTS_EVT_SYS_ATTR_MISSING:
  303. // No system attributes have been stored.
  304. err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
  305. APP_ERROR_CHECK(err_code);
  306. break;
  307. case BLE_GATTC_EVT_TIMEOUT:
  308. // Disconnect on GATT Client timeout event.
  309. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
  310. APP_ERROR_CHECK(err_code);
  311. break;
  312. case BLE_GATTS_EVT_TIMEOUT:
  313. // Disconnect on GATT Server timeout event.
  314. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
  315. APP_ERROR_CHECK(err_code);
  316. break;
  317. default:
  318. // No implementation needed.
  319. break;
  320. }
  321. }
  322. /**@brief Function for the SoftDevice initialization.
  323. *
  324. * @details This function initializes the SoftDevice and the BLE event interrupt.
  325. */
  326. static void ble_stack_init(void) {
  327. ret_code_t err_code;
  328. err_code = nrf_sdh_enable_request();
  329. APP_ERROR_CHECK(err_code);
  330. // Configure the BLE stack using the default settings.
  331. // Fetch the start address of the application RAM.
  332. uint32_t ram_start = 0;
  333. err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
  334. APP_ERROR_CHECK(err_code);
  335. // Enable BLE stack.
  336. err_code = nrf_sdh_ble_enable(&ram_start);
  337. APP_ERROR_CHECK(err_code);
  338. // Register a handler for BLE events.
  339. NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
  340. }
  341. /**@brief Function for handling events from the GATT library. */
  342. void gatt_evt_handler(nrf_ble_gatt_t *p_gatt, nrf_ble_gatt_evt_t const *p_evt) {
  343. if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)) {
  344. m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
  345. NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
  346. }
  347. NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x", p_gatt->att_mtu_desired_central, p_gatt->att_mtu_desired_periph);
  348. }
  349. /**@brief Function for initializing the GATT library. */
  350. void gatt_init(void) {
  351. ret_code_t err_code;
  352. err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
  353. APP_ERROR_CHECK(err_code);
  354. err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
  355. APP_ERROR_CHECK(err_code);
  356. }
  357. /**@brief Function for handling events from the BSP module.
  358. *
  359. * @param[in] event Event generated by button press.
  360. */
  361. void bsp_event_handler(bsp_event_t event) {
  362. uint32_t err_code;
  363. switch (event) {
  364. case BSP_EVENT_SLEEP:
  365. sleep_mode_enter();
  366. break;
  367. case BSP_EVENT_DISCONNECT:
  368. err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
  369. if (err_code != NRF_ERROR_INVALID_STATE) {
  370. APP_ERROR_CHECK(err_code);
  371. }
  372. break;
  373. case BSP_EVENT_WHITELIST_OFF:
  374. if (m_conn_handle == BLE_CONN_HANDLE_INVALID) {
  375. err_code = ble_advertising_restart_without_whitelist(&m_advertising);
  376. if (err_code != NRF_ERROR_INVALID_STATE) {
  377. APP_ERROR_CHECK(err_code);
  378. }
  379. }
  380. break;
  381. default:
  382. break;
  383. }
  384. }
  385. /**@brief Function for handling app_uart events.
  386. *
  387. * @details This function will receive a single character from the app_uart module and append it to
  388. * a string. The string will be be sent over BLE when the last character received was a
  389. * 'new line' '\n' (hex 0x0A) or if the string has reached the maximum data length.
  390. */
  391. /**@snippet [Handling the data received over UART] */
  392. void uart_event_handle(app_uart_evt_t *p_event) {
  393. static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
  394. static uint8_t index = 0;
  395. uint32_t err_code;
  396. switch (p_event->evt_type) {
  397. case APP_UART_DATA_READY:
  398. UNUSED_VARIABLE(app_uart_get(&data_array[index]));
  399. index++;
  400. if ((data_array[index - 1] == '\n') || (data_array[index - 1] == '\r') || (index >= m_ble_nus_max_data_len)) {
  401. if (index > 1) {
  402. NRF_LOG_DEBUG("Ready to send data over BLE NUS");
  403. NRF_LOG_HEXDUMP_DEBUG(data_array, index);
  404. do {
  405. uint16_t length = (uint16_t)index;
  406. err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
  407. if ((err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_RESOURCES) && (err_code != NRF_ERROR_NOT_FOUND)) {
  408. APP_ERROR_CHECK(err_code);
  409. }
  410. } while (err_code == NRF_ERROR_RESOURCES);
  411. }
  412. index = 0;
  413. }
  414. break;
  415. case APP_UART_COMMUNICATION_ERROR:
  416. APP_ERROR_HANDLER(p_event->data.error_communication);
  417. break;
  418. case APP_UART_FIFO_ERROR:
  419. APP_ERROR_HANDLER(p_event->data.error_code);
  420. break;
  421. default:
  422. break;
  423. }
  424. }
  425. /**@snippet [Handling the data received over UART] */
  426. /**@brief Function for initializing the UART module.
  427. */
  428. /**@snippet [UART Initialization] */
  429. static void uart_init(void) {
  430. uint32_t err_code;
  431. app_uart_comm_params_t const comm_params = {
  432. .rx_pin_no = RX_PIN_NUMBER,
  433. .tx_pin_no = TX_PIN_NUMBER,
  434. .rts_pin_no = RTS_PIN_NUMBER,
  435. .cts_pin_no = CTS_PIN_NUMBER,
  436. .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
  437. .use_parity = false,
  438. #if defined(UART_PRESENT)
  439. .baud_rate = NRF_UART_BAUDRATE_115200
  440. #else
  441. .baud_rate = NRF_UARTE_BAUDRATE_115200
  442. #endif
  443. };
  444. APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_event_handle, APP_IRQ_PRIORITY_LOWEST, err_code);
  445. APP_ERROR_CHECK(err_code);
  446. }
  447. /**@snippet [UART Initialization] */
  448. /**@brief Function for initializing the Advertising functionality.
  449. */
  450. static void advertising_init(void) {
  451. uint32_t err_code;
  452. ble_advertising_init_t init;
  453. memset(&init, 0, sizeof(init));
  454. init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
  455. init.advdata.include_appearance = false;
  456. init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
  457. init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
  458. init.srdata.uuids_complete.p_uuids = m_adv_uuids;
  459. init.config.ble_adv_fast_enabled = true;
  460. init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
  461. init.config.ble_adv_fast_timeout = APP_ADV_DURATION;
  462. init.evt_handler = on_adv_evt;
  463. err_code = ble_advertising_init(&m_advertising, &init);
  464. APP_ERROR_CHECK(err_code);
  465. ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
  466. }
  467. /**@brief Function for initializing buttons and leds.
  468. *
  469. * @param[out] p_erase_bonds Will be true if the clear bonding button was pressed to wake the application up.
  470. */
  471. static void buttons_leds_init(bool *p_erase_bonds) {
  472. bsp_event_t startup_event;
  473. uint32_t err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler);
  474. APP_ERROR_CHECK(err_code);
  475. err_code = bsp_btn_ble_init(NULL, &startup_event);
  476. APP_ERROR_CHECK(err_code);
  477. *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
  478. }
  479. /**@brief Function for initializing the nrf log module.
  480. */
  481. static void log_init(void) {
  482. ret_code_t err_code = NRF_LOG_INIT(NULL);
  483. APP_ERROR_CHECK(err_code);
  484. NRF_LOG_DEFAULT_BACKENDS_INIT();
  485. }
  486. /**@brief Function for initializing power management.
  487. */
  488. static void power_management_init(void) {
  489. ret_code_t err_code;
  490. err_code = nrf_pwr_mgmt_init();
  491. APP_ERROR_CHECK(err_code);
  492. }
  493. /**@brief Function for handling the idle state (main loop).
  494. *
  495. * @details If there is no pending log operation, then sleep until next the next event occurs.
  496. */
  497. static void idle_state_handle(void) {
  498. if (NRF_LOG_PROCESS() == false) {
  499. nrf_pwr_mgmt_run();
  500. }
  501. }
  502. /**@brief Function for starting advertising.
  503. */
  504. static void advertising_start(void) {
  505. uint32_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
  506. APP_ERROR_CHECK(err_code);
  507. }
  508. /**@brief Application main function.
  509. */
  510. int main(void) {
  511. bool erase_bonds;
  512. // Initialize.
  513. uart_init();
  514. log_init();
  515. timers_init();
  516. buttons_leds_init(&erase_bonds);
  517. power_management_init();
  518. ble_stack_init();
  519. gap_params_init();
  520. gatt_init();
  521. services_init();
  522. advertising_init();
  523. conn_params_init();
  524. // Start execution.
  525. printf("\r\nUART started.\r\n");
  526. NRF_LOG_INFO("Debug logging for UART over RTT started.");
  527. advertising_start();
  528. // Enter main loop.
  529. for (;;) {
  530. idle_state_handle();
  531. }
  532. }
  533. /**
  534. * @}
  535. */