timer.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * SPDX-FileCopyrightText: 2016 Intel Corporation
  3. * SPDX-FileCopyrightText: 2016 Wind River Systems, Inc.
  4. * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
  5. *
  6. * SPDX-License-Identifier: Apache-2.0
  7. */
  8. #include <errno.h>
  9. #include "osi/hash_map.h"
  10. #include "osi/alarm.h"
  11. #include "osi/hash_functions.h"
  12. #include "mesh/config.h"
  13. #include "mesh/common.h"
  14. static hash_map_t *bm_alarm_hash_map;
  15. static const size_t BLE_MESH_ALARM_HASH_MAP_SIZE = 20 + CONFIG_BLE_MESH_PBA_SAME_TIME +
  16. CONFIG_BLE_MESH_PBG_SAME_TIME;
  17. typedef struct alarm_t {
  18. /* timer id point to here */
  19. esp_timer_handle_t alarm_hdl;
  20. osi_alarm_callback_t cb;
  21. void *cb_data;
  22. int64_t deadline_us;
  23. } osi_alarm_t;
  24. int64_t k_uptime_get(void)
  25. {
  26. /* k_uptime_get_32 is in in milliseconds,
  27. * but esp_timer_get_time is in microseconds
  28. */
  29. return (esp_timer_get_time() / 1000);
  30. }
  31. uint32_t k_uptime_get_32(void)
  32. {
  33. /* k_uptime_get_32 is in in milliseconds,
  34. * but esp_timer_get_time is in microseconds
  35. */
  36. return (uint32_t)(esp_timer_get_time() / 1000);
  37. }
  38. void bt_mesh_timer_init(void)
  39. {
  40. bm_alarm_hash_map = hash_map_new(BLE_MESH_ALARM_HASH_MAP_SIZE,
  41. hash_function_pointer, NULL,
  42. (data_free_fn)osi_alarm_free, NULL);
  43. __ASSERT(bm_alarm_hash_map, "Failed to create hash map");
  44. }
  45. #if CONFIG_BLE_MESH_DEINIT
  46. void bt_mesh_timer_deinit(void)
  47. {
  48. if (bm_alarm_hash_map) {
  49. hash_map_free(bm_alarm_hash_map);
  50. bm_alarm_hash_map = NULL;
  51. }
  52. }
  53. #endif /* CONFIG_BLE_MESH_DEINIT */
  54. int k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler)
  55. {
  56. osi_alarm_t *alarm = NULL;
  57. if (!work || !bm_alarm_hash_map) {
  58. BT_ERR("%s, Invalid parameter", __func__);
  59. return -EINVAL;
  60. }
  61. k_work_init(&work->work, handler);
  62. bt_mesh_alarm_lock();
  63. alarm = hash_map_get(bm_alarm_hash_map, work);
  64. if (alarm) {
  65. BT_ERR("Init, alarm already exists");
  66. bt_mesh_alarm_unlock();
  67. return -EEXIST;
  68. }
  69. alarm = osi_alarm_new("bt_mesh", (osi_alarm_callback_t)handler, (void *)&work->work, 0);
  70. if (alarm == NULL) {
  71. BT_ERR("Init, alarm not created");
  72. bt_mesh_alarm_unlock();
  73. return -EIO;
  74. }
  75. if (!hash_map_set(bm_alarm_hash_map, work, (void *)alarm)) {
  76. BT_ERR("Init, alarm not set");
  77. bt_mesh_alarm_unlock();
  78. return -EIO;
  79. }
  80. // Just init the work timer only, don't start it.
  81. osi_alarm_cancel(alarm);
  82. bt_mesh_alarm_unlock();
  83. return 0;
  84. }
  85. int k_delayed_work_submit(struct k_delayed_work *work, int32_t delay)
  86. {
  87. osi_alarm_t *alarm = NULL;
  88. if (!work || !bm_alarm_hash_map) {
  89. BT_ERR("%s, Invalid parameter", __func__);
  90. return -EINVAL;
  91. }
  92. /* If delay is 0, call the corresponding timeout handler. */
  93. if (delay == 0) {
  94. k_work_submit(&work->work);
  95. return 0;
  96. }
  97. bt_mesh_alarm_lock();
  98. alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
  99. if (alarm == NULL) {
  100. BT_WARN("Submit, alarm not found");
  101. bt_mesh_alarm_unlock();
  102. return -EINVAL;
  103. }
  104. // Cancel the alarm first, before start the alarm.
  105. osi_alarm_cancel(alarm);
  106. osi_alarm_set(alarm, delay);
  107. bt_mesh_alarm_unlock();
  108. return 0;
  109. }
  110. int k_delayed_work_submit_periodic(struct k_delayed_work *work, int32_t period)
  111. {
  112. osi_alarm_t *alarm = NULL;
  113. if (!work || !bm_alarm_hash_map) {
  114. BT_ERR("%s, Invalid parameter", __func__);
  115. return -EINVAL;
  116. }
  117. /* If period is 0, call the corresponding timeout handler. */
  118. if (period == 0) {
  119. k_work_submit(&work->work);
  120. return 0;
  121. }
  122. bt_mesh_alarm_lock();
  123. alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
  124. if (alarm == NULL) {
  125. BT_WARN("Submit, alarm not found");
  126. bt_mesh_alarm_unlock();
  127. return -EINVAL;
  128. }
  129. /* Cancel the alarm first before starting it. */
  130. osi_alarm_cancel(alarm);
  131. osi_alarm_set_periodic(alarm, period);
  132. bt_mesh_alarm_unlock();
  133. return 0;
  134. }
  135. int k_delayed_work_cancel(struct k_delayed_work *work)
  136. {
  137. osi_alarm_t *alarm = NULL;
  138. if (!work || !bm_alarm_hash_map) {
  139. BT_ERR("%s, Invalid parameter", __func__);
  140. return -EINVAL;
  141. }
  142. bt_mesh_alarm_lock();
  143. alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
  144. if (alarm == NULL) {
  145. BT_WARN("Cancel, alarm not found");
  146. bt_mesh_alarm_unlock();
  147. return -EINVAL;
  148. }
  149. osi_alarm_cancel(alarm);
  150. alarm->deadline_us = 0;
  151. bt_mesh_alarm_unlock();
  152. return 0;
  153. }
  154. int k_delayed_work_free(struct k_delayed_work *work)
  155. {
  156. osi_alarm_t *alarm = NULL;
  157. if (!work || !bm_alarm_hash_map) {
  158. BT_ERR("%s, Invalid parameter", __func__);
  159. return -EINVAL;
  160. }
  161. bt_mesh_alarm_lock();
  162. alarm = hash_map_get(bm_alarm_hash_map, work);
  163. if (alarm == NULL) {
  164. BT_DBG("Free, alarm not found");
  165. bt_mesh_alarm_unlock();
  166. return -EINVAL;
  167. }
  168. osi_alarm_cancel(alarm);
  169. hash_map_erase(bm_alarm_hash_map, work);
  170. bt_mesh_alarm_unlock();
  171. return 0;
  172. }
  173. int32_t k_delayed_work_remaining_get(struct k_delayed_work *work)
  174. {
  175. osi_alarm_t *alarm = NULL;
  176. int32_t time = 0;
  177. if (!work || !bm_alarm_hash_map) {
  178. BT_ERR("%s, Invalid parameter", __func__);
  179. return 0;
  180. }
  181. bt_mesh_alarm_lock();
  182. alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
  183. if (alarm == NULL) {
  184. BT_WARN("Get time, alarm not found");
  185. bt_mesh_alarm_unlock();
  186. return 0;
  187. }
  188. time = osi_alarm_get_remaining_ms(alarm);
  189. bt_mesh_alarm_unlock();
  190. return time;
  191. }