board.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #include "board.h"
  2. #include "drv_uart.h"
  3. #include "app_util_platform.h"
  4. #include "nrf_drv_common.h"
  5. #include "nrf_systick.h"
  6. #include "nrf_rtc.h"
  7. #include "nrf_drv_clock.h"
  8. #include "softdevice_handler.h"
  9. #include "nrf_drv_uart.h"
  10. #include "nrf_gpio.h"
  11. #include <rtthread.h>
  12. #include <rthw.h>
  13. #define TICK_RATE_HZ RT_TICK_PER_SECOND
  14. #define SYSTICK_CLOCK_HZ ( 32768UL )
  15. #define NRF_RTC_REG NRF_RTC1
  16. /* IRQn used by the selected RTC */
  17. #define NRF_RTC_IRQn RTC1_IRQn
  18. /* Constants required to manipulate the NVIC. */
  19. #define NRF_RTC_PRESCALER ( (uint32_t) (ROUNDED_DIV(SYSTICK_CLOCK_HZ, TICK_RATE_HZ) - 1) )
  20. /* Maximum RTC ticks */
  21. #define NRF_RTC_MAXTICKS ((1U<<24)-1U)
  22. static volatile uint32_t m_tick_overflow_count = 0;
  23. #define NRF_RTC_BITWIDTH 24
  24. #define OSTick_Handler RTC1_IRQHandler
  25. #define EXPECTED_IDLE_TIME_BEFORE_SLEEP 2
  26. void SysTick_Configuration(void)
  27. {
  28. nrf_drv_clock_lfclk_request(NULL);
  29. /* Configure SysTick to interrupt at the requested rate. */
  30. nrf_rtc_prescaler_set(NRF_RTC_REG, NRF_RTC_PRESCALER);
  31. nrf_rtc_int_enable (NRF_RTC_REG, RTC_INTENSET_TICK_Msk);
  32. nrf_rtc_task_trigger (NRF_RTC_REG, NRF_RTC_TASK_CLEAR);
  33. nrf_rtc_task_trigger (NRF_RTC_REG, NRF_RTC_TASK_START);
  34. nrf_rtc_event_enable(NRF_RTC_REG, RTC_EVTEN_OVRFLW_Msk);
  35. NVIC_SetPriority(NRF_RTC_IRQn, 0xF);
  36. NVIC_EnableIRQ(NRF_RTC_IRQn);
  37. }
  38. static rt_tick_t _tick_distance(void)
  39. {
  40. nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0);
  41. uint32_t systick_counter = nrf_rtc_counter_get(NRF_RTC_REG);
  42. nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_TICK);
  43. /* check for overflow in TICK counter */
  44. if(nrf_rtc_event_pending(NRF_RTC_REG, NRF_RTC_EVENT_OVERFLOW))
  45. {
  46. nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_OVERFLOW);
  47. m_tick_overflow_count++;
  48. }
  49. return ((m_tick_overflow_count << NRF_RTC_BITWIDTH) + systick_counter) - rt_tick_get();
  50. }
  51. void OSTick_Handler( void )
  52. {
  53. uint32_t diff;
  54. /* enter interrupt */
  55. rt_interrupt_enter();
  56. diff = _tick_distance();
  57. while((diff--) > 0)
  58. {
  59. if (rt_thread_self() != RT_NULL)
  60. {
  61. rt_tick_increase();
  62. }
  63. }
  64. /* leave interrupt */
  65. rt_interrupt_leave();
  66. }
  67. static void _wakeup_tick_adjust(void)
  68. {
  69. uint32_t diff;
  70. uint32_t level;
  71. level = rt_hw_interrupt_disable();
  72. diff = _tick_distance();
  73. rt_tick_set(rt_tick_get() + diff);
  74. if (rt_thread_self() != RT_NULL)
  75. {
  76. struct rt_thread *thread;
  77. /* check time slice */
  78. thread = rt_thread_self();
  79. if (thread->remaining_tick <= diff)
  80. {
  81. /* change to initialized tick */
  82. thread->remaining_tick = thread->init_tick;
  83. /* yield */
  84. rt_thread_yield();
  85. }
  86. else
  87. {
  88. thread->remaining_tick -= diff;
  89. }
  90. /* check timer */
  91. rt_timer_check();
  92. }
  93. rt_hw_interrupt_enable(level);
  94. }
  95. static void _sleep_ongo( uint32_t sleep_tick )
  96. {
  97. uint32_t enterTime;
  98. uint32_t entry_tick;
  99. /* Make sure the SysTick reload value does not overflow the counter. */
  100. if ( sleep_tick > NRF_RTC_MAXTICKS - EXPECTED_IDLE_TIME_BEFORE_SLEEP )
  101. {
  102. sleep_tick = NRF_RTC_MAXTICKS - EXPECTED_IDLE_TIME_BEFORE_SLEEP;
  103. }
  104. rt_enter_critical();
  105. enterTime = nrf_rtc_counter_get(NRF_RTC_REG);
  106. {
  107. uint32_t wakeupTime = (enterTime + sleep_tick) & NRF_RTC_MAXTICKS;
  108. /* Stop tick events */
  109. nrf_rtc_int_disable(NRF_RTC_REG, NRF_RTC_INT_TICK_MASK);
  110. /* Configure CTC interrupt */
  111. nrf_rtc_cc_set(NRF_RTC_REG, 0, wakeupTime);
  112. nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0);
  113. nrf_rtc_int_enable(NRF_RTC_REG, NRF_RTC_INT_COMPARE0_MASK);
  114. entry_tick = rt_tick_get();
  115. __DSB();
  116. if ( sleep_tick > 0 )
  117. {
  118. #ifdef SOFTDEVICE_PRESENT
  119. if (softdevice_handler_is_enabled())
  120. {
  121. uint32_t err_code = sd_app_evt_wait();
  122. APP_ERROR_CHECK(err_code);
  123. }
  124. else
  125. #endif
  126. {
  127. /* No SD - we would just block interrupts globally.
  128. * BASEPRI cannot be used for that because it would prevent WFE from wake up.
  129. */
  130. do{
  131. __WFE();
  132. } while (0 == (NVIC->ISPR[0] | NVIC->ISPR[1]));
  133. }
  134. }
  135. nrf_rtc_int_disable(NRF_RTC_REG, NRF_RTC_INT_COMPARE0_MASK);
  136. nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0);
  137. _wakeup_tick_adjust();
  138. /* Correct the system ticks */
  139. {
  140. nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_TICK);
  141. nrf_rtc_int_enable (NRF_RTC_REG, NRF_RTC_INT_TICK_MASK);
  142. /* It is important that we clear pending here so that our corrections are latest and in sync with tick_interrupt handler */
  143. NVIC_ClearPendingIRQ(NRF_RTC_IRQn);
  144. }
  145. // rt_kprintf("entry tick:%u, expected:%u, current tick:%u\n", entry_tick, sleep_tick, rt_tick_get());
  146. }
  147. rt_exit_critical();
  148. }
  149. void rt_hw_system_powersave(void)
  150. {
  151. uint32_t sleep_tick;
  152. sleep_tick = rt_timer_next_timeout_tick() - rt_tick_get();
  153. if ( sleep_tick >= EXPECTED_IDLE_TIME_BEFORE_SLEEP)
  154. {
  155. // rt_kprintf("sleep entry:%u\n", rt_tick_get());
  156. _sleep_ongo( sleep_tick );
  157. }
  158. }
  159. void rt_hw_board_init(void)
  160. {
  161. // sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE);
  162. /* Activate deep sleep mode */
  163. SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  164. nrf_drv_clock_init();
  165. // nrf_drv_clock_hfclk_request(0);
  166. SysTick_Configuration();
  167. rt_thread_idle_sethook(rt_hw_system_powersave);
  168. rt_hw_uart_init();
  169. #ifdef RT_USING_CONSOLE
  170. rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
  171. #endif
  172. #ifdef RT_USING_COMPONENTS_INIT
  173. rt_components_board_init();
  174. #endif
  175. }