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