nrf_drv_rtc.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. */
  12. #include "nrf_drv_rtc.h"
  13. #include "nrf_rtc.h"
  14. #include "nrf_assert.h"
  15. #include "app_util_platform.h"
  16. /**@brief RTC driver instance control block structure. */
  17. typedef struct
  18. {
  19. nrf_drv_state_t state; /**< Instance state. */
  20. bool reliable; /**< Reliable mode flag. */
  21. uint8_t tick_latency; /**< Maximum length of interrupt handler in ticks (max 7.7 ms). */
  22. } nrf_drv_rtc_cb_t;
  23. // User callbacks local storage.
  24. static nrf_drv_rtc_handler_t m_handlers[RTC_COUNT];
  25. static nrf_drv_rtc_cb_t m_cb[RTC_COUNT];
  26. static const nrf_drv_rtc_config_t m_default_config[] = {
  27. #if RTC0_ENABLED
  28. NRF_DRV_RTC_DEFAULT_CONFIG(0),
  29. #endif
  30. #if RTC1_ENABLED
  31. NRF_DRV_RTC_DEFAULT_CONFIG(1),
  32. #endif
  33. #if RTC2_ENABLED
  34. NRF_DRV_RTC_DEFAULT_CONFIG(2)
  35. #endif
  36. };
  37. ret_code_t nrf_drv_rtc_init(nrf_drv_rtc_t const * const p_instance,
  38. nrf_drv_rtc_config_t const * p_config,
  39. nrf_drv_rtc_handler_t handler)
  40. {
  41. if (handler)
  42. {
  43. m_handlers[p_instance->instance_id] = handler;
  44. }
  45. else
  46. {
  47. return NRF_ERROR_INVALID_PARAM;
  48. }
  49. if (p_config == NULL)
  50. {
  51. p_config = &m_default_config[p_instance->instance_id];
  52. }
  53. if (m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED)
  54. {
  55. return NRF_ERROR_INVALID_STATE;
  56. }
  57. nrf_drv_common_irq_enable(p_instance->irq, p_config->interrupt_priority);
  58. nrf_rtc_prescaler_set(p_instance->p_reg, p_config->prescaler);
  59. m_cb[p_instance->instance_id].reliable = p_config->reliable;
  60. m_cb[p_instance->instance_id].tick_latency = p_config->tick_latency;
  61. m_cb[p_instance->instance_id].state = NRF_DRV_STATE_INITIALIZED;
  62. return NRF_SUCCESS;
  63. }
  64. void nrf_drv_rtc_uninit(nrf_drv_rtc_t const * const p_instance)
  65. {
  66. uint32_t mask = NRF_RTC_INT_TICK_MASK |
  67. NRF_RTC_INT_OVERFLOW_MASK |
  68. NRF_RTC_INT_COMPARE0_MASK |
  69. NRF_RTC_INT_COMPARE1_MASK |
  70. NRF_RTC_INT_COMPARE2_MASK |
  71. NRF_RTC_INT_COMPARE3_MASK;
  72. ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED);
  73. nrf_drv_common_irq_disable(p_instance->irq);
  74. nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_STOP);
  75. nrf_rtc_event_disable(p_instance->p_reg, mask);
  76. nrf_rtc_int_disable(p_instance->p_reg, mask);
  77. m_cb[p_instance->instance_id].state = NRF_DRV_STATE_UNINITIALIZED;
  78. }
  79. void nrf_drv_rtc_enable(nrf_drv_rtc_t const * const p_instance)
  80. {
  81. ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_INITIALIZED);
  82. nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_START);
  83. m_cb[p_instance->instance_id].state = NRF_DRV_STATE_POWERED_ON;
  84. }
  85. void nrf_drv_rtc_disable(nrf_drv_rtc_t const * const p_instance)
  86. {
  87. ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON);
  88. nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_STOP);
  89. m_cb[p_instance->instance_id].state = NRF_DRV_STATE_INITIALIZED;
  90. }
  91. ret_code_t nrf_drv_rtc_cc_disable(nrf_drv_rtc_t const * const p_instance, uint32_t channel)
  92. {
  93. ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED);
  94. ASSERT(channel<p_instance->cc_channel_count);
  95. uint32_t int_mask = RTC_CHANNEL_INT_MASK(channel);
  96. nrf_rtc_event_t event = RTC_CHANNEL_EVENT_ADDR(channel);
  97. nrf_rtc_event_disable(p_instance->p_reg,int_mask);
  98. if (nrf_rtc_int_is_enabled(p_instance->p_reg,int_mask))
  99. {
  100. nrf_rtc_int_disable(p_instance->p_reg,int_mask);
  101. if (nrf_rtc_event_pending(p_instance->p_reg,event))
  102. {
  103. nrf_rtc_event_clear(p_instance->p_reg,event);
  104. return NRF_ERROR_TIMEOUT;
  105. }
  106. }
  107. return NRF_SUCCESS;
  108. }
  109. ret_code_t nrf_drv_rtc_cc_set(nrf_drv_rtc_t const * const p_instance,
  110. uint32_t channel,
  111. uint32_t val,
  112. bool enable_irq)
  113. {
  114. ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED);
  115. ASSERT(channel<p_instance->cc_channel_count);
  116. uint32_t int_mask = RTC_CHANNEL_INT_MASK(channel);
  117. nrf_rtc_event_t event = RTC_CHANNEL_EVENT_ADDR(channel);
  118. nrf_rtc_event_disable(p_instance->p_reg, int_mask);
  119. nrf_rtc_int_disable(p_instance->p_reg, int_mask);
  120. val = RTC_WRAP(val);
  121. if (m_cb[p_instance->instance_id].reliable)
  122. {
  123. nrf_rtc_cc_set(p_instance->p_reg,channel,val);
  124. uint32_t cnt = nrf_rtc_counter_get(p_instance->p_reg);
  125. int32_t diff = cnt - val;
  126. if (cnt < val)
  127. {
  128. diff += RTC_COUNTER_COUNTER_Msk;
  129. }
  130. if (diff < m_cb[p_instance->instance_id].tick_latency)
  131. {
  132. return NRF_ERROR_TIMEOUT;
  133. }
  134. }
  135. else
  136. {
  137. nrf_rtc_cc_set(p_instance->p_reg,channel,val);
  138. }
  139. if (enable_irq)
  140. {
  141. nrf_rtc_event_clear(p_instance->p_reg,event);
  142. nrf_rtc_int_enable(p_instance->p_reg, int_mask);
  143. }
  144. nrf_rtc_event_enable(p_instance->p_reg,int_mask);
  145. return NRF_SUCCESS;
  146. }
  147. void nrf_drv_rtc_tick_enable(nrf_drv_rtc_t const * const p_instance, bool enable_irq)
  148. {
  149. nrf_rtc_event_t event = NRF_RTC_EVENT_TICK;
  150. uint32_t mask = NRF_RTC_INT_TICK_MASK;
  151. nrf_rtc_event_clear(p_instance->p_reg, event);
  152. nrf_rtc_event_enable(p_instance->p_reg, mask);
  153. if (enable_irq)
  154. {
  155. nrf_rtc_int_enable(p_instance->p_reg, mask);
  156. }
  157. }
  158. void nrf_drv_rtc_tick_disable(nrf_drv_rtc_t const * const p_instance)
  159. {
  160. uint32_t mask = NRF_RTC_INT_TICK_MASK;
  161. nrf_rtc_event_disable(p_instance->p_reg, mask);
  162. nrf_rtc_int_disable(p_instance->p_reg, mask);
  163. }
  164. void nrf_drv_rtc_overflow_enable(nrf_drv_rtc_t const * const p_instance, bool enable_irq)
  165. {
  166. nrf_rtc_event_t event = NRF_RTC_EVENT_OVERFLOW;
  167. uint32_t mask = NRF_RTC_INT_OVERFLOW_MASK;
  168. nrf_rtc_event_clear(p_instance->p_reg, event);
  169. nrf_rtc_event_enable(p_instance->p_reg, mask);
  170. if (enable_irq)
  171. {
  172. nrf_rtc_int_enable(p_instance->p_reg, mask);
  173. }
  174. }
  175. void nrf_drv_rtc_overflow_disable(nrf_drv_rtc_t const * const p_instance)
  176. {
  177. uint32_t mask = NRF_RTC_INT_OVERFLOW_MASK;
  178. nrf_rtc_event_disable(p_instance->p_reg, mask);
  179. nrf_rtc_int_disable(p_instance->p_reg, mask);
  180. }
  181. uint32_t nrf_drv_rtc_max_ticks_get(nrf_drv_rtc_t const * const p_instance)
  182. {
  183. ASSERT(m_cb[p_instance->instance_id].reliable);
  184. uint32_t ticks;
  185. if (m_cb[p_instance->instance_id].reliable)
  186. {
  187. ticks = RTC_COUNTER_COUNTER_Msk - m_cb[p_instance->instance_id].tick_latency;
  188. }
  189. else
  190. {
  191. ticks = RTC_COUNTER_COUNTER_Msk;
  192. }
  193. return ticks;
  194. }
  195. /**@brief Generic function for handling RTC interrupt
  196. *
  197. * @param[in] p_reg Pointer to instance register structure.
  198. * @param[in] instance_id Index of instance.
  199. */
  200. __STATIC_INLINE void nrf_drv_rtc_int_handler(NRF_RTC_Type * p_reg,
  201. uint32_t instance_id,
  202. uint32_t channel_count)
  203. {
  204. uint32_t i;
  205. uint32_t int_mask = (uint32_t)NRF_RTC_INT_COMPARE0_MASK;
  206. nrf_rtc_event_t event = NRF_RTC_EVENT_COMPARE_0;
  207. for (i = 0; i < channel_count; i++)
  208. {
  209. if (nrf_rtc_int_is_enabled(p_reg,int_mask) && nrf_rtc_event_pending(p_reg,event))
  210. {
  211. nrf_rtc_event_disable(p_reg,int_mask);
  212. nrf_rtc_int_disable(p_reg,int_mask);
  213. nrf_rtc_event_clear(p_reg,event);
  214. m_handlers[instance_id]((nrf_drv_rtc_int_type_t)i);
  215. }
  216. int_mask <<= 1;
  217. event = (nrf_rtc_event_t)((uint32_t)event + sizeof(uint32_t));
  218. }
  219. event = NRF_RTC_EVENT_TICK;
  220. if (nrf_rtc_int_is_enabled(p_reg,NRF_RTC_INT_TICK_MASK) &&
  221. nrf_rtc_event_pending(p_reg, event))
  222. {
  223. nrf_rtc_event_clear(p_reg, event);
  224. m_handlers[instance_id](NRF_DRV_RTC_INT_TICK);
  225. }
  226. event = NRF_RTC_EVENT_OVERFLOW;
  227. if (nrf_rtc_int_is_enabled(p_reg,NRF_RTC_INT_OVERFLOW_MASK) &&
  228. nrf_rtc_event_pending(p_reg, event))
  229. {
  230. nrf_rtc_event_clear(p_reg,event);
  231. m_handlers[instance_id](NRF_DRV_RTC_INT_OVERFLOW);
  232. }
  233. }
  234. #if RTC0_ENABLED
  235. void RTC0_IRQHandler(void)
  236. {
  237. nrf_drv_rtc_int_handler(NRF_RTC0,RTC0_INSTANCE_INDEX, NRF_RTC_CC_CHANNEL_COUNT(0));
  238. }
  239. #endif
  240. #if RTC1_ENABLED
  241. void RTC1_IRQHandler(void)
  242. {
  243. nrf_drv_rtc_int_handler(NRF_RTC1,RTC1_INSTANCE_INDEX, NRF_RTC_CC_CHANNEL_COUNT(1));
  244. }
  245. #endif
  246. #if RTC2_ENABLED
  247. void RTC2_IRQHandler(void)
  248. {
  249. nrf_drv_rtc_int_handler(NRF_RTC2,RTC2_INSTANCE_INDEX, NRF_RTC_CC_CHANNEL_COUNT(2));
  250. }
  251. #endif