1 /*
2  * Copyright (c) 2020 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/arch/arm/arch.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/sys_clock.h>
10 #include <zephyr/timing/timing.h>
11 #include <nrfx.h>
12 
13 #if defined(CONFIG_NRF_RTC_TIMER)
14 
15 #define CYCLES_PER_SEC (16000000 / (1 << NRF_TIMER2->PRESCALER))
16 
soc_timing_init(void)17 void soc_timing_init(void)
18 {
19 	NRF_TIMER2->TASKS_CLEAR = 1; /* Clear Timer */
20 	NRF_TIMER2->MODE = 0; /* Timer Mode */
21 	NRF_TIMER2->PRESCALER = 0; /* 16M Hz */
22 #if defined(CONFIG_SOC_SERIES_NRF51X)
23 	NRF_TIMER2->BITMODE = 0; /* 16 - bit */
24 #else
25 	NRF_TIMER2->BITMODE = 3; /* 32 - bit */
26 #endif
27 }
28 
soc_timing_start(void)29 void soc_timing_start(void)
30 {
31 	NRF_TIMER2->TASKS_START = 1;
32 }
33 
soc_timing_stop(void)34 void soc_timing_stop(void)
35 {
36 	NRF_TIMER2->TASKS_STOP = 1; /* Stop Timer */
37 }
38 
soc_timing_counter_get(void)39 timing_t soc_timing_counter_get(void)
40 {
41 	NRF_TIMER2->TASKS_CAPTURE[0] = 1;
42 	return NRF_TIMER2->CC[0] * ((SystemCoreClock) / CYCLES_PER_SEC);
43 }
44 
soc_timing_cycles_get(volatile timing_t * const start,volatile timing_t * const end)45 uint64_t soc_timing_cycles_get(volatile timing_t *const start,
46 			       volatile timing_t *const end)
47 {
48 #if defined(CONFIG_SOC_SERIES_NRF51X)
49 #define COUNTER_SPAN BIT(16)
50 	if (*end >= *start) {
51 		return (*end - *start);
52 	} else {
53 		return COUNTER_SPAN + *end - *start;
54 	}
55 #else
56 	return (*end - *start);
57 #endif
58 }
59 
soc_timing_freq_get(void)60 uint64_t soc_timing_freq_get(void)
61 {
62 	return SystemCoreClock;
63 }
64 
soc_timing_cycles_to_ns(uint64_t cycles)65 uint64_t soc_timing_cycles_to_ns(uint64_t cycles)
66 {
67 	return (cycles) * (NSEC_PER_SEC) / (SystemCoreClock);
68 }
69 
soc_timing_cycles_to_ns_avg(uint64_t cycles,uint32_t count)70 uint64_t soc_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count)
71 {
72 	return soc_timing_cycles_to_ns(cycles) / count;
73 }
74 
soc_timing_freq_get_mhz(void)75 uint32_t soc_timing_freq_get_mhz(void)
76 {
77 	return (uint32_t)(soc_timing_freq_get() / 1000000);
78 }
79 
80 #endif
81