1 // Copyright 2015-2016 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 #include <stdio.h>
16 #include "esp_log.h"
17 #include "esp_err.h"
18 #include "esp_osal/esp_osal.h"
19 #include "esp_osal/semphr.h"
20 #include "esp_osal/xtensa_api.h"
21 #include "esp_osal/task.h"
22 #include "soc/gpio_periph.h"
23 #include "driver/mcpwm.h"
24 #include "driver/periph_ctrl.h"
25 #include "sdkconfig.h"
26 #include "hal/mcpwm_hal.h"
27 #include "hal/gpio_hal.h"
28 #include "esp_rom_gpio.h"
29
30 typedef struct {
31 mcpwm_hal_context_t hal;
32 portMUX_TYPE spinlock;
33 } mcpwm_context_t;
34
35 #define CONTEXT_INITIALIZER() { \
36 .spinlock = portMUX_INITIALIZER_UNLOCKED, \
37 .hal = { \
38 .prescale = MCPWM_CLK_PRESCL, \
39 }, \
40 }
41
42
43 static const char *MCPWM_TAG = "MCPWM";
44
45 #define MCPWM_CHECK(a, str, ret_val) if (!(a)) { \
46 ESP_LOGE(MCPWM_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
47 return (ret_val); \
48 }
49
50 #define MCPWM_DRIVER_INIT_ERROR "MCPWM DRIVER NOT INITIALIZED"
51 #define MCPWM_UNIT_NUM_ERROR "MCPWM UNIT NUM ERROR"
52 #define MCPWM_TIMER_ERROR "MCPWM TIMER NUM ERROR"
53 #define MCPWM_PARAM_ADDR_ERROR "MCPWM PARAM ADDR ERROR"
54 #define MCPWM_DUTY_TYPE_ERROR "MCPWM DUTY TYPE ERROR"
55 #define MCPWM_GPIO_ERROR "MCPWM GPIO NUM ERROR"
56 #define MCPWM_GEN_ERROR "MCPWM GENERATOR ERROR"
57 #define MCPWM_DB_ERROR "MCPWM DEADTIME TYPE ERROR"
58
59 #define MCPWM_CLK_PRESCL 15 //MCPWM clock prescale
60 #define TIMER_CLK_PRESCALE 9 //MCPWM timer prescales
61 #define MCPWM_CLK (MCPWM_BASE_CLK/(MCPWM_CLK_PRESCL +1))
62 #define MCPWM_PIN_IGNORE (-1)
63 #define OFFSET_FOR_GPIO_IDX_1 6
64 #define OFFSET_FOR_GPIO_IDX_2 75
65
66 _Static_assert(SOC_MCPWM_OP_NUM >= SOC_MCPWM_TIMER_NUM, "This driver assumes the timer num equals to the operator num.");
67 _Static_assert(SOC_MCPWM_COMPARATOR_NUM >= SOC_MCPWM_GENERATOR_NUM, "This driver assumes the generator num equals to the generator num.");
68 _Static_assert(SOC_MCPWM_GENERATOR_NUM == 2, "This driver assumes the generator num equals to 2.");
69
70 #define MCPWM_TIMER_ID_CHECK(mcpwm_num, timer_num) do {\
71 MCPWM_CHECK((mcpwm_num) < SOC_MCPWM_PERIPH_NUM, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG); \
72 MCPWM_CHECK((timer_num) < SOC_MCPWM_TIMER_NUM, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG); \
73 } while(0)
74
75 #define MCPWM_TIMER_CHECK(mcpwm_num, timer_num) do{\
76 MCPWM_TIMER_ID_CHECK(mcpwm_num, timer_num); \
77 MCPWM_CHECK(context[mcpwm_num].hal.dev != NULL, MCPWM_DRIVER_INIT_ERROR, ESP_ERR_INVALID_STATE); \
78 } while(0)
79
80 #define MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen) do{ \
81 MCPWM_TIMER_CHECK(mcpwm_num, timer_num); \
82 MCPWM_CHECK(gen < MCPWM_GEN_MAX, MCPWM_GEN_ERROR, ESP_ERR_INVALID_ARG); \
83 } while(0)
84
85
86 static mcpwm_context_t context[SOC_MCPWM_PERIPH_NUM] = {
87 CONTEXT_INITIALIZER(),
88 CONTEXT_INITIALIZER(),
89 };
90
91
mcpwm_critical_enter(mcpwm_unit_t mcpwm_num)92 static inline void mcpwm_critical_enter(mcpwm_unit_t mcpwm_num)
93 {
94 portENTER_CRITICAL(&context[mcpwm_num].spinlock);
95 }
96
mcpwm_critical_exit(mcpwm_unit_t mcpwm_num)97 static inline void mcpwm_critical_exit(mcpwm_unit_t mcpwm_num)
98 {
99 portEXIT_CRITICAL(&context[mcpwm_num].spinlock);
100 }
101
mcpwm_gpio_init(mcpwm_unit_t mcpwm_num,mcpwm_io_signals_t io_signal,int gpio_num)102 esp_err_t mcpwm_gpio_init(mcpwm_unit_t mcpwm_num, mcpwm_io_signals_t io_signal, int gpio_num)
103 {
104 if (gpio_num == MCPWM_PIN_IGNORE) {
105 //IGNORE
106 return ESP_OK;
107 }
108
109 MCPWM_CHECK(mcpwm_num < SOC_MCPWM_PERIPH_NUM, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
110 MCPWM_CHECK((GPIO_IS_VALID_GPIO(gpio_num)), MCPWM_GPIO_ERROR, ESP_ERR_INVALID_ARG);
111
112 periph_module_enable(PERIPH_PWM0_MODULE + mcpwm_num);
113 gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO);
114 bool mcpwm_gpio_sig = (io_signal <= MCPWM2B);
115 if (mcpwm_num == MCPWM_UNIT_0) {
116 if (mcpwm_gpio_sig) {
117 MCPWM_CHECK((GPIO_IS_VALID_OUTPUT_GPIO(gpio_num)), MCPWM_GPIO_ERROR, ESP_ERR_INVALID_ARG);
118 gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
119 esp_rom_gpio_connect_out_signal(gpio_num, PWM0_OUT0A_IDX + io_signal, 0, 0);
120 } else {
121 gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
122 esp_rom_gpio_connect_in_signal(gpio_num, PWM0_SYNC0_IN_IDX + io_signal - OFFSET_FOR_GPIO_IDX_1, 0);
123 }
124 } else { //MCPWM_UNIT_1
125 if (mcpwm_gpio_sig) {
126 MCPWM_CHECK((GPIO_IS_VALID_OUTPUT_GPIO(gpio_num)), MCPWM_GPIO_ERROR, ESP_ERR_INVALID_ARG);
127 gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
128 esp_rom_gpio_connect_out_signal(gpio_num, PWM1_OUT0A_IDX + io_signal, 0, 0);
129 } else if (io_signal >= MCPWM_SYNC_0 && io_signal <= MCPWM_FAULT_2) {
130 gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
131 esp_rom_gpio_connect_in_signal(gpio_num, PWM1_SYNC0_IN_IDX + io_signal - OFFSET_FOR_GPIO_IDX_1, 0);
132 } else {
133 gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
134 esp_rom_gpio_connect_in_signal(gpio_num, PWM1_SYNC0_IN_IDX + io_signal - OFFSET_FOR_GPIO_IDX_2, 0);
135 }
136 }
137 return ESP_OK;
138 }
139
mcpwm_set_pin(mcpwm_unit_t mcpwm_num,const mcpwm_pin_config_t * mcpwm_pin)140 esp_err_t mcpwm_set_pin(mcpwm_unit_t mcpwm_num, const mcpwm_pin_config_t *mcpwm_pin)
141 {
142 MCPWM_CHECK(mcpwm_num < SOC_MCPWM_PERIPH_NUM, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
143 mcpwm_gpio_init(mcpwm_num, MCPWM0A, mcpwm_pin->mcpwm0a_out_num); //MCPWM0A
144 mcpwm_gpio_init(mcpwm_num, MCPWM0B, mcpwm_pin->mcpwm0b_out_num); //MCPWM0B
145 mcpwm_gpio_init(mcpwm_num, MCPWM1A, mcpwm_pin->mcpwm1a_out_num); //MCPWM1A
146 mcpwm_gpio_init(mcpwm_num, MCPWM1B, mcpwm_pin->mcpwm1b_out_num); //MCPWM1B
147 mcpwm_gpio_init(mcpwm_num, MCPWM2A, mcpwm_pin->mcpwm2a_out_num); //MCPWM2A
148 mcpwm_gpio_init(mcpwm_num, MCPWM2B, mcpwm_pin->mcpwm2b_out_num); //MCPWM2B
149 mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_0, mcpwm_pin->mcpwm_sync0_in_num); //SYNC0
150 mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_1, mcpwm_pin->mcpwm_sync1_in_num); //SYNC1
151 mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_2, mcpwm_pin->mcpwm_sync2_in_num); //SYNC2
152 mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_0, mcpwm_pin->mcpwm_fault0_in_num); //FAULT0
153 mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_1, mcpwm_pin->mcpwm_fault1_in_num); //FAULT1
154 mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_2, mcpwm_pin->mcpwm_fault2_in_num); //FAULT2
155 mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_0, mcpwm_pin->mcpwm_cap0_in_num); //CAP0
156 mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_1, mcpwm_pin->mcpwm_cap1_in_num); //CAP1
157 mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_2, mcpwm_pin->mcpwm_cap2_in_num); //CAP2
158 return ESP_OK;
159 }
160
mcpwm_start(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)161 esp_err_t mcpwm_start(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
162 {
163 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
164
165 mcpwm_critical_enter(mcpwm_num);
166 mcpwm_hal_timer_start(&context[mcpwm_num].hal, timer_num);
167 mcpwm_critical_exit(mcpwm_num);
168 return ESP_OK;
169 }
170
mcpwm_stop(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)171 esp_err_t mcpwm_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
172 {
173 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
174
175 mcpwm_critical_enter(mcpwm_num);
176 mcpwm_hal_timer_stop(&context[mcpwm_num].hal, timer_num);
177 mcpwm_critical_exit(mcpwm_num);
178 return ESP_OK;
179 }
180
mcpwm_set_frequency(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,uint32_t frequency)181 esp_err_t mcpwm_set_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint32_t frequency)
182 {
183 //the driver currently always use the timer x for operator x
184 const int op = timer_num;
185 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
186 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
187
188 mcpwm_critical_enter(mcpwm_num);
189 hal->timer[timer_num].freq = frequency;
190 mcpwm_hal_timer_update_basic(hal, timer_num);
191 //update the operator to update the duty
192 mcpwm_hal_operator_update_basic(hal, op);
193 mcpwm_critical_exit(mcpwm_num);
194 return ESP_OK;
195 }
196
mcpwm_set_duty(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_generator_t gen,float duty)197 esp_err_t mcpwm_set_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, float duty)
198 {
199 //the driver currently always use the timer x for operator x
200 const int op = timer_num;
201 //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
202 const int cmp = gen;
203 MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
204 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
205
206 mcpwm_critical_enter(mcpwm_num);
207 hal->op[op].duty[cmp] = duty;
208 mcpwm_hal_operator_update_comparator(hal, op, gen);
209 mcpwm_critical_exit(mcpwm_num);
210 return ESP_OK;
211 }
212
mcpwm_set_duty_in_us(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_generator_t gen,uint32_t duty_in_us)213 esp_err_t mcpwm_set_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, uint32_t duty_in_us)
214 {
215 //the driver currently always use the timer x for operator x
216 const int op = timer_num;
217 //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
218 const int cmp = gen;
219 MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
220 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
221
222 mcpwm_critical_enter(mcpwm_num);
223 hal->op[op].duty[cmp] = (100 * duty_in_us * hal->timer[timer_num].freq) / (1000 * 1000.);
224 mcpwm_hal_operator_update_comparator(hal, op, gen);
225 mcpwm_critical_exit(mcpwm_num);
226 return ESP_OK;
227 }
228
mcpwm_set_duty_type(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_generator_t gen,mcpwm_duty_type_t duty_type)229 esp_err_t mcpwm_set_duty_type(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen,
230 mcpwm_duty_type_t duty_type)
231 {
232 //the driver currently always use the timer x for operator x
233 const int op = timer_num;
234 MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
235 MCPWM_CHECK(duty_type < MCPWM_DUTY_MODE_MAX, MCPWM_DUTY_TYPE_ERROR, ESP_ERR_INVALID_ARG);
236 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
237
238 mcpwm_critical_enter(mcpwm_num);
239 hal->op[op].gen[gen] = (mcpwm_hal_generator_config_t) {
240 .comparator = gen, //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
241 .duty_type = duty_type,
242 };
243 mcpwm_hal_operator_update_generator(hal, op, gen);
244 mcpwm_critical_exit(mcpwm_num);
245 return ESP_OK;
246 }
247
248
mcpwm_init(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,const mcpwm_config_t * mcpwm_conf)249 esp_err_t mcpwm_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_config_t *mcpwm_conf)
250 {
251 //the driver currently always use the timer x for operator x
252 const int op = timer_num;
253 MCPWM_TIMER_ID_CHECK(mcpwm_num, op);
254 periph_module_enable(PERIPH_PWM0_MODULE + mcpwm_num);
255
256 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
257 mcpwm_hal_init_config_t init_config = {
258 .host_id = mcpwm_num,
259 };
260
261 mcpwm_critical_enter(mcpwm_num);
262 mcpwm_hal_init(hal, &init_config);
263 mcpwm_hal_hw_init(hal);
264
265 hal->timer[timer_num].timer_prescale = TIMER_CLK_PRESCALE;
266 hal->timer[timer_num].freq = mcpwm_conf->frequency;
267 hal->timer[timer_num].count_mode = mcpwm_conf->counter_mode;
268
269 //the driver currently always use the timer x for operator x
270 hal->op[op].timer = timer_num;
271 hal->op[op].duty[0] = mcpwm_conf->cmpr_a;
272 hal->op[op].duty[1] = mcpwm_conf->cmpr_b;
273
274 mcpwm_hal_timer_update_basic(hal, timer_num);
275 //update the comparer to keep the same duty rate
276 mcpwm_hal_operator_update_basic(hal, op);
277
278 for (int gen = 0; gen < SOC_MCPWM_GENERATOR_NUM; gen++) {
279 hal->op[op].gen[gen] = (mcpwm_hal_generator_config_t) {
280 .comparator = gen, //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
281 .duty_type = mcpwm_conf->duty_mode,
282 };
283 mcpwm_hal_operator_update_generator(hal, op, gen);
284 }
285
286 mcpwm_hal_timer_start(hal, timer_num);
287 mcpwm_critical_exit(mcpwm_num);
288
289 return ESP_OK;
290 }
291
mcpwm_get_frequency(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)292 uint32_t mcpwm_get_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
293 {
294 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
295 return context[mcpwm_num].hal.timer[timer_num].freq;
296 }
297
mcpwm_get_duty(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_generator_t gen)298 float mcpwm_get_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen)
299 {
300 //the driver currently always use the timer x for operator x
301 const int op = timer_num;
302 MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
303 return context[mcpwm_num].hal.op[op].duty[gen];
304 }
305
306 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_GEN_A, 0);
307 STATIC_HAL_REG_CHECK(MCPWM, MCPWM_GEN_B, 1);
308
mcpwm_set_signal_high(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_generator_t gen)309 esp_err_t mcpwm_set_signal_high(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen)
310 {
311 //the driver currently always use the timer x for operator x
312 const int op = timer_num;
313 MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
314 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
315
316 mcpwm_critical_enter(mcpwm_num);
317 hal->op[op].gen[gen] = (mcpwm_hal_generator_config_t) {
318 .comparator = gen, //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
319 .duty_type = MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH,
320 };
321 mcpwm_hal_operator_update_generator(hal, op, gen);
322 mcpwm_critical_exit(mcpwm_num);
323 return ESP_OK;
324 }
325
mcpwm_set_signal_low(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_generator_t gen)326 esp_err_t mcpwm_set_signal_low(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen)
327 {
328 //the driver currently always use the timer x for operator x
329 const int op = timer_num;
330 MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
331 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
332
333 mcpwm_critical_enter(mcpwm_num);
334 hal->op[op].gen[gen] = (mcpwm_hal_generator_config_t) {
335 .comparator = gen, //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
336 .duty_type = MCPWM_HAL_GENERATOR_MODE_FORCE_LOW,
337 };
338 mcpwm_hal_operator_update_generator(hal, op, gen);
339 mcpwm_critical_exit(mcpwm_num);
340 return ESP_OK;
341 }
342
mcpwm_carrier_enable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)343 esp_err_t mcpwm_carrier_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
344 {
345 //the driver currently always use the timer x for operator x
346 const int op = timer_num;
347 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
348
349 mcpwm_critical_enter(mcpwm_num);
350 mcpwm_ll_carrier_enable(context[mcpwm_num].hal.dev, op, true);
351 mcpwm_critical_exit(mcpwm_num);
352 return ESP_OK;
353 }
354
mcpwm_carrier_disable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)355 esp_err_t mcpwm_carrier_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
356 {
357 //the driver currently always use the timer x for operator x
358 const int op = timer_num;
359 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
360
361 mcpwm_critical_enter(mcpwm_num);
362 mcpwm_ll_carrier_enable(context[mcpwm_num].hal.dev, op, false);
363 mcpwm_critical_exit(mcpwm_num);
364 return ESP_OK;
365 }
366
mcpwm_carrier_set_period(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,uint8_t carrier_period)367 esp_err_t mcpwm_carrier_set_period(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_period)
368 {
369 //the driver currently always use the timer x for operator x
370 const int op = timer_num;
371 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
372
373 mcpwm_critical_enter(mcpwm_num);
374 mcpwm_ll_carrier_set_prescale(context[mcpwm_num].hal.dev, op, carrier_period);
375 mcpwm_critical_exit(mcpwm_num);
376 return ESP_OK;
377 }
378
mcpwm_carrier_set_duty_cycle(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,uint8_t carrier_duty)379 esp_err_t mcpwm_carrier_set_duty_cycle(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_duty)
380 {
381 //the driver currently always use the timer x for operator x
382 const int op = timer_num;
383 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
384
385 mcpwm_critical_enter(mcpwm_num);
386 mcpwm_ll_carrier_set_duty(context[mcpwm_num].hal.dev, op, carrier_duty);
387 mcpwm_critical_exit(mcpwm_num);
388 return ESP_OK;
389 }
390
mcpwm_carrier_oneshot_mode_enable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,uint8_t pulse_width)391 esp_err_t mcpwm_carrier_oneshot_mode_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t pulse_width)
392 {
393 //the driver currently always use the timer x for operator x
394 const int op = timer_num;
395 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
396
397 mcpwm_critical_enter(mcpwm_num);
398 mcpwm_ll_carrier_set_oneshot_width(context[mcpwm_num].hal.dev, op, pulse_width);
399 mcpwm_critical_exit(mcpwm_num);
400 return ESP_OK;
401 }
402
mcpwm_carrier_oneshot_mode_disable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)403 esp_err_t mcpwm_carrier_oneshot_mode_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
404 {
405 return mcpwm_carrier_oneshot_mode_enable(mcpwm_num, timer_num, 0);
406 }
407
mcpwm_carrier_output_invert(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_carrier_out_ivt_t carrier_ivt_mode)408 esp_err_t mcpwm_carrier_output_invert(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num,
409 mcpwm_carrier_out_ivt_t carrier_ivt_mode)
410 {
411 //the driver currently always use the timer x for operator x
412 const int op = timer_num;
413 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
414
415 mcpwm_critical_enter(mcpwm_num);
416 mcpwm_ll_carrier_out_invert(context[mcpwm_num].hal.dev, op, carrier_ivt_mode);
417 mcpwm_critical_exit(mcpwm_num);
418 return ESP_OK;
419 }
420
mcpwm_carrier_init(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,const mcpwm_carrier_config_t * carrier_conf)421 esp_err_t mcpwm_carrier_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_carrier_config_t *carrier_conf)
422 {
423 //the driver currently always use the timer x for operator x
424 const int op = timer_num;
425 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
426 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
427
428 mcpwm_hal_carrier_conf_t carrier = {
429 .period = carrier_conf->carrier_period,
430 .duty = carrier_conf->carrier_duty,
431 .inverted = carrier_conf->carrier_ivt_mode,
432 };
433 if (carrier_conf->carrier_os_mode == MCPWM_ONESHOT_MODE_EN) {
434 carrier.oneshot_pulse_width = carrier_conf->pulse_width_in_os;
435 } else {
436 carrier.oneshot_pulse_width = 0;
437 }
438
439 mcpwm_critical_enter(mcpwm_num);
440 mcpwm_hal_operator_enable_carrier(hal, op, &carrier);
441 mcpwm_critical_exit(mcpwm_num);
442 return ESP_OK;
443 }
444
mcpwm_deadtime_enable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_deadtime_type_t dt_mode,uint32_t red,uint32_t fed)445 esp_err_t mcpwm_deadtime_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_deadtime_type_t dt_mode,
446 uint32_t red, uint32_t fed)
447 {
448 //the driver currently always use the timer x for operator x
449 const int op = timer_num;
450 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
451 MCPWM_CHECK(dt_mode < MCPWM_DEADTIME_TYPE_MAX, MCPWM_DB_ERROR, ESP_ERR_INVALID_ARG);
452 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
453 mcpwm_hal_deadzone_conf_t deadzone = {
454 .red = red,
455 .fed = fed,
456 .mode = dt_mode,
457 };
458
459 mcpwm_critical_enter(mcpwm_num);
460 mcpwm_hal_operator_update_deadzone(hal, op, &deadzone);
461 mcpwm_critical_exit(mcpwm_num);
462 return ESP_OK;
463 }
464
mcpwm_deadtime_disable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)465 esp_err_t mcpwm_deadtime_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
466 {
467 //the driver currently always use the timer x for operator x
468 const int op = timer_num;
469 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
470 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
471 mcpwm_hal_deadzone_conf_t deadzone = { .mode = MCPWM_DEADTIME_BYPASS };
472
473 mcpwm_critical_enter(mcpwm_num);
474 mcpwm_hal_operator_update_deadzone(hal, op, &deadzone);
475 mcpwm_critical_exit(mcpwm_num);
476 return ESP_OK;
477 }
478
mcpwm_fault_init(mcpwm_unit_t mcpwm_num,mcpwm_fault_input_level_t intput_level,mcpwm_fault_signal_t fault_sig)479 esp_err_t mcpwm_fault_init(mcpwm_unit_t mcpwm_num, mcpwm_fault_input_level_t intput_level, mcpwm_fault_signal_t fault_sig)
480 {
481 MCPWM_CHECK(mcpwm_num < SOC_MCPWM_PERIPH_NUM, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
482
483 mcpwm_critical_enter(mcpwm_num);
484 mcpwm_hal_fault_init(&context[mcpwm_num].hal, fault_sig, intput_level);
485 mcpwm_critical_exit(mcpwm_num);
486 return ESP_OK;
487 }
488
mcpwm_fault_deinit(mcpwm_unit_t mcpwm_num,mcpwm_fault_signal_t fault_sig)489 esp_err_t mcpwm_fault_deinit(mcpwm_unit_t mcpwm_num, mcpwm_fault_signal_t fault_sig)
490 {
491 MCPWM_CHECK(mcpwm_num < SOC_MCPWM_PERIPH_NUM, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
492
493 mcpwm_critical_enter(mcpwm_num);
494 mcpwm_hal_fault_disable(&context[mcpwm_num].hal, fault_sig);
495 mcpwm_critical_exit(mcpwm_num);
496 return ESP_OK;
497 }
498
mcpwm_fault_set_cyc_mode(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_fault_signal_t fault_sig,mcpwm_output_action_t action_on_pwmxa,mcpwm_output_action_t action_on_pwmxb)499 esp_err_t mcpwm_fault_set_cyc_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig,
500 mcpwm_output_action_t action_on_pwmxa, mcpwm_output_action_t action_on_pwmxb)
501 {
502 //the driver currently always use the timer x for operator x
503 const int op = timer_num;
504 MCPWM_TIMER_CHECK(mcpwm_num, op);
505 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
506
507 mcpwm_critical_enter(mcpwm_num);
508 mcpwm_ll_fault_cbc_enable_signal(hal->dev, op, fault_sig, true);
509 mcpwm_ll_fault_oneshot_enable_signal(hal->dev, op, fault_sig, false);
510 mcpwm_ll_fault_set_cyc_action(hal->dev, op, 0, action_on_pwmxa, action_on_pwmxa);
511 mcpwm_ll_fault_set_cyc_action(hal->dev, op, 1, action_on_pwmxb, action_on_pwmxb);
512 mcpwm_critical_exit(mcpwm_num);
513 return ESP_OK;
514 }
515
mcpwm_fault_set_oneshot_mode(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_fault_signal_t fault_sig,mcpwm_action_on_pwmxa_t action_on_pwmxa,mcpwm_action_on_pwmxb_t action_on_pwmxb)516 esp_err_t mcpwm_fault_set_oneshot_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig,
517 mcpwm_action_on_pwmxa_t action_on_pwmxa, mcpwm_action_on_pwmxb_t action_on_pwmxb)
518 {
519 //the driver currently always use the timer x for operator x
520 const int op = timer_num;
521 MCPWM_TIMER_CHECK(mcpwm_num, op);
522 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
523
524 mcpwm_critical_enter(mcpwm_num);
525 mcpwm_hal_fault_oneshot_clear(hal, op);
526 mcpwm_ll_fault_cbc_enable_signal(hal->dev, op, fault_sig, false);
527 mcpwm_ll_fault_oneshot_enable_signal(hal->dev, op, fault_sig, true);
528 mcpwm_ll_fault_set_oneshot_action(hal->dev, op, 0, action_on_pwmxa, action_on_pwmxa);
529 mcpwm_ll_fault_set_oneshot_action(hal->dev, op, 1, action_on_pwmxb, action_on_pwmxb);
530 mcpwm_critical_exit(mcpwm_num);
531 return ESP_OK;
532 }
533
mcpwm_capture_enable(mcpwm_unit_t mcpwm_num,mcpwm_capture_signal_t cap_sig,mcpwm_capture_on_edge_t cap_edge,uint32_t num_of_pulse)534 esp_err_t mcpwm_capture_enable(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig, mcpwm_capture_on_edge_t cap_edge,
535 uint32_t num_of_pulse)
536 {
537 MCPWM_CHECK(mcpwm_num < SOC_MCPWM_PERIPH_NUM, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
538 mcpwm_hal_init_config_t init_config = {
539 .host_id = mcpwm_num,
540 };
541 mcpwm_hal_capture_config_t cap_conf = {
542 .cap_edge = cap_edge,
543 .prescale = num_of_pulse,
544 };
545 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
546
547 mcpwm_critical_enter(mcpwm_num);
548 //We have to do this here, since there is no standalone init function
549 //without enabling any PWM channels.
550 mcpwm_hal_init(hal, &init_config);
551 mcpwm_hal_hw_init(hal);
552 mcpwm_hal_capture_enable(hal, cap_sig, &cap_conf);
553 mcpwm_critical_exit(mcpwm_num);
554 return ESP_OK;
555 }
556
mcpwm_capture_disable(mcpwm_unit_t mcpwm_num,mcpwm_capture_signal_t cap_sig)557 esp_err_t mcpwm_capture_disable(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig)
558 {
559 MCPWM_CHECK(mcpwm_num < SOC_MCPWM_PERIPH_NUM, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
560
561 mcpwm_critical_enter(mcpwm_num);
562 mcpwm_hal_capture_disable(&context[mcpwm_num].hal, cap_sig);
563 mcpwm_critical_exit(mcpwm_num);
564 return ESP_OK;
565 }
566
mcpwm_capture_signal_get_value(mcpwm_unit_t mcpwm_num,mcpwm_capture_signal_t cap_sig)567 uint32_t mcpwm_capture_signal_get_value(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig)
568 {
569 MCPWM_CHECK(mcpwm_num < SOC_MCPWM_PERIPH_NUM, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
570
571 uint32_t captured_value;
572 mcpwm_hal_capture_get_result(&context[mcpwm_num].hal, cap_sig, &captured_value, NULL);
573 return captured_value;
574 }
575
mcpwm_capture_signal_get_edge(mcpwm_unit_t mcpwm_num,mcpwm_capture_signal_t cap_sig)576 uint32_t mcpwm_capture_signal_get_edge(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig)
577 {
578 MCPWM_CHECK(mcpwm_num < SOC_MCPWM_PERIPH_NUM, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
579 mcpwm_capture_on_edge_t edge;
580 mcpwm_hal_capture_get_result(&context[mcpwm_num].hal, cap_sig, NULL, &edge);
581 return (edge == MCPWM_NEG_EDGE ? 2 : 1);
582 }
583
mcpwm_sync_enable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num,mcpwm_sync_signal_t sync_sig,uint32_t phase_val)584 esp_err_t mcpwm_sync_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_sync_signal_t sync_sig,
585 uint32_t phase_val)
586 {
587 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
588 mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
589 mcpwm_hal_sync_config_t sync_config = {
590 .reload_permillage = phase_val,
591 .sync_sig = sync_sig,
592 };
593
594 mcpwm_critical_enter(mcpwm_num);
595 mcpwm_hal_timer_enable_sync(hal, timer_num, &sync_config);
596 mcpwm_critical_exit(mcpwm_num);
597 return ESP_OK;
598 }
599
mcpwm_sync_disable(mcpwm_unit_t mcpwm_num,mcpwm_timer_t timer_num)600 esp_err_t mcpwm_sync_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
601 {
602 MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
603
604 mcpwm_critical_enter(mcpwm_num);
605 mcpwm_hal_timer_disable_sync(&context[mcpwm_num].hal, timer_num);
606 mcpwm_critical_exit(mcpwm_num);
607 return ESP_OK;
608 }
609
mcpwm_isr_register(mcpwm_unit_t mcpwm_num,void (* fn)(void *),void * arg,int intr_alloc_flags,intr_handle_t * handle)610 esp_err_t mcpwm_isr_register(mcpwm_unit_t mcpwm_num, void (*fn)(void *), void *arg, int intr_alloc_flags, intr_handle_t *handle)
611 {
612 esp_err_t ret;
613 MCPWM_CHECK(mcpwm_num < SOC_MCPWM_PERIPH_NUM, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
614 MCPWM_CHECK(fn != NULL, MCPWM_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG);
615 ret = esp_intr_alloc((ETS_PWM0_INTR_SOURCE + mcpwm_num), intr_alloc_flags, fn, arg, handle);
616 return ret;
617 }
618