• 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 V150 HAL timer \n
16  *
17  * History: \n
18  * 2022-12-08, Create file. \n
19  */
20 #include <stdint.h>
21 #include <stdbool.h>
22 #include "common_def.h"
23 #include "hal_timer_v150_regs_op.h"
24 #include "timer_porting.h"
25 #include "hal_timer_v150.h"
26 
27 #define TIMER_COUNT_HIGH_32BIT_RIGHT_SHIFT 32
28 #define TIMER_LOAD_COUNT1_LOCK_VALUE 0x5A5A5A5A
29 #define TIMER_CURRENT_COUNT_LOCK_TIMEOUT 0xFFFF
30 
31 static hal_timer_callback_t g_hal_timer_callback[TIMER_MAX_NUM] = {NULL};
32 
33 static bool const g_hal_timer_width[TIMER_MAX_NUM + 1] = {
34     CONFIG_TIMER_0_WIDTH_64 == 1 ? true : false,
35 #if defined(CONFIG_TIMER_1_WIDTH_64)
36     CONFIG_TIMER_1_WIDTH_64 == 1 ? true : false,
37 #endif  /* CONFIG_TIMER_1_WIDTH_64 */
38 #if defined(CONFIG_TIMER_2_WIDTH_64)
39     CONFIG_TIMER_2_WIDTH_64 == 1 ? true : false,
40 #endif  /* CONFIG_TIMER_2_WIDTH_64 */
41 #if defined(CONFIG_TIMER_3_WIDTH_64)
42     CONFIG_TIMER_3_WIDTH_64 == 1 ? true : false,
43 #endif  /* CONFIG_TIMER_3_WIDTH_64 */
44 #if defined(CONFIG_TIMER_4_WIDTH_64)
45     CONFIG_TIMER_4_WIDTH_64 == 1 ? true : false,
46 #endif  /* CONFIG_TIMER_4_WIDTH_64 */
47 #if defined(CONFIG_TIMER_5_WIDTH_64)
48     CONFIG_TIMER_5_WIDTH_64 == 1 ? true : false,
49 #endif  /* CONFIG_TIMER_5_WIDTH_64 */
50 #if defined(CONFIG_TIMER_6_WIDTH_64)
51     CONFIG_TIMER_6_WIDTH_64 == 1 ? true : false,
52 #endif  /* CONFIG_TIMER_6_WIDTH_64 */
53 #if defined(CONFIG_TIMER_7_WIDTH_64)
54     CONFIG_TIMER_7_WIDTH_64 == 1 ? true : false,
55 #endif  /* CONFIG_TIMER_7_WIDTH_64 */
56     false
57 };
58 
59 #pragma weak hal_timer_init = hal_timer_v150_init
hal_timer_v150_init(timer_index_t index,hal_timer_callback_t callback)60 errcode_t hal_timer_v150_init(timer_index_t index, hal_timer_callback_t callback)
61 {
62     if ((hal_timer_regs_init(index)) != ERRCODE_SUCC) {
63         return ERRCODE_TIMER_INVALID_REG_ADDR;
64     }
65     g_hal_timer_callback[index] = callback;
66     return ERRCODE_SUCC;
67 }
68 
69 #pragma weak hal_timer_deinit = hal_timer_v150_deinit
hal_timer_v150_deinit(timer_index_t index)70 void hal_timer_v150_deinit(timer_index_t index)
71 {
72     g_hal_timer_callback[index] = NULL;
73     hal_timer_regs_deinit(index);
74 }
75 
76 #pragma weak hal_timer_start = hal_timer_v150_start
hal_timer_v150_start(timer_index_t index)77 void hal_timer_v150_start(timer_index_t index)
78 {
79     hal_timer_v150_control_reg_set_enable(index, 1);
80 }
81 
82 #pragma weak hal_timer_stop = hal_timer_v150_stop
hal_timer_v150_stop(timer_index_t index)83 void hal_timer_v150_stop(timer_index_t index)
84 {
85     hal_timer_v150_control_reg_set_enable(index, 0);
86 }
87 
88 #pragma weak hal_timer_config_load = hal_timer_v150_config_load
hal_timer_v150_config_load(timer_index_t index,uint64_t delay_count)89 void hal_timer_v150_config_load(timer_index_t index, uint64_t delay_count)
90 {
91     hal_timer_v150_control_reg_set_mode(index, (uint32_t)TIMER_V150_MODE_ONE_SHOT);
92     hal_timer_v150_set_load_count0(index, (uint32_t)delay_count);
93     if (g_hal_timer_width[index]) {
94         hal_timer_v150_set_load_lock(index, (uint32_t)TIMER_LOAD_COUNT1_LOCK_VALUE);
95         hal_timer_v150_set_load_count1(index, (uint32_t)(delay_count >> TIMER_COUNT_HIGH_32BIT_RIGHT_SHIFT));
96         hal_timer_v150_set_load_lock(index, (uint32_t)0);
97     }
98 }
99 
100 #pragma weak hal_timer_get_current_value = hal_timer_v150_get_current_value
hal_timer_v150_get_current_value(timer_index_t index)101 uint64_t hal_timer_v150_get_current_value(timer_index_t index)
102 {
103     uint64_t count = 0;
104     uint32_t timeout = 0;
105 
106     /*
107      * TIMER_V150 使能信号无效时读取到的当前COUNT值会保持原值不变,
108      * 因此判断enable不为1时认为时钟已到期,返回0。
109      */
110     if (hal_timer_v150_control_reg_get_enable(index) != 1) {
111         return 0;
112     }
113 
114     hal_timer_v150_ctrl_set_cnt_req(index);
115     while (timeout < TIMER_CURRENT_COUNT_LOCK_TIMEOUT) {
116         if (hal_timer_v150_ctrl_get_cnt_lock(index) == 1) {
117             count = (uint64_t)hal_timer_v150_get_current_value0(index);
118             if (g_hal_timer_width[index]) {
119                 count += ((uint64_t)hal_timer_v150_get_current_value1(index) << TIMER_COUNT_HIGH_32BIT_RIGHT_SHIFT);
120             }
121             break;
122         }
123         timeout++;
124     }
125     return count;
126 }
127 
hal_timer_v150_interrupt_clear(timer_index_t index)128 void hal_timer_v150_interrupt_clear(timer_index_t index)
129 {
130     if (index < TIMER_MAX_NUM) {
131         hal_timer_v150_int_clr(index);
132     }
133 }
134 
135 #pragma weak hal_timer_irq_handler = hal_timer_v150_irq_handler
hal_timer_v150_irq_handler(timer_index_t index)136 void hal_timer_v150_irq_handler(timer_index_t index)
137 {
138     /* Clear the interrupt */
139     hal_timer_v150_int_clr(index);
140 
141     if (g_hal_timer_callback[index]) {
142         g_hal_timer_callback[index](index);
143     }
144 }
145