• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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