• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15  * Description: Provides systick driver source \n
16  *
17  * History: \n
18  * 2022-08-01, Create file. \n
19  */
20 #include <stdbool.h>
21 #include "securec.h"
22 #include "interrupt/osal_interrupt.h"
23 
24 #include "systick_porting.h"
25 #include "hal_systick.h"
26 #include "systick.h"
27 
28 static bool g_systick_hw_inited = false;
29 
30 #if defined(CONFIG_SYSTICK_SUPPORT_LPM)
31 static uint64_t g_systick_sleep_compensation_count = 0;
32 static uint64_t g_systick_sleep_suspend_current_count = 0;
33 #endif
34 
uapi_systick_init(void)35 void uapi_systick_init(void)
36 {
37     uint32_t irq_sts = osal_irq_lock();
38     if (unlikely(g_systick_hw_inited)) {
39         osal_irq_restore(irq_sts);
40         return;
41     }
42 
43     hal_systick_init();
44     g_systick_hw_inited = true;
45     osal_irq_restore(irq_sts);
46 }
47 
uapi_systick_deinit(void)48 void uapi_systick_deinit(void)
49 {
50     uint32_t irq_sts = osal_irq_lock();
51     if (unlikely(!g_systick_hw_inited)) {
52         osal_irq_restore(irq_sts);
53         return;
54     }
55 
56     hal_systick_deinit();
57     g_systick_hw_inited = false;
58     osal_irq_restore(irq_sts);
59 }
60 
uapi_systick_count_clear(void)61 errcode_t uapi_systick_count_clear(void)
62 {
63     errcode_t ret;
64     uint32_t irq_sts = osal_irq_lock();
65     if (unlikely(!g_systick_hw_inited)) {
66         osal_irq_restore(irq_sts);
67         return ERRCODE_SYSTICK_NOT_INIT;
68     }
69 
70     ret = hal_systick_count_clear();
71     osal_irq_restore(irq_sts);
72 
73     return ret;
74 }
75 
uapi_systick_get_count(void)76 uint64_t uapi_systick_get_count(void)
77 {
78     uint64_t count = 0;
79 
80     uint32_t irq_sts = osal_irq_lock();
81     if (unlikely(!g_systick_hw_inited)) {
82         osal_irq_restore(irq_sts);
83         return count;
84     }
85 
86     count = hal_systick_get_count();
87     osal_irq_restore(irq_sts);
88 
89 #if defined(CONFIG_SYSTICK_SUPPORT_LPM)
90     return count + g_systick_sleep_compensation_count;
91 #else
92     return count;
93 #endif
94 }
95 
uapi_systick_get_s(void)96 uint64_t uapi_systick_get_s(void)
97 {
98     return convert_count_2_s(uapi_systick_get_count());
99 }
100 
uapi_systick_get_ms(void)101 uint64_t uapi_systick_get_ms(void)
102 {
103     return convert_count_2_ms(uapi_systick_get_count());
104 }
105 
uapi_systick_get_us(void)106 uint64_t uapi_systick_get_us(void)
107 {
108     return convert_count_2_us(uapi_systick_get_count());
109 }
110 
uapi_systick_delay_count(uint64_t c_delay)111 errcode_t uapi_systick_delay_count(uint64_t c_delay)
112 {
113     if (unlikely(!g_systick_hw_inited)) {
114         return ERRCODE_SYSTICK_NOT_INIT;
115     }
116 
117     uint64_t current_ticks;
118     uint64_t origin_ticks;
119 
120     origin_ticks = uapi_systick_get_count();
121     for (;;) {
122         current_ticks = uapi_systick_get_count();
123         if ((current_ticks - origin_ticks) >= c_delay) {
124             break;
125         }
126     }
127     return ERRCODE_SUCC;
128 }
129 
uapi_systick_delay_s(uint32_t s_delay)130 errcode_t uapi_systick_delay_s(uint32_t s_delay)
131 {
132     if (unlikely(!g_systick_hw_inited)) {
133         return ERRCODE_SYSTICK_NOT_INIT;
134     }
135 
136     uapi_systick_delay_count((uint64_t)convert_s_2_count((uint64_t)s_delay));
137 
138     return ERRCODE_SUCC;
139 }
140 
uapi_systick_delay_ms(uint32_t m_delay)141 errcode_t uapi_systick_delay_ms(uint32_t m_delay)
142 {
143     if (unlikely(!g_systick_hw_inited)) {
144         return ERRCODE_SYSTICK_NOT_INIT;
145     }
146 
147     uapi_systick_delay_count((uint64_t)convert_ms_2_count((uint64_t)m_delay));
148 
149     return ERRCODE_SUCC;
150 }
151 
uapi_systick_delay_us(uint32_t u_delay)152 errcode_t uapi_systick_delay_us(uint32_t u_delay)
153 {
154     if (unlikely(!g_systick_hw_inited)) {
155         return ERRCODE_SYSTICK_NOT_INIT;
156     }
157 
158     uapi_systick_delay_count((uint64_t)convert_us_2_count((uint64_t)u_delay));
159     return ERRCODE_SUCC;
160 }
161 
162 #if defined(CONFIG_SYSTICK_SUPPORT_LPM)
uapi_systick_suspend(uintptr_t arg)163 errcode_t uapi_systick_suspend(uintptr_t arg)
164 {
165     uint64_t sleep_compensation_count = uapi_systick_get_count();
166     uint32_t irq_sts = osal_irq_lock();
167     g_systick_sleep_suspend_current_count = sleep_compensation_count;
168     osal_irq_restore(irq_sts);
169 
170     if ((uint64_t *)arg != NULL) {
171         *(uint64_t *)arg = sleep_compensation_count;
172     }
173     return ERRCODE_SUCC;
174 }
175 
uapi_systick_resume(uintptr_t arg)176 errcode_t uapi_systick_resume(uintptr_t arg)
177 {
178     errcode_t ret;
179     uint32_t irq_sts;
180     uint64_t sleep_compensation_count = *(uint64_t *)arg;
181     uapi_systick_deinit();
182     uapi_systick_init();
183     ret = uapi_systick_count_clear();
184     if (ret != ERRCODE_SUCC) {
185         return ret;
186     }
187 
188     irq_sts = osal_irq_lock();
189     g_systick_sleep_compensation_count = g_systick_sleep_suspend_current_count + sleep_compensation_count;
190     osal_irq_restore(irq_sts);
191 
192     return ERRCODE_SUCC;
193 }
194 #endif  /* CONFIG_SYSTICK_SUPPORT_LPM */