mcpwm.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  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. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. #include <stdio.h>
  14. #include "esp_log.h"
  15. #include "esp_err.h"
  16. #include "freertos/FreeRTOS.h"
  17. #include "freertos/semphr.h"
  18. #include "freertos/xtensa_api.h"
  19. #include "freertos/task.h"
  20. #include "soc/mcpwm_periph.h"
  21. #include "soc/gpio_periph.h"
  22. #include "driver/mcpwm.h"
  23. #include "driver/periph_ctrl.h"
  24. static mcpwm_dev_t *MCPWM[2] = {&MCPWM0, &MCPWM1};
  25. static const char *MCPWM_TAG = "MCPWM";
  26. static portMUX_TYPE mcpwm_spinlock = portMUX_INITIALIZER_UNLOCKED;
  27. #define MCPWM_CHECK(a, str, ret_val) if (!(a)) { \
  28. ESP_LOGE(MCPWM_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
  29. return (ret_val); \
  30. }
  31. #define MCPWM_UNIT_NUM_ERROR "MCPWM UNIT NUM ERROR"
  32. #define MCPWM_TIMER_ERROR "MCPWM TIMER NUM ERROR"
  33. #define MCPWM_PARAM_ADDR_ERROR "MCPWM PARAM ADDR ERROR"
  34. #define MCPWM_DUTY_TYPE_ERROR "MCPWM DUTY TYPE ERROR"
  35. #define MCPWM_GPIO_ERROR "MCPWM GPIO NUM ERROR"
  36. #define MCPWM_OP_ERROR "MCPWM OPERATOR ERROR"
  37. #define MCPWM_DB_ERROR "MCPWM DEADTIME TYPE ERROR"
  38. #define MCPWM_BASE_CLK (2 * APB_CLK_FREQ) //2*APB_CLK_FREQ 160Mhz
  39. #define MCPWM_CLK_PRESCL 15 //MCPWM clock prescale
  40. #define TIMER_CLK_PRESCALE 9 //MCPWM timer prescales
  41. #define MCPWM_CLK (MCPWM_BASE_CLK/(MCPWM_CLK_PRESCL +1))
  42. #define MCPWM_PIN_IGNORE (-1)
  43. #define OFFSET_FOR_GPIO_IDX_1 6
  44. #define OFFSET_FOR_GPIO_IDX_2 75
  45. esp_err_t mcpwm_gpio_init(mcpwm_unit_t mcpwm_num, mcpwm_io_signals_t io_signal, int gpio_num)
  46. {
  47. if (gpio_num == MCPWM_PIN_IGNORE) {
  48. //IGNORE
  49. return ESP_OK;
  50. }
  51. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  52. MCPWM_CHECK((GPIO_IS_VALID_GPIO(gpio_num)), MCPWM_GPIO_ERROR, ESP_ERR_INVALID_ARG);
  53. periph_module_enable(PERIPH_PWM0_MODULE + mcpwm_num);
  54. PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO);
  55. bool mcpwm_gpio_sig = (io_signal <= MCPWM2B);
  56. if (mcpwm_num == MCPWM_UNIT_0) {
  57. if (mcpwm_gpio_sig) {
  58. MCPWM_CHECK((GPIO_IS_VALID_OUTPUT_GPIO(gpio_num)), MCPWM_GPIO_ERROR, ESP_ERR_INVALID_ARG);
  59. gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
  60. gpio_matrix_out(gpio_num, PWM0_OUT0A_IDX + io_signal, 0, 0);
  61. } else {
  62. gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
  63. gpio_matrix_in(gpio_num, PWM0_SYNC0_IN_IDX + io_signal - OFFSET_FOR_GPIO_IDX_1, 0);
  64. }
  65. } else { //MCPWM_UNIT_1
  66. if (mcpwm_gpio_sig) {
  67. MCPWM_CHECK((GPIO_IS_VALID_OUTPUT_GPIO(gpio_num)), MCPWM_GPIO_ERROR, ESP_ERR_INVALID_ARG);
  68. gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
  69. gpio_matrix_out(gpio_num, PWM1_OUT0A_IDX + io_signal, 0, 0);
  70. } else if (io_signal >= MCPWM_SYNC_0 && io_signal <= MCPWM_FAULT_2) {
  71. gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
  72. gpio_matrix_in(gpio_num, PWM1_SYNC0_IN_IDX + io_signal - OFFSET_FOR_GPIO_IDX_1, 0);
  73. } else {
  74. gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
  75. gpio_matrix_in(gpio_num, PWM1_SYNC0_IN_IDX + io_signal - OFFSET_FOR_GPIO_IDX_2, 0);
  76. }
  77. }
  78. return ESP_OK;
  79. }
  80. esp_err_t mcpwm_set_pin(mcpwm_unit_t mcpwm_num, const mcpwm_pin_config_t *mcpwm_pin)
  81. {
  82. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  83. mcpwm_gpio_init(mcpwm_num, MCPWM0A, mcpwm_pin->mcpwm0a_out_num); //MCPWM0A
  84. mcpwm_gpio_init(mcpwm_num, MCPWM0B, mcpwm_pin->mcpwm0b_out_num); //MCPWM0B
  85. mcpwm_gpio_init(mcpwm_num, MCPWM1A, mcpwm_pin->mcpwm1a_out_num); //MCPWM1A
  86. mcpwm_gpio_init(mcpwm_num, MCPWM1B, mcpwm_pin->mcpwm1b_out_num); //MCPWM1B
  87. mcpwm_gpio_init(mcpwm_num, MCPWM2A, mcpwm_pin->mcpwm2a_out_num); //MCPWM2A
  88. mcpwm_gpio_init(mcpwm_num, MCPWM2B, mcpwm_pin->mcpwm2b_out_num); //MCPWM2B
  89. mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_0, mcpwm_pin->mcpwm_sync0_in_num); //SYNC0
  90. mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_1, mcpwm_pin->mcpwm_sync1_in_num); //SYNC1
  91. mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_2, mcpwm_pin->mcpwm_sync2_in_num); //SYNC2
  92. mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_0, mcpwm_pin->mcpwm_fault0_in_num); //FAULT0
  93. mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_0, mcpwm_pin->mcpwm_fault1_in_num); //FAULT1
  94. mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_0, mcpwm_pin->mcpwm_fault2_in_num); //FAULT2
  95. mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_0, mcpwm_pin->mcpwm_cap0_in_num); //CAP0
  96. mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_1, mcpwm_pin->mcpwm_cap1_in_num); //CAP1
  97. mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_2, mcpwm_pin->mcpwm_cap2_in_num); //CAP2
  98. return ESP_OK;
  99. }
  100. esp_err_t mcpwm_start(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  101. {
  102. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  103. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  104. portENTER_CRITICAL(&mcpwm_spinlock);
  105. MCPWM[mcpwm_num]->timer[timer_num].mode.start = 2;
  106. portEXIT_CRITICAL(&mcpwm_spinlock);
  107. return ESP_OK;
  108. }
  109. esp_err_t mcpwm_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  110. {
  111. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  112. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  113. portENTER_CRITICAL(&mcpwm_spinlock);
  114. MCPWM[mcpwm_num]->timer[timer_num].mode.start = 0;
  115. portEXIT_CRITICAL(&mcpwm_spinlock);
  116. return ESP_OK;
  117. }
  118. esp_err_t mcpwm_set_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint32_t frequency)
  119. {
  120. uint32_t mcpwm_num_of_pulse;
  121. uint32_t previous_period;
  122. uint32_t set_duty_a, set_duty_b;
  123. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  124. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  125. portENTER_CRITICAL(&mcpwm_spinlock);
  126. mcpwm_num_of_pulse = MCPWM_CLK / (frequency * (TIMER_CLK_PRESCALE + 1));
  127. previous_period = MCPWM[mcpwm_num]->timer[timer_num].period.period;
  128. MCPWM[mcpwm_num]->timer[timer_num].period.prescale = TIMER_CLK_PRESCALE;
  129. MCPWM[mcpwm_num]->timer[timer_num].period.period = mcpwm_num_of_pulse;
  130. MCPWM[mcpwm_num]->timer[timer_num].period.upmethod = 0;
  131. set_duty_a = (((MCPWM[mcpwm_num]->channel[timer_num].cmpr_value[0].cmpr_val) * mcpwm_num_of_pulse) / previous_period);
  132. set_duty_b = (((MCPWM[mcpwm_num]->channel[timer_num].cmpr_value[1].cmpr_val) * mcpwm_num_of_pulse) / previous_period);
  133. MCPWM[mcpwm_num]->channel[timer_num].cmpr_value[0].cmpr_val = set_duty_a;
  134. MCPWM[mcpwm_num]->channel[timer_num].cmpr_value[1].cmpr_val = set_duty_b;
  135. MCPWM[mcpwm_num]->channel[timer_num].cmpr_cfg.a_upmethod = 0;
  136. MCPWM[mcpwm_num]->channel[timer_num].cmpr_cfg.b_upmethod = 0;
  137. portEXIT_CRITICAL(&mcpwm_spinlock);
  138. return ESP_OK;
  139. }
  140. esp_err_t mcpwm_set_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t op_num, float duty)
  141. {
  142. uint32_t set_duty;
  143. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  144. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  145. MCPWM_CHECK(op_num < MCPWM_OPR_MAX, MCPWM_OP_ERROR, ESP_ERR_INVALID_ARG);
  146. portENTER_CRITICAL(&mcpwm_spinlock);
  147. set_duty = (MCPWM[mcpwm_num]->timer[timer_num].period.period) * (duty) / 100;
  148. MCPWM[mcpwm_num]->channel[timer_num].cmpr_value[op_num].cmpr_val = set_duty;
  149. MCPWM[mcpwm_num]->channel[timer_num].cmpr_cfg.a_upmethod = BIT(0);
  150. MCPWM[mcpwm_num]->channel[timer_num].cmpr_cfg.b_upmethod = BIT(0);
  151. portEXIT_CRITICAL(&mcpwm_spinlock);
  152. return ESP_OK;
  153. }
  154. esp_err_t mcpwm_set_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t op_num, uint32_t duty)
  155. {
  156. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  157. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  158. MCPWM_CHECK(op_num < MCPWM_OPR_MAX, MCPWM_OP_ERROR, ESP_ERR_INVALID_ARG);
  159. portENTER_CRITICAL(&mcpwm_spinlock);
  160. MCPWM[mcpwm_num]->channel[timer_num].cmpr_value[op_num].cmpr_val = duty;
  161. MCPWM[mcpwm_num]->channel[timer_num].cmpr_cfg.a_upmethod = BIT(0);
  162. MCPWM[mcpwm_num]->channel[timer_num].cmpr_cfg.b_upmethod = BIT(0);
  163. portEXIT_CRITICAL(&mcpwm_spinlock);
  164. return ESP_OK;
  165. }
  166. esp_err_t mcpwm_set_duty_type(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t op_num,
  167. mcpwm_duty_type_t duty_num)
  168. {
  169. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  170. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  171. MCPWM_CHECK(op_num < MCPWM_OPR_MAX, MCPWM_OP_ERROR, ESP_ERR_INVALID_ARG);
  172. MCPWM_CHECK(duty_num < MCPWM_DUTY_MODE_MAX, MCPWM_DUTY_TYPE_ERROR, ESP_ERR_INVALID_ARG);
  173. portENTER_CRITICAL(&mcpwm_spinlock);
  174. if (op_num == MCPWM_OPR_A) {
  175. if (MCPWM[mcpwm_num]->timer[timer_num].mode.mode == MCPWM_UP_COUNTER) {
  176. if (duty_num == MCPWM_DUTY_MODE_1) {
  177. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utez = 1;
  178. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utea = 2;
  179. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utep = 0;
  180. } else { //MCPWM_DUTY_MODE_0
  181. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utez = 2;
  182. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utea = 1;
  183. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utep = 0;
  184. }
  185. } else if (MCPWM[mcpwm_num]->timer[timer_num].mode.mode == MCPWM_DOWN_COUNTER) {
  186. if (duty_num == MCPWM_DUTY_MODE_1) {
  187. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtep = 2;
  188. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtea = 1;
  189. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtez = 0;
  190. } else { //MCPWM_DUTY_MODE_0
  191. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtep = 1;
  192. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtea = 2;
  193. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtez = 0;
  194. }
  195. } else { //Timer count up-down
  196. if (duty_num == MCPWM_DUTY_MODE_1) {
  197. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utez = 1;
  198. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utea = 2;
  199. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtea = 1;
  200. } else { //MCPWM_DUTY_MODE_0
  201. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utez = 2;
  202. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utea = 1;
  203. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtea = 2;
  204. }
  205. }
  206. }
  207. if (op_num == MCPWM_OPR_B) {
  208. if (MCPWM[mcpwm_num]->timer[timer_num].mode.mode == MCPWM_UP_COUNTER) {
  209. if (duty_num == MCPWM_DUTY_MODE_1) {
  210. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utez = 1;
  211. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].uteb = 2;
  212. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utep = 0;
  213. } else { //MCPWM_DUTY_MODE_0
  214. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utez = 2;
  215. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].uteb = 1;
  216. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utep = 0;
  217. }
  218. } else if (MCPWM[mcpwm_num]->timer[timer_num].mode.mode == MCPWM_DOWN_COUNTER) {
  219. if (duty_num == MCPWM_DUTY_MODE_1) {
  220. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtep = 2;
  221. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dteb = 1;
  222. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtez = 0;
  223. } else { //MCPWM_DUTY_MODE_0
  224. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtep = 1;
  225. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dteb = 2;
  226. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtez = 0;
  227. }
  228. } else { //Timer count up-down
  229. if (duty_num == MCPWM_DUTY_MODE_1) {
  230. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utez = 1;
  231. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].uteb = 2;
  232. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dteb = 1;
  233. } else { //MCPWM_DUTY_MODE_0
  234. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utez = 2;
  235. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].uteb = 1;
  236. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dteb = 2;
  237. }
  238. }
  239. }
  240. portEXIT_CRITICAL(&mcpwm_spinlock);
  241. return ESP_OK;
  242. }
  243. esp_err_t mcpwm_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_config_t *mcpwm_conf)
  244. {
  245. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  246. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  247. periph_module_enable(PERIPH_PWM0_MODULE + mcpwm_num);
  248. portENTER_CRITICAL(&mcpwm_spinlock);
  249. MCPWM[mcpwm_num]->clk_cfg.prescale = MCPWM_CLK_PRESCL;
  250. mcpwm_set_frequency(mcpwm_num, timer_num, mcpwm_conf->frequency);
  251. MCPWM[mcpwm_num]->timer[timer_num].mode.mode = mcpwm_conf ->counter_mode;
  252. mcpwm_set_duty(mcpwm_num, timer_num, 0, mcpwm_conf->cmpr_a);
  253. mcpwm_set_duty(mcpwm_num, timer_num, 1, mcpwm_conf->cmpr_b);
  254. mcpwm_set_duty_type(mcpwm_num, timer_num, 0, mcpwm_conf->duty_mode);
  255. mcpwm_set_duty_type(mcpwm_num, timer_num, 1, mcpwm_conf->duty_mode);
  256. mcpwm_start(mcpwm_num, timer_num);
  257. MCPWM[mcpwm_num]->timer_sel.operator0_sel = 0;
  258. MCPWM[mcpwm_num]->timer_sel.operator1_sel = 1;
  259. MCPWM[mcpwm_num]->timer_sel.operator2_sel = 2;
  260. MCPWM[mcpwm_num]->update_cfg.global_up_en = 1;
  261. MCPWM[mcpwm_num]->update_cfg.global_force_up = 1;
  262. MCPWM[mcpwm_num]->update_cfg.global_force_up = 0;
  263. portEXIT_CRITICAL(&mcpwm_spinlock);
  264. return ESP_OK;
  265. }
  266. uint32_t mcpwm_get_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  267. {
  268. uint32_t frequency;
  269. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  270. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  271. frequency = MCPWM_CLK / ((MCPWM[mcpwm_num]->timer[timer_num].period.period) * (TIMER_CLK_PRESCALE + 1));
  272. return frequency;
  273. }
  274. float mcpwm_get_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t op_num)
  275. {
  276. float duty;
  277. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  278. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  279. MCPWM_CHECK(op_num < MCPWM_OPR_MAX, MCPWM_OP_ERROR, ESP_ERR_INVALID_ARG);
  280. portENTER_CRITICAL(&mcpwm_spinlock);
  281. duty = 100.0 * (MCPWM[mcpwm_num]->channel[timer_num].cmpr_value[op_num].cmpr_val) / (MCPWM[mcpwm_num]->timer[timer_num].period.period);
  282. portEXIT_CRITICAL(&mcpwm_spinlock);
  283. return duty;
  284. }
  285. esp_err_t mcpwm_set_signal_high(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t op_num)
  286. {
  287. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  288. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  289. MCPWM_CHECK(op_num < MCPWM_OPR_MAX, MCPWM_OP_ERROR, ESP_ERR_INVALID_ARG);
  290. portENTER_CRITICAL(&mcpwm_spinlock);
  291. if (op_num == MCPWM_OPR_A) {
  292. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utez = 2;
  293. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utea = 2;
  294. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utep = 2;
  295. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtez = 2;
  296. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtea = 2;
  297. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtep = 2;
  298. } else { //MCPWM_OPR_B
  299. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utez = 2;
  300. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].uteb = 2;
  301. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utep = 2;
  302. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtez = 2;
  303. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dteb = 2;
  304. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtep = 2;
  305. }
  306. portEXIT_CRITICAL(&mcpwm_spinlock);
  307. return ESP_OK;
  308. }
  309. esp_err_t mcpwm_set_signal_low(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t op_num)
  310. {
  311. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  312. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  313. MCPWM_CHECK(op_num < MCPWM_OPR_MAX, MCPWM_OP_ERROR, ESP_ERR_INVALID_ARG);
  314. portENTER_CRITICAL(&mcpwm_spinlock);
  315. if (op_num == 0) {
  316. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utez = 1;
  317. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utea = 1;
  318. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utep = 1;
  319. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtez = 1;
  320. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtea = 1;
  321. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtep = 1;
  322. } if (op_num == 1) {
  323. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utez = 1;
  324. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].uteb = 1;
  325. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].utep = 1;
  326. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtez = 1;
  327. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dteb = 1;
  328. MCPWM[mcpwm_num]->channel[timer_num].generator[op_num].dtep = 1;
  329. }
  330. portEXIT_CRITICAL(&mcpwm_spinlock);
  331. return ESP_OK;
  332. }
  333. esp_err_t mcpwm_carrier_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  334. {
  335. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  336. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  337. portENTER_CRITICAL(&mcpwm_spinlock);
  338. MCPWM[mcpwm_num]->channel[timer_num].carrier_cfg.en = 1;
  339. portEXIT_CRITICAL(&mcpwm_spinlock);
  340. return ESP_OK;
  341. }
  342. esp_err_t mcpwm_carrier_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  343. {
  344. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  345. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  346. portENTER_CRITICAL(&mcpwm_spinlock);
  347. MCPWM[mcpwm_num]->channel[timer_num].carrier_cfg.en = 0;
  348. portEXIT_CRITICAL(&mcpwm_spinlock);
  349. return ESP_OK;
  350. }
  351. esp_err_t mcpwm_carrier_set_period(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_period)
  352. {
  353. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  354. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  355. portENTER_CRITICAL(&mcpwm_spinlock);
  356. MCPWM[mcpwm_num]->channel[timer_num].carrier_cfg.prescale = carrier_period;
  357. portEXIT_CRITICAL(&mcpwm_spinlock);
  358. return ESP_OK;
  359. }
  360. esp_err_t mcpwm_carrier_set_duty_cycle(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_duty)
  361. {
  362. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  363. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  364. portENTER_CRITICAL(&mcpwm_spinlock);
  365. MCPWM[mcpwm_num]->channel[timer_num].carrier_cfg.duty = carrier_duty;
  366. portEXIT_CRITICAL(&mcpwm_spinlock);
  367. return ESP_OK;
  368. }
  369. esp_err_t mcpwm_carrier_oneshot_mode_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t pulse_width)
  370. {
  371. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  372. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  373. portENTER_CRITICAL(&mcpwm_spinlock);
  374. MCPWM[mcpwm_num]->channel[timer_num].carrier_cfg.oshtwth = pulse_width;
  375. portEXIT_CRITICAL(&mcpwm_spinlock);
  376. return ESP_OK;
  377. }
  378. esp_err_t mcpwm_carrier_oneshot_mode_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  379. {
  380. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  381. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  382. portENTER_CRITICAL(&mcpwm_spinlock);
  383. MCPWM[mcpwm_num]->channel[timer_num].carrier_cfg.oshtwth = 0;
  384. portEXIT_CRITICAL(&mcpwm_spinlock);
  385. return ESP_OK;
  386. }
  387. esp_err_t mcpwm_carrier_output_invert(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num,
  388. mcpwm_carrier_out_ivt_t carrier_ivt_mode)
  389. {
  390. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  391. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  392. portENTER_CRITICAL(&mcpwm_spinlock);
  393. MCPWM[mcpwm_num]->channel[timer_num].carrier_cfg.out_invert = carrier_ivt_mode;
  394. portEXIT_CRITICAL(&mcpwm_spinlock);
  395. return ESP_OK;
  396. }
  397. esp_err_t mcpwm_carrier_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_carrier_config_t *carrier_conf)
  398. {
  399. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  400. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  401. portENTER_CRITICAL(&mcpwm_spinlock);
  402. mcpwm_carrier_enable(mcpwm_num, timer_num);
  403. mcpwm_carrier_set_period(mcpwm_num, timer_num, carrier_conf->carrier_period);
  404. mcpwm_carrier_set_duty_cycle(mcpwm_num, timer_num, carrier_conf->carrier_duty);
  405. if (carrier_conf->carrier_os_mode == MCPWM_ONESHOT_MODE_EN) {
  406. mcpwm_carrier_oneshot_mode_enable(mcpwm_num, timer_num, carrier_conf->pulse_width_in_os);
  407. } else {
  408. mcpwm_carrier_oneshot_mode_disable(mcpwm_num, timer_num);
  409. }
  410. mcpwm_carrier_output_invert(mcpwm_num, timer_num, carrier_conf->carrier_ivt_mode);
  411. MCPWM[mcpwm_num]->channel[timer_num].carrier_cfg.in_invert = 0;
  412. portEXIT_CRITICAL(&mcpwm_spinlock);
  413. return ESP_OK;
  414. }
  415. esp_err_t mcpwm_deadtime_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_deadtime_type_t dt_mode,
  416. uint32_t red, uint32_t fed)
  417. {
  418. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  419. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  420. MCPWM_CHECK(dt_mode < MCPWM_DEADTIME_TYPE_MAX, MCPWM_DB_ERROR, ESP_ERR_INVALID_ARG );
  421. portENTER_CRITICAL(&mcpwm_spinlock);
  422. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_upmethod = BIT(0);
  423. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_upmethod = BIT(0);
  424. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.clk_sel = 0;
  425. MCPWM[mcpwm_num]->channel[timer_num].db_red_cfg.red = red;
  426. MCPWM[mcpwm_num]->channel[timer_num].db_fed_cfg.fed = fed;
  427. switch (dt_mode) {
  428. case MCPWM_BYPASS_RED:
  429. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.b_outbypass = 0; //S0
  430. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.a_outbypass = 1; //S1
  431. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_outinvert = 0; //S2
  432. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_outinvert = 0; //S3
  433. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_insel = 0; //S4
  434. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_insel = 1; //S5
  435. break;
  436. case MCPWM_BYPASS_FED:
  437. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.b_outbypass = 1; //S0
  438. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.a_outbypass = 0; //S1
  439. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_outinvert = 0; //S2
  440. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_outinvert = 0; //S3
  441. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_insel = 0; //S4
  442. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_insel = 0; //S5
  443. break;
  444. case MCPWM_ACTIVE_HIGH_MODE:
  445. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.b_outbypass = 0; //S0
  446. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.a_outbypass = 0; //S1
  447. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_outinvert = 0; //S2
  448. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_outinvert = 0; //S3
  449. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_insel = 0; //S4
  450. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_insel = 1; //S5
  451. break;
  452. case MCPWM_ACTIVE_LOW_MODE:
  453. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.b_outbypass = 0; //S0
  454. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.a_outbypass = 0; //S1
  455. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_outinvert = 1; //S2
  456. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_outinvert = 1; //S3
  457. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_insel = 0; //S4
  458. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_insel = 1; //S5
  459. break;
  460. case MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE:
  461. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.b_outbypass = 0; //S0
  462. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.a_outbypass = 0; //S1
  463. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_outinvert = 0; //S2
  464. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_outinvert = 1; //S3
  465. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_insel = 0; //S4
  466. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_insel = 1; //S5
  467. break;
  468. case MCPWM_ACTIVE_LOW_COMPLIMENT_MODE:
  469. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.b_outbypass = 0; //S0
  470. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.a_outbypass = 0; //S1
  471. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_outinvert = 1; //S2
  472. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_outinvert = 0; //S3
  473. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_insel = 1; //S4
  474. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_insel = 0; //S5
  475. break;
  476. case MCPWM_ACTIVE_RED_FED_FROM_PWMXA:
  477. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.b_outbypass = 0; //S0
  478. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_outinvert = 0; //S3
  479. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_insel = 1; //S4
  480. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.a_outswap = 1; //S6
  481. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.b_outswap = 0; //S7
  482. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.deb_mode = 1; //S8
  483. break;
  484. case MCPWM_ACTIVE_RED_FED_FROM_PWMXB:
  485. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.b_outbypass = 0; //S0
  486. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_outinvert = 0; //S3
  487. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_insel = 0; //S4
  488. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.a_outswap = 1; //S6
  489. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.b_outswap = 0; //S7
  490. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.deb_mode = 1; //S8
  491. break;
  492. default :
  493. break;
  494. }
  495. portEXIT_CRITICAL(&mcpwm_spinlock);
  496. return ESP_OK;
  497. }
  498. esp_err_t mcpwm_deadtime_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  499. {
  500. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  501. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  502. portENTER_CRITICAL(&mcpwm_spinlock);
  503. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.b_outbypass = 1; //S0
  504. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.a_outbypass = 1; //S1
  505. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_outinvert = 0; //S2
  506. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_outinvert = 0; //S3
  507. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.red_insel = 0; //S4
  508. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.fed_insel = 0; //S5
  509. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.a_outswap = 0; //S6
  510. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.b_outswap = 0; //S7
  511. MCPWM[mcpwm_num]->channel[timer_num].db_cfg.deb_mode = 0; //S8
  512. portEXIT_CRITICAL(&mcpwm_spinlock);
  513. return ESP_OK;
  514. }
  515. esp_err_t mcpwm_fault_init(mcpwm_unit_t mcpwm_num, mcpwm_fault_input_level_t intput_level, mcpwm_fault_signal_t fault_sig)
  516. {
  517. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  518. portENTER_CRITICAL(&mcpwm_spinlock);
  519. switch (fault_sig) {
  520. case MCPWM_SELECT_F0:
  521. MCPWM[mcpwm_num]->fault_detect.f0_en = 1;
  522. MCPWM[mcpwm_num]->fault_detect.f0_pole = intput_level;
  523. break;
  524. case MCPWM_SELECT_F1:
  525. MCPWM[mcpwm_num]->fault_detect.f1_en = 1;
  526. MCPWM[mcpwm_num]->fault_detect.f1_pole = intput_level;
  527. break;
  528. case MCPWM_SELECT_F2:
  529. MCPWM[mcpwm_num]->fault_detect.f2_en = 1;
  530. MCPWM[mcpwm_num]->fault_detect.f2_pole = intput_level;
  531. break;
  532. default :
  533. break;
  534. }
  535. portEXIT_CRITICAL(&mcpwm_spinlock);
  536. return ESP_OK;
  537. }
  538. esp_err_t mcpwm_fault_deinit(mcpwm_unit_t mcpwm_num, mcpwm_fault_signal_t fault_sig)
  539. {
  540. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  541. portENTER_CRITICAL(&mcpwm_spinlock);
  542. if (fault_sig == MCPWM_SELECT_F0) {
  543. MCPWM[mcpwm_num]->fault_detect.f0_en = 0;
  544. } else if (fault_sig == MCPWM_SELECT_F1) {
  545. MCPWM[mcpwm_num]->fault_detect.f1_en = 0;
  546. } else { //MCPWM_SELECT_F2
  547. MCPWM[mcpwm_num]->fault_detect.f2_en = 0;
  548. }
  549. portEXIT_CRITICAL(&mcpwm_spinlock);
  550. return ESP_OK;
  551. }
  552. esp_err_t mcpwm_fault_set_cyc_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig,
  553. mcpwm_action_on_pwmxa_t action_on_pwmxa, mcpwm_action_on_pwmxb_t action_on_pwmxb)
  554. {
  555. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  556. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  557. portENTER_CRITICAL(&mcpwm_spinlock);
  558. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg1.cbcpulse = BIT(0);
  559. if (fault_sig == MCPWM_SELECT_F0) {
  560. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.f0_cbc = 1;
  561. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.f0_ost = 0;
  562. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.a_cbc_d = action_on_pwmxa;
  563. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.a_cbc_u = action_on_pwmxa;
  564. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.b_cbc_d = action_on_pwmxb;
  565. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.b_cbc_u = action_on_pwmxb;
  566. } else if (fault_sig == MCPWM_SELECT_F1) {
  567. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.f1_cbc = 1;
  568. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.f1_ost = 0;
  569. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.a_cbc_d = action_on_pwmxa;
  570. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.a_cbc_u = action_on_pwmxa;
  571. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.b_cbc_d = action_on_pwmxb;
  572. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.b_cbc_u = action_on_pwmxb;
  573. } else { //MCPWM_SELECT_F2
  574. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.f2_cbc = 1;
  575. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.f2_ost = 0;
  576. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.a_cbc_d = action_on_pwmxa;
  577. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.a_cbc_u = action_on_pwmxa;
  578. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.b_cbc_d = action_on_pwmxb;
  579. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.b_cbc_u = action_on_pwmxb;
  580. }
  581. portEXIT_CRITICAL(&mcpwm_spinlock);
  582. return ESP_OK;
  583. }
  584. esp_err_t mcpwm_fault_set_oneshot_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig,
  585. mcpwm_action_on_pwmxa_t action_on_pwmxa, mcpwm_action_on_pwmxb_t action_on_pwmxb)
  586. {
  587. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  588. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  589. portENTER_CRITICAL(&mcpwm_spinlock);
  590. //clear the ost triggered status
  591. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg1.clr_ost = 1;
  592. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg1.clr_ost = 0;
  593. if (fault_sig == MCPWM_SELECT_F0) {
  594. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.f0_ost = 1;
  595. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.f0_cbc = 0;
  596. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.a_ost_d = action_on_pwmxa;
  597. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.a_ost_u = action_on_pwmxa;
  598. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.b_ost_d = action_on_pwmxb;
  599. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.b_ost_u = action_on_pwmxb;
  600. } else if (fault_sig == MCPWM_SELECT_F1) {
  601. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.f1_ost = 1;
  602. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.f1_cbc = 0;
  603. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.a_ost_d = action_on_pwmxa;
  604. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.a_ost_u = action_on_pwmxa;
  605. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.b_ost_d = action_on_pwmxb;
  606. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.b_ost_u = action_on_pwmxb;
  607. } else { //MCPWM_SELECT_F2
  608. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.f2_ost = 1;
  609. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.f2_cbc = 0;
  610. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.a_ost_d = action_on_pwmxa;
  611. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.a_ost_u = action_on_pwmxa;
  612. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.b_ost_d = action_on_pwmxb;
  613. MCPWM[mcpwm_num]->channel[timer_num].tz_cfg0.b_ost_u = action_on_pwmxb;
  614. }
  615. portEXIT_CRITICAL(&mcpwm_spinlock);
  616. return ESP_OK;
  617. }
  618. esp_err_t mcpwm_capture_enable(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig, mcpwm_capture_on_edge_t cap_edge,
  619. uint32_t num_of_pulse)
  620. {
  621. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  622. portENTER_CRITICAL(&mcpwm_spinlock);
  623. //We have to do this here, since there is no standalone init function
  624. //without enabling any PWM channels.
  625. MCPWM[mcpwm_num]->clk_cfg.prescale = MCPWM_CLK_PRESCL;
  626. MCPWM[mcpwm_num]->cap_timer_cfg.timer_en = 1;
  627. MCPWM[mcpwm_num]->cap_cfg_ch[cap_sig].en = 1;
  628. MCPWM[mcpwm_num]->cap_cfg_ch[cap_sig].mode = (1 << cap_edge);
  629. MCPWM[mcpwm_num]->cap_cfg_ch[cap_sig].prescale = num_of_pulse;
  630. portEXIT_CRITICAL(&mcpwm_spinlock);
  631. return ESP_OK;
  632. }
  633. esp_err_t mcpwm_capture_disable(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig)
  634. {
  635. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  636. portENTER_CRITICAL(&mcpwm_spinlock);
  637. MCPWM[mcpwm_num]->cap_cfg_ch[cap_sig].en = 0;
  638. portEXIT_CRITICAL(&mcpwm_spinlock);
  639. return ESP_OK;
  640. }
  641. uint32_t mcpwm_capture_signal_get_value(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig)
  642. {
  643. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  644. return MCPWM[mcpwm_num]->cap_val_ch[cap_sig];
  645. }
  646. uint32_t mcpwm_capture_signal_get_edge(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig)
  647. {
  648. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  649. if (cap_sig == MCPWM_SELECT_CAP0) {
  650. return ( MCPWM[mcpwm_num]->cap_status.cap0_edge + 1);
  651. } else if (cap_sig == MCPWM_SELECT_CAP1) {
  652. return (MCPWM[mcpwm_num]->cap_status.cap1_edge + 1);
  653. } else { //MCPWM_SELECT_CAP2
  654. return (MCPWM[mcpwm_num]->cap_status.cap2_edge + 1);
  655. }
  656. return 0;
  657. }
  658. esp_err_t mcpwm_sync_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_sync_signal_t sync_sig,
  659. uint32_t phase_val)
  660. {
  661. uint32_t set_phase;
  662. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  663. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  664. portENTER_CRITICAL(&mcpwm_spinlock);
  665. set_phase = (MCPWM[mcpwm_num]->timer[timer_num].period.period) * (phase_val) / 1000;
  666. MCPWM[mcpwm_num]->timer[timer_num].sync.timer_phase = set_phase;
  667. if (timer_num == MCPWM_TIMER_0) {
  668. MCPWM[mcpwm_num]->timer_synci_cfg.t0_in_sel = sync_sig;
  669. } else if (timer_num == MCPWM_TIMER_1) {
  670. MCPWM[mcpwm_num]->timer_synci_cfg.t1_in_sel = sync_sig;
  671. } else { //MCPWM_TIMER_2
  672. MCPWM[mcpwm_num]->timer_synci_cfg.t2_in_sel = sync_sig;
  673. }
  674. MCPWM[mcpwm_num]->timer[timer_num].sync.out_sel = 0;
  675. MCPWM[mcpwm_num]->timer[timer_num].sync.in_en = 1;
  676. portEXIT_CRITICAL(&mcpwm_spinlock);
  677. return ESP_OK;
  678. }
  679. esp_err_t mcpwm_sync_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
  680. {
  681. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  682. MCPWM_CHECK(timer_num < MCPWM_TIMER_MAX, MCPWM_TIMER_ERROR, ESP_ERR_INVALID_ARG);
  683. portENTER_CRITICAL(&mcpwm_spinlock);
  684. MCPWM[mcpwm_num]->timer[timer_num].sync.in_en = 0;
  685. portEXIT_CRITICAL(&mcpwm_spinlock);
  686. return ESP_OK;
  687. }
  688. esp_err_t mcpwm_isr_register(mcpwm_unit_t mcpwm_num, void (*fn)(void *), void *arg, int intr_alloc_flags, intr_handle_t *handle)
  689. {
  690. esp_err_t ret;
  691. MCPWM_CHECK(mcpwm_num < MCPWM_UNIT_MAX, MCPWM_UNIT_NUM_ERROR, ESP_ERR_INVALID_ARG);
  692. MCPWM_CHECK(fn != NULL, MCPWM_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG);
  693. ret = esp_intr_alloc((ETS_PWM0_INTR_SOURCE + mcpwm_num), intr_alloc_flags, fn, arg, handle);
  694. return ret;
  695. }