• 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 rtc driver source \n
16  *
17  * History: \n
18  * 2023-03-06, Create file. \n
19  */
20 #include <stdbool.h>
21 #include <limits.h>
22 #include "securec.h"
23 #include "common_def.h"
24 #include "interrupt/osal_interrupt.h"
25 #include "tcxo.h"
26 #include "rtc_porting.h"
27 #include "rtc.h"
28 
29 #ifndef UINT64_MAX
30 #define UINT64_MAX (0xFFFFFFFFFFFFFFFFUL)
31 #endif
32 
33 #if defined(CONFIG_RTC_USING_OLD_VERSION)
34 #define RTC_OLD_VERSION_LOAD_COUNT_MASK (uint64_t)0x0F
35 #endif
36 
37 #ifdef CONFIG_RTC_MAX_RTCS_NUM
38 #ifndef CONFIG_RTC_MAX_RTCS_NUM_0
39 #define CONFIG_RTC_MAX_RTCS_NUM_0 CONFIG_RTC_MAX_RTCS_NUM
40 #endif
41 #ifndef CONFIG_RTC_MAX_RTCS_NUM_1
42 #define CONFIG_RTC_MAX_RTCS_NUM_1 CONFIG_RTC_MAX_RTCS_NUM
43 #endif
44 #ifndef CONFIG_RTC_MAX_RTCS_NUM_2
45 #define CONFIG_RTC_MAX_RTCS_NUM_2 CONFIG_RTC_MAX_RTCS_NUM
46 #endif
47 #ifndef CONFIG_RTC_MAX_RTCS_NUM_3
48 #define CONFIG_RTC_MAX_RTCS_NUM_3 CONFIG_RTC_MAX_RTCS_NUM
49 #endif
50 #ifndef CONFIG_RTC_MAX_RTCS_NUM_EXTRA
51 #define CONFIG_RTC_MAX_RTCS_NUM_EXTRA CONFIG_RTC_MAX_RTCS_NUM
52 #endif
53 #endif
54 
55 typedef enum rtc_flag {
56     RTC_FLAG_NORMAL,
57     RTC_FLAG_PERMANENT
58 } rtc_flag_t;
59 
60 typedef struct rtc_info {
61     rtc_handle_t        key;
62     rtc_index_t         index;
63     bool                enable;
64     bool                is_run;
65     rtc_flag_t          flag;
66     uint64_t            cycle;
67     rtc_callback_t      callback;
68     uintptr_t           data;
69 } rtc_info_t;
70 
71 typedef struct soft_rtc_cfg {
72     uintptr_t   rtc_addr;
73     uint8_t     rtc_num;
74 } soft_rtc_cfg_t;
75 
76 #define CUR_MAX_HARDWARE_RTC_NUM 4
77 #define RTC_SIZE_0 0
78 #define RTC_SIZE_1 1
79 #define RTC_SIZE_2 2
80 #define RTC_SIZE_3 3
81 #define RTC_SIZE_4 4
82 
83 #if defined(CONFIG_RTC_MAX_NUM) && (CONFIG_RTC_MAX_NUM > RTC_SIZE_0)
84 static rtc_info_t g_rtclist_0[CONFIG_RTC_MAX_RTCS_NUM_0];
85 #endif
86 #if defined(CONFIG_RTC_MAX_NUM) && (CONFIG_RTC_MAX_NUM > RTC_SIZE_1)
87 static rtc_info_t g_rtclist_1[CONFIG_RTC_MAX_RTCS_NUM_1];
88 #endif
89 #if defined(CONFIG_RTC_MAX_NUM) && (CONFIG_RTC_MAX_NUM > RTC_SIZE_2)
90 static rtc_info_t g_rtclist_2[CONFIG_RTC_MAX_RTCS_NUM_2];
91 #endif
92 #if defined(CONFIG_RTC_MAX_NUM) && (CONFIG_RTC_MAX_NUM > RTC_SIZE_3)
93 static rtc_info_t g_rtclist_3[CONFIG_RTC_MAX_RTCS_NUM_3];
94 #endif
95 #if defined(CONFIG_RTC_MAX_NUM) && (CONFIG_RTC_MAX_NUM > RTC_SIZE_4)
96 static rtc_info_t g_rtclist_extra[CONFIG_RTC_MAX_NUM - CUR_MAX_HARDWARE_RTC_NUM][CONFIG_RTC_MAX_RTCS_NUM_EXTRA];
97 #endif
98 typedef struct rtcs_manager {
99     uint64_t            last_rtc_load_cycle;
100     rtc_info_t         *rtcs;
101     uint32_t            rtc_irq_id;
102     uint16_t            rtc_int_priority;
103     bool                in_rtc_irq;
104     uint8_t             soft_rtc_num;
105 #if defined(CONFIG_RTC_USING_OLD_VERSION)
106     int32_t             rtc_load_cycle_deviation;
107 #endif
108 } rtcs_manager_t;
109 
110 static bool g_rtc_inited = false;
111 static bool g_rtc_adapted[CONFIG_RTC_MAX_NUM];
112 rtcs_manager_t g_rtcs_manager[CONFIG_RTC_MAX_NUM] = { 0 };
113 
114 
115 /* 计算对齐后的cycle和偏差值 */
rtc_get_cycle_with_mask(rtc_index_t index,uint64_t cycle,int32_t * cycle_deviation)116 STATIC uint64_t rtc_get_cycle_with_mask(rtc_index_t index, uint64_t cycle, int32_t *cycle_deviation)
117 {
118 #if defined(CONFIG_RTC_USING_OLD_VERSION)
119     /* 内部函数, 不进行空指针检查 */
120     int32_t rtc_load_cycle_deviation = g_rtcs_manager[index].rtc_load_cycle_deviation;
121 
122     /* cycle值小于等于0xF, 或当前累积偏差值不到0xF时, cycle向上对齐到0xF */
123     if (cycle <= RTC_OLD_VERSION_LOAD_COUNT_MASK
124         || rtc_load_cycle_deviation <= (int32_t)RTC_OLD_VERSION_LOAD_COUNT_MASK) {
125         *cycle_deviation =
126             (int32_t)RTC_OLD_VERSION_LOAD_COUNT_MASK - (int32_t)(cycle & RTC_OLD_VERSION_LOAD_COUNT_MASK);
127         return (cycle | RTC_OLD_VERSION_LOAD_COUNT_MASK);
128     }
129 
130     /* 当前累积偏差值超过0xF时, cycle向下对齐到(0xF - 0x10) */
131     *cycle_deviation = -1 - (int32_t)(cycle & RTC_OLD_VERSION_LOAD_COUNT_MASK);
132     return (cycle | RTC_OLD_VERSION_LOAD_COUNT_MASK) - (RTC_OLD_VERSION_LOAD_COUNT_MASK + 1);
133 #else
134     unused(index);
135     unused(cycle_deviation);
136     return cycle;
137 #endif
138 }
139 
140 /* load对齐后的cycle和偏差值 */
rtc_load_cycle_with_mask(rtc_index_t index,uint64_t cycle_with_mask,int32_t cycle_deviation)141 STATIC void rtc_load_cycle_with_mask(rtc_index_t index, uint64_t cycle_with_mask, int32_t cycle_deviation)
142 {
143 #if defined(CONFIG_RTC_USING_OLD_VERSION)
144     g_rtcs_manager[index].rtc_load_cycle_deviation += cycle_deviation;
145 #else
146     unused(index);
147     unused(cycle_deviation);
148 #endif
149     hal_rtc_config_load(index, cycle_with_mask);
150 }
151 
152 /* Reduces the rtc left for all the rtcs by rtc us amount */
rtc_update_rtcs_rtc(rtc_index_t index,uint64_t update_amount_cycle)153 STATIC bool rtc_update_rtcs_rtc(rtc_index_t index, uint64_t update_amount_cycle)
154 {
155     bool has_new_rtc = false;
156     uint32_t irq_sts = osal_irq_lock();
157     uint8_t soft_rtc_num = g_rtcs_manager[index].soft_rtc_num;
158     for (uint32_t i = 0; i < soft_rtc_num; i++) {
159         if (g_rtcs_manager[index].rtcs[i].cycle <= update_amount_cycle) {
160             g_rtcs_manager[index].rtcs[i].cycle = 0;
161             if (g_rtcs_manager[index].rtcs[i].is_run == true) {
162                 has_new_rtc = true;
163             }
164         } else {
165             g_rtcs_manager[index].rtcs[i].cycle -= update_amount_cycle;
166         }
167     }
168     osal_irq_restore(irq_sts);
169     return has_new_rtc;
170 }
171 
172 /*
173  * Loops through the rtcs to see if any need to be processed
174  */
rtc_process_rtcs(rtc_index_t index)175 STATIC bool rtc_process_rtcs(rtc_index_t index)
176 {
177     bool re_run = false;
178     uint64_t start_rtc = uapi_tcxo_get_count();
179     uint8_t soft_rtc_num = g_rtcs_manager[index].soft_rtc_num;
180     for (uint32_t i = 0; i < soft_rtc_num; i++) {
181         if (g_rtcs_manager[index].rtcs[i].enable &&
182             g_rtcs_manager[index].rtcs[i].cycle == 0 &&
183             g_rtcs_manager[index].rtcs[i].is_run) {
184             g_rtcs_manager[index].rtcs[i].is_run = false;
185             if (g_rtcs_manager[index].rtcs[i].callback) {
186                 g_rtcs_manager[index].rtcs[i].callback(g_rtcs_manager[index].rtcs[i].data);
187             }
188             re_run = true;
189         }
190     }
191 
192     if (re_run) {
193         uint64_t end_rtc = uapi_tcxo_get_count();
194         uint64_t diff = end_rtc - start_rtc;
195         uint64_t cycle = 0;
196         cycle = rtc_porting_compensat_by_tcxo(diff);
197         re_run = rtc_update_rtcs_rtc(index, cycle);
198     }
199 
200     return re_run;
201 }
202 
203 /*
204  * Gets the index of the next rtc to expire
205  */
rtc_get_next_rtc(rtc_index_t index)206 STATIC uint32_t rtc_get_next_rtc(rtc_index_t index)
207 {
208     uint64_t shortest_rtc_found = UINT64_MAX;
209     uint8_t soft_rtc_num = g_rtcs_manager[index].soft_rtc_num;
210     uint32_t rtc_found = soft_rtc_num;
211     for (uint8_t i = 0; i < soft_rtc_num; i++) {
212         if (g_rtcs_manager[index].rtcs[i].enable &&
213             g_rtcs_manager[index].rtcs[i].cycle <= shortest_rtc_found &&
214             g_rtcs_manager[index].rtcs[i].is_run) {
215             shortest_rtc_found = g_rtcs_manager[index].rtcs[i].cycle;
216             rtc_found = i;
217         }
218     }
219     return rtc_found;
220 }
221 
222 /*
223  * Gets the rtc in us till the next interrupt, MAX_UINT32 indicates that no rtc is set
224  */
rtc_get_rtc_till_interrupt(rtc_index_t index)225 STATIC uint64_t rtc_get_rtc_till_interrupt(rtc_index_t index)
226 {
227     uint64_t current_value = hal_rtc_get_current_value(index);
228     if (current_value != 0) {
229         return current_value;
230     }
231 
232     uint32_t next_rtc = rtc_get_next_rtc(index);
233     if (next_rtc >= g_rtcs_manager[index].soft_rtc_num) {
234         return UINT64_MAX;
235     }
236 
237     uint64_t cycle_with_mask;
238     int32_t cycle_deviation = 0;
239     cycle_with_mask = rtc_get_cycle_with_mask(index, g_rtcs_manager[index].rtcs[next_rtc].cycle, &cycle_deviation);
240     if (g_rtcs_manager[index].in_rtc_irq) {
241         return cycle_with_mask;
242     }
243 
244     hal_rtc_stop(index);
245     rtc_load_cycle_with_mask(index, cycle_with_mask, cycle_deviation);
246     hal_rtc_start(index);
247     return cycle_with_mask;
248 }
249 
250 /*
251  * Searches through the rtcs to find the one with the lowest callback rtc
252  */
rtc_set_next_rtc_interrupt(rtc_index_t index)253 STATIC void rtc_set_next_rtc_interrupt(rtc_index_t index)
254 {
255     uint32_t irq_sts = osal_irq_lock();
256     hal_rtc_stop(index);
257     uint32_t rtc_found = rtc_get_next_rtc(index);
258     if (rtc_found < g_rtcs_manager[index].soft_rtc_num) {
259         uint64_t cycle_with_mask;
260         int32_t cycle_deviation = 0;
261         cycle_with_mask =
262             rtc_get_cycle_with_mask(index, g_rtcs_manager[index].rtcs[rtc_found].cycle, &cycle_deviation);
263         rtc_load_cycle_with_mask(index, cycle_with_mask, cycle_deviation);
264         hal_rtc_start(index);
265         g_rtcs_manager[index].last_rtc_load_cycle = cycle_with_mask;
266     }
267     osal_irq_restore(irq_sts);
268 }
269 
rtc_int_callback(rtc_index_t index)270 STATIC void rtc_int_callback(rtc_index_t index)
271 {
272     uint32_t irq_sts = osal_irq_lock();
273     g_rtcs_manager[index].in_rtc_irq = true;
274     rtc_update_rtcs_rtc(index, g_rtcs_manager[index].last_rtc_load_cycle);
275     g_rtcs_manager[index].last_rtc_load_cycle = 0;
276     osal_irq_restore(irq_sts);
277 
278     while (rtc_process_rtcs(index)) {
279     }
280 
281     rtc_set_next_rtc_interrupt(index);
282     g_rtcs_manager[index].in_rtc_irq = false;
283 }
284 
soft_rtc_list_cfg_get(uint32_t index,soft_rtc_cfg_t * rtc_info)285 STATIC errcode_t soft_rtc_list_cfg_get(uint32_t index, soft_rtc_cfg_t *rtc_info)
286 {
287     switch (index) {
288 #if defined(CONFIG_RTC_MAX_NUM) && (CONFIG_RTC_MAX_NUM > RTC_SIZE_0)
289         case RTC_SIZE_0:
290             rtc_info->rtc_num = CONFIG_RTC_MAX_RTCS_NUM_0;
291             rtc_info->rtc_addr = (uintptr_t)g_rtclist_0;
292             break;
293 #endif
294 #if defined(CONFIG_RTC_MAX_NUM) && (CONFIG_RTC_MAX_NUM > RTC_SIZE_1)
295         case RTC_SIZE_1:
296             rtc_info->rtc_num = CONFIG_RTC_MAX_RTCS_NUM_1;
297             rtc_info->rtc_addr = (uintptr_t)g_rtclist_1;
298             break;
299 #endif
300 #if defined(CONFIG_RTC_MAX_NUM) && (CONFIG_RTC_MAX_NUM > RTC_SIZE_2)
301         case RTC_SIZE_2:
302             rtc_info->rtc_num = CONFIG_RTC_MAX_RTCS_NUM_2;
303             rtc_info->rtc_addr = (uintptr_t)g_rtclist_2;
304             break;
305 #endif
306 #if defined(CONFIG_RTC_MAX_NUM) && (CONFIG_RTC_MAX_NUM > RTC_SIZE_3)
307         case RTC_SIZE_3:
308             rtc_info->rtc_num = CONFIG_RTC_MAX_RTCS_NUM_3;
309             rtc_info->rtc_addr = (uintptr_t)g_rtclist_3;
310             break;
311 #endif
312         default:
313 #if defined(CONFIG_RTC_MAX_NUM) && (CONFIG_RTC_MAX_NUM > RTC_SIZE_4)
314             rtc_info->rtc_num = CONFIG_RTC_MAX_RTCS_NUM_EXTRA;
315             rtc_info->rtc_addr = (uintptr_t)&g_rtclist_extra[index - CUR_MAX_HARDWARE_RTC_NUM];
316 #endif
317             break;
318     }
319     if (memset_s((uint8_t *)rtc_info->rtc_addr, sizeof(rtc_info_t) * rtc_info->rtc_num, 0,
320         sizeof(rtc_info_t) * rtc_info->rtc_num) != EOK) {
321         return ERRCODE_MEMSET;
322     }
323     return ERRCODE_SUCC;
324 }
325 
uapi_rtc_init(void)326 errcode_t uapi_rtc_init(void)
327 {
328     uint32_t irq_sts = osal_irq_lock();
329     if (unlikely(g_rtc_inited)) {
330         osal_irq_restore(irq_sts);
331         return ERRCODE_SUCC;
332     }
333 
334     if (unlikely(memset_s(&g_rtcs_manager, sizeof(g_rtcs_manager), 0, sizeof(g_rtcs_manager)) != EOK)) {
335         osal_irq_restore(irq_sts);
336         return ERRCODE_MEMSET;
337     }
338 
339     for (uint32_t i = 0; i < CONFIG_RTC_MAX_NUM; i++) {
340         soft_rtc_cfg_t rtc_info;
341         uint32_t ret;
342         g_rtc_adapted[i] = false;
343         ret = soft_rtc_list_cfg_get(i, &rtc_info);
344         if (unlikely(ret != ERRCODE_SUCC)) {
345             osal_irq_restore(irq_sts);
346             return ret;
347         }
348         g_rtcs_manager[i].soft_rtc_num = rtc_info.rtc_num;
349         g_rtcs_manager[i].rtcs = (rtc_info_t *)rtc_info.rtc_addr;
350     }
351 
352     g_rtc_inited = true;
353     osal_irq_restore(irq_sts);
354     return ERRCODE_SUCC;
355 }
356 
uapi_rtc_adapter(rtc_index_t index,uint32_t int_id,uint16_t int_priority)357 errcode_t uapi_rtc_adapter(rtc_index_t index, uint32_t int_id, uint16_t int_priority)
358 {
359     if (unlikely(index >= RTC_MAX_NUM)) {
360         return ERRCODE_INVALID_PARAM;
361     }
362 
363     uint32_t irq_sts = osal_irq_lock();
364     if (unlikely(g_rtc_inited == 0)) {
365         osal_irq_restore(irq_sts);
366         return ERRCODE_RTC_NOT_INITED;
367     }
368 
369     if (unlikely(g_rtc_adapted[index] != 0)) {
370         osal_irq_restore(irq_sts);
371         return ERRCODE_SUCC;
372     }
373 
374     errcode_t ret = hal_rtc_init(index, rtc_int_callback);
375     if (ret != ERRCODE_SUCC) {
376         osal_irq_restore(irq_sts);
377         return ret;
378     }
379 
380     rtc_port_register_irq(index, int_id, int_priority);
381 
382     g_rtcs_manager[index].rtc_irq_id = int_id;
383     g_rtcs_manager[index].rtc_int_priority = int_priority;
384 
385     g_rtc_adapted[index] = true;
386     osal_irq_restore(irq_sts);
387 
388     return ERRCODE_SUCC;
389 }
390 
uapi_rtc_deinit(void)391 errcode_t uapi_rtc_deinit(void)
392 {
393     uint32_t irq_sts = osal_irq_lock();
394     if (unlikely(!g_rtc_inited)) {
395         osal_irq_restore(irq_sts);
396         return ERRCODE_SUCC;
397     }
398 
399     for (uint32_t i = 0; i < CONFIG_RTC_MAX_NUM; i++) {
400         if (g_rtc_adapted[i]) {
401             hal_rtc_stop(i);
402             rtc_port_unregister_irq(i, g_rtcs_manager[i].rtc_irq_id);
403         }
404     }
405 
406     if (unlikely(memset_s(&g_rtcs_manager, sizeof(g_rtcs_manager), 0, sizeof(g_rtcs_manager)) != EOK)) {
407         osal_irq_restore(irq_sts);
408         return ERRCODE_MEMSET;
409     }
410 
411     for (uint32_t i = 0; i < CONFIG_RTC_MAX_NUM; i++) {
412         if (g_rtc_adapted[i]) {
413             hal_rtc_deinit(i);
414         }
415     }
416 
417     g_rtc_inited = false;
418     for (uint32_t i = 0; i < CONFIG_RTC_MAX_NUM; i++) {
419         g_rtc_adapted[i] = false;
420     }
421     osal_irq_restore(irq_sts);
422     return ERRCODE_SUCC;
423 }
424 
uapi_rtc_create(rtc_index_t index,rtc_handle_t * rtc)425 errcode_t uapi_rtc_create(rtc_index_t index, rtc_handle_t *rtc)
426 {
427     if (unlikely(index >= RTC_MAX_NUM || rtc == NULL)) {
428         return ERRCODE_INVALID_PARAM;
429     }
430 
431     uint32_t irq_sts = osal_irq_lock();
432     for (uint32_t i = 0; i < g_rtcs_manager[index].soft_rtc_num; i++) {
433         if (g_rtcs_manager[index].rtcs[i].enable == false) {
434             g_rtcs_manager[index].rtcs[i].enable = true;
435             g_rtcs_manager[index].rtcs[i].is_run = false;
436             g_rtcs_manager[index].rtcs[i].index = index;
437             g_rtcs_manager[index].rtcs[i].key = &g_rtcs_manager[index].rtcs[i];
438 
439             *rtc = g_rtcs_manager[index].rtcs[i].key;
440             osal_irq_restore(irq_sts);
441             return ERRCODE_SUCC;
442         }
443     }
444 
445     *rtc = NULL;
446     osal_irq_restore(irq_sts);
447     return ERRCODE_RTC_NO_ENOUGH;
448 }
449 
uapi_rtc_delete(rtc_handle_t rtc)450 errcode_t uapi_rtc_delete(rtc_handle_t rtc)
451 {
452     if (unlikely(rtc == NULL)) {
453         return ERRCODE_INVALID_PARAM;
454     }
455 
456     rtc_info_t *rtc_info = (rtc_info_t *)rtc;
457     uint32_t irq_sts = osal_irq_lock();
458     rtc_info->enable = false;
459     osal_irq_restore(irq_sts);
460     return ERRCODE_SUCC;
461 }
462 
uapi_rtc_get_max_ms(void)463 uint32_t uapi_rtc_get_max_ms(void)
464 {
465     return RTC_MAX_MS;
466 }
467 
uapi_rtc_start(rtc_handle_t rtc,uint32_t rtc_ms,rtc_callback_t callback,uintptr_t data)468 errcode_t uapi_rtc_start(rtc_handle_t rtc, uint32_t rtc_ms, rtc_callback_t callback, uintptr_t data)
469 {
470     rtc_index_t index;
471     uint32_t rtc_max_ms = RTC_MAX_MS;
472     if (unlikely(rtc == NULL) || unlikely(callback == NULL) || unlikely(rtc_ms == 0) || unlikely(rtc_ms > rtc_max_ms)) {
473         return ERRCODE_INVALID_PARAM;
474     }
475 
476     rtc_info_t *rtc_info = (rtc_info_t *)rtc;
477     uint32_t irq_sts = osal_irq_lock();
478     if (unlikely(rtc_info->enable == false)) {
479         osal_irq_restore(irq_sts);
480         return ERRCODE_RTC_NOT_CREATED;
481     }
482 
483     uint64_t cycle;
484     int32_t cycle_deviation = 0;
485     index = rtc_info->index;
486     cycle = rtc_get_cycle_with_mask(index, rtc_porting_ms_2_cycle(rtc_ms), &cycle_deviation);
487     rtc_info->cycle = cycle;
488     rtc_info->callback = callback;
489     rtc_info->data = data;
490 
491     uint64_t remain_rtc_cycle = rtc_get_rtc_till_interrupt(index);
492     if (cycle <= remain_rtc_cycle) {
493         if (remain_rtc_cycle != UINT64_MAX && g_rtcs_manager[index].last_rtc_load_cycle != 0) {
494             rtc_update_rtcs_rtc(index, g_rtcs_manager[index].last_rtc_load_cycle - remain_rtc_cycle);
495         }
496         g_rtcs_manager[index].last_rtc_load_cycle = cycle;
497         hal_rtc_stop(index);
498         rtc_load_cycle_with_mask(index, cycle, cycle_deviation);
499         hal_rtc_start(index);
500     } else {
501         rtc_info->cycle += (g_rtcs_manager[index].last_rtc_load_cycle - remain_rtc_cycle);
502     }
503 
504     rtc_info->is_run = true;
505     osal_irq_restore(irq_sts);
506     return ERRCODE_SUCC;
507 }
508 
uapi_rtc_stop(rtc_handle_t rtc)509 errcode_t uapi_rtc_stop(rtc_handle_t rtc)
510 {
511     if (unlikely(rtc == NULL)) {
512         return ERRCODE_INVALID_PARAM;
513     }
514 
515     rtc_info_t *rtc_info = (rtc_info_t *)rtc;
516 
517     uint32_t irq_sts = osal_irq_lock();
518     if (unlikely(rtc_info->enable == false)) {
519         osal_irq_restore(irq_sts);
520         return ERRCODE_RTC_NOT_CREATED;
521     }
522 
523     if (unlikely(rtc_info->is_run == false)) {
524         osal_irq_restore(irq_sts);
525         return ERRCODE_SUCC;
526     }
527 
528     rtc_info->is_run = false;
529     rtc_info->cycle = 0;
530     rtc_info->callback = NULL;
531     rtc_info->data = 0;
532 
533     /* 检查当前是否还有在运行的定时器, 若没有定时器则停止硬件计时 */
534     rtc_index_t index = rtc_info->index;
535     uint32_t rtc_found = rtc_get_next_rtc(index);
536     if (rtc_found >= g_rtcs_manager[index].soft_rtc_num) {
537         hal_rtc_stop(index);
538     }
539     osal_irq_restore(irq_sts);
540     return ERRCODE_SUCC;
541 }
542 
uapi_rtc_int_cnt_record_get(rtc_index_t index)543 uint32_t uapi_rtc_int_cnt_record_get(rtc_index_t index)
544 {
545     if (unlikely(index >= RTC_MAX_NUM)) {
546         return 0;
547     }
548 
549     uint32_t int_cnt_record = hal_rtc_get_int_cnt_record();
550     return int_cnt_record;
551 }
552 
uapi_rtc_get_current_time_count(rtc_index_t index,uint64_t * current_time_count)553 errcode_t uapi_rtc_get_current_time_count(rtc_index_t index, uint64_t *current_time_count)
554 {
555     if (unlikely(index >= RTC_MAX_NUM || current_time_count == NULL)) {
556         return ERRCODE_INVALID_PARAM;
557     }
558 
559     uint32_t irq_sts = osal_irq_lock();
560     uint64_t current_value = hal_rtc_get_current_value(index);
561     osal_irq_restore(irq_sts);
562     *current_time_count = current_value;
563     return ERRCODE_SUCC;
564 }
565 
uapi_rtc_get_current_time_us(rtc_index_t index,uint32_t * current_time_us)566 errcode_t uapi_rtc_get_current_time_us(rtc_index_t index, uint32_t *current_time_us)
567 {
568     if (unlikely(index >= RTC_MAX_NUM || current_time_us == NULL)) {
569         return ERRCODE_INVALID_PARAM;
570     }
571 
572     uint32_t irq_sts = osal_irq_lock();
573     uint64_t current_value = hal_rtc_get_current_value(index);
574     osal_irq_restore(irq_sts);
575     *current_time_us = rtc_porting_cycle_2_us(current_value);
576     return ERRCODE_SUCC;
577 }
578 
uapi_rtc_start_hw_rtc(rtc_index_t index,uint64_t rtc_ms)579 errcode_t uapi_rtc_start_hw_rtc(rtc_index_t index, uint64_t rtc_ms)
580 {
581     if (unlikely(index >= RTC_MAX_NUM)) {
582         return ERRCODE_INVALID_PARAM;
583     }
584 
585     uint64_t rtc_max_ms = RTC_HW_MAX_MS;
586     if (unlikely(rtc_ms == 0) || unlikely(rtc_ms > rtc_max_ms)) {
587         return ERRCODE_INVALID_PARAM;
588     }
589 
590     uint32_t irq_sts = osal_irq_lock();
591     hal_rtc_stop(index);
592 #if defined(CONFIG_RTC_USING_OLD_VERSION)
593     hal_rtc_config_load(index, rtc_hw_porting_ms_2_cycle(rtc_ms) | RTC_OLD_VERSION_LOAD_COUNT_MASK);
594 #else
595     hal_rtc_config_load(index, rtc_hw_porting_ms_2_cycle(rtc_ms));
596 #endif
597     hal_rtc_start(index);
598     osal_irq_restore(irq_sts);
599 
600     return ERRCODE_SUCC;
601 }
602 
uapi_rtc_stop_hw_rtc(rtc_index_t index)603 errcode_t uapi_rtc_stop_hw_rtc(rtc_index_t index)
604 {
605     if (unlikely(index >= RTC_MAX_NUM)) {
606         return ERRCODE_INVALID_PARAM;
607     }
608 
609     uint32_t irq_sts = osal_irq_lock();
610     hal_rtc_stop(index);
611     osal_irq_restore(irq_sts);
612 
613     return ERRCODE_SUCC;
614 }
615 
616 #if defined(CONFIG_RTC_SUPPORT_LPM)
uapi_rtc_get_latest_timeout(void)617 uint32_t uapi_rtc_get_latest_timeout(void)
618 {
619     uint64_t nxt_count = UINT64_MAX;
620     uint64_t cur_count = UINT64_MAX;
621     for (uint32_t index = 0; index < RTC_MAX_NUM; index++) {
622         if (g_rtc_adapted[index] == false) {
623             continue;
624         }
625         cur_count = hal_rtc_get_current_value(index);
626         /* 值为0分为两种情况:timer已全部过期或在功耗调度中到期,可通过中断状态区分。前者视为超时时间为U64最大值 */
627         if (cur_count == 0 && hal_rtc_get_int_status(index) == 0) {
628             cur_count = UINT64_MAX;
629         }
630         nxt_count = cur_count < nxt_count ? cur_count : nxt_count;
631     }
632     uint32_t nxt_ms = rtc_porting_cycle_2_ms(nxt_count);
633     return nxt_ms;
634 }
635 
uapi_rtc_suspend(uintptr_t val)636 errcode_t uapi_rtc_suspend(uintptr_t val)
637 {
638     unused(val);
639     uint32_t int_sts = osal_irq_lock();
640     for (uint32_t index = 0; index < RTC_MAX_NUM; index++) {
641         if (g_rtc_adapted[index] == false) {
642             continue;
643         }
644         rtc_update_rtcs_rtc(index,
645             g_rtcs_manager[index].last_rtc_load_cycle - hal_rtc_get_current_value(index));
646         g_rtcs_manager[index].last_rtc_load_cycle = 0;
647         rtc_set_next_rtc_interrupt(index);
648     }
649     osal_irq_restore(int_sts);
650     return ERRCODE_SUCC;
651 }
652 
uapi_rtc_resume(uintptr_t val)653 errcode_t uapi_rtc_resume(uintptr_t val)
654 {
655     uint32_t int_sts = osal_irq_lock();
656     uint64_t compansation_count = *(uint64_t *)val;
657     for (uint32_t index = 0; index < RTC_MAX_NUM; index++) {
658         if (g_rtc_adapted[index] == false) {
659             continue;
660         }
661         g_rtcs_manager[index].last_rtc_load_cycle = compansation_count;
662         hal_rtc_stop(index);
663         hal_rtc_config_load(index, rtc_porting_ms_2_cycle(1));
664         hal_rtc_start(index);
665     }
666     osal_irq_restore(int_sts);
667     return ERRCODE_SUCC;
668 }
669 #endif /* CONFIG_RTC_SUPPORT_LPM */