bsp_btn_ble.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #include "bsp_btn_ble.h"
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <stddef.h>
  5. #include "ble.h"
  6. #include "bsp.h"
  7. #define BTN_ID_WAKEUP 0 /**< ID of button used to wake up the application. */
  8. #define BTN_ID_SLEEP 0 /**< ID of button used to put the application into sleep mode. */
  9. #define BTN_ID_DISCONNECT 0 /**< ID of button used to gracefully terminate a connection on long press. */
  10. #define BTN_ID_WAKEUP_BOND_DELETE 1 /**< ID of button used to wake up the application and delete all bonding information. */
  11. #define BTN_ID_WHITELIST_OFF 1 /**< ID of button used to turn off usage of the whitelist. */
  12. #define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */
  13. #define BTN_ACTION_DISCONNECT BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to gracefully terminate a connection on long press. */
  14. #define BTN_ACTION_WHITELIST_OFF BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to turn off usage of the whitelist. */
  15. /**@brief This macro will return from the current function if err_code
  16. * is not NRF_SUCCESS.
  17. */
  18. #define RETURN_ON_ERROR(err_code) \
  19. do \
  20. { \
  21. if ((err_code) != NRF_SUCCESS) \
  22. { \
  23. return err_code; \
  24. } \
  25. } \
  26. while(0)
  27. /**@brief This macro will return from the current function if err_code
  28. * is not NRF_SUCCESS or NRF_ERROR_INVALID_PARAM.
  29. */
  30. #define RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code) \
  31. do \
  32. { \
  33. if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_INVALID_PARAM)) \
  34. { \
  35. return err_code; \
  36. } \
  37. } \
  38. while(0)
  39. /**@brief This macro will return from the current function if err_code
  40. * is not NRF_SUCCESS or NRF_ERROR_NOT_SUPPORTED.
  41. */
  42. #define RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code) \
  43. do \
  44. { \
  45. if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_NOT_SUPPORTED)) \
  46. { \
  47. return err_code; \
  48. } \
  49. } \
  50. while(0)
  51. /**@brief This macro will call the registered error handler if err_code
  52. * is not NRF_SUCCESS and the error handler is not NULL.
  53. */
  54. #define CALL_HANDLER_ON_ERROR(err_code) \
  55. do \
  56. { \
  57. if (((err_code) != NRF_SUCCESS) && (m_error_handler != NULL)) \
  58. { \
  59. m_error_handler(err_code); \
  60. } \
  61. } \
  62. while(0)
  63. static bsp_btn_ble_error_handler_t m_error_handler = NULL; /**< Error handler registered by the user. */
  64. static uint32_t m_num_connections = 0; /**< Number of connections the device is currently in. */
  65. /**@brief Function for configuring the buttons for connection.
  66. *
  67. * @retval NRF_SUCCESS Configured successfully.
  68. * @return A propagated error code.
  69. */
  70. static uint32_t connection_buttons_configure()
  71. {
  72. uint32_t err_code;
  73. err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP,
  74. BTN_ACTION_SLEEP,
  75. BSP_EVENT_DEFAULT);
  76. RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
  77. err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF,
  78. BTN_ACTION_WHITELIST_OFF,
  79. BSP_EVENT_WHITELIST_OFF);
  80. RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
  81. err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT,
  82. BTN_ACTION_DISCONNECT,
  83. BSP_EVENT_DISCONNECT);
  84. RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
  85. return NRF_SUCCESS;
  86. }
  87. /**@brief Function for configuring the buttons for advertisement.
  88. *
  89. * @retval NRF_SUCCESS Configured successfully.
  90. * @return A propagated error code.
  91. */
  92. static uint32_t advertising_buttons_configure()
  93. {
  94. uint32_t err_code;
  95. err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT,
  96. BTN_ACTION_DISCONNECT,
  97. BSP_EVENT_DEFAULT);
  98. RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
  99. err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF,
  100. BTN_ACTION_WHITELIST_OFF,
  101. BSP_EVENT_WHITELIST_OFF);
  102. RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
  103. err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP,
  104. BTN_ACTION_SLEEP,
  105. BSP_EVENT_SLEEP);
  106. RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
  107. return NRF_SUCCESS;
  108. }
  109. /**@brief Function for extracting the BSP event valid at startup.
  110. *
  111. * @details When a button was used to wake up the device, the button press will not generate an
  112. * interrupt. This function reads which button was pressed at startup, and returns the
  113. * appropriate BSP event.
  114. *
  115. * @param[out] p_startup_event Where to put the extracted BSP event.
  116. *
  117. * @retval NRF_SUCCESS Extraction was successful.
  118. * @return A propagated error code.
  119. */
  120. static uint32_t startup_event_extract(bsp_event_t * p_startup_event)
  121. {
  122. uint32_t err_code;
  123. bool wakeup_button_is_pressed, bond_erase_button_is_pressed;
  124. // Read buttons
  125. err_code = bsp_button_is_pressed(BTN_ID_WAKEUP, &wakeup_button_is_pressed);
  126. RETURN_ON_ERROR(err_code);
  127. err_code = bsp_button_is_pressed(BTN_ID_WAKEUP_BOND_DELETE, &bond_erase_button_is_pressed);
  128. RETURN_ON_ERROR(err_code);
  129. // React to button states
  130. if (bond_erase_button_is_pressed)
  131. {
  132. *p_startup_event = BSP_EVENT_CLEAR_BONDING_DATA;
  133. }
  134. else if (wakeup_button_is_pressed)
  135. {
  136. *p_startup_event = BSP_EVENT_WAKEUP;
  137. }
  138. else
  139. {
  140. *p_startup_event = BSP_EVENT_NOTHING;
  141. }
  142. return NRF_SUCCESS;
  143. }
  144. uint32_t bsp_btn_ble_sleep_mode_prepare(void)
  145. {
  146. uint32_t err_code = bsp_wakeup_buttons_set((1 << BTN_ID_WAKEUP) | (1 << BTN_ID_WAKEUP_BOND_DELETE));
  147. RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code);
  148. return NRF_SUCCESS;
  149. }
  150. void bsp_btn_ble_on_ble_evt(ble_evt_t * p_ble_evt)
  151. {
  152. uint32_t err_code;
  153. switch (p_ble_evt->header.evt_id)
  154. {
  155. case BLE_GAP_EVT_CONNECTED:
  156. if (m_num_connections == 0)
  157. {
  158. err_code = connection_buttons_configure();
  159. CALL_HANDLER_ON_ERROR(err_code);
  160. }
  161. m_num_connections++;
  162. break;
  163. case BLE_GAP_EVT_DISCONNECTED:
  164. m_num_connections--;
  165. if (m_num_connections == 0)
  166. {
  167. err_code = advertising_buttons_configure();
  168. CALL_HANDLER_ON_ERROR(err_code);
  169. }
  170. break;
  171. default:
  172. break;
  173. }
  174. }
  175. uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt)
  176. {
  177. uint32_t err_code = NRF_SUCCESS;
  178. m_error_handler = error_handler;
  179. if (p_startup_bsp_evt != NULL)
  180. {
  181. err_code = startup_event_extract(p_startup_bsp_evt);
  182. RETURN_ON_ERROR(err_code);
  183. }
  184. if (m_num_connections == 0)
  185. {
  186. err_code = advertising_buttons_configure();
  187. }
  188. return err_code;
  189. }