mcpwm.c 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdio.h>
  7. #include "sdkconfig.h"
  8. #include "freertos/FreeRTOS.h"
  9. #include "freertos/semphr.h"
  10. #include "freertos/xtensa_api.h"
  11. #include "freertos/task.h"
  12. #include "esp_log.h"
  13. #include "esp_err.h"
  14. #include "esp_check.h"
  15. #include "esp_rom_gpio.h"
  16. #include "soc/gpio_periph.h"
  17. #include "soc/mcpwm_periph.h"
  18. #include "hal/mcpwm_hal.h"
  19. #include "hal/gpio_hal.h"
  20. #include "hal/mcpwm_ll.h"
  21. #include "driver/mcpwm.h"
  22. #include "driver/periph_ctrl.h"
  23. static const char *TAG = "mcpwm";
  24. #define MCPWM_DRIVER_INIT_ERROR "MCPWM DRIVER NOT INITIALIZED"
  25. #define MCPWM_GROUP_NUM_ERROR "MCPWM GROUP NUM ERROR"
  26. #define MCPWM_PRESCALE_ERROR "MCPWM PRESCALE ERROR"
  27. #define MCPWM_TIMER_ERROR "MCPWM TIMER NUM ERROR"
  28. #define MCPWM_CAPTURE_ERROR "MCPWM CAPTURE NUM ERROR"
  29. #define MCPWM_PARAM_ADDR_ERROR "MCPWM PARAM ADDR ERROR"
  30. #define MCPWM_DUTY_TYPE_ERROR "MCPWM DUTY TYPE ERROR"
  31. #define MCPWM_GPIO_ERROR "MCPWM GPIO NUM ERROR"
  32. #define MCPWM_GEN_ERROR "MCPWM GENERATOR ERROR"
  33. #define MCPWM_DT_ERROR "MCPWM DEADTIME TYPE ERROR"
  34. #define MCPWM_CAP_EXIST_ERROR "MCPWM USER CAP INT SERVICE ALREADY EXISTS"
  35. #ifdef CONFIG_MCPWM_ISR_IN_IRAM
  36. #define MCPWM_ISR_ATTR IRAM_ATTR
  37. #define MCPWM_INTR_FLAG (ESP_INTR_FLAG_IRAM)
  38. #else
  39. #define MCPWM_ISR_ATTR
  40. #define MCPWM_INTR_FLAG 0
  41. #endif
  42. #define MCPWM_GROUP_CLK_PRESCALE (16)
  43. #define MCPWM_GROUP_CLK_HZ (SOC_MCPWM_BASE_CLK_HZ / MCPWM_GROUP_CLK_PRESCALE)
  44. #define MCPWM_TIMER_CLK_HZ (MCPWM_GROUP_CLK_HZ / 10)
  45. _Static_assert(SOC_MCPWM_OPERATORS_PER_GROUP >= SOC_MCPWM_TIMERS_PER_GROUP, "This driver assumes the timer num equals to the operator num.");
  46. _Static_assert(SOC_MCPWM_COMPARATORS_PER_OPERATOR >= SOC_MCPWM_GENERATORS_PER_OPERATOR, "This driver assumes the generator num equals to the generator num.");
  47. _Static_assert(SOC_MCPWM_GENERATORS_PER_OPERATOR == 2, "This driver assumes the generator num equals to 2.");
  48. #define MCPWM_TIMER_ID_CHECK(mcpwm_num, timer_num) \
  49. do { \
  50. ESP_RETURN_ON_FALSE((mcpwm_num) < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR); \
  51. ESP_RETURN_ON_FALSE((timer_num) < SOC_MCPWM_TIMERS_PER_GROUP, ESP_ERR_INVALID_ARG, TAG, MCPWM_TIMER_ERROR); \
  52. } while (0)
  53. #define MCPWM_TIMER_CHECK(mcpwm_num, timer_num) \
  54. do { \
  55. MCPWM_TIMER_ID_CHECK(mcpwm_num, timer_num); \
  56. ESP_RETURN_ON_FALSE(context[mcpwm_num].hal.dev, ESP_ERR_INVALID_STATE, TAG, MCPWM_DRIVER_INIT_ERROR); \
  57. } while (0)
  58. #define MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen) \
  59. do { \
  60. MCPWM_TIMER_CHECK(mcpwm_num, timer_num); \
  61. ESP_RETURN_ON_FALSE((gen) < MCPWM_GEN_MAX, ESP_ERR_INVALID_ARG, TAG, MCPWM_GEN_ERROR); \
  62. } while (0)
  63. typedef struct {
  64. cap_isr_cb_t fn; // isr function
  65. void *args; // isr function args
  66. } cap_isr_func_t;
  67. typedef struct {
  68. mcpwm_hal_context_t hal;
  69. portMUX_TYPE spinlock;
  70. _lock_t mutex_lock;
  71. const int group_id;
  72. int group_pre_scale; // starts from 1, not 0. will be subtracted by 1 in ll driver
  73. int timer_pre_scale[SOC_MCPWM_TIMERS_PER_GROUP]; // same as above
  74. intr_handle_t mcpwm_intr_handle; // handler for ISR register, one per MCPWM group
  75. cap_isr_func_t cap_isr_func[SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER]; // handler for ISR callback, one for each cap ch
  76. } mcpwm_context_t;
  77. static mcpwm_context_t context[SOC_MCPWM_GROUPS] = {
  78. [0] = {
  79. .hal = {MCPWM_LL_GET_HW(0)},
  80. .spinlock = portMUX_INITIALIZER_UNLOCKED,
  81. .group_id = 0,
  82. .group_pre_scale = SOC_MCPWM_BASE_CLK_HZ / MCPWM_GROUP_CLK_HZ,
  83. .timer_pre_scale = {[0 ... SOC_MCPWM_TIMERS_PER_GROUP - 1] =
  84. MCPWM_GROUP_CLK_HZ / MCPWM_TIMER_CLK_HZ},
  85. .mcpwm_intr_handle = NULL,
  86. .cap_isr_func = {[0 ... SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER - 1] = {NULL, NULL}},
  87. },
  88. [1] = {
  89. .hal = {MCPWM_LL_GET_HW(1)},
  90. .spinlock = portMUX_INITIALIZER_UNLOCKED,
  91. .group_id = 1,
  92. .group_pre_scale = SOC_MCPWM_BASE_CLK_HZ / MCPWM_GROUP_CLK_HZ,
  93. .timer_pre_scale = {[0 ... SOC_MCPWM_TIMERS_PER_GROUP - 1] =
  94. MCPWM_GROUP_CLK_HZ / MCPWM_TIMER_CLK_HZ},
  95. .mcpwm_intr_handle = NULL,
  96. .cap_isr_func = {[0 ... SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER - 1] = {NULL, NULL}},
  97. }
  98. };
  99. typedef void (*mcpwm_ll_gen_set_event_action_t)(mcpwm_dev_t *mcpwm, int op, int gen, int action);
  100. static inline void mcpwm_critical_enter(mcpwm_unit_t mcpwm_num)
  101. {
  102. portENTER_CRITICAL(&context[mcpwm_num].spinlock);
  103. }
  104. static inline void mcpwm_critical_exit(mcpwm_unit_t mcpwm_num)
  105. {
  106. portEXIT_CRITICAL(&context[mcpwm_num].spinlock);
  107. }
  108. static inline void mcpwm_mutex_lock(mcpwm_unit_t mcpwm_num){
  109. _lock_acquire(&context[mcpwm_num].mutex_lock);
  110. }
  111. static inline void mcpwm_mutex_unlock(mcpwm_unit_t mcpwm_num){
  112. _lock_release(&context[mcpwm_num].mutex_lock);
  113. }
  114. esp_err_t mcpwm_gpio_init(mcpwm_unit_t mcpwm_num, mcpwm_io_signals_t io_signal, int gpio_num)
  115. {
  116. if (gpio_num < 0) { // ignore on minus gpio number
  117. return ESP_OK;
  118. }
  119. ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
  120. ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, MCPWM_GPIO_ERROR);
  121. if (io_signal <= MCPWM2B) { // Generator output signal
  122. ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, MCPWM_GPIO_ERROR);
  123. gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
  124. int operator_id = io_signal / 2;
  125. int generator_id = io_signal % 2;
  126. esp_rom_gpio_connect_out_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].operators[operator_id].generators[generator_id].pwm_sig, 0, 0);
  127. } else if (io_signal <= MCPWM_SYNC_2) { // External sync input signal
  128. gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
  129. int gpio_sync_id = io_signal - MCPWM_SYNC_0;
  130. esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].gpio_synchros[gpio_sync_id].sync_sig, 0);
  131. } else if (io_signal <= MCPWM_FAULT_2) { // Fault input signal
  132. gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
  133. int fault_id = io_signal - MCPWM_FAULT_0;
  134. esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].gpio_faults[fault_id].fault_sig, 0);
  135. } else if (io_signal >= MCPWM_CAP_0 && io_signal <= MCPWM_CAP_2) { // Capture input signal
  136. gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
  137. int capture_id = io_signal - MCPWM_CAP_0;
  138. esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].captures[capture_id].cap_sig, 0);
  139. }
  140. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO);
  141. return ESP_OK;
  142. }
  143. esp_err_t mcpwm_set_pin(mcpwm_unit_t mcpwm_num, const mcpwm_pin_config_t *mcpwm_pin)
  144. {
  145. ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
  146. mcpwm_gpio_init(mcpwm_num, MCPWM0A, mcpwm_pin->mcpwm0a_out_num); //MCPWM0A
  147. mcpwm_gpio_init(mcpwm_num, MCPWM0B, mcpwm_pin->mcpwm0b_out_num); //MCPWM0B
  148. mcpwm_gpio_init(mcpwm_num, MCPWM1A, mcpwm_pin->mcpwm1a_out_num); //MCPWM1A
  149. mcpwm_gpio_init(mcpwm_num, MCPWM1B, mcpwm_pin->mcpwm1b_out_num); //MCPWM1B
  150. mcpwm_gpio_init(mcpwm_num, MCPWM2A, mcpwm_pin->mcpwm2a_out_num); //MCPWM2A
  151. mcpwm_gpio_init(mcpwm_num, MCPWM2B, mcpwm_pin->mcpwm2b_out_num); //MCPWM2B
  152. mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_0, mcpwm_pin->mcpwm_sync0_in_num); //SYNC0
  153. mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_1, mcpwm_pin->mcpwm_sync1_in_num); //SYNC1
  154. mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_2, mcpwm_pin->mcpwm_sync2_in_num); //SYNC2
  155. mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_0, mcpwm_pin->mcpwm_fault0_in_num); //FAULT0
  156. mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_1, mcpwm_pin->mcpwm_fault1_in_num); //FAULT1
  157. mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_2, mcpwm_pin->mcpwm_fault2_in_num); //FAULT2
  158. mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_0, mcpwm_pin->mcpwm_cap0_in_num); //CAP0
  159. mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_1, mcpwm_pin->mcpwm_cap1_in_num); //CAP1
  160. mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_2, mcpwm_pin->mcpwm_cap2_in_num); //CAP2
  161. return ESP_OK;
  162. }
  163. esp_err_t mcpwm_start(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  164. {
  165. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  166. mcpwm_critical_enter(mcpwm_num);
  167. mcpwm_ll_timer_set_execute_command(context[mcpwm_num].hal.dev, timer_num, MCPWM_TIMER_START_NO_STOP);
  168. mcpwm_critical_exit(mcpwm_num);
  169. return ESP_OK;
  170. }
  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. mcpwm_critical_enter(mcpwm_num);
  175. mcpwm_ll_timer_set_execute_command(context[mcpwm_num].hal.dev, timer_num, MCPWM_TIMER_STOP_AT_ZERO);
  176. mcpwm_critical_exit(mcpwm_num);
  177. return ESP_OK;
  178. }
  179. esp_err_t mcpwm_group_set_resolution(mcpwm_unit_t mcpwm_num, unsigned long int resolution) {
  180. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  181. int pre_scale_temp = SOC_MCPWM_BASE_CLK_HZ / resolution;
  182. ESP_RETURN_ON_FALSE(pre_scale_temp >= 1, ESP_ERR_INVALID_ARG, TAG, "invalid resolution");
  183. context[mcpwm_num].group_pre_scale = pre_scale_temp;
  184. mcpwm_critical_enter(mcpwm_num);
  185. mcpwm_ll_group_set_clock_prescale(hal->dev, context[mcpwm_num].group_pre_scale);
  186. mcpwm_critical_exit(mcpwm_num);
  187. return ESP_OK;
  188. }
  189. esp_err_t mcpwm_timer_set_resolution(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, unsigned long int resolution) {
  190. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  191. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  192. int pre_scale_temp = SOC_MCPWM_BASE_CLK_HZ / context[mcpwm_num].group_pre_scale / resolution;
  193. ESP_RETURN_ON_FALSE(pre_scale_temp >= 1, ESP_ERR_INVALID_ARG, TAG, "invalid resolution");
  194. context[mcpwm_num].timer_pre_scale[timer_num] = pre_scale_temp;
  195. mcpwm_critical_enter(mcpwm_num);
  196. mcpwm_ll_timer_set_clock_prescale(hal->dev, timer_num, context[mcpwm_num].timer_pre_scale[timer_num]);
  197. mcpwm_critical_exit(mcpwm_num);
  198. return ESP_OK;
  199. }
  200. esp_err_t mcpwm_set_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint32_t frequency)
  201. {
  202. //the driver currently always use the timer x for operator x
  203. const int op = timer_num;
  204. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  205. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  206. mcpwm_critical_enter(mcpwm_num);
  207. mcpwm_ll_timer_update_period_at_once(hal->dev, timer_num);
  208. uint32_t previous_peak = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false);
  209. int real_group_prescale = mcpwm_ll_group_get_clock_prescale(hal->dev);
  210. unsigned long int real_timer_clk_hz =
  211. SOC_MCPWM_BASE_CLK_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
  212. uint32_t new_peak = real_timer_clk_hz / frequency;
  213. mcpwm_ll_timer_set_peak(hal->dev, timer_num, new_peak, false);
  214. // keep the duty cycle unchanged
  215. float scale = ((float)new_peak) / previous_peak;
  216. // the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
  217. uint32_t previous_cmp_a = mcpwm_ll_operator_get_compare_value(hal->dev, op, 0);
  218. uint32_t previous_cmp_b = mcpwm_ll_operator_get_compare_value(hal->dev, op, 1);
  219. // update compare value immediately
  220. mcpwm_ll_operator_update_compare_at_once(hal->dev, op, 0);
  221. mcpwm_ll_operator_update_compare_at_once(hal->dev, op, 1);
  222. mcpwm_ll_operator_set_compare_value(hal->dev, op, 0, (uint32_t)(previous_cmp_a * scale));
  223. mcpwm_ll_operator_set_compare_value(hal->dev, op, 1, (uint32_t)(previous_cmp_b * scale));
  224. mcpwm_critical_exit(mcpwm_num);
  225. return ESP_OK;
  226. }
  227. esp_err_t mcpwm_set_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, float duty)
  228. {
  229. //the driver currently always use the timer x for operator x
  230. const int op = timer_num;
  231. //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
  232. const int cmp = gen;
  233. MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
  234. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  235. mcpwm_critical_enter(mcpwm_num);
  236. uint32_t set_duty = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false) * duty / 100;
  237. mcpwm_ll_operator_set_compare_value(hal->dev, op, cmp, set_duty);
  238. mcpwm_ll_operator_enable_update_compare_on_tez(hal->dev, op, cmp, true);
  239. mcpwm_critical_exit(mcpwm_num);
  240. return ESP_OK;
  241. }
  242. 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)
  243. {
  244. //the driver currently always use the timer x for operator x
  245. const int op = timer_num;
  246. //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
  247. const int cmp = gen;
  248. MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
  249. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  250. mcpwm_critical_enter(mcpwm_num);
  251. int real_group_prescale = mcpwm_ll_group_get_clock_prescale(hal->dev);
  252. unsigned long int real_timer_clk_hz =
  253. SOC_MCPWM_BASE_CLK_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
  254. mcpwm_ll_operator_set_compare_value(hal->dev, op, cmp, duty_in_us * real_timer_clk_hz / 1000000);
  255. mcpwm_ll_operator_enable_update_compare_on_tez(hal->dev, op, cmp, true);
  256. mcpwm_critical_exit(mcpwm_num);
  257. return ESP_OK;
  258. }
  259. esp_err_t mcpwm_set_duty_type(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen,
  260. mcpwm_duty_type_t duty_type)
  261. {
  262. //the driver currently always use the timer x for operator x
  263. const int op = timer_num;
  264. MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
  265. ESP_RETURN_ON_FALSE(duty_type < MCPWM_DUTY_MODE_MAX, ESP_ERR_INVALID_ARG, TAG, MCPWM_DUTY_TYPE_ERROR);
  266. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  267. //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output
  268. mcpwm_critical_enter(mcpwm_num);
  269. switch (mcpwm_ll_timer_get_count_mode(hal->dev, timer_num)) {
  270. case MCPWM_TIMER_COUNT_MODE_UP:
  271. if (duty_type == MCPWM_DUTY_MODE_0) {
  272. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_ZERO, MCPWM_GEN_ACTION_HIGH);
  273. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_PEAK, MCPWM_GEN_ACTION_KEEP);
  274. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_LOW);
  275. } else if (duty_type == MCPWM_DUTY_MODE_1) {
  276. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_ZERO, MCPWM_GEN_ACTION_LOW);
  277. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_NO_CHANGE);
  278. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_HIGH);
  279. } else if (duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_LOW) {
  280. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_FORCE_LOW);
  281. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_FORCE_LOW);
  282. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_LOW);
  283. } else if (duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH) {
  284. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_FORCE_HIGH);
  285. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_FORCE_HIGH);
  286. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_HIGH);
  287. }
  288. break;
  289. case MCPWM_TIMER_COUNT_MODE_DOWN:
  290. if (duty_type == MCPWM_DUTY_MODE_0) {
  291. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_FORCE_LOW);
  292. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_NO_CHANGE);
  293. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_HIGH);
  294. } else if (duty_type == MCPWM_DUTY_MODE_1) {
  295. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_FORCE_HIGH);
  296. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_NO_CHANGE);
  297. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_LOW);
  298. } else if (duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_LOW) {
  299. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_FORCE_LOW);
  300. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_FORCE_LOW);
  301. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_LOW);
  302. } else if (duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH) {
  303. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_FORCE_HIGH);
  304. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_FORCE_HIGH);
  305. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_HIGH);
  306. }
  307. break;
  308. case MCPWM_TIMER_COUNT_MODE_UP_DOWN:
  309. if (duty_type == MCPWM_DUTY_MODE_0) {
  310. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_FORCE_HIGH);
  311. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_LOW);
  312. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_HIGH);
  313. } else if (duty_type == MCPWM_DUTY_MODE_1) {
  314. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_FORCE_LOW);
  315. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_HIGH);
  316. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_LOW);
  317. } else if (duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_LOW) {
  318. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_FORCE_LOW);
  319. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_FORCE_LOW);
  320. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_FORCE_LOW);
  321. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_FORCE_LOW);
  322. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_LOW);
  323. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_LOW);
  324. } else if (duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH) {
  325. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_FORCE_HIGH);
  326. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_FORCE_HIGH);
  327. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_ZERO, MCPWM_ACTION_FORCE_HIGH);
  328. mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_PEAK, MCPWM_ACTION_FORCE_HIGH);
  329. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_HIGH);
  330. mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_HIGH);
  331. }
  332. break;
  333. default:
  334. break;
  335. }
  336. mcpwm_critical_exit(mcpwm_num);
  337. return ESP_OK;
  338. }
  339. esp_err_t mcpwm_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_config_t *mcpwm_conf)
  340. {
  341. const int op = timer_num;
  342. MCPWM_TIMER_ID_CHECK(mcpwm_num, op);
  343. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  344. periph_module_enable(mcpwm_periph_signals.groups[mcpwm_num].module);
  345. mcpwm_hal_init_config_t config = {
  346. .host_id = mcpwm_num
  347. };
  348. mcpwm_hal_init(hal, &config);
  349. mcpwm_critical_enter(mcpwm_num);
  350. mcpwm_ll_group_set_clock_prescale(hal->dev, context[mcpwm_num].group_pre_scale);
  351. mcpwm_ll_group_enable_shadow_mode(hal->dev);
  352. mcpwm_ll_group_flush_shadow(hal->dev);
  353. mcpwm_ll_timer_set_clock_prescale(hal->dev, timer_num, context[mcpwm_num].timer_pre_scale[timer_num]);
  354. mcpwm_ll_timer_set_count_mode(hal->dev, timer_num, mcpwm_conf->counter_mode);
  355. mcpwm_ll_timer_update_period_at_once(hal->dev, timer_num);
  356. int real_group_prescale = mcpwm_ll_group_get_clock_prescale(hal->dev);
  357. unsigned long int real_timer_clk_hz =
  358. SOC_MCPWM_BASE_CLK_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
  359. mcpwm_ll_timer_set_peak(hal->dev, timer_num, real_timer_clk_hz / mcpwm_conf->frequency, false);
  360. mcpwm_ll_operator_select_timer(hal->dev, timer_num, timer_num); //the driver currently always use the timer x for operator x
  361. mcpwm_critical_exit(mcpwm_num);
  362. mcpwm_set_duty(mcpwm_num, timer_num, 0, mcpwm_conf->cmpr_a);
  363. mcpwm_set_duty(mcpwm_num, timer_num, 1, mcpwm_conf->cmpr_b);
  364. mcpwm_set_duty_type(mcpwm_num, timer_num, 0, mcpwm_conf->duty_mode);
  365. mcpwm_set_duty_type(mcpwm_num, timer_num, 1, mcpwm_conf->duty_mode);
  366. mcpwm_start(mcpwm_num, timer_num);
  367. return ESP_OK;
  368. }
  369. uint32_t mcpwm_get_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  370. {
  371. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  372. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  373. mcpwm_critical_enter(mcpwm_num);
  374. int real_group_prescale = mcpwm_ll_group_get_clock_prescale(hal->dev);
  375. unsigned long int real_timer_clk_hz =
  376. SOC_MCPWM_BASE_CLK_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
  377. uint32_t peak = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false);
  378. uint32_t freq = real_timer_clk_hz / peak;
  379. mcpwm_critical_exit(mcpwm_num);
  380. return freq;
  381. }
  382. float mcpwm_get_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen)
  383. {
  384. //the driver currently always use the timer x for operator x
  385. const int op = timer_num;
  386. MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
  387. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  388. mcpwm_critical_enter(mcpwm_num);
  389. float duty = 100.0 * mcpwm_ll_operator_get_compare_value(hal->dev, op, gen) / mcpwm_ll_timer_get_peak(hal->dev, timer_num, false);
  390. mcpwm_critical_exit(mcpwm_num);
  391. return duty;
  392. }
  393. uint32_t mcpwm_get_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t gen){
  394. //the driver currently always use the timer x for operator x
  395. const int op = timer_num;
  396. MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen);
  397. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  398. mcpwm_critical_enter(mcpwm_num);
  399. int real_group_prescale = mcpwm_ll_group_get_clock_prescale(hal->dev);
  400. unsigned long int real_timer_clk_hz =
  401. SOC_MCPWM_BASE_CLK_HZ / real_group_prescale / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
  402. uint32_t duty = mcpwm_ll_operator_get_compare_value(hal->dev, op, gen) * (1000000.0 / real_timer_clk_hz);
  403. mcpwm_critical_exit(mcpwm_num);
  404. return duty;
  405. }
  406. esp_err_t mcpwm_set_signal_high(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen)
  407. {
  408. //the driver currently always use the timer x for operator x
  409. return mcpwm_set_duty_type(mcpwm_num, timer_num, gen, MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH);
  410. }
  411. esp_err_t mcpwm_set_signal_low(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen)
  412. {
  413. //the driver currently always use the timer x for operator x
  414. return mcpwm_set_duty_type(mcpwm_num, timer_num, gen, MCPWM_HAL_GENERATOR_MODE_FORCE_LOW);
  415. }
  416. esp_err_t mcpwm_carrier_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  417. {
  418. //the driver currently always use the timer x for operator x
  419. const int op = timer_num;
  420. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  421. mcpwm_critical_enter(mcpwm_num);
  422. mcpwm_ll_carrier_enable(context[mcpwm_num].hal.dev, op, true);
  423. mcpwm_critical_exit(mcpwm_num);
  424. return ESP_OK;
  425. }
  426. esp_err_t mcpwm_carrier_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  427. {
  428. //the driver currently always use the timer x for operator x
  429. const int op = timer_num;
  430. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  431. mcpwm_critical_enter(mcpwm_num);
  432. mcpwm_ll_carrier_enable(context[mcpwm_num].hal.dev, op, false);
  433. mcpwm_critical_exit(mcpwm_num);
  434. return ESP_OK;
  435. }
  436. esp_err_t mcpwm_carrier_set_period(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_period)
  437. {
  438. //the driver currently always use the timer x for operator x
  439. const int op = timer_num;
  440. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  441. mcpwm_critical_enter(mcpwm_num);
  442. mcpwm_ll_carrier_set_prescale(context[mcpwm_num].hal.dev, op, carrier_period + 1);
  443. mcpwm_critical_exit(mcpwm_num);
  444. return ESP_OK;
  445. }
  446. esp_err_t mcpwm_carrier_set_duty_cycle(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_duty)
  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_critical_enter(mcpwm_num);
  452. mcpwm_ll_carrier_set_duty(context[mcpwm_num].hal.dev, op, carrier_duty);
  453. mcpwm_critical_exit(mcpwm_num);
  454. return ESP_OK;
  455. }
  456. esp_err_t mcpwm_carrier_oneshot_mode_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t pulse_width)
  457. {
  458. //the driver currently always use the timer x for operator x
  459. const int op = timer_num;
  460. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  461. mcpwm_critical_enter(mcpwm_num);
  462. mcpwm_ll_carrier_set_oneshot_width(context[mcpwm_num].hal.dev, op, pulse_width + 1);
  463. mcpwm_critical_exit(mcpwm_num);
  464. return ESP_OK;
  465. }
  466. esp_err_t mcpwm_carrier_oneshot_mode_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  467. {
  468. return mcpwm_carrier_oneshot_mode_enable(mcpwm_num, timer_num, 0);
  469. }
  470. esp_err_t mcpwm_carrier_output_invert(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num,
  471. mcpwm_carrier_out_ivt_t carrier_ivt_mode)
  472. {
  473. //the driver currently always use the timer x for operator x
  474. const int op = timer_num;
  475. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  476. mcpwm_critical_enter(mcpwm_num);
  477. mcpwm_ll_carrier_out_invert(context[mcpwm_num].hal.dev, op, carrier_ivt_mode);
  478. mcpwm_critical_exit(mcpwm_num);
  479. return ESP_OK;
  480. }
  481. esp_err_t mcpwm_carrier_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_carrier_config_t *carrier_conf)
  482. {
  483. //the driver currently always use the timer x for operator x
  484. const int op = timer_num;
  485. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  486. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  487. mcpwm_carrier_enable(mcpwm_num, timer_num);
  488. mcpwm_carrier_set_period(mcpwm_num, timer_num, carrier_conf->carrier_period);
  489. mcpwm_carrier_set_duty_cycle(mcpwm_num, timer_num, carrier_conf->carrier_duty);
  490. if (carrier_conf->carrier_os_mode == MCPWM_ONESHOT_MODE_EN) {
  491. mcpwm_carrier_oneshot_mode_enable(mcpwm_num, timer_num, carrier_conf->pulse_width_in_os);
  492. } else {
  493. mcpwm_carrier_oneshot_mode_disable(mcpwm_num, timer_num);
  494. }
  495. mcpwm_carrier_output_invert(mcpwm_num, timer_num, carrier_conf->carrier_ivt_mode);
  496. mcpwm_critical_enter(mcpwm_num);
  497. mcpwm_ll_carrier_in_invert(hal->dev, op, false);
  498. mcpwm_critical_exit(mcpwm_num);
  499. return ESP_OK;
  500. }
  501. esp_err_t mcpwm_deadtime_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_deadtime_type_t dt_mode,
  502. uint32_t red, uint32_t fed)
  503. {
  504. //the driver currently always use the timer x for operator x
  505. const int op = timer_num;
  506. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  507. ESP_RETURN_ON_FALSE(dt_mode < MCPWM_DEADTIME_TYPE_MAX, ESP_ERR_INVALID_ARG, TAG, MCPWM_DT_ERROR);
  508. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  509. mcpwm_critical_enter(mcpwm_num);
  510. mcpwm_ll_deadtime_enable_update_delay_on_tez(hal->dev, op, true);
  511. // The dead time delay unit equals to MCPWM group resolution
  512. mcpwm_ll_deadtime_resolution_to_timer(hal->dev, op, false);
  513. mcpwm_ll_deadtime_set_rising_delay(hal->dev, op, red + 1);
  514. mcpwm_ll_deadtime_set_falling_delay(hal->dev, op, fed + 1);
  515. switch (dt_mode) {
  516. case MCPWM_BYPASS_RED:
  517. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0
  518. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, true); // S1=1
  519. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2=0
  520. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0
  521. mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0
  522. mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0
  523. break;
  524. case MCPWM_BYPASS_FED:
  525. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, true); // S0=1
  526. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false); // S1=0
  527. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2=0
  528. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0
  529. mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0
  530. mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0
  531. break;
  532. case MCPWM_ACTIVE_HIGH_MODE:
  533. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0
  534. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false); // S1=0
  535. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2=0
  536. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0
  537. mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0
  538. mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0
  539. break;
  540. case MCPWM_ACTIVE_LOW_MODE:
  541. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0
  542. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false); // S1=0
  543. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, true); // S2=1
  544. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, true); // S3=1
  545. mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0
  546. mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0
  547. break;
  548. case MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE:
  549. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0
  550. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false); // S1=0
  551. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2=0
  552. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, true); // S3=1
  553. mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0
  554. mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0
  555. break;
  556. case MCPWM_ACTIVE_LOW_COMPLIMENT_MODE:
  557. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0
  558. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false); // S1=0
  559. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, true); // S2=1
  560. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0
  561. mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0
  562. mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0
  563. break;
  564. case MCPWM_ACTIVE_RED_FED_FROM_PWMXA:
  565. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0
  566. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0
  567. mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0
  568. mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 0, true); // S6=1
  569. mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 1, false); // S7=0
  570. mcpwm_ll_deadtime_enable_deb(hal->dev, op, true); // S8=1
  571. break;
  572. case MCPWM_ACTIVE_RED_FED_FROM_PWMXB:
  573. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0
  574. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0
  575. mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 1); // S4=1
  576. mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 0, true); // S6=1
  577. mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 1, false); // S7=0
  578. mcpwm_ll_deadtime_enable_deb(hal->dev, op, true); // S8=1
  579. break;
  580. default :
  581. break;
  582. }
  583. mcpwm_critical_exit(mcpwm_num);
  584. return ESP_OK;
  585. }
  586. esp_err_t mcpwm_deadtime_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  587. {
  588. //the driver currently always use the timer x for operator x
  589. const int op = timer_num;
  590. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  591. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  592. mcpwm_critical_enter(mcpwm_num);
  593. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, true); // S0
  594. mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, true); // S1
  595. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2
  596. mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3
  597. mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4
  598. mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5
  599. mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 0, false); // S6
  600. mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 1, false); // S7
  601. mcpwm_ll_deadtime_enable_deb(hal->dev, op, false); // S8
  602. mcpwm_critical_exit(mcpwm_num);
  603. return ESP_OK;
  604. }
  605. esp_err_t mcpwm_fault_init(mcpwm_unit_t mcpwm_num, mcpwm_fault_input_level_t intput_level, mcpwm_fault_signal_t fault_sig)
  606. {
  607. ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
  608. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  609. mcpwm_critical_enter(mcpwm_num);
  610. mcpwm_ll_fault_enable_detection(hal->dev, fault_sig, true);
  611. mcpwm_ll_fault_set_active_level(hal->dev, fault_sig, intput_level);
  612. mcpwm_critical_exit(mcpwm_num);
  613. return ESP_OK;
  614. }
  615. esp_err_t mcpwm_fault_deinit(mcpwm_unit_t mcpwm_num, mcpwm_fault_signal_t fault_sig)
  616. {
  617. ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
  618. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  619. mcpwm_critical_enter(mcpwm_num);
  620. mcpwm_ll_fault_enable_detection(hal->dev, fault_sig, false);
  621. for (int i = 0; i < SOC_MCPWM_OPERATORS_PER_GROUP; i++) {
  622. mcpwm_ll_fault_clear_ost(hal->dev, i); // make sure operator has exit the ost fault state totally
  623. }
  624. mcpwm_critical_exit(mcpwm_num);
  625. return ESP_OK;
  626. }
  627. esp_err_t mcpwm_fault_set_cyc_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig,
  628. mcpwm_output_action_t action_on_pwmxa, mcpwm_output_action_t action_on_pwmxb)
  629. {
  630. //the driver currently always use the timer x for operator x
  631. const int op = timer_num;
  632. MCPWM_TIMER_CHECK(mcpwm_num, op);
  633. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  634. mcpwm_critical_enter(mcpwm_num);
  635. mcpwm_ll_fault_enable_cbc_mode(hal->dev, op, fault_sig, true);
  636. mcpwm_ll_fault_enable_cbc_refresh_on_tez(hal->dev, op, true);
  637. mcpwm_ll_fault_enable_oneshot_mode(hal->dev, op, fault_sig, false);
  638. mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TRIP_TYPE_CBC, action_on_pwmxa);
  639. mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_UP, MCPWM_TRIP_TYPE_CBC, action_on_pwmxa);
  640. mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TRIP_TYPE_CBC, action_on_pwmxb);
  641. mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_UP, MCPWM_TRIP_TYPE_CBC, action_on_pwmxb);
  642. mcpwm_critical_exit(mcpwm_num);
  643. return ESP_OK;
  644. }
  645. esp_err_t mcpwm_fault_set_oneshot_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig,
  646. mcpwm_action_on_pwmxa_t action_on_pwmxa, mcpwm_action_on_pwmxb_t action_on_pwmxb)
  647. {
  648. //the driver currently always use the timer x for operator x
  649. const int op = timer_num;
  650. MCPWM_TIMER_CHECK(mcpwm_num, op);
  651. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  652. mcpwm_critical_enter(mcpwm_num);
  653. mcpwm_ll_fault_clear_ost(hal->dev, op);
  654. mcpwm_ll_fault_enable_oneshot_mode(hal->dev, op, fault_sig, true);
  655. mcpwm_ll_fault_enable_cbc_mode(hal->dev, op, fault_sig, false);
  656. mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TRIP_TYPE_OST, action_on_pwmxa);
  657. mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_UP, MCPWM_TRIP_TYPE_OST, action_on_pwmxa);
  658. mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TRIP_TYPE_OST, action_on_pwmxb);
  659. mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_UP, MCPWM_TRIP_TYPE_OST, action_on_pwmxb);
  660. mcpwm_critical_exit(mcpwm_num);
  661. return ESP_OK;
  662. }
  663. static void MCPWM_ISR_ATTR mcpwm_default_isr_handler(void *arg) {
  664. mcpwm_context_t *curr_context = (mcpwm_context_t *) arg;
  665. uint32_t intr_status = mcpwm_ll_intr_get_capture_status(curr_context->hal.dev);
  666. mcpwm_ll_intr_clear_capture_status(curr_context->hal.dev, intr_status);
  667. bool need_yield = false;
  668. for (int i = 0; i < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER; ++i) {
  669. if ((intr_status >> i) & 0x1) {
  670. if (curr_context->cap_isr_func[i].fn != NULL) {
  671. cap_event_data_t edata;
  672. edata.cap_edge = mcpwm_ll_capture_is_negedge(curr_context->hal.dev, i) ? MCPWM_NEG_EDGE
  673. : MCPWM_POS_EDGE;
  674. edata.cap_value = mcpwm_ll_capture_get_value(curr_context->hal.dev, i);
  675. if (curr_context->cap_isr_func[i].fn(curr_context->group_id, i, &edata,
  676. curr_context->cap_isr_func[i].args)) {
  677. need_yield = true;
  678. }
  679. }
  680. }
  681. }
  682. if (need_yield) {
  683. portYIELD_FROM_ISR();
  684. }
  685. }
  686. esp_err_t mcpwm_capture_enable(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig, mcpwm_capture_on_edge_t cap_edge,
  687. uint32_t num_of_pulse)
  688. {
  689. ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
  690. ESP_RETURN_ON_FALSE(num_of_pulse <= MCPWM_LL_MAX_CAPTURE_PRESCALE, ESP_ERR_INVALID_ARG, TAG, MCPWM_PRESCALE_ERROR);
  691. ESP_RETURN_ON_FALSE(cap_sig < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR);
  692. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  693. // enable MCPWM module incase user don't use `mcpwm_init` at all
  694. periph_module_enable(mcpwm_periph_signals.groups[mcpwm_num].module);
  695. mcpwm_hal_init_config_t init_config = {
  696. .host_id = mcpwm_num,
  697. };
  698. mcpwm_critical_enter(mcpwm_num);
  699. mcpwm_hal_init(hal, &init_config);
  700. mcpwm_ll_group_set_clock_prescale(hal->dev, context[mcpwm_num].group_pre_scale);
  701. mcpwm_ll_capture_enable_timer(hal->dev, true);
  702. mcpwm_ll_capture_enable_channel(hal->dev, cap_sig, true);
  703. mcpwm_ll_capture_enable_negedge(hal->dev, cap_sig, cap_edge & MCPWM_NEG_EDGE);
  704. mcpwm_ll_capture_enable_posedge(hal->dev, cap_sig, cap_edge & MCPWM_POS_EDGE);
  705. mcpwm_ll_capture_set_prescale(hal->dev, cap_sig, num_of_pulse + 1);
  706. // capture feature should be used with interupt, so enable it by default
  707. mcpwm_ll_intr_enable_capture(hal->dev, cap_sig, true);
  708. mcpwm_ll_intr_clear_capture_status(hal->dev, 1 << cap_sig);
  709. mcpwm_critical_exit(mcpwm_num);
  710. return ESP_OK;
  711. }
  712. esp_err_t mcpwm_capture_disable(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig)
  713. {
  714. ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
  715. ESP_RETURN_ON_FALSE(cap_sig < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR);
  716. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  717. mcpwm_critical_enter(mcpwm_num);
  718. mcpwm_ll_capture_enable_channel(hal->dev, cap_sig, false);
  719. mcpwm_ll_intr_enable_capture(hal->dev, cap_sig, false);
  720. mcpwm_critical_exit(mcpwm_num);
  721. periph_module_disable(mcpwm_periph_signals.groups[mcpwm_num].module);
  722. return ESP_OK;
  723. }
  724. esp_err_t mcpwm_capture_enable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_channel_id_t cap_channel, const mcpwm_capture_config_t *cap_conf)
  725. {
  726. ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
  727. ESP_RETURN_ON_FALSE(cap_channel < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR);
  728. ESP_RETURN_ON_FALSE(context[mcpwm_num].cap_isr_func[cap_channel].fn == NULL, ESP_ERR_INVALID_STATE, TAG,
  729. MCPWM_CAP_EXIST_ERROR);
  730. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  731. // enable MCPWM module incase user don't use `mcpwm_init` at all. always increase reference count
  732. periph_module_enable(mcpwm_periph_signals.groups[mcpwm_num].module);
  733. mcpwm_hal_init_config_t init_config = {
  734. .host_id = mcpwm_num
  735. };
  736. mcpwm_hal_init(hal, &init_config);
  737. mcpwm_critical_enter(mcpwm_num);
  738. mcpwm_ll_group_set_clock_prescale(hal->dev, context[mcpwm_num].group_pre_scale);
  739. mcpwm_ll_capture_enable_timer(hal->dev, true);
  740. mcpwm_ll_capture_enable_channel(hal->dev, cap_channel, true);
  741. mcpwm_ll_capture_enable_negedge(hal->dev, cap_channel, cap_conf->cap_edge & MCPWM_NEG_EDGE);
  742. mcpwm_ll_capture_enable_posedge(hal->dev, cap_channel, cap_conf->cap_edge & MCPWM_POS_EDGE);
  743. mcpwm_ll_capture_set_prescale(hal->dev, cap_channel, cap_conf->cap_prescale);
  744. // capture feature should be used with interupt, so enable it by default
  745. mcpwm_ll_intr_enable_capture(hal->dev, cap_channel, true);
  746. mcpwm_ll_intr_clear_capture_status(hal->dev, 1 << cap_channel);
  747. mcpwm_critical_exit(mcpwm_num);
  748. mcpwm_mutex_lock(mcpwm_num);
  749. context[mcpwm_num].cap_isr_func[cap_channel].fn = cap_conf->capture_cb;
  750. context[mcpwm_num].cap_isr_func[cap_channel].args = cap_conf->user_data;
  751. esp_err_t ret = ESP_OK;
  752. if (context[mcpwm_num].mcpwm_intr_handle == NULL) {
  753. ret = esp_intr_alloc(mcpwm_periph_signals.groups[mcpwm_num].irq_id, MCPWM_INTR_FLAG,
  754. mcpwm_default_isr_handler,
  755. (void *) (context + mcpwm_num), &(context[mcpwm_num].mcpwm_intr_handle));
  756. }
  757. mcpwm_mutex_unlock(mcpwm_num);
  758. return ret;
  759. }
  760. esp_err_t mcpwm_capture_disable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_channel_id_t cap_channel)
  761. {
  762. ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
  763. ESP_RETURN_ON_FALSE(cap_channel < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR);
  764. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  765. mcpwm_critical_enter(mcpwm_num);
  766. mcpwm_ll_capture_enable_channel(hal->dev, cap_channel, false);
  767. mcpwm_ll_intr_enable_capture(hal->dev, cap_channel, false);
  768. mcpwm_critical_exit(mcpwm_num);
  769. mcpwm_mutex_lock(mcpwm_num);
  770. context[mcpwm_num].cap_isr_func[cap_channel].fn = NULL;
  771. context[mcpwm_num].cap_isr_func[cap_channel].args = NULL;
  772. // if all user defined ISR callback is disabled, free the handle
  773. bool should_free_handle = true;
  774. for (int i = 0; i < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER; ++i) {
  775. if (context[mcpwm_num].cap_isr_func[i].fn != NULL) {
  776. should_free_handle = false;
  777. break;
  778. }
  779. }
  780. esp_err_t ret = ESP_OK;
  781. if (should_free_handle) {
  782. ret = esp_intr_free(context[mcpwm_num].mcpwm_intr_handle);
  783. if (ret != ESP_OK){
  784. ESP_LOGE(TAG, "failed to free interrupt handle");
  785. }
  786. context[mcpwm_num].mcpwm_intr_handle = NULL;
  787. }
  788. mcpwm_mutex_unlock(mcpwm_num);
  789. // always decrease reference count
  790. periph_module_disable(mcpwm_periph_signals.groups[mcpwm_num].module);
  791. return ret;
  792. }
  793. uint32_t MCPWM_ISR_ATTR mcpwm_capture_signal_get_value(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig)
  794. {
  795. ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
  796. ESP_RETURN_ON_FALSE(cap_sig < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR);
  797. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  798. return mcpwm_ll_capture_get_value(hal->dev, cap_sig);
  799. }
  800. uint32_t MCPWM_ISR_ATTR mcpwm_capture_signal_get_edge(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig)
  801. {
  802. ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
  803. ESP_RETURN_ON_FALSE(cap_sig < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR);
  804. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  805. return mcpwm_ll_capture_is_negedge(hal->dev, cap_sig) ? 2 : 1;
  806. }
  807. esp_err_t mcpwm_sync_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_sync_signal_t sync_sig,
  808. uint32_t phase_val)
  809. {
  810. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  811. ESP_RETURN_ON_FALSE(sync_sig <= MCPWM_SELECT_GPIO_SYNC2, ESP_ERR_INVALID_ARG, TAG, "invalid sync_sig");
  812. ESP_RETURN_ON_FALSE(phase_val < 1000, ESP_ERR_INVALID_ARG, TAG, "phase_val must within 0~999");
  813. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  814. mcpwm_critical_enter(mcpwm_num);
  815. uint32_t set_phase = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false) * phase_val / 1000;
  816. mcpwm_ll_timer_set_sync_phase_value(hal->dev, timer_num, set_phase);
  817. if (sync_sig == MCPWM_SELECT_NO_INPUT) {
  818. mcpwm_ll_timer_set_soft_synchro(hal->dev, timer_num);
  819. } else if (sync_sig <= MCPWM_SELECT_TIMER2_SYNC) {
  820. mcpwm_ll_timer_set_timer_synchro(hal->dev, timer_num, sync_sig - MCPWM_SELECT_TIMER0_SYNC);
  821. } else {
  822. mcpwm_ll_timer_set_gpio_synchro(hal->dev, timer_num, sync_sig - MCPWM_SELECT_GPIO_SYNC0);
  823. }
  824. mcpwm_ll_timer_enable_sync_input(hal->dev, timer_num, true);
  825. mcpwm_critical_exit(mcpwm_num);
  826. return ESP_OK;
  827. }
  828. esp_err_t mcpwm_sync_configure(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_sync_config_t *sync_conf)
  829. {
  830. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  831. ESP_RETURN_ON_FALSE(sync_conf->sync_sig <= MCPWM_SELECT_GPIO_SYNC2, ESP_ERR_INVALID_ARG, TAG, "invalid sync_sig");
  832. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  833. mcpwm_critical_enter(mcpwm_num);
  834. mcpwm_ll_timer_set_sync_phase_direction(hal->dev, timer_num, sync_conf->count_direction);
  835. // sync TEP with current setting
  836. uint32_t set_phase = 0;
  837. set_phase = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false) * sync_conf->timer_val / 1000;
  838. mcpwm_ll_timer_set_sync_phase_value(hal->dev, timer_num, set_phase);
  839. if (sync_conf->sync_sig == MCPWM_SELECT_NO_INPUT){
  840. mcpwm_ll_timer_set_soft_synchro(hal->dev, timer_num);
  841. } else if (sync_conf->sync_sig <= MCPWM_SELECT_TIMER2_SYNC) {
  842. mcpwm_ll_timer_set_timer_synchro(hal->dev, timer_num, sync_conf->sync_sig - MCPWM_SELECT_TIMER0_SYNC);
  843. } else {
  844. mcpwm_ll_timer_set_gpio_synchro(hal->dev, timer_num, sync_conf->sync_sig - MCPWM_SELECT_GPIO_SYNC0);
  845. }
  846. mcpwm_ll_timer_enable_sync_input(hal->dev, timer_num, true);
  847. mcpwm_critical_exit(mcpwm_num);
  848. return ESP_OK;
  849. }
  850. esp_err_t mcpwm_sync_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  851. {
  852. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  853. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  854. mcpwm_critical_enter(mcpwm_num);
  855. mcpwm_ll_timer_enable_sync_input(hal->dev, timer_num, false);
  856. mcpwm_critical_exit(mcpwm_num);
  857. return ESP_OK;
  858. }
  859. esp_err_t mcpwm_timer_trigger_soft_sync(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  860. {
  861. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  862. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  863. mcpwm_critical_enter(mcpwm_num);
  864. mcpwm_ll_timer_trigger_soft_sync(hal->dev, timer_num);
  865. mcpwm_critical_exit(mcpwm_num);
  866. return ESP_OK;
  867. }
  868. esp_err_t mcpwm_sync_invert_gpio_synchro(mcpwm_unit_t mcpwm_num, mcpwm_sync_signal_t sync_sig, bool invert){
  869. ESP_RETURN_ON_FALSE(sync_sig >= MCPWM_SELECT_GPIO_SYNC0 && sync_sig <= MCPWM_SELECT_GPIO_SYNC2,
  870. ESP_ERR_INVALID_ARG, TAG, "invalid sync sig");
  871. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  872. mcpwm_critical_enter(mcpwm_num);
  873. mcpwm_ll_invert_gpio_synchro(hal->dev, sync_sig - MCPWM_SELECT_GPIO_SYNC0, invert);
  874. mcpwm_critical_exit(mcpwm_num);
  875. return ESP_OK;
  876. }
  877. esp_err_t mcpwm_set_timer_sync_output(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_timer_sync_trigger_t trigger)
  878. {
  879. MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
  880. mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
  881. mcpwm_critical_enter(mcpwm_num);
  882. switch (trigger) {
  883. case MCPWM_SWSYNC_SOURCE_SYNCIN:
  884. mcpwm_ll_timer_sync_out_penetrate(hal->dev, timer_num);
  885. break;
  886. case MCPWM_SWSYNC_SOURCE_TEZ:
  887. mcpwm_ll_timer_sync_out_on_timer_event(hal->dev, timer_num, MCPWM_TIMER_EVENT_ZERO);
  888. break;
  889. case MCPWM_SWSYNC_SOURCE_TEP:
  890. mcpwm_ll_timer_sync_out_on_timer_event(hal->dev, timer_num, MCPWM_TIMER_EVENT_PEAK);
  891. break;
  892. case MCPWM_SWSYNC_SOURCE_DISABLED:
  893. default:
  894. mcpwm_ll_timer_disable_sync_out(hal->dev, timer_num);
  895. break;
  896. }
  897. mcpwm_critical_exit(mcpwm_num);
  898. return ESP_OK;
  899. }
  900. esp_err_t mcpwm_isr_register(mcpwm_unit_t mcpwm_num, void (*fn)(void *), void *arg, int intr_alloc_flags, intr_handle_t *handle)
  901. {
  902. esp_err_t ret;
  903. ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
  904. ESP_RETURN_ON_FALSE(fn, ESP_ERR_INVALID_ARG, TAG, MCPWM_PARAM_ADDR_ERROR);
  905. ret = esp_intr_alloc(mcpwm_periph_signals.groups[mcpwm_num].irq_id, intr_alloc_flags, fn, arg, handle);
  906. return ret;
  907. }