mcpwm.c 24 KB

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