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