1 /*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 */
7
8 #include <rtthread.h>
9 #include <rthw.h>
10
11 #include "board.h"
12 #include "drv_uart.h"
13
14 #include "nrfx.h"
15 #include "nrfx_rtc.h"
16 #include "nrfx_clock.h"
17
18 #ifdef __CC_ARM
19 extern int Image$$RW_IRAM1$$ZI$$Limit;
20 #define NRF_SRAM_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit)
21 #elif __ICCARM__
22 #pragma section="HEAP"
23 #define NRF_SRAM_BEGIN (__segment_end("HEAP"))
24 #else
25 extern int __bss_end;
26 #define NRF_SRAM_BEGIN (&__bss_end)
27 #endif
28
29 #define OSTICK_CLOCK_HZ ( 32768UL )
30 #define COUNTER_MAX 0x00ffffff
31 #define CYC_PER_TICK (OSTICK_CLOCK_HZ / RT_TICK_PER_SECOND)
32 #define MAX_TICKS ((COUNTER_MAX - CYC_PER_TICK) / CYC_PER_TICK)
33 #define MIN_DELAY 32
34
35 #define TICK_RATE_HZ RT_TICK_PER_SECOND
36
37 #define NRF_RTC_REG NRF_RTC1
38 /* IRQn used by the selected RTC */
39 #define NRF_RTC_IRQn RTC1_IRQn
40
41 static uint32_t last_count;
42
counter_sub(uint32_t a,uint32_t b)43 static uint32_t counter_sub(uint32_t a, uint32_t b)
44 {
45 return (a - b) & COUNTER_MAX;
46 }
47
set_comparator(uint32_t cyc)48 static void set_comparator(uint32_t cyc)
49 {
50 nrf_rtc_cc_set(NRF_RTC_REG, 0, cyc & COUNTER_MAX);
51 }
52
RTC1_IRQHandler(void)53 void RTC1_IRQHandler(void)
54 {
55 uint32_t t, dticks, next;
56
57 NRF_RTC_REG->EVENTS_COMPARE[0] = 0;
58
59 t = nrf_rtc_counter_get(NRF_RTC_REG);
60 dticks = counter_sub(t, last_count) / CYC_PER_TICK;
61 last_count += dticks * CYC_PER_TICK;
62 next = last_count + CYC_PER_TICK;
63
64 if ((int32_t)(next - t) < MIN_DELAY)
65 {
66 next += CYC_PER_TICK;
67 }
68 set_comparator(next);
69
70 rt_tick_increase();
71 }
72
_timer_cycle_get_32(void)73 uint32_t _timer_cycle_get_32(void)
74 {
75 // k_spinlock_key_t key = k_spin_lock(&lock);
76 uint32_t ret = counter_sub(nrf_rtc_counter_get(NRF_RTC_REG), last_count) + last_count;
77
78 // k_spin_unlock(&lock, key);
79 return ret;
80 }
81
os_tick_init(void)82 void os_tick_init(void)
83 {
84 nrf_clock_lf_src_set((nrf_clock_lfclk_t)NRFX_CLOCK_CONFIG_LF_SRC);
85 nrfx_clock_lfclk_start();
86
87 nrf_rtc_prescaler_set(NRF_RTC_REG, 0);
88
89 nrf_rtc_cc_set(NRF_RTC_REG, 0, CYC_PER_TICK);
90 nrf_rtc_event_enable(NRF_RTC_REG, RTC_EVTENSET_COMPARE0_Msk);
91 nrf_rtc_int_enable(NRF_RTC_REG, RTC_INTENSET_COMPARE0_Msk);
92
93 /* Clear the event flag and possible pending interrupt */
94 nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0);
95 NVIC_ClearPendingIRQ(NRF_RTC_IRQn);
96
97 NVIC_SetPriority(NRF_RTC_IRQn, 1);
98 NVIC_EnableIRQ(NRF_RTC_IRQn);
99
100 nrf_rtc_task_trigger(NRF_RTC_REG, NRF_RTC_TASK_CLEAR);
101 nrf_rtc_task_trigger(NRF_RTC_REG, NRF_RTC_TASK_START);
102
103 set_comparator(nrf_rtc_counter_get(NRF_RTC_REG) + CYC_PER_TICK);
104 }
105
rt_hw_board_init(void)106 void rt_hw_board_init(void)
107 {
108 os_tick_init();
109
110 #ifdef RT_USING_HEAP
111 rt_system_heap_init((void *)NRF_SRAM_BEGIN, (void *)CHIP_SRAM_END);
112 #endif
113
114 #ifdef RT_USING_COMPONENTS_INIT
115 rt_components_board_init();
116 #endif
117
118 #ifdef RT_USING_CONSOLE
119 rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
120 #endif
121 }
122
reboot(void)123 static int reboot(void)
124 {
125 rt_hw_cpu_reset();
126
127 return 0;
128 }
129 MSH_CMD_EXPORT_ALIAS(reboot, reboot, "reset system");
130