1 // Copyright (C) 2022 Beken Corporation
2 //
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 #pragma once
16
17 #include <soc/soc.h>
18 #include "timer_hw.h"
19 #include "hal_port.h"
20 #include <driver/hal/hal_timer_types.h>
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 #define TIMER_LL_REG_BASE(_timer_unit_id) (SOC_TIMER0_REG_BASE)
27 #define TIMER_LL_GROUP(chan) ((chan) / SOC_TIMER_CHAN_NUM_PER_GROUP)
28 #define TIMER_LL_CHAN(chan) ((chan) % SOC_TIMER_CHAN_NUM_PER_GROUP)
29
30 typedef enum {
31 TIMER_GROUP_CHAN0 = 0,
32 TIMER_GROUP_CHAN1 = 1,
33 TIMRE_GROUP_CHAN2 = 2,
34 } timer_group_chan_t;
35
timer_ll_init(timer_hw_t * hw,uint32_t chan)36 static inline void timer_ll_init(timer_hw_t *hw, uint32_t chan)
37 {
38 #if CONFIG_TIMER_SUPPORT_ID_BITS
39 if ((~CONFIG_TIMER_SUPPORT_ID_BITS) & BIT(chan)) {
40 return;
41 }
42 #endif
43
44 uint32_t group = TIMER_LL_GROUP(chan);
45 uint32_t group_chan = TIMER_LL_CHAN(chan);
46
47 if (TIMER_GROUP_CHAN0 == group_chan) {
48 hw->group[group].ctrl.timer0_en = 0;
49 hw->group[group].ctrl.timer0_int_en = 0;
50 } else if (TIMER_GROUP_CHAN1 == group_chan) {
51 hw->group[group].ctrl.timer1_en = 0;
52 hw->group[group].ctrl.timer1_int_en = 0;
53 } else {
54 hw->group[group].ctrl.timer2_en = 0;
55 hw->group[group].ctrl.timer2_int_en = 0;
56 }
57
58 hw->group[group].read_ctrl.v = 0;
59 hw->group[group].timer_read_value = 0;
60 }
61
timer_ll_set_enable(timer_hw_t * hw,uint32_t group,uint32_t chan,uint32_t value)62 static inline void timer_ll_set_enable(timer_hw_t *hw, uint32_t group, uint32_t chan, uint32_t value)
63 {
64 if (chan == TIMER_GROUP_CHAN0)
65 hw->group[group].ctrl.timer0_en = value;
66 else if (chan == TIMER_GROUP_CHAN1)
67 hw->group[group].ctrl.timer1_en = value;
68 else
69 hw->group[group].ctrl.timer2_en = value;
70 }
71
timer_ll_enable(timer_hw_t * hw,uint32_t chan)72 static inline void timer_ll_enable(timer_hw_t *hw, uint32_t chan)
73 {
74 timer_ll_set_enable(hw, TIMER_LL_GROUP(chan), TIMER_LL_CHAN(chan), 1);
75 }
76
timer_ll_disable(timer_hw_t * hw,uint32_t chan)77 static inline void timer_ll_disable(timer_hw_t *hw, uint32_t chan)
78 {
79 timer_ll_set_enable(hw, TIMER_LL_GROUP(chan), TIMER_LL_CHAN(chan), 0);
80 }
81
timer_ll_get_enable_status(timer_hw_t * hw)82 static inline uint32_t timer_ll_get_enable_status(timer_hw_t *hw)
83 {
84 uint32_t bit_pos = 0;
85 uint32_t status = 0;
86
87 for (int group = 0; group < SOC_TIMER_GROUP_NUM; group++) {
88 status |= hw->group[group].ctrl.timer0_en << (bit_pos++);
89 status |= hw->group[group].ctrl.timer1_en << (bit_pos++);
90 status |= hw->group[group].ctrl.timer2_en << (bit_pos++);
91 }
92
93 return status;
94 }
95
timer_ll_set_interrupt(timer_hw_t * hw,uint32_t group,uint32_t chan,uint32_t value)96 static inline void timer_ll_set_interrupt(timer_hw_t *hw, uint32_t group, uint32_t chan, uint32_t value)
97 {
98 if (chan == TIMER_GROUP_CHAN0)
99 hw->group[group].ctrl.timer0_int_en = value;
100 else if (chan == TIMER_GROUP_CHAN1)
101 hw->group[group].ctrl.timer1_int_en = value;
102 else
103 hw->group[group].ctrl.timer2_int_en = value;
104 }
105
timer_ll_enable_interrupt(timer_hw_t * hw,uint32_t chan)106 static inline void timer_ll_enable_interrupt(timer_hw_t *hw, uint32_t chan)
107 {
108 timer_ll_set_interrupt(hw, TIMER_LL_GROUP(chan), TIMER_LL_CHAN(chan), 1);
109 }
110
timer_ll_disable_interrupt(timer_hw_t * hw,uint32_t chan)111 static inline void timer_ll_disable_interrupt(timer_hw_t *hw, uint32_t chan)
112 {
113 timer_ll_set_interrupt(hw, TIMER_LL_GROUP(chan), TIMER_LL_CHAN(chan), 0);
114 }
115
timer_ll_is_interrupt_triggered(timer_hw_t * hw,uint32_t chan,uint32_t status)116 static inline bool timer_ll_is_interrupt_triggered(timer_hw_t *hw, uint32_t chan, uint32_t status)
117 {
118 return (status & BIT(chan));
119 }
120
timer_ll_set_chan_interrupt_status(timer_hw_t * hw,uint32_t chan,uint32_t value)121 static inline void timer_ll_set_chan_interrupt_status(timer_hw_t *hw, uint32_t chan, uint32_t value)
122 {
123 uint32_t group = TIMER_LL_GROUP(chan);
124 uint32_t group_chan = TIMER_LL_CHAN(chan);
125
126 if (group_chan == TIMER_GROUP_CHAN0)
127 hw->group[group].ctrl.timer0_int_en = value;
128 else if (group_chan == TIMER_GROUP_CHAN1)
129 hw->group[group].ctrl.timer1_int_en = value;
130 else
131 hw->group[group].ctrl.timer2_int_en = value;
132 }
133
timer_ll_get_chan_interrupt_status(timer_hw_t * hw,uint32_t chan)134 static inline uint32_t timer_ll_get_chan_interrupt_status(timer_hw_t *hw, uint32_t chan)
135 {
136 uint32_t group = TIMER_LL_GROUP(chan);
137 uint32_t group_chan = TIMER_LL_CHAN(chan);
138
139 if (TIMER_GROUP_CHAN0 == group_chan)
140 return hw->group[group].ctrl.timer0_int_en;
141 else if (TIMER_GROUP_CHAN1 == group_chan)
142 return hw->group[group].ctrl.timer1_int_en;
143 else
144 return hw->group[group].ctrl.timer2_int_en;
145 }
146
timer_ll_clear_chan_interrupt_status(timer_hw_t * hw,uint32_t chan)147 static inline void timer_ll_clear_chan_interrupt_status(timer_hw_t *hw, uint32_t chan)
148 {
149 BK_DO_WHILE(timer_ll_set_chan_interrupt_status(hw, chan, 1),
150 timer_ll_get_chan_interrupt_status(hw, chan));
151 }
152
timer_ll_get_interrupt_status(timer_hw_t * hw)153 static inline uint32_t timer_ll_get_interrupt_status(timer_hw_t *hw)
154 {
155 uint32_t bit_pos = 0;
156 uint32_t status = 0;
157
158 for (int group = 0; group < SOC_TIMER_GROUP_NUM; group++) {
159 status |= hw->group[group].ctrl.timer0_int_en << (bit_pos++);
160 status |= hw->group[group].ctrl.timer1_int_en << (bit_pos++);
161 status |= hw->group[group].ctrl.timer2_int_en << (bit_pos++);
162 }
163
164 return status;
165 }
166
timer_ll_clear_interrupt_status(timer_hw_t * hw,uint32_t status)167 static inline void timer_ll_clear_interrupt_status(timer_hw_t *hw, uint32_t status)
168 {
169 for (int id = 0; id < SOC_TIMER_CHAN_NUM_PER_UNIT; id++) {
170 if (status & BIT(id)) {
171 timer_ll_clear_chan_interrupt_status(hw, id);
172 }
173 }
174 }
175
timer_ll_set_end_count(timer_hw_t * hw,uint32_t chan,uint32_t timer_cnt)176 static inline void timer_ll_set_end_count(timer_hw_t *hw, uint32_t chan, uint32_t timer_cnt)
177 {
178 hw->group[TIMER_LL_GROUP(chan)].timer_cnt[TIMER_LL_CHAN(chan)] = timer_cnt;
179 }
180
timer_ll_get_end_count(timer_hw_t * hw,uint32_t chan)181 static inline uint32_t timer_ll_get_end_count(timer_hw_t *hw, uint32_t chan)
182 {
183 return hw->group[TIMER_LL_GROUP(chan)].timer_cnt[TIMER_LL_CHAN(chan)];
184 }
185
timer_ll_set_clk_div(timer_hw_t * hw,uint32_t chan,uint32_t clk_div)186 static inline void timer_ll_set_clk_div(timer_hw_t *hw, uint32_t chan, uint32_t clk_div)
187 {
188 hw->group[TIMER_LL_GROUP(chan)].ctrl.clk_div = clk_div & TIMER_F_CLK_DIV_V;
189 }
190
timer_ll_set_cnt_read(timer_hw_t * hw,uint32_t chan)191 static inline void timer_ll_set_cnt_read(timer_hw_t *hw, uint32_t chan)
192 {
193 hw->group[TIMER_LL_GROUP(chan)].read_ctrl.timer_cnt_read = 1;
194 }
195
timer_ll_is_cnt_read_valid(timer_hw_t * hw,uint32_t chan)196 static inline bool timer_ll_is_cnt_read_valid(timer_hw_t *hw, uint32_t chan)
197 {
198 return !(hw->group[TIMER_LL_GROUP(chan)].read_ctrl.timer_cnt_read & 0x1);
199 }
200
timer_ll_set_read_index(timer_hw_t * hw,uint32_t chan)201 static inline void timer_ll_set_read_index(timer_hw_t *hw, uint32_t chan)
202 {
203 hw->group[TIMER_LL_GROUP(chan)].read_ctrl.timer_index = TIMER_LL_CHAN(chan);
204 }
205
timer_ll_clear_timer_count(timer_hw_t * hw,uint32_t chan)206 static inline void timer_ll_clear_timer_count(timer_hw_t *hw, uint32_t chan)
207 {
208 hw->group[TIMER_LL_GROUP(chan)].timer_read_value = 0;
209 }
210
timer_ll_get_timer_count(timer_hw_t * hw,uint32_t chan)211 static inline uint32_t timer_ll_get_timer_count(timer_hw_t *hw, uint32_t chan)
212 {
213 return hw->group[TIMER_LL_GROUP(chan)].timer_read_value;
214 }
215
timer_ll_reset_config_to_default(timer_hw_t * hw,uint32_t chan)216 static inline void timer_ll_reset_config_to_default(timer_hw_t *hw, uint32_t chan)
217 {
218 timer_ll_set_end_count(hw, chan, 0);
219 timer_ll_set_clk_div(hw, chan, 0);
220 }
221
222 #ifdef __cplusplus
223 }
224 #endif
225