board.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #include "board.h"
  2. #include "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. static rt_bool_t osready = RT_FALSE;
  13. #if 0
  14. /*******************************************************************************
  15. * Function Name : SysTick_Configuration
  16. * Description : Configures the SysTick for OS tick.
  17. * Input : None
  18. * Output : None
  19. * Return : None
  20. *******************************************************************************/
  21. void SysTick_Configuration(void)
  22. {
  23. nrf_drv_common_irq_enable(SysTick_IRQn, APP_TIMER_CONFIG_IRQ_PRIORITY);
  24. nrf_systick_load_set(SystemCoreClock / RT_TICK_PER_SECOND);
  25. nrf_systick_val_clear();
  26. nrf_systick_csr_set(NRF_SYSTICK_CSR_CLKSOURCE_CPU | NRF_SYSTICK_CSR_TICKINT_ENABLE
  27. | NRF_SYSTICK_CSR_ENABLE);
  28. }
  29. /**
  30. * This is the timer interrupt service routine.
  31. *
  32. */
  33. void SysTick_Handler(void)
  34. {
  35. if (osready)
  36. {
  37. /* enter interrupt */
  38. rt_interrupt_enter();
  39. rt_tick_increase();
  40. /* leave interrupt */
  41. rt_interrupt_leave();
  42. }
  43. }
  44. #else
  45. #define TICK_RATE_HZ RT_TICK_PER_SECOND
  46. #define SYSTICK_CLOCK_HZ ( 32768UL )
  47. #define NRF_RTC_REG NRF_RTC1
  48. /* IRQn used by the selected RTC */
  49. #define NRF_RTC_IRQn RTC1_IRQn
  50. /* Constants required to manipulate the NVIC. */
  51. #define NRF_RTC_PRESCALER ( (uint32_t) (ROUNDED_DIV(SYSTICK_CLOCK_HZ, TICK_RATE_HZ) - 1) )
  52. /* Maximum RTC ticks */
  53. #define NRF_RTC_MAXTICKS ((1U<<24)-1U)
  54. static volatile uint32_t m_tick_overflow_count = 0;
  55. #define NRF_RTC_BITWIDTH 24
  56. #define OSTick_Handler RTC1_IRQHandler
  57. #define EXPECTED_IDLE_TIME_BEFORE_SLEEP 2
  58. void SysTick_Configuration(void)
  59. {
  60. nrf_drv_clock_lfclk_request(NULL);
  61. /* Configure SysTick to interrupt at the requested rate. */
  62. nrf_rtc_prescaler_set(NRF_RTC_REG, NRF_RTC_PRESCALER);
  63. nrf_rtc_int_enable (NRF_RTC_REG, RTC_INTENSET_TICK_Msk);
  64. nrf_rtc_task_trigger (NRF_RTC_REG, NRF_RTC_TASK_CLEAR);
  65. nrf_rtc_task_trigger (NRF_RTC_REG, NRF_RTC_TASK_START);
  66. nrf_rtc_event_enable(NRF_RTC_REG, RTC_EVTEN_OVRFLW_Msk);
  67. NVIC_SetPriority(NRF_RTC_IRQn, 0xF);
  68. NVIC_EnableIRQ(NRF_RTC_IRQn);
  69. }
  70. void OSTick_Handler( void )
  71. {
  72. nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0);
  73. uint32_t systick_counter = nrf_rtc_counter_get(NRF_RTC_REG);
  74. nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_TICK);
  75. /* check for overflow in TICK counter */
  76. if(nrf_rtc_event_pending(NRF_RTC_REG, NRF_RTC_EVENT_OVERFLOW))
  77. {
  78. nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_OVERFLOW);
  79. m_tick_overflow_count++;
  80. }
  81. {
  82. uint32_t diff;
  83. diff = ((m_tick_overflow_count << NRF_RTC_BITWIDTH) + systick_counter) - rt_tick_get();
  84. while((diff--) > 0)
  85. {
  86. if (osready)
  87. {
  88. /* enter interrupt */
  89. rt_interrupt_enter();
  90. rt_tick_increase();
  91. /* leave interrupt */
  92. rt_interrupt_leave();
  93. }
  94. }
  95. }
  96. }
  97. static void _sleep_ongo( uint32_t sleep_tick )
  98. {
  99. /*
  100. * Implementation note:
  101. *
  102. * To help debugging the option configUSE_TICKLESS_IDLE_SIMPLE_DEBUG was presented.
  103. * This option would make sure that even if program execution was stopped inside
  104. * this function no more than expected number of ticks would be skipped.
  105. *
  106. * Normally RTC works all the time even if firmware execution was stopped
  107. * and that may lead to skipping too much of ticks.
  108. */
  109. uint32_t enterTime;
  110. uint32_t entry_tick;
  111. /* Make sure the SysTick reload value does not overflow the counter. */
  112. if ( sleep_tick > NRF_RTC_MAXTICKS - EXPECTED_IDLE_TIME_BEFORE_SLEEP )
  113. {
  114. sleep_tick = NRF_RTC_MAXTICKS - EXPECTED_IDLE_TIME_BEFORE_SLEEP;
  115. }
  116. rt_enter_critical();
  117. enterTime = nrf_rtc_counter_get(NRF_RTC_REG);
  118. // if ( eTaskConfirmSleepModeStatus() != eAbortSleep )
  119. {
  120. uint32_t wakeupTime = (enterTime + sleep_tick) & NRF_RTC_MAXTICKS;
  121. /* Stop tick events */
  122. nrf_rtc_int_disable(NRF_RTC_REG, NRF_RTC_INT_TICK_MASK);
  123. /* Configure CTC interrupt */
  124. nrf_rtc_cc_set(NRF_RTC_REG, 0, wakeupTime);
  125. nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0);
  126. nrf_rtc_int_enable(NRF_RTC_REG, NRF_RTC_INT_COMPARE0_MASK);
  127. entry_tick = rt_tick_get();
  128. __DSB();
  129. if ( sleep_tick > 0 )
  130. {
  131. #ifdef SOFTDEVICE_PRESENT
  132. if (softdevice_handler_is_enabled())
  133. {
  134. uint32_t err_code = sd_app_evt_wait();
  135. APP_ERROR_CHECK(err_code);
  136. }
  137. else
  138. #endif
  139. {
  140. /* No SD - we would just block interrupts globally.
  141. * BASEPRI cannot be used for that because it would prevent WFE from wake up.
  142. */
  143. do{
  144. __WFE();
  145. } while (0 == (NVIC->ISPR[0] | NVIC->ISPR[1]));
  146. }
  147. }
  148. nrf_rtc_int_disable(NRF_RTC_REG, NRF_RTC_INT_COMPARE0_MASK);
  149. nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0);
  150. /* Correct the system ticks */
  151. {
  152. nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_TICK);
  153. nrf_rtc_int_enable (NRF_RTC_REG, NRF_RTC_INT_TICK_MASK);
  154. /* It is important that we clear pending here so that our corrections are latest and in sync with tick_interrupt handler */
  155. NVIC_ClearPendingIRQ(NRF_RTC_IRQn);
  156. }
  157. rt_kprintf("entry tick:%u, expected:%u, current tick:%u\n", entry_tick, sleep_tick, rt_tick_get());
  158. }
  159. rt_exit_critical();
  160. }
  161. #endif
  162. void rt_os_ready(void)
  163. {
  164. osready = 1;
  165. }
  166. void rt_hw_system_powersave(void)
  167. {
  168. uint32_t sleep_tick;
  169. sleep_tick = rt_timer_next_timeout_tick() - rt_tick_get();
  170. if ( sleep_tick >= EXPECTED_IDLE_TIME_BEFORE_SLEEP)
  171. {
  172. // rt_kprintf("sleep entry:%u\n", rt_tick_get());
  173. _sleep_ongo( sleep_tick );
  174. }
  175. }
  176. void rt_hw_board_init(void)
  177. {
  178. // sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE);
  179. /* Activate deep sleep mode */
  180. SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  181. nrf_drv_clock_init();
  182. // nrf_drv_clock_hfclk_request(0);
  183. SysTick_Configuration();
  184. rt_thread_idle_sethook(rt_hw_system_powersave);
  185. rt_hw_uart_init();
  186. #ifdef RT_USING_CONSOLE
  187. rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
  188. #endif
  189. #ifdef RT_USING_COMPONENTS_INIT
  190. rt_components_board_init();
  191. #endif
  192. }