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