bsp_btn_ble.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /**
  2. * Copyright (c) 2014 - 2020, 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. #include "bsp_btn_ble.h"
  41. #include "nrf_sdh_ble.h"
  42. #include "bsp.h"
  43. #define BTN_ID_WAKEUP 0 /**< ID of button used to wake up the application. */
  44. #define BTN_ID_SLEEP 0 /**< ID of button used to put the application into sleep mode. */
  45. #define BTN_ID_DISCONNECT 0 /**< ID of button used to gracefully terminate a connection on long press. */
  46. #define BTN_ID_WAKEUP_BOND_DELETE 1 /**< ID of button used to wake up the application and delete all bonding information. */
  47. #define BTN_ID_WHITELIST_OFF 1 /**< ID of button used to turn off usage of the whitelist. */
  48. #define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */
  49. #define BTN_ACTION_DISCONNECT BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to gracefully terminate a connection on long press. */
  50. #define BTN_ACTION_WHITELIST_OFF BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to turn off usage of the whitelist. */
  51. /**@brief This macro will return from the current function if err_code
  52. * is not NRF_SUCCESS or NRF_ERROR_INVALID_PARAM.
  53. */
  54. #define RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code) \
  55. do \
  56. { \
  57. if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_INVALID_PARAM)) \
  58. { \
  59. return err_code; \
  60. } \
  61. } \
  62. while (0)
  63. /**@brief This macro will return from the current function if err_code
  64. * is not NRF_SUCCESS or NRF_ERROR_NOT_SUPPORTED.
  65. */
  66. #define RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code) \
  67. do \
  68. { \
  69. if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_NOT_SUPPORTED)) \
  70. { \
  71. return err_code; \
  72. } \
  73. } \
  74. while (0)
  75. /**@brief This macro will call the registered error handler if err_code
  76. * is not NRF_SUCCESS and the error handler is not NULL.
  77. */
  78. #define CALL_HANDLER_ON_ERROR(err_code) \
  79. do \
  80. { \
  81. if (((err_code) != NRF_SUCCESS) && (m_error_handler != NULL)) \
  82. { \
  83. m_error_handler(err_code); \
  84. } \
  85. } \
  86. while (0)
  87. static bsp_btn_ble_error_handler_t m_error_handler = NULL; /**< Error handler registered by the user. */
  88. static uint32_t m_num_connections = 0; /**< Number of connections the device is currently in. */
  89. /**@brief Function for configuring the buttons for connection.
  90. *
  91. * @retval NRF_SUCCESS Configured successfully.
  92. * @return A propagated error code.
  93. */
  94. static uint32_t connection_buttons_configure()
  95. {
  96. uint32_t err_code;
  97. #if 0
  98. err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP,
  99. BTN_ACTION_SLEEP,
  100. BSP_EVENT_DEFAULT);
  101. RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
  102. err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF,
  103. BTN_ACTION_WHITELIST_OFF,
  104. BSP_EVENT_WHITELIST_OFF);
  105. RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
  106. err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT,
  107. BTN_ACTION_DISCONNECT,
  108. BSP_EVENT_DISCONNECT);
  109. RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
  110. #endif
  111. return NRF_SUCCESS;
  112. }
  113. /**@brief Function for configuring the buttons for advertisement.
  114. *
  115. * @retval NRF_SUCCESS Configured successfully.
  116. * @return A propagated error code.
  117. */
  118. static uint32_t advertising_buttons_configure()
  119. {
  120. uint32_t err_code;
  121. #if 0
  122. err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT,
  123. BTN_ACTION_DISCONNECT,
  124. BSP_EVENT_DEFAULT);
  125. RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
  126. err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF,
  127. BTN_ACTION_WHITELIST_OFF,
  128. BSP_EVENT_WHITELIST_OFF);
  129. RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
  130. err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP,
  131. BTN_ACTION_SLEEP,
  132. BSP_EVENT_SLEEP);
  133. RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
  134. #endif
  135. return NRF_SUCCESS;
  136. }
  137. /**@brief Function for extracting the BSP event valid at startup.
  138. *
  139. * @details When a button was used to wake up the device, the button press will not generate an
  140. * interrupt. This function reads which button was pressed at startup, and returns the
  141. * appropriate BSP event.
  142. *
  143. * @param[out] p_startup_event Where to put the extracted BSP event.
  144. */
  145. static void startup_event_extract(bsp_event_t * p_startup_event)
  146. {
  147. // React to button states
  148. if (bsp_button_is_pressed(BTN_ID_WAKEUP_BOND_DELETE))
  149. {
  150. *p_startup_event = BSP_EVENT_CLEAR_BONDING_DATA;
  151. }
  152. else if (bsp_button_is_pressed(BTN_ID_WAKEUP))
  153. {
  154. *p_startup_event = BSP_EVENT_WAKEUP;
  155. }
  156. else
  157. {
  158. *p_startup_event = BSP_EVENT_NOTHING;
  159. }
  160. }
  161. uint32_t bsp_btn_ble_sleep_mode_prepare(void)
  162. {
  163. uint32_t err_code;
  164. err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP);
  165. RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code);
  166. err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP_BOND_DELETE);
  167. RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code);
  168. return NRF_SUCCESS;
  169. }
  170. /**
  171. * @brief Function for handling BLE events.
  172. *
  173. * @param[in] p_ble_evt Event received from the BLE stack.
  174. * @param[in] p_context Context.
  175. */
  176. static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
  177. {
  178. uint32_t err_code;
  179. switch (p_ble_evt->header.evt_id)
  180. {
  181. case BLE_GAP_EVT_CONNECTED:
  182. if (m_num_connections == 0)
  183. {
  184. err_code = connection_buttons_configure();
  185. CALL_HANDLER_ON_ERROR(err_code);
  186. }
  187. m_num_connections++;
  188. break;
  189. case BLE_GAP_EVT_DISCONNECTED:
  190. m_num_connections--;
  191. if (m_num_connections == 0)
  192. {
  193. err_code = advertising_buttons_configure();
  194. CALL_HANDLER_ON_ERROR(err_code);
  195. }
  196. break;
  197. default:
  198. break;
  199. }
  200. }
  201. NRF_SDH_BLE_OBSERVER(m_ble_observer, BSP_BTN_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
  202. uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt)
  203. {
  204. uint32_t err_code = NRF_SUCCESS;
  205. m_error_handler = error_handler;
  206. if (p_startup_bsp_evt != NULL)
  207. {
  208. startup_event_extract(p_startup_bsp_evt);
  209. }
  210. if (m_num_connections == 0)
  211. {
  212. err_code = advertising_buttons_configure();
  213. }
  214. return err_code;
  215. }