mcpwm_hal.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // The HAL layer for MCPWM (common part)
  15. #include "hal/mcpwm_hal.h"
  16. #include "soc/soc_caps.h"
  17. void mcpwm_hal_init(mcpwm_hal_context_t *hal, const mcpwm_hal_init_config_t *init_config)
  18. {
  19. hal->dev = MCPWM_LL_GET_HW(init_config->host_id);
  20. }
  21. void mcpwm_hal_hw_init(mcpwm_hal_context_t *hal)
  22. {
  23. mcpwm_ll_init(hal->dev);
  24. mcpwm_ll_set_clock_prescale(hal->dev, hal->prescale);
  25. }
  26. void mcpwm_hal_timer_start(mcpwm_hal_context_t *hal, int timer)
  27. {
  28. mcpwm_ll_timer_start(hal->dev, timer);
  29. }
  30. void mcpwm_hal_timer_stop(mcpwm_hal_context_t *hal, int timer)
  31. {
  32. mcpwm_ll_timer_stop(hal->dev, timer);
  33. }
  34. void mcpwm_hal_timer_update_basic(mcpwm_hal_context_t *hal, int timer)
  35. {
  36. mcpwm_ll_timer_set_prescale(hal->dev, timer, hal->timer[timer].timer_prescale);
  37. uint32_t period = MCPWM_BASE_CLK / (hal->timer[timer].freq *
  38. (hal->prescale +1) * (hal->timer[timer].timer_prescale + 1));
  39. mcpwm_ll_timer_set_period(hal->dev, timer, period);
  40. //write back the actual value to the context
  41. hal->timer[timer].freq = MCPWM_BASE_CLK / (period *
  42. (hal->prescale +1) * (hal->timer[timer].timer_prescale + 1));
  43. mcpwm_ll_timer_set_count_mode(hal->dev, timer, hal->timer[timer].count_mode);
  44. }
  45. void mcpwm_hal_timer_enable_sync(mcpwm_hal_context_t *hal, int timer, const mcpwm_hal_sync_config_t *sync_conf)
  46. {
  47. uint32_t set_phase = mcpwm_ll_timer_get_period(hal->dev, timer) * sync_conf->reload_permillage / 1000;
  48. mcpwm_ll_sync_set_phase(hal->dev, timer, set_phase);
  49. mcpwm_ll_sync_set_input(hal->dev, timer, sync_conf->sync_sig);
  50. mcpwm_ll_sync_enable(hal->dev, timer, 1);
  51. }
  52. void mcpwm_hal_timer_disable_sync(mcpwm_hal_context_t *hal, int timer)
  53. {
  54. mcpwm_ll_sync_enable(hal->dev, timer, 0);
  55. }
  56. void mcpwm_hal_operator_update_basic(mcpwm_hal_context_t *hal, int op)
  57. {
  58. mcpwm_hal_operator_config_t *op_conf = &hal->op[op];
  59. mcpwm_ll_operator_select_timer(hal->dev, op, op_conf->timer);
  60. for (int cmp = 0; cmp < SOC_MCPWM_COMPARATOR_NUM; cmp++) {
  61. mcpwm_hal_operator_update_comparator(hal, op, cmp);
  62. }
  63. for (int gen = 0; gen < SOC_MCPWM_GENERATOR_NUM; gen++) {
  64. mcpwm_hal_operator_update_generator(hal, op, gen);
  65. }
  66. }
  67. void mcpwm_hal_operator_update_comparator(mcpwm_hal_context_t *hal, int op, int cmp)
  68. {
  69. int timer = hal->op[op].timer;
  70. uint32_t period = mcpwm_ll_timer_get_period(hal->dev, timer);
  71. mcpwm_ll_operator_set_compare(hal->dev, op, cmp, (hal->op[op].duty[cmp] * period) / 100);
  72. mcpwm_ll_operator_set_compare_upmethod(hal->dev, timer);
  73. }
  74. void mcpwm_hal_operator_update_generator(mcpwm_hal_context_t *hal, int op, int gen_num)
  75. {
  76. mcpwm_hal_generator_config_t* gen_config = &(hal->op[op].gen[gen_num]);
  77. if (gen_config->duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH) {
  78. mcpwm_ll_gen_set_zero_action(hal->dev, op, gen_num, MCPWM_ACTION_FORCE_HIGH);
  79. mcpwm_ll_gen_set_period_action(hal->dev, op, gen_num, MCPWM_ACTION_FORCE_HIGH);
  80. mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, 0, MCPWM_ACTION_FORCE_HIGH, MCPWM_ACTION_FORCE_HIGH);
  81. mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, 1, MCPWM_ACTION_FORCE_HIGH, MCPWM_ACTION_FORCE_HIGH);
  82. } else if (gen_config->duty_type == MCPWM_HAL_GENERATOR_MODE_FORCE_LOW) {
  83. mcpwm_ll_gen_set_zero_action(hal->dev, op, gen_num, MCPWM_ACTION_FORCE_LOW);
  84. mcpwm_ll_gen_set_period_action(hal->dev, op, gen_num, MCPWM_ACTION_FORCE_LOW);
  85. mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, 0, MCPWM_ACTION_FORCE_LOW, MCPWM_ACTION_FORCE_LOW);
  86. mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, 1, MCPWM_ACTION_FORCE_LOW, MCPWM_ACTION_FORCE_LOW);
  87. } else if (gen_config->duty_type == MCPWM_DUTY_MODE_1 || gen_config->duty_type == MCPWM_DUTY_MODE_0) {
  88. const int timer_used = hal->op[op].timer;
  89. const int cmp_used = gen_config->comparator;
  90. const int cmp_not_used = 1 - gen_config->comparator;
  91. mcpwm_output_action_t inactive_action;
  92. mcpwm_output_action_t active_action;
  93. const mcpwm_output_action_t no_action = MCPWM_ACTION_NO_CHANGE;
  94. if (gen_config->duty_type == MCPWM_DUTY_MODE_1) {
  95. active_action = MCPWM_ACTION_FORCE_LOW; //active low
  96. inactive_action = MCPWM_ACTION_FORCE_HIGH; //inactive high
  97. } else { //MCPWM_DUTY_MODE_0
  98. inactive_action = MCPWM_ACTION_FORCE_LOW; //inactive low
  99. active_action = MCPWM_ACTION_FORCE_HIGH; //active high
  100. }
  101. if (hal->timer[timer_used].count_mode == MCPWM_UP_COUNTER) {
  102. mcpwm_ll_gen_set_zero_action(hal->dev, op, gen_num, active_action);
  103. mcpwm_ll_gen_set_period_action(hal->dev, op, gen_num, no_action);
  104. mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, cmp_used, inactive_action, no_action);
  105. } else if (hal->timer[timer_used].count_mode == MCPWM_DOWN_COUNTER) {
  106. mcpwm_ll_gen_set_zero_action(hal->dev, op, gen_num, no_action);
  107. mcpwm_ll_gen_set_period_action(hal->dev, op, gen_num, inactive_action);
  108. mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, cmp_used, no_action, active_action);
  109. } else { //Timer count up-down
  110. mcpwm_ll_gen_set_zero_action(hal->dev, op, gen_num, active_action);
  111. mcpwm_ll_gen_set_period_action(hal->dev, op, gen_num, no_action);
  112. mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, cmp_used, inactive_action, active_action);
  113. }
  114. mcpwm_ll_gen_set_cmp_action(hal->dev, op, gen_num, cmp_not_used, no_action, no_action);
  115. }
  116. }
  117. void mcpwm_hal_operator_enable_carrier(mcpwm_hal_context_t *hal, int op, const mcpwm_hal_carrier_conf_t *carrier_conf)
  118. {
  119. mcpwm_ll_carrier_init(hal->dev, op);
  120. mcpwm_ll_carrier_set_prescale(hal->dev, op, carrier_conf->period);
  121. mcpwm_ll_carrier_set_duty(hal->dev, op, carrier_conf->duty);
  122. mcpwm_ll_carrier_enable(hal->dev, op, true);
  123. mcpwm_ll_carrier_set_oneshot_width(hal->dev, op, carrier_conf->oneshot_pulse_width);
  124. mcpwm_ll_carrier_out_invert(hal->dev, op, carrier_conf->inverted);
  125. }
  126. void mcpwm_hal_operator_disable_carrier(mcpwm_hal_context_t *hal, int op)
  127. {
  128. mcpwm_ll_carrier_enable(hal->dev, op, false);
  129. }
  130. void mcpwm_hal_operator_update_deadzone(mcpwm_hal_context_t *hal, int op, const mcpwm_hal_deadzone_conf_t *deadzone)
  131. {
  132. if (deadzone->mode != MCPWM_DEADTIME_BYPASS) {
  133. mcpwm_ll_deadtime_init(hal->dev, op);
  134. mcpwm_ll_deadtime_set_rising_delay(hal->dev, op, deadzone->red);
  135. mcpwm_ll_deadtime_set_falling_delay(hal->dev, op, deadzone->fed);
  136. mcpwm_ll_set_deadtime_mode(hal->dev, op, deadzone->mode);
  137. } else {
  138. mcpwm_ll_deadtime_bypass(hal->dev, op);
  139. }
  140. }
  141. void mcpwm_hal_fault_init(mcpwm_hal_context_t *hal, int fault_sig, bool level)
  142. {
  143. mcpwm_ll_fault_enable(hal->dev, fault_sig, level);
  144. }
  145. void mcpwm_hal_operator_update_fault(mcpwm_hal_context_t *hal, int op, const mcpwm_hal_fault_conf_t *fault_conf)
  146. {
  147. for (int fault_sig = 0; fault_sig < SOC_MCPWM_FAULT_SIG_NUM; fault_sig++) {
  148. bool enabled = (fault_conf->cbc_enabled_mask & BIT(fault_sig)) ? true : false;
  149. mcpwm_ll_fault_cbc_enable_signal(hal->dev, op, fault_sig, enabled);
  150. }
  151. for (int fault_sig = 0; fault_sig < SOC_MCPWM_FAULT_SIG_NUM; fault_sig++) {
  152. bool enabled = (fault_conf->ost_enabled_mask & BIT(fault_sig)) ? true : false;
  153. mcpwm_ll_fault_oneshot_enable_signal(hal->dev, op, fault_sig, enabled);
  154. }
  155. if (fault_conf->cbc_enabled_mask) {
  156. for (int gen = 0; gen < SOC_MCPWM_GENERATOR_NUM; gen++) {
  157. mcpwm_ll_fault_set_cyc_action(hal->dev, op, gen, fault_conf->action_on_fault[gen], fault_conf->action_on_fault[gen]);
  158. }
  159. }
  160. if (fault_conf->ost_enabled_mask) {
  161. for (int gen = 0; gen < SOC_MCPWM_GENERATOR_NUM; gen++) {
  162. mcpwm_ll_fault_set_oneshot_action(hal->dev, op, gen, fault_conf->action_on_fault[gen], fault_conf->action_on_fault[gen]);
  163. }
  164. }
  165. }
  166. void mcpwm_hal_fault_oneshot_clear(mcpwm_hal_context_t *hal, int op)
  167. {
  168. mcpwm_ll_fault_clear_ost(hal->dev, op);
  169. }
  170. void mcpwm_hal_fault_disable(mcpwm_hal_context_t *hal, int fault_sig)
  171. {
  172. for (int op = 0; op < SOC_MCPWM_OP_NUM; op++) {
  173. if (mcpwm_ll_fault_oneshot_signal_enabled(hal->dev, op, fault_sig)) {
  174. mcpwm_ll_fault_clear_ost(hal->dev, op);
  175. }
  176. }
  177. mcpwm_ll_fault_disable(hal->dev, fault_sig);
  178. }
  179. void mcpwm_hal_capture_enable(mcpwm_hal_context_t *hal, int cap_sig, const mcpwm_hal_capture_config_t *conf)
  180. {
  181. mcpwm_ll_capture_enable(hal->dev, cap_sig, 1);
  182. mcpwm_ll_capture_select_edge(hal->dev, cap_sig, conf->cap_edge);
  183. mcpwm_ll_capture_set_prescale(hal->dev, cap_sig, conf->prescale);
  184. }
  185. esp_err_t mcpwm_hal_capture_get_result(mcpwm_hal_context_t *hal, int cap_sig, uint32_t *out_count, mcpwm_capture_on_edge_t *out_edge)
  186. {
  187. const mcpwm_intr_t sig_intr = mcpwm_ll_get_cap_intr_def(cap_sig);
  188. //unconditionally update the output value
  189. if (out_edge) {
  190. *out_edge = mcpwm_ll_get_captured_edge(hal->dev, cap_sig);
  191. }
  192. if (out_count) {
  193. *out_count = mcpwm_ll_get_capture_val(hal->dev, cap_sig);
  194. }
  195. if (mcpwm_ll_get_intr(hal->dev) & sig_intr) {
  196. mcpwm_ll_clear_intr(hal->dev, sig_intr);
  197. }
  198. return (mcpwm_ll_get_intr(hal->dev) & sig_intr ? ESP_OK : ESP_ERR_NOT_FOUND);
  199. }
  200. void mcpwm_hal_capture_disable(mcpwm_hal_context_t *hal, int cap_sig)
  201. {
  202. mcpwm_ll_capture_enable(hal->dev, cap_sig, 0);
  203. }