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 43 static uint32_t counter_sub(uint32_t a, uint32_t b) 44 { 45 return (a - b) & COUNTER_MAX; 46 } 47 48 static void set_comparator(uint32_t cyc) 49 { 50 nrf_rtc_cc_set(NRF_RTC_REG, 0, cyc & COUNTER_MAX); 51 } 52 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 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 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 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 123