1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3 * Copyright (c) 2020-2021 Rockchip Electronics Co., Ltd.
4 */
5
6 #include "hal_base.h"
7
8 #ifdef HAL_TIMER_MODULE_ENABLED
9
10 /** @addtogroup RK_HAL_Driver
11 * @{
12 */
13
14 /** @addtogroup TIMER
15 * @{
16 */
17
18 /** @defgroup TIMER_How_To_Use How To Use
19 * @{
20
21 The TIMER driver can be used as follows:
22
23 - IT mode: Resgister TIMER handler.
24 - Initialize the TIMER by calling HAL_TIMER_Init():
25 - Set TIMER count by calling HAL_TIMER_SetCount().
26 - Start the TIMER by calling HAL_TIMER_Start() or HAL_TIMER_Start_IT().
27 - Stop the TIMER by calling HAL_TIMER_Stop() or HAL_TIMER_Stop_IT().
28
29 SYS_TIMER
30
31 - SYS_TIMER is a rk timer fixed to serve the delay system. Invoke HAL_TIMER_SysTimerInit() to init.
32
33 @} */
34
35 /** @defgroup TIMER_Private_Definition Private Definition
36 * @{
37 */
38 /********************* Private MACRO Definition ******************************/
39 #define TIMER_CONTROLREG_TIMER_MODE_FREE_RUNNING (0x0U << TIMER_CONTROLREG_TIMER_MODE_SHIFT)
40
41 #define TIMER_CONTROLREG_TIMER_ENABLE_ENABLED (0x1U << TIMER_CONTROLREG_TIMER_ENABLE_SHIFT)
42 #define TIMER_CONTROLREG_TIMER_ENABLE_DISABLED (0x0U << TIMER_CONTROLREG_TIMER_ENABLE_SHIFT)
43
44 #define TIMER_CONTROLREG_TIMER_INT_MASK_UNMASK (0x1U << TIMER_CONTROLREG_TIMER_INT_MASK_SHIFT)
45
46 /********************* Private Structure Definition **************************/
47
48 /********************* Private Variable Definition ***************************/
49
50 /********************* Private Function Definition ***************************/
51
52 /** @} */
53 /********************* Public Function Definition ****************************/
54
55 /** @defgroup TIMER_Exported_Functions_Group4 Init and DeInit Functions
56
57 This section provides functions allowing to init and deinit module as follows:
58
59 * @{
60 */
61
62 /**
63 * @brief Timer init.
64 * @param pReg: Choose TIMER.
65 * @param mode: Choose TIMER mode.
66 * @return HAL_Status.
67 */
HAL_TIMER_Init(struct TIMER_REG * pReg,eTIMER_MODE mode)68 HAL_Status HAL_TIMER_Init(struct TIMER_REG *pReg, eTIMER_MODE mode)
69 {
70 HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
71 #ifdef SYS_TIMER
72 if (pReg == SYS_TIMER) {
73 return HAL_BUSY;
74 }
75 #endif
76
77 WRITE_REG(pReg->CONTROLREG, mode << TIMER_CONTROLREG_TIMER_MODE_SHIFT);
78
79 return HAL_OK;
80 }
81
82 /**
83 * @brief System Timer init.
84 * @return HAL_Status.
85 * @attention this API allow direct use in the HAL layer. SYS_TTIMER is used for delay system.
86 */
HAL_TIMER_SysTimerInit(struct TIMER_REG * pReg)87 HAL_Status HAL_TIMER_SysTimerInit(struct TIMER_REG *pReg)
88 {
89 HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
90
91 if (READ_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_ENABLE_MASK)) {
92 return HAL_OK;
93 }
94
95 WRITE_REG(pReg->CONTROLREG, TIMER_FREE_RUNNING);
96 pReg->LOAD_COUNT[0] = 0xFFFFFFFFU;
97 pReg->LOAD_COUNT[1] = 0xFFFFFFFFU;
98 CLEAR_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_INT_MASK_MASK);
99 SET_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_ENABLE_MASK);
100
101 return HAL_OK;
102 }
103
104 /**
105 * @brief Timer deinit.
106 * @param pReg: Choose TIMER.
107 * @return HAL_Status.
108 */
HAL_TIMER_DeInit(struct TIMER_REG * pReg)109 HAL_Status HAL_TIMER_DeInit(struct TIMER_REG *pReg)
110 {
111 HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
112 #ifdef SYS_TIMER
113 if (pReg == SYS_TIMER) {
114 return HAL_BUSY;
115 }
116 #endif
117
118 WRITE_REG(pReg->CONTROLREG, 0);
119
120 return HAL_OK;
121 }
122
123 /** @} */
124
125 /** @defgroup TIMER_Exported_Functions_Group5 Other Functions
126 * @{
127 */
128
129 /**
130 * @brief Start TIMER counter.
131 * @param pReg: Choose TIMER.
132 * @return HAL_Status.
133 */
HAL_TIMER_Start(struct TIMER_REG * pReg)134 HAL_Status HAL_TIMER_Start(struct TIMER_REG *pReg)
135 {
136 HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
137 #ifdef SYS_TIMER
138 if (pReg == SYS_TIMER) {
139 return HAL_BUSY;
140 }
141 #endif
142
143 CLEAR_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_INT_MASK_MASK);
144 SET_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_ENABLE_MASK);
145
146 return HAL_OK;
147 }
148
149 /**
150 * @brief Stop TIMER counter.
151 * @param pReg: Choose TIMER.
152 * @return HAL_Status.
153 * Just disable TIMER, and keep TIMER configuration.
154 */
HAL_TIMER_Stop(struct TIMER_REG * pReg)155 HAL_Status HAL_TIMER_Stop(struct TIMER_REG *pReg)
156 {
157 HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
158 #ifdef SYS_TIMER
159 if (pReg == SYS_TIMER) {
160 return HAL_BUSY;
161 }
162 #endif
163
164 CLEAR_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_ENABLE_MASK);
165
166 return HAL_OK;
167 }
168
169 /**
170 * @brief Start TIMER counter in interrupt mode.
171 * @param pReg: Choose TIMER.
172 * @return HAL_Status.
173 */
HAL_TIMER_Start_IT(struct TIMER_REG * pReg)174 HAL_Status HAL_TIMER_Start_IT(struct TIMER_REG *pReg)
175 {
176 HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
177 #ifdef SYS_TIMER
178 if (pReg == SYS_TIMER) {
179 return HAL_BUSY;
180 }
181 #endif
182
183 SET_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_ENABLE_ENABLED | TIMER_CONTROLREG_TIMER_INT_MASK_UNMASK);
184
185 return HAL_OK;
186 }
187
188 /**
189 * @brief Stop TIMER counter in interrupt mode.
190 * @param pReg: Choose TIMER.
191 * @return HAL_Status.
192 * Just disable TIMER, and keep TIMER configuration.
193 */
HAL_TIMER_Stop_IT(struct TIMER_REG * pReg)194 HAL_Status HAL_TIMER_Stop_IT(struct TIMER_REG *pReg)
195 {
196 HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
197 #ifdef SYS_TIMER
198 if (pReg == SYS_TIMER) {
199 return HAL_BUSY;
200 }
201 #endif
202
203 CLEAR_BIT(pReg->CONTROLREG, TIMER_CONTROLREG_TIMER_ENABLE_MASK);
204
205 return HAL_OK;
206 }
207
208 /**
209 * @brief Set TIMER count number.
210 * @param pReg: Choose TIMER.
211 * @param timerCount: TIMER counter loading number.
212 * @return HAL_Status.
213 * Set timer count number.
214 */
HAL_TIMER_SetCount(struct TIMER_REG * pReg,uint64_t timerCount)215 HAL_Status HAL_TIMER_SetCount(struct TIMER_REG *pReg, uint64_t timerCount)
216 {
217 uint64_t loadCount = 0;
218
219 HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
220 #ifdef SYS_TIMER
221 if (pReg == SYS_TIMER) {
222 return HAL_BUSY;
223 }
224 #endif
225
226 loadCount = timerCount;
227 pReg->LOAD_COUNT[0] = (loadCount & 0xffffffff);
228 pReg->LOAD_COUNT[1] = ((loadCount >> 32) & 0xffffffff);
229
230 return HAL_OK;
231 }
232
233 /**
234 * @brief Get TIMER count number.
235 * @param pReg: Choose TIMER.
236 * @return uint64_t: Current conut number.
237 */
238 HAL_SECTION_SRAM_CODE
HAL_TIMER_GetCount(struct TIMER_REG * pReg)239 uint64_t HAL_TIMER_GetCount(struct TIMER_REG *pReg)
240 {
241 uint32_t high, low, temp;
242
243 HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
244
245 do {
246 high = pReg->CURRENT_VALUE[1];
247 low = pReg->CURRENT_VALUE[0];
248 temp = pReg->CURRENT_VALUE[1];
249 } while (high != temp);
250
251 return ((uint64_t)high << 32) | low;
252 }
253
254 /**
255 * @brief Clear TIMER interrupt status.
256 * @param pReg: Choose TIMER.
257 * @return HAL_Status: HAL_OK.
258 */
HAL_TIMER_ClrInt(struct TIMER_REG * pReg)259 HAL_Status HAL_TIMER_ClrInt(struct TIMER_REG *pReg)
260 {
261 uint32_t timeOut = 1000;
262
263 HAL_ASSERT(IS_TIMER_INSTANCE(pReg));
264
265 pReg->INTSTATUS = 0x1;
266 while (pReg->INTSTATUS && timeOut) {
267 timeOut--;
268 }
269
270 if (timeOut == 0) {
271 return HAL_TIMEOUT;
272 } else {
273 return HAL_OK;
274 }
275 }
276
277 /**
278 * @brief TIMER0 interrupt handler.
279 * @return HAL_Status: HAL_OK.
280 * Clear interrupt status.
281 */
HAL_TIMER0_Handler(void)282 __WEAK HAL_Status HAL_TIMER0_Handler(void)
283 {
284 HAL_TIMER_ClrInt(TIMER0);
285
286 return HAL_OK;
287 }
288
289 /**
290 * @brief TIMER1 interrupt handler.
291 * @return HAL_Status: HAL_OK.
292 * Clear interrupt status.
293 */
HAL_TIMER1_Handler(void)294 __WEAK HAL_Status HAL_TIMER1_Handler(void)
295 {
296 HAL_TIMER_ClrInt(TIMER1);
297
298 return HAL_OK;
299 }
300
301 /** @} */
302
303 /** @} */
304
305 /** @} */
306
307 #endif /* HAL_TIMER_MODULE_ENABLED */
308