1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author            Notes
8  * 2017-12-23     Bernard           first version
9  * 2022-06-14     Meco Man          suuport pref_counter
10  */
11 
12 #include <rthw.h>
13 #include <rtdevice.h>
14 #include <rtthread.h>
15 
16 #include <board.h>
17 #ifdef PKG_USING_PERF_COUNTER
18 #include <perf_counter.h>
19 #endif
20 
21 /* Use Cycle counter of Data Watchpoint and Trace Register for CPU time */
cortexm_cputime_getres(void)22 static uint64_t cortexm_cputime_getres(void)
23 {
24     uint64_t ret = 1000UL * 1000 * 1000;
25 
26     ret = (ret * (1000UL * 1000)) / SystemCoreClock;
27     return ret;
28 }
29 
cortexm_cputime_gettime(void)30 static uint64_t cortexm_cputime_gettime(void)
31 {
32 #ifdef PKG_USING_PERF_COUNTER
33     return get_system_ticks();
34 #else
35     return DWT->CYCCNT;
36 #endif
37 }
38 
39 const static struct rt_clock_cputime_ops _cortexm_ops =
40 {
41     cortexm_cputime_getres,
42     cortexm_cputime_gettime
43 };
44 
45 
cortexm_cputime_init(void)46 int cortexm_cputime_init(void)
47 {
48 #ifdef PKG_USING_PERF_COUNTER
49     clock_cpu_setops(&_cortexm_ops);
50 #else
51     /* check support bit */
52     if ((DWT->CTRL & (1UL << DWT_CTRL_NOCYCCNT_Pos)) == 0)
53     {
54         /* enable trace*/
55         CoreDebug->DEMCR |= (1UL << CoreDebug_DEMCR_TRCENA_Pos);
56 
57         /* whether cycle counter not enabled */
58         if ((DWT->CTRL & (1UL << DWT_CTRL_CYCCNTENA_Pos)) == 0)
59         {
60             /* enable cycle counter */
61             DWT->CTRL |= (1UL << DWT_CTRL_CYCCNTENA_Pos);
62         }
63 
64         clock_cpu_setops(&_cortexm_ops);
65     }
66 #endif /* PKG_USING_PERF_COUNTER */
67     return 0;
68 }
69 INIT_BOARD_EXPORT(cortexm_cputime_init);
70