1150812a8SEvalZero /*
2150812a8SEvalZero * Copyright (c) 2006-2018, RT-Thread Development Team
3150812a8SEvalZero *
4150812a8SEvalZero * SPDX-License-Identifier: Apache-2.0
5150812a8SEvalZero *
6150812a8SEvalZero */
7150812a8SEvalZero
8150812a8SEvalZero #include <rtthread.h>
9150812a8SEvalZero #include <rthw.h>
10150812a8SEvalZero
11150812a8SEvalZero #include "board.h"
12150812a8SEvalZero #include "drv_uart.h"
13150812a8SEvalZero
14150812a8SEvalZero #include "nrfx.h"
15150812a8SEvalZero #include "nrfx_rtc.h"
16150812a8SEvalZero #include "nrfx_clock.h"
17150812a8SEvalZero
18150812a8SEvalZero #ifdef __CC_ARM
19150812a8SEvalZero extern int Image$$RW_IRAM1$$ZI$$Limit;
20150812a8SEvalZero #define NRF_SRAM_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit)
21150812a8SEvalZero #elif __ICCARM__
22150812a8SEvalZero #pragma section="HEAP"
23150812a8SEvalZero #define NRF_SRAM_BEGIN (__segment_end("HEAP"))
24150812a8SEvalZero #else
25150812a8SEvalZero extern int __bss_end;
26150812a8SEvalZero #define NRF_SRAM_BEGIN (&__bss_end)
27150812a8SEvalZero #endif
28150812a8SEvalZero
29150812a8SEvalZero #define OSTICK_CLOCK_HZ ( 32768UL )
30150812a8SEvalZero #define COUNTER_MAX 0x00ffffff
31150812a8SEvalZero #define CYC_PER_TICK (OSTICK_CLOCK_HZ / RT_TICK_PER_SECOND)
32150812a8SEvalZero #define MAX_TICKS ((COUNTER_MAX - CYC_PER_TICK) / CYC_PER_TICK)
33150812a8SEvalZero #define MIN_DELAY 32
34150812a8SEvalZero
35150812a8SEvalZero #define TICK_RATE_HZ RT_TICK_PER_SECOND
36150812a8SEvalZero
37150812a8SEvalZero #define NRF_RTC_REG NRF_RTC1
38150812a8SEvalZero /* IRQn used by the selected RTC */
39150812a8SEvalZero #define NRF_RTC_IRQn RTC1_IRQn
40150812a8SEvalZero
41150812a8SEvalZero static uint32_t last_count;
42150812a8SEvalZero
counter_sub(uint32_t a,uint32_t b)43150812a8SEvalZero static uint32_t counter_sub(uint32_t a, uint32_t b)
44150812a8SEvalZero {
45150812a8SEvalZero return (a - b) & COUNTER_MAX;
46150812a8SEvalZero }
47150812a8SEvalZero
set_comparator(uint32_t cyc)48150812a8SEvalZero static void set_comparator(uint32_t cyc)
49150812a8SEvalZero {
50150812a8SEvalZero nrf_rtc_cc_set(NRF_RTC_REG, 0, cyc & COUNTER_MAX);
51150812a8SEvalZero }
52150812a8SEvalZero
RTC1_IRQHandler(void)53150812a8SEvalZero void RTC1_IRQHandler(void)
54150812a8SEvalZero {
55150812a8SEvalZero uint32_t t, dticks, next;
56150812a8SEvalZero
57150812a8SEvalZero NRF_RTC_REG->EVENTS_COMPARE[0] = 0;
58150812a8SEvalZero
59150812a8SEvalZero t = nrf_rtc_counter_get(NRF_RTC_REG);
60150812a8SEvalZero dticks = counter_sub(t, last_count) / CYC_PER_TICK;
61150812a8SEvalZero last_count += dticks * CYC_PER_TICK;
62150812a8SEvalZero next = last_count + CYC_PER_TICK;
63150812a8SEvalZero
64150812a8SEvalZero if ((int32_t)(next - t) < MIN_DELAY)
65150812a8SEvalZero {
66150812a8SEvalZero next += CYC_PER_TICK;
67150812a8SEvalZero }
68150812a8SEvalZero set_comparator(next);
69150812a8SEvalZero
70150812a8SEvalZero rt_tick_increase();
71150812a8SEvalZero }
72150812a8SEvalZero
_timer_cycle_get_32(void)73150812a8SEvalZero uint32_t _timer_cycle_get_32(void)
74150812a8SEvalZero {
75150812a8SEvalZero // k_spinlock_key_t key = k_spin_lock(&lock);
76150812a8SEvalZero uint32_t ret = counter_sub(nrf_rtc_counter_get(NRF_RTC_REG), last_count) + last_count;
77150812a8SEvalZero
78150812a8SEvalZero // k_spin_unlock(&lock, key);
79150812a8SEvalZero return ret;
80150812a8SEvalZero }
81150812a8SEvalZero
os_tick_init(void)82150812a8SEvalZero void os_tick_init(void)
83150812a8SEvalZero {
84150812a8SEvalZero nrf_clock_lf_src_set((nrf_clock_lfclk_t)NRFX_CLOCK_CONFIG_LF_SRC);
85150812a8SEvalZero nrfx_clock_lfclk_start();
86150812a8SEvalZero
87150812a8SEvalZero nrf_rtc_prescaler_set(NRF_RTC_REG, 0);
88150812a8SEvalZero
89150812a8SEvalZero nrf_rtc_cc_set(NRF_RTC_REG, 0, CYC_PER_TICK);
90150812a8SEvalZero nrf_rtc_event_enable(NRF_RTC_REG, RTC_EVTENSET_COMPARE0_Msk);
91150812a8SEvalZero nrf_rtc_int_enable(NRF_RTC_REG, RTC_INTENSET_COMPARE0_Msk);
92150812a8SEvalZero
93150812a8SEvalZero /* Clear the event flag and possible pending interrupt */
94150812a8SEvalZero nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0);
95150812a8SEvalZero NVIC_ClearPendingIRQ(NRF_RTC_IRQn);
96150812a8SEvalZero
97150812a8SEvalZero NVIC_SetPriority(NRF_RTC_IRQn, 1);
98150812a8SEvalZero NVIC_EnableIRQ(NRF_RTC_IRQn);
99150812a8SEvalZero
100150812a8SEvalZero nrf_rtc_task_trigger(NRF_RTC_REG, NRF_RTC_TASK_CLEAR);
101150812a8SEvalZero nrf_rtc_task_trigger(NRF_RTC_REG, NRF_RTC_TASK_START);
102150812a8SEvalZero
103150812a8SEvalZero set_comparator(nrf_rtc_counter_get(NRF_RTC_REG) + CYC_PER_TICK);
104150812a8SEvalZero }
105150812a8SEvalZero
rt_hw_board_init(void)106150812a8SEvalZero void rt_hw_board_init(void)
107150812a8SEvalZero {
108150812a8SEvalZero os_tick_init();
109150812a8SEvalZero
110150812a8SEvalZero #ifdef RT_USING_HEAP
111150812a8SEvalZero rt_system_heap_init((void *)NRF_SRAM_BEGIN, (void *)CHIP_SRAM_END);
112150812a8SEvalZero #endif
113150812a8SEvalZero
114150812a8SEvalZero #ifdef RT_USING_COMPONENTS_INIT
115150812a8SEvalZero rt_components_board_init();
116150812a8SEvalZero #endif
117150812a8SEvalZero
118150812a8SEvalZero #ifdef RT_USING_CONSOLE
119150812a8SEvalZero rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
120150812a8SEvalZero #endif
121150812a8SEvalZero }
122150812a8SEvalZero
reboot(void)123*27a220c6SEvalZero static int reboot(void)
124*27a220c6SEvalZero {
125*27a220c6SEvalZero rt_hw_cpu_reset();
126*27a220c6SEvalZero
127*27a220c6SEvalZero return 0;
128*27a220c6SEvalZero }
129*27a220c6SEvalZero MSH_CMD_EXPORT_ALIAS(reboot, reboot, "reset system");
130