• 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 #include "timer_hal.h"
16 #include "timer_ll.h"
17 
18 #if (CONFIG_SYSTEM_CTRL)
19 #include "sys_hal.h"
20 #endif
21 /*
22  * timer_s = counter_value * (1 / (freq /div))
23  */
timer_hal_cal_end_count(timer_id_t chan,uint64_t time,uint32_t div,timer_value_unit_t unit_type)24 uint32_t timer_hal_cal_end_count(timer_id_t chan, uint64_t time, uint32_t div, timer_value_unit_t unit_type)
25 {
26     if (div == 0) {
27         div = 1;
28     }
29     uint64_t value = 0;
30     uint16_t unit_factor = 1;
31 
32     unit_factor = (unit_type == TIMER_UNIT_MS) ? 1 : 1000;
33 
34 #if (CONFIG_SYSTEM_CTRL)
35 	uint32_t group_index = 0;
36 	uint32_t timer_clock = TIMER_SCLK_XTAL;
37 
38 	group_index = chan / SOC_TIMER_CHAN_NUM_PER_GROUP;
39 	switch(group_index)
40 	{
41 		case 0:
42 			timer_clock = sys_hal_timer_select_clock_get(SYS_SEL_TIMER0);
43 			break;
44 		case 1:
45 			timer_clock = sys_hal_timer_select_clock_get(SYS_SEL_TIMER1);
46 			break;
47 		default:
48 			break;
49 	}
50 
51 	if(timer_clock == TIMER_SCLK_XTAL) {
52         	value = time * TIMER_CLOCK_FREQ_26M / unit_factor / div;
53 	} else {
54         	value = time * TIMER_CLOCK_FREQ_32K / unit_factor / div;
55 	}
56 
57 #else
58     if (chan < SOC_TIMER_CHAN_NUM_PER_GROUP) {
59         value = time * TIMER_CLOCK_FREQ_26M / unit_factor / div;
60     } else {
61         value = time * TIMER_CLOCK_FREQ_32K / unit_factor / div;
62     }
63 #endif
64     if (value > 0xffffffff)
65         value = 0xffffffff;
66 
67     return (uint32_t)value;
68 }
69 
timer_hal_init(timer_hal_t * hal)70 bk_err_t timer_hal_init(timer_hal_t *hal)
71 {
72     hal->hw = (timer_hw_t *)TIMER_LL_REG_BASE(hal->id);
73 
74     for (int chan = 0; chan < SOC_TIMER_CHAN_NUM_PER_UNIT; chan++) {
75         timer_ll_init(hal->hw, chan);
76     }
77 
78     return BK_OK;
79 }
80 
timer_hal_init_timer(timer_hal_t * hal,timer_id_t chan,uint64_t time,timer_value_unit_t unit_type)81 bk_err_t timer_hal_init_timer(timer_hal_t *hal, timer_id_t chan, uint64_t time, timer_value_unit_t unit_type)
82 {
83     uint32_t end_count = timer_hal_cal_end_count(chan, time, 1, unit_type);
84     timer_ll_set_end_count(hal->hw, chan, end_count);
85     timer_ll_set_clk_div(hal->hw, chan, 0);
86     timer_ll_clear_chan_interrupt_status(hal->hw, chan);
87     return BK_OK;
88 }
89 
timer_hal_set_period(timer_hal_t * hal,timer_id_t chan,uint32_t time_ms)90 bk_err_t timer_hal_set_period(timer_hal_t *hal, timer_id_t chan, uint32_t time_ms)
91 {
92     uint32_t end_count = timer_hal_cal_end_count(chan, time_ms, 1, TIMER_UNIT_MS);
93     timer_ll_set_end_count(hal->hw, chan, end_count);
94     return BK_OK;
95 }
96 
97 
timer_hal_start_common(timer_hal_t * hal,timer_id_t chan)98 bk_err_t timer_hal_start_common(timer_hal_t *hal, timer_id_t chan)
99 {
100     timer_ll_enable(hal->hw, chan);
101     return BK_OK;
102 }
103 
timer_hal_stop_common(timer_hal_t * hal,timer_id_t chan)104 bk_err_t timer_hal_stop_common(timer_hal_t *hal, timer_id_t chan)
105 {
106     timer_ll_disable_interrupt(hal->hw, chan);
107     timer_ll_clear_chan_interrupt_status(hal->hw, chan);
108     timer_ll_disable(hal->hw, chan);
109     return BK_OK;
110 }
111 
timer_hal_get_count(timer_hal_t * hal,timer_id_t chan)112 uint32_t timer_hal_get_count(timer_hal_t *hal, timer_id_t chan)
113 {
114     uint32_t en_status = timer_ll_get_enable_status(hal->hw);
115     if (!(en_status & BIT(chan))) {
116         return 0;
117     }
118     timer_ll_set_read_index(hal->hw, chan);
119     timer_ll_set_cnt_read(hal->hw, chan);
120 
121     //Wait hardware to prepare the data
122     BK_WHILE (!timer_ll_is_cnt_read_valid(hal->hw, chan));
123 
124     return timer_ll_get_timer_count(hal->hw, chan);
125 }
126 
127