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 V151 HAL pwm \n
16 *
17 * History: \n
18 * 2022-09-16, Create file. \n
19 */
20 #include "common_def.h"
21 #include "osal_debug.h"
22 #include "hal_pwm.h"
23 #include "tcxo.h"
24 #include "hal_pwm_v151.h"
25
26 #define PWM_INT_MASK_BIT 3
27
28 static hal_pwm_callback_t g_hal_pwm_v151_callback[CONFIG_PWM_CHANNEL_NUM] = { NULL };
29 static uint32_t g_freq_time = 0;
30 static bool g_repeat_flag = 0;
31
hal_pwm_v151_init(void)32 static errcode_t hal_pwm_v151_init(void)
33 {
34 if (hal_pwm_regs_init() != ERRCODE_SUCC) {
35 return ERRCODE_PWM_REG_ADDR_INVALID;
36 }
37
38 /* Remove interrupt mask */
39 hal_pwm_int_mask_set_pwm_int_mask(PWM_INT_MASK_BIT);
40 return ERRCODE_SUCC;
41 }
42
hal_pwm_v151_deinit(void)43 static void hal_pwm_v151_deinit(void)
44 {
45 hal_pwm_regs_deinit();
46 }
47
hal_pwm_v151_set_low_time(hal_pwm_set_time_id_t id,pwm_channel_t channel,uint32_t time)48 static void hal_pwm_v151_set_low_time(hal_pwm_set_time_id_t id, pwm_channel_t channel, uint32_t time)
49 {
50 unused(id);
51 unused(channel);
52 g_freq_time = 0;
53 g_freq_time += time;
54 }
55
hal_pwm_v151_set_high_time(hal_pwm_set_time_id_t id,pwm_channel_t channel,uint32_t time)56 static void hal_pwm_v151_set_high_time(hal_pwm_set_time_id_t id, pwm_channel_t channel, uint32_t time)
57 {
58 unused(id);
59 g_freq_time += time;
60
61 hal_pwm_duty_l_set_pwm_duty_l_j(channel, time);
62 }
63
hal_pwm_v151_set_offset_time(hal_pwm_set_time_id_t id,pwm_channel_t channel,uint32_t time)64 static void hal_pwm_v151_set_offset_time(hal_pwm_set_time_id_t id, pwm_channel_t channel, uint32_t time)
65 {
66 unused(id);
67
68 /* set offset time */
69 hal_pwm_offset_l_set_pwm_offset_l_j(channel, time);
70
71 /* set freq time */
72 hal_pwm_freq_l_set_pwm_freq_l_j(channel, g_freq_time);
73 g_freq_time = 0;
74 }
75
76 static hal_pwm_set_time_t g_hal_pwm_set_func_array[PWM_SET_TIEM_MAX] = {
77 hal_pwm_v151_set_low_time,
78 hal_pwm_v151_set_high_time,
79 hal_pwm_v151_set_offset_time,
80 };
81
hal_pwm_v151_set_time(hal_pwm_set_time_id_t id,pwm_channel_t channel,uint32_t time)82 static void hal_pwm_v151_set_time(hal_pwm_set_time_id_t id, pwm_channel_t channel, uint32_t time)
83 {
84 g_hal_pwm_set_func_array[id](id, channel, time);
85 }
86
hal_pwm_v151_set_group(pwm_v151_group_t group,uint16_t channel_id)87 static void hal_pwm_v151_set_group(pwm_v151_group_t group, uint16_t channel_id)
88 {
89 /* Each bit in channel_id corresponds to one pwm channel */
90 hal_pwm_sel_set_pwm_sel_i(group, channel_id);
91 }
92
hal_pwm_v151_set_group_en(pwm_v151_group_t group,bool en)93 static void hal_pwm_v151_set_group_en(pwm_v151_group_t group, bool en)
94 {
95 uint16_t channel_id = hal_pwm_sel_get_pwm_sel_i(group);
96 for (uint8_t i = 0; i < CONFIG_PWM_CHANNEL_NUM; i++) {
97 if ((channel_id & (1 << i)) != 0) {
98 hal_pwm_en_set_pwm_en_j(i, en);
99 }
100 }
101 hal_pwm_startclrcnt_en_set_pwm_startclrcnt_en_i(group, 1);
102 hal_pwm_start_set_pwm_start_i(group, 1);
103
104 #if !defined(CONFIG_PWM_PRELOAD)
105 if (g_repeat_flag == false) {
106 for (uint8_t i = 0; i < CONFIG_PWM_CHANNEL_NUM; i++) {
107 if ((channel_id & (1 << i)) > 0 && hal_pwm_period_val_get_pwm_period_val_j(i) > 0) {
108 hal_pwm_en_set_pwm_en_j(i, 0);
109 }
110 }
111 }
112
113 hal_pwm_startclrcnt_en_set_pwm_startclrcnt_en_i(group, 0);
114 hal_pwm_start_set_pwm_start_i(group, 1);
115 #else
116 hal_pwm_startclrcnt_en_set_pwm_startclrcnt_en_i(group, 0);
117 #endif /* CONFIG_PWM_PRELOAD */
118 }
119
120 #if defined(CONFIG_PWM_PRELOAD)
hal_pwm_config_preload(uint8_t group)121 static void hal_pwm_config_preload(uint8_t group)
122 {
123 hal_pwm_start_set_pwm_start_i(group, 1);
124 }
125 #endif /* CONFIG_PWM_PRELOAD */
126
hal_pwm_v151_start(pwm_v151_group_t group)127 static void hal_pwm_v151_start(pwm_v151_group_t group)
128 {
129 hal_pwm_v151_set_group_en(group, true);
130 }
131
hal_pwm_v151_stop(pwm_v151_group_t group)132 static void hal_pwm_v151_stop(pwm_v151_group_t group)
133 {
134 hal_pwm_v151_set_group_en(group, false);
135 }
136
hal_pwm_v151_set_action(uint8_t group,pwm_action_t action)137 static void hal_pwm_v151_set_action(uint8_t group, pwm_action_t action)
138 {
139 if (action == PWM_ACTION_START) {
140 hal_pwm_v151_start((pwm_v151_group_t)group);
141 } else if (action == PWM_ACTION_STOP) {
142 hal_pwm_v151_stop((pwm_v151_group_t)group);
143 } else if (action == PWM_ACTION_CONTINUE_SET) {
144 g_repeat_flag = true;
145 }
146 }
147
hal_pwm_v151_set_cycles(pwm_channel_t channel,uint16_t cycles)148 static void hal_pwm_v151_set_cycles(pwm_channel_t channel, uint16_t cycles)
149 {
150 hal_pwm_period_val_set_pwm_period_val_j(channel, cycles);
151 }
152
hal_pwm_v151_intr_clear(pwm_channel_t channel)153 static void hal_pwm_v151_intr_clear(pwm_channel_t channel)
154 {
155 uint32_t abnor_state0 = hal_pwm_abnor_state0_get_pwm_abnor_state0();
156 uint32_t abnor_state1 = hal_pwm_abnor_state1_get_pwm_abnor_state1();
157 uint32_t flag = hal_pwm_periodload_flag_get_pwm_periodload_flag_j(channel);
158
159 hal_pwm_abnor_state_clr0_set_pwm_abnor_state_clr0(abnor_state0);
160 hal_pwm_abnor_state_clr1_set_pwm_abnor_state_clr1(abnor_state1);
161
162 if (flag != 0) {
163 uint32_t cfg_int_clr0 = (bit((uint32_t)channel));
164 hal_pwm_cfg_int_clr0_set_pwm_cfg_int_clr0(cfg_int_clr0);
165 }
166 }
167
hal_pwm_v151_register_callback(pwm_channel_t channel,hal_pwm_callback_t callback)168 static void hal_pwm_v151_register_callback(pwm_channel_t channel, hal_pwm_callback_t callback)
169 {
170 g_hal_pwm_v151_callback[channel] = callback;
171 }
172
hal_pwm_v151_unregister_callback(pwm_channel_t channel)173 static void hal_pwm_v151_unregister_callback(pwm_channel_t channel)
174 {
175 g_hal_pwm_v151_callback[channel] = NULL;
176 }
177
hal_pwm_v151_irq_handler(void)178 void hal_pwm_v151_irq_handler(void)
179 {
180 uint32_t abnor_state0 = hal_pwm_abnor_state0_get_pwm_abnor_state0();
181 uint32_t abnor_state1 = hal_pwm_abnor_state1_get_pwm_abnor_state1();
182 bool int_flag = false;
183 for (uint8_t ch = 0; ch < CONFIG_PWM_CHANNEL_NUM; ch++) {
184 int_flag = false;
185 if ((((abnor_state0 >> ch) & 1) == 1)) {
186 osal_printk("pwm %d group cfg err\r\n", ch);
187 int_flag = true;
188 }
189 if ((((abnor_state1 >> ch) & 1) == 1)) {
190 osal_printk("pwm %d time cfg err\r\n", ch);
191 int_flag = true;
192 }
193 if (hal_pwm_periodload_flag_get_pwm_periodload_flag_j(ch) == 1) {
194 if (g_hal_pwm_v151_callback[(pwm_channel_t)ch] != NULL) {
195 g_hal_pwm_v151_callback[(pwm_channel_t)ch]((pwm_channel_t)ch);
196 }
197 int_flag = true;
198 }
199 if (int_flag) {
200 hal_pwm_v151_intr_clear((pwm_channel_t)ch);
201 }
202 }
203 }
204
205 static hal_pwm_funcs_t g_hal_pwm_v151_funcs = {
206 .init = hal_pwm_v151_init,
207 .deinit = hal_pwm_v151_deinit,
208 .set_time = hal_pwm_v151_set_time,
209 .set_cycles = hal_pwm_v151_set_cycles,
210 .set_action = hal_pwm_v151_set_action,
211 .isrclear = hal_pwm_v151_intr_clear,
212 .registerfunc = hal_pwm_v151_register_callback,
213 .unregisterfunc = hal_pwm_v151_unregister_callback,
214 .set_group = hal_pwm_v151_set_group,
215 #if defined(CONFIG_PWM_PRELOAD)
216 .config_preload = hal_pwm_config_preload,
217 #endif /* CONFIG_PWM_PRELOAD */
218 };
219
hal_pwm_v151_funcs_get(void)220 hal_pwm_funcs_t *hal_pwm_v151_funcs_get(void)
221 {
222 return &g_hal_pwm_v151_funcs;
223 }
224