• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
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 // The HAL layer for MCPWM (common part)
16 
17 #include "hal/mcpwm_hal.h"
18 #include "soc/soc_caps.h"
19 
mcpwm_hal_init(mcpwm_hal_context_t * hal,const mcpwm_hal_init_config_t * init_config)20 void mcpwm_hal_init(mcpwm_hal_context_t *hal, const mcpwm_hal_init_config_t *init_config)
21 {
22     hal->dev = MCPWM_LL_GET_HW(init_config->host_id);
23 }
24 
mcpwm_hal_hw_init(mcpwm_hal_context_t * hal)25 void mcpwm_hal_hw_init(mcpwm_hal_context_t *hal)
26 {
27     mcpwm_ll_init(hal->dev);
28     mcpwm_ll_set_clock_prescale(hal->dev, hal->prescale);
29 }
30 
mcpwm_hal_timer_start(mcpwm_hal_context_t * hal,int timer)31 void mcpwm_hal_timer_start(mcpwm_hal_context_t *hal, int timer)
32 {
33     mcpwm_ll_timer_start(hal->dev, timer);
34 }
35 
mcpwm_hal_timer_stop(mcpwm_hal_context_t * hal,int timer)36 void mcpwm_hal_timer_stop(mcpwm_hal_context_t *hal, int timer)
37 {
38     mcpwm_ll_timer_stop(hal->dev, timer);
39 }
40 
mcpwm_hal_timer_update_basic(mcpwm_hal_context_t * hal,int timer)41 void mcpwm_hal_timer_update_basic(mcpwm_hal_context_t *hal, int timer)
42 {
43     mcpwm_ll_timer_set_prescale(hal->dev, timer, hal->timer[timer].timer_prescale);
44 
45     uint32_t period = MCPWM_BASE_CLK / (hal->timer[timer].freq *
46             (hal->prescale +1) * (hal->timer[timer].timer_prescale + 1));
47     mcpwm_ll_timer_set_period(hal->dev, timer, period);
48     //write back the actual value to the context
49     hal->timer[timer].freq = MCPWM_BASE_CLK / (period *
50             (hal->prescale +1) * (hal->timer[timer].timer_prescale + 1));
51 
52     mcpwm_ll_timer_set_count_mode(hal->dev, timer, hal->timer[timer].count_mode);
53 }
54 
mcpwm_hal_timer_enable_sync(mcpwm_hal_context_t * hal,int timer,const mcpwm_hal_sync_config_t * sync_conf)55 void mcpwm_hal_timer_enable_sync(mcpwm_hal_context_t *hal, int timer, const mcpwm_hal_sync_config_t *sync_conf)
56 {
57     uint32_t set_phase = mcpwm_ll_timer_get_period(hal->dev, timer) * sync_conf->reload_permillage / 1000;
58     mcpwm_ll_sync_set_phase(hal->dev, timer, set_phase);
59 
60     mcpwm_ll_sync_set_input(hal->dev, timer, sync_conf->sync_sig);
61     mcpwm_ll_sync_enable(hal->dev, timer, 1);
62 }
63 
mcpwm_hal_timer_disable_sync(mcpwm_hal_context_t * hal,int timer)64 void mcpwm_hal_timer_disable_sync(mcpwm_hal_context_t *hal, int timer)
65 {
66     mcpwm_ll_sync_enable(hal->dev, timer, 0);
67 }
68 
mcpwm_hal_operator_update_basic(mcpwm_hal_context_t * hal,int op)69 void mcpwm_hal_operator_update_basic(mcpwm_hal_context_t *hal, int op)
70 {
71     mcpwm_hal_operator_config_t *op_conf = &hal->op[op];
72     mcpwm_ll_operator_select_timer(hal->dev, op, op_conf->timer);
73     for (int cmp = 0; cmp < SOC_MCPWM_COMPARATOR_NUM; cmp++) {
74         mcpwm_hal_operator_update_comparator(hal, op, cmp);
75     }
76     for (int gen = 0; gen < SOC_MCPWM_GENERATOR_NUM; gen++) {
77         mcpwm_hal_operator_update_generator(hal, op, gen);
78     }
79 }
80 
mcpwm_hal_operator_update_comparator(mcpwm_hal_context_t * hal,int op,int cmp)81 void mcpwm_hal_operator_update_comparator(mcpwm_hal_context_t *hal, int op, int cmp)
82 {
83     int timer = hal->op[op].timer;
84     uint32_t period = mcpwm_ll_timer_get_period(hal->dev, timer);
85     mcpwm_ll_operator_set_compare(hal->dev, op, cmp, (hal->op[op].duty[cmp] * period) / 100);
86     mcpwm_ll_operator_set_compare_upmethod(hal->dev, timer);
87 }
88 
mcpwm_hal_operator_update_generator(mcpwm_hal_context_t * hal,int op,int gen_num)89 void mcpwm_hal_operator_update_generator(mcpwm_hal_context_t *hal, int op, int gen_num)
90 {
91     mcpwm_hal_generator_config_t* gen_config = &(hal->op[op].gen[gen_num]);
92     if (gen_config->duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH) {
93         mcpwm_ll_gen_set_zero_action(hal->dev, op, gen_num, MCPWM_ACTION_FORCE_HIGH);
94         mcpwm_ll_gen_set_period_action(hal->dev, op, gen_num, MCPWM_ACTION_FORCE_HIGH);
95         mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, 0, MCPWM_ACTION_FORCE_HIGH, MCPWM_ACTION_FORCE_HIGH);
96         mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, 1, MCPWM_ACTION_FORCE_HIGH, MCPWM_ACTION_FORCE_HIGH);
97     } else if (gen_config->duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_LOW) {
98         mcpwm_ll_gen_set_zero_action(hal->dev, op, gen_num, MCPWM_ACTION_FORCE_LOW);
99         mcpwm_ll_gen_set_period_action(hal->dev, op, gen_num, MCPWM_ACTION_FORCE_LOW);
100         mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, 0, MCPWM_ACTION_FORCE_LOW, MCPWM_ACTION_FORCE_LOW);
101         mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, 1, MCPWM_ACTION_FORCE_LOW, MCPWM_ACTION_FORCE_LOW);
102     } else if (gen_config->duty_type == MCPWM_DUTY_MODE_1 || gen_config->duty_type == MCPWM_DUTY_MODE_0) {
103         const int timer_used = hal->op[op].timer;
104         const int cmp_used = gen_config->comparator;
105         const int cmp_not_used = 1 - gen_config->comparator;
106 
107         mcpwm_output_action_t inactive_action;
108         mcpwm_output_action_t active_action;
109         const mcpwm_output_action_t no_action = MCPWM_ACTION_NO_CHANGE;
110         if (gen_config->duty_type == MCPWM_DUTY_MODE_1) {
111             active_action = MCPWM_ACTION_FORCE_LOW;      //active low
112             inactive_action = MCPWM_ACTION_FORCE_HIGH;    //inactive high
113         } else {   //MCPWM_DUTY_MODE_0
114             inactive_action = MCPWM_ACTION_FORCE_LOW;    //inactive low
115             active_action = MCPWM_ACTION_FORCE_HIGH;      //active high
116         }
117 
118         if (hal->timer[timer_used].count_mode == MCPWM_UP_COUNTER) {
119             mcpwm_ll_gen_set_zero_action(hal->dev, op, gen_num, active_action);
120             mcpwm_ll_gen_set_period_action(hal->dev, op, gen_num, no_action);
121             mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, cmp_used, inactive_action, no_action);
122         } else if (hal->timer[timer_used].count_mode == MCPWM_DOWN_COUNTER) {
123             mcpwm_ll_gen_set_zero_action(hal->dev, op, gen_num, no_action);
124             mcpwm_ll_gen_set_period_action(hal->dev, op, gen_num, inactive_action);
125             mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, cmp_used, no_action, active_action);
126         } else {   //Timer count up-down
127             mcpwm_ll_gen_set_zero_action(hal->dev, op, gen_num, active_action);
128             mcpwm_ll_gen_set_period_action(hal->dev, op, gen_num, no_action);
129             mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, cmp_used, inactive_action, active_action);
130         }
131         mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, cmp_not_used, no_action, no_action);
132     }
133 }
134 
mcpwm_hal_operator_enable_carrier(mcpwm_hal_context_t * hal,int op,const mcpwm_hal_carrier_conf_t * carrier_conf)135 void mcpwm_hal_operator_enable_carrier(mcpwm_hal_context_t *hal, int op, const mcpwm_hal_carrier_conf_t *carrier_conf)
136 {
137     mcpwm_ll_carrier_init(hal->dev, op);
138     mcpwm_ll_carrier_set_prescale(hal->dev, op, carrier_conf->period);
139     mcpwm_ll_carrier_set_duty(hal->dev, op, carrier_conf->duty);
140     mcpwm_ll_carrier_enable(hal->dev, op, true);
141     mcpwm_ll_carrier_set_oneshot_width(hal->dev, op, carrier_conf->oneshot_pulse_width);
142     mcpwm_ll_carrier_out_invert(hal->dev, op, carrier_conf->inverted);
143 }
144 
mcpwm_hal_operator_disable_carrier(mcpwm_hal_context_t * hal,int op)145 void mcpwm_hal_operator_disable_carrier(mcpwm_hal_context_t *hal, int op)
146 {
147     mcpwm_ll_carrier_enable(hal->dev, op, false);
148 }
149 
mcpwm_hal_operator_update_deadzone(mcpwm_hal_context_t * hal,int op,const mcpwm_hal_deadzone_conf_t * deadzone)150 void mcpwm_hal_operator_update_deadzone(mcpwm_hal_context_t *hal, int op, const mcpwm_hal_deadzone_conf_t *deadzone)
151 {
152     if (deadzone->mode != MCPWM_DEADTIME_BYPASS) {
153         mcpwm_ll_deadtime_init(hal->dev, op);
154         mcpwm_ll_deadtime_set_rising_delay(hal->dev, op, deadzone->red);
155         mcpwm_ll_deadtime_set_falling_delay(hal->dev, op, deadzone->fed);
156         mcpwm_ll_set_deadtime_mode(hal->dev, op, deadzone->mode);
157     } else {
158         mcpwm_ll_deadtime_bypass(hal->dev, op);
159     }
160 }
161 
mcpwm_hal_fault_init(mcpwm_hal_context_t * hal,int fault_sig,bool level)162 void mcpwm_hal_fault_init(mcpwm_hal_context_t *hal, int fault_sig, bool level)
163 {
164     mcpwm_ll_fault_enable(hal->dev, fault_sig, level);
165 }
166 
mcpwm_hal_operator_update_fault(mcpwm_hal_context_t * hal,int op,const mcpwm_hal_fault_conf_t * fault_conf)167 void mcpwm_hal_operator_update_fault(mcpwm_hal_context_t *hal, int op, const mcpwm_hal_fault_conf_t *fault_conf)
168 {
169     for (int fault_sig = 0; fault_sig < SOC_MCPWM_FAULT_SIG_NUM; fault_sig++) {
170         bool enabled = (fault_conf->cbc_enabled_mask & BIT(fault_sig)) ? true : false;
171         mcpwm_ll_fault_cbc_enable_signal(hal->dev, op, fault_sig, enabled);
172     }
173     for (int fault_sig = 0; fault_sig < SOC_MCPWM_FAULT_SIG_NUM; fault_sig++) {
174         bool enabled = (fault_conf->ost_enabled_mask & BIT(fault_sig)) ? true : false;
175         mcpwm_ll_fault_oneshot_enable_signal(hal->dev, op, fault_sig, enabled);
176     }
177     if (fault_conf->cbc_enabled_mask) {
178         for (int gen = 0; gen < SOC_MCPWM_GENERATOR_NUM; gen++) {
179             mcpwm_ll_fault_set_cyc_action(hal->dev, op, gen, fault_conf->action_on_fault[gen], fault_conf->action_on_fault[gen]);
180         }
181     }
182     if (fault_conf->ost_enabled_mask) {
183         for (int gen = 0; gen < SOC_MCPWM_GENERATOR_NUM; gen++) {
184             mcpwm_ll_fault_set_oneshot_action(hal->dev, op, gen, fault_conf->action_on_fault[gen], fault_conf->action_on_fault[gen]);
185         }
186     }
187 }
188 
mcpwm_hal_fault_oneshot_clear(mcpwm_hal_context_t * hal,int op)189 void mcpwm_hal_fault_oneshot_clear(mcpwm_hal_context_t *hal, int op)
190 {
191     mcpwm_ll_fault_clear_ost(hal->dev, op);
192 }
193 
mcpwm_hal_fault_disable(mcpwm_hal_context_t * hal,int fault_sig)194 void mcpwm_hal_fault_disable(mcpwm_hal_context_t *hal, int fault_sig)
195 {
196     for (int op = 0; op < SOC_MCPWM_OP_NUM; op++) {
197         if (mcpwm_ll_fault_oneshot_signal_enabled(hal->dev, op, fault_sig)) {
198             mcpwm_ll_fault_clear_ost(hal->dev, op);
199         }
200     }
201     mcpwm_ll_fault_disable(hal->dev, fault_sig);
202 }
203 
mcpwm_hal_capture_enable(mcpwm_hal_context_t * hal,int cap_sig,const mcpwm_hal_capture_config_t * conf)204 void mcpwm_hal_capture_enable(mcpwm_hal_context_t *hal, int cap_sig, const mcpwm_hal_capture_config_t *conf)
205 {
206     mcpwm_ll_capture_enable(hal->dev, cap_sig, 1);
207     mcpwm_ll_capture_select_edge(hal->dev, cap_sig, conf->cap_edge);
208     mcpwm_ll_capture_set_prescale(hal->dev, cap_sig, conf->prescale);
209 }
210 
mcpwm_hal_capture_get_result(mcpwm_hal_context_t * hal,int cap_sig,uint32_t * out_count,mcpwm_capture_on_edge_t * out_edge)211 esp_err_t mcpwm_hal_capture_get_result(mcpwm_hal_context_t *hal, int cap_sig, uint32_t *out_count, mcpwm_capture_on_edge_t *out_edge)
212 {
213     const mcpwm_intr_t sig_intr = mcpwm_ll_get_cap_intr_def(cap_sig);
214     //unconditionally update the output value
215     if (out_edge) {
216         *out_edge = mcpwm_ll_get_captured_edge(hal->dev, cap_sig);
217     }
218     if (out_count) {
219         *out_count = mcpwm_ll_get_capture_val(hal->dev, cap_sig);
220     }
221     if (mcpwm_ll_get_intr(hal->dev) & sig_intr) {
222         mcpwm_ll_clear_intr(hal->dev, sig_intr);
223     }
224     return (mcpwm_ll_get_intr(hal->dev) & sig_intr ? ESP_OK : ESP_ERR_NOT_FOUND);
225 }
226 
mcpwm_hal_capture_disable(mcpwm_hal_context_t * hal,int cap_sig)227 void mcpwm_hal_capture_disable(mcpwm_hal_context_t *hal, int cap_sig)
228 {
229     mcpwm_ll_capture_enable(hal->dev, cap_sig, 0);
230 }
231