test_pwm.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. /**
  2. * To test PWM, use the PCNT to calculateit to judge it work right or not.
  3. * e.g: judge the start and stop.
  4. * If started right, the PCNT will count the pulse.
  5. * If stopped right, the PCNT will count no pulse.
  6. *
  7. *
  8. * test environment UT_T1_MCPWM:
  9. * 1. connect GPIO4 to GPIO5
  10. * 2. connect GPIO13 to GPIO12
  11. * 3. connect GPIO27 to GPIO14
  12. *
  13. * all of case separate different timer to test in case that one case cost too much time
  14. */
  15. #include <stdio.h>
  16. #include "esp_system.h"
  17. #include "driver/mcpwm.h"
  18. #include "driver/pcnt.h"
  19. #include "unity.h"
  20. #include "test_utils.h"
  21. #include "freertos/FreeRTOS.h"
  22. #include "freertos/task.h"
  23. #include "soc/mcpwm_periph.h"
  24. #include "freertos/queue.h"
  25. #include "esp_attr.h"
  26. #include "esp_log.h"
  27. #include "soc/rtc.h"
  28. #include "esp32/rom/ets_sys.h"
  29. #define GPIO_PWMA_OUT 4
  30. #define GPIO_PWMB_OUT 13
  31. #define GPIO_CAP_IN 27
  32. #define GPIO_SYNC_IN 27
  33. #define GPIO_FAULT_IN 27
  34. #define CAP_SIG_NUM 14
  35. #define SYN_SIG_NUM 14
  36. #define FAULT_SIG_NUM 14
  37. #define GPIO_PWMA_PCNT_INPUT 5
  38. #define GPIO_PWMB_PCNT_INPUT 12
  39. #define PCNT_CTRL_FLOATING_IO1 25
  40. #define PCNT_CTRL_FLOATING_IO2 26
  41. #define CAP0_INT_EN BIT(27)
  42. #define CAP1_INT_EN BIT(28)
  43. #define CAP2_INT_EN BIT(29)
  44. #define INITIAL_DUTY 10.0
  45. #define MCPWM_GPIO_INIT 0
  46. #define HIGHEST_LIMIT 10000
  47. #define LOWEST_LIMIT -10000
  48. static mcpwm_dev_t *MCPWM[2] = {&MCPWM0, &MCPWM1};
  49. static xQueueHandle cap_queue;
  50. static volatile int cap0_times = 0;
  51. static volatile int cap1_times = 0;
  52. static volatile int cap2_times = 0;
  53. typedef struct {
  54. uint32_t capture_signal;
  55. mcpwm_capture_signal_t sel_cap_signal;
  56. } capture;
  57. // universal settings of mcpwm
  58. static void mcpwm_basic_config(mcpwm_unit_t unit, mcpwm_io_signals_t mcpwm_a, mcpwm_io_signals_t mcpwm_b, mcpwm_timer_t timer)
  59. {
  60. mcpwm_gpio_init(unit, mcpwm_a, GPIO_PWMA_OUT);
  61. mcpwm_gpio_init(unit, mcpwm_b, GPIO_PWMB_OUT);
  62. mcpwm_config_t pwm_config = {
  63. .frequency = 1000,
  64. .cmpr_a = 50.0, //duty cycle of PWMxA = 50.0%
  65. .cmpr_b = 50.0, //duty cycle of PWMxb = 50.0%
  66. .counter_mode = MCPWM_UP_COUNTER,
  67. .duty_mode = MCPWM_DUTY_MODE_0,
  68. };
  69. mcpwm_init(unit, timer, &pwm_config);
  70. }
  71. static void pcnt_init(int pulse_gpio_num, int ctrl_gpio_num)
  72. {
  73. pcnt_config_t pcnt_config = {
  74. .pulse_gpio_num = pulse_gpio_num,
  75. .ctrl_gpio_num = ctrl_gpio_num,
  76. .channel = PCNT_CHANNEL_0,
  77. .unit = PCNT_UNIT_0,
  78. .pos_mode = PCNT_COUNT_INC,
  79. .neg_mode = PCNT_COUNT_DIS,
  80. .lctrl_mode = PCNT_MODE_REVERSE,
  81. .hctrl_mode = PCNT_MODE_KEEP,
  82. .counter_h_lim = HIGHEST_LIMIT,
  83. .counter_l_lim = LOWEST_LIMIT,
  84. };
  85. TEST_ESP_OK(pcnt_unit_config(&pcnt_config));
  86. }
  87. // initialize the PCNT
  88. // PCNT is used to count the MCPWM pulse
  89. static int16_t pcnt_count(int pulse_gpio_num, int ctrl_gpio_num, int last_time)
  90. {
  91. pcnt_config_t pcnt_config = {
  92. .pulse_gpio_num = pulse_gpio_num,
  93. .ctrl_gpio_num = ctrl_gpio_num,
  94. .channel = PCNT_CHANNEL_0,
  95. .unit = PCNT_UNIT_0,
  96. .pos_mode = PCNT_COUNT_INC,
  97. .neg_mode = PCNT_COUNT_DIS,
  98. .lctrl_mode = PCNT_MODE_REVERSE,
  99. .hctrl_mode = PCNT_MODE_KEEP,
  100. .counter_h_lim = HIGHEST_LIMIT,
  101. .counter_l_lim = LOWEST_LIMIT,
  102. };
  103. TEST_ESP_OK(pcnt_unit_config(&pcnt_config));
  104. int16_t test_counter;
  105. TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0));
  106. TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0));
  107. TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0));
  108. TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
  109. printf("COUNT: %d\n", test_counter);
  110. vTaskDelay(last_time / portTICK_RATE_MS);
  111. TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &test_counter));
  112. printf("COUNT: %d\n", test_counter);
  113. return test_counter;
  114. }
  115. // judge the counting value right or not in specific error
  116. static void judge_count_value(int allow_error ,int expect_freq)
  117. {
  118. int16_t countA, countB;
  119. countA = pcnt_count(GPIO_PWMA_PCNT_INPUT, PCNT_CTRL_FLOATING_IO1, 1000);
  120. countB = pcnt_count(GPIO_PWMB_PCNT_INPUT, PCNT_CTRL_FLOATING_IO2, 1000);
  121. TEST_ASSERT_INT16_WITHIN(allow_error, countA, expect_freq);
  122. TEST_ASSERT_INT16_WITHIN(allow_error, countB, expect_freq);
  123. }
  124. // test the duty configuration
  125. static void timer_duty_test(mcpwm_unit_t unit, mcpwm_io_signals_t mcpwm_a, mcpwm_io_signals_t mcpwm_b, mcpwm_timer_t timer)
  126. {
  127. mcpwm_basic_config(unit, mcpwm_a, mcpwm_b, timer);
  128. vTaskDelay(1000 / portTICK_RATE_MS); // stay this status for a while so that can view its waveform by logic anylyzer
  129. TEST_ESP_OK(mcpwm_set_duty(unit, timer, MCPWM_OPR_A, (INITIAL_DUTY * 1)));
  130. TEST_ESP_OK(mcpwm_set_duty(unit, timer, MCPWM_OPR_B, (INITIAL_DUTY * 2)));
  131. TEST_ASSERT_EQUAL_INT(mcpwm_get_duty(unit, timer, MCPWM_OPR_A), INITIAL_DUTY * 1);
  132. TEST_ASSERT_EQUAL_INT(mcpwm_get_duty(unit, timer, MCPWM_OPR_B), INITIAL_DUTY * 2);
  133. vTaskDelay(1000 / portTICK_RATE_MS); // stay this status for a while so that can view its waveform by logic anylyzer
  134. mcpwm_set_duty(unit, timer, MCPWM_OPR_A, 55.5f);
  135. mcpwm_set_duty_type(unit, timer, MCPWM_OPR_A, MCPWM_DUTY_MODE_0);
  136. printf("mcpwm check = %f\n", mcpwm_get_duty(unit, timer, MCPWM_OPR_A));
  137. mcpwm_set_duty_in_us(unit, timer, MCPWM_OPR_B, 500);
  138. printf("mcpwm check = %f\n", mcpwm_get_duty(unit, timer, MCPWM_OPR_B));
  139. vTaskDelay(1000 / portTICK_RATE_MS); // stay this status for a while so that can view its waveform by logic anylyzer
  140. }
  141. // test the start and stop function work or not
  142. static void start_stop_test(mcpwm_unit_t unit, mcpwm_io_signals_t mcpwm_a, mcpwm_io_signals_t mcpwm_b, mcpwm_timer_t timer)
  143. {
  144. mcpwm_basic_config(unit, mcpwm_a, mcpwm_b, timer);
  145. judge_count_value(2, 1000);
  146. TEST_ESP_OK(mcpwm_stop(unit, timer));
  147. vTaskDelay(10 / portTICK_RATE_MS); // wait for a while, stop totally
  148. judge_count_value(0, 0);
  149. TEST_ESP_OK(mcpwm_start(unit, timer));
  150. vTaskDelay(10 / portTICK_RATE_MS); // wait for a while, start totally
  151. judge_count_value(2, 1000);
  152. }
  153. // test the deadtime
  154. static void deadtime_test(mcpwm_unit_t unit, mcpwm_io_signals_t mcpwm_a, mcpwm_io_signals_t mcpwm_b, mcpwm_timer_t timer)
  155. {
  156. mcpwm_basic_config(unit, mcpwm_a, mcpwm_b, timer);
  157. mcpwm_deadtime_type_t deadtime_type[8] = {MCPWM_BYPASS_RED, MCPWM_BYPASS_FED, MCPWM_ACTIVE_HIGH_MODE,
  158. MCPWM_ACTIVE_LOW_MODE, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, MCPWM_ACTIVE_LOW_COMPLIMENT_MODE,
  159. MCPWM_ACTIVE_RED_FED_FROM_PWMXA, MCPWM_ACTIVE_RED_FED_FROM_PWMXB};
  160. for(int i=0; i<8; i++) {
  161. mcpwm_deadtime_enable(unit, timer, deadtime_type[i], 1000, 1000);
  162. vTaskDelay(1000 / portTICK_RATE_MS);
  163. mcpwm_deadtime_disable(unit, timer);
  164. }
  165. }
  166. /**
  167. * there are two kind of methods to set the carrier:
  168. * 1. by mcpwm_carrier_init
  169. * 2. by different single setting function
  170. */
  171. static void carrier_with_set_function_test(mcpwm_unit_t unit, mcpwm_io_signals_t mcpwm_a, mcpwm_io_signals_t mcpwm_b, mcpwm_timer_t timer,
  172. mcpwm_carrier_out_ivt_t invert_or_not, uint8_t period, uint8_t duty, uint8_t os_width)
  173. {
  174. // no inversion and no one shot
  175. mcpwm_basic_config(unit, mcpwm_a, mcpwm_b, timer);
  176. TEST_ESP_OK(mcpwm_carrier_enable(unit, timer));
  177. TEST_ESP_OK(mcpwm_carrier_set_period(unit, timer, period)); //carrier revolution
  178. TEST_ESP_OK(mcpwm_carrier_set_duty_cycle(unit, timer, duty)); // carrier duty
  179. judge_count_value(500, 50000/5.6);
  180. // with invert
  181. TEST_ESP_OK(mcpwm_carrier_output_invert(unit, timer, invert_or_not));
  182. vTaskDelay(2000 / portTICK_RATE_MS);
  183. }
  184. static void carrier_with_configuration_test(mcpwm_unit_t unit, mcpwm_io_signals_t mcpwm_a, mcpwm_io_signals_t mcpwm_b, mcpwm_timer_t timer,
  185. mcpwm_carrier_os_t oneshot_or_not, mcpwm_carrier_out_ivt_t invert_or_not, uint8_t period, uint8_t duty, uint8_t os_width)
  186. {
  187. mcpwm_basic_config(unit, mcpwm_a, mcpwm_b, timer);
  188. mcpwm_carrier_config_t chop_config;
  189. chop_config.carrier_period = period; //carrier period = (period + 1)*800ns
  190. chop_config.carrier_duty = duty; // carrier duty cycle, carrier_duty should be less then 8(increment every 12.5%). carrier duty = (3)*12.5%
  191. chop_config.carrier_os_mode = oneshot_or_not; //If one shot mode is enabled then set pulse width, if disabled no need to set pulse width
  192. chop_config.pulse_width_in_os = os_width; //pulse width of first pulse in one shot mode = (carrier period)*(pulse_width_in_os + 1), should be less then 16.first pulse width = (3 + 1)*carrier_period
  193. chop_config.carrier_ivt_mode = invert_or_not; //output signal inversion enable
  194. mcpwm_carrier_init(unit, timer, &chop_config);
  195. if(!oneshot_or_not) {
  196. // the pwm frequency is 1000
  197. // the carrrier duration in one second is 500ms
  198. // the carrier wave count is: 500ms/carrier_period = 500ms/(period + 1)*800ns
  199. // = 62500/(period + 1)
  200. judge_count_value(500, 62500/(period + 1));
  201. } else {
  202. judge_count_value(500, 40000/((period + 1))); // (500-500*0.125*3)/((period + 1)*800)
  203. }
  204. TEST_ESP_OK(mcpwm_carrier_disable(unit, timer));
  205. judge_count_value(2, 1000);
  206. }
  207. static void get_action_level(mcpwm_fault_input_level_t input_sig, mcpwm_action_on_pwmxa_t action_a, mcpwm_action_on_pwmxb_t action_b, int freq, int allow_err)
  208. {
  209. if(action_a == MCPWM_NO_CHANGE_IN_MCPWMXA) {
  210. TEST_ASSERT_INT16_WITHIN(allow_err, pcnt_count(GPIO_PWMA_PCNT_INPUT, PCNT_CTRL_FLOATING_IO1, 1000), freq);
  211. } else if(action_a == MCPWM_FORCE_MCPWMXA_LOW) {
  212. TEST_ASSERT(gpio_get_level(GPIO_PWMA_PCNT_INPUT) == 0);
  213. } else if(action_a == MCPWM_FORCE_MCPWMXA_HIGH) {
  214. TEST_ASSERT(gpio_get_level(GPIO_PWMA_PCNT_INPUT) == 1);
  215. }else {
  216. int level = gpio_get_level(GPIO_PWMA_PCNT_INPUT);
  217. vTaskDelay(100 / portTICK_RATE_MS);
  218. TEST_ASSERT(gpio_get_level(GPIO_PWMA_PCNT_INPUT) == level);
  219. }
  220. if(action_b == MCPWM_NO_CHANGE_IN_MCPWMXB) {
  221. TEST_ASSERT_INT16_WITHIN(allow_err, pcnt_count(GPIO_PWMB_PCNT_INPUT, PCNT_CTRL_FLOATING_IO1, 1000), freq);
  222. } else if(action_b == MCPWM_FORCE_MCPWMXB_LOW) {
  223. TEST_ASSERT(gpio_get_level(GPIO_PWMB_PCNT_INPUT) == 0);
  224. } else if(action_b == MCPWM_FORCE_MCPWMXB_HIGH) {
  225. TEST_ASSERT(gpio_get_level(GPIO_PWMB_PCNT_INPUT) == 1);
  226. }else {
  227. int level = gpio_get_level(GPIO_PWMB_PCNT_INPUT);
  228. vTaskDelay(100 / portTICK_RATE_MS);
  229. TEST_ASSERT(gpio_get_level(GPIO_PWMB_PCNT_INPUT) == level);
  230. }
  231. }
  232. // test the fault event
  233. static void cycle_fault_test(mcpwm_unit_t unit, mcpwm_io_signals_t mcpwm_a, mcpwm_io_signals_t mcpwm_b, mcpwm_timer_t timer,
  234. mcpwm_fault_signal_t fault_sig, mcpwm_fault_input_level_t input_sig, mcpwm_io_signals_t fault_io,
  235. mcpwm_action_on_pwmxa_t action_a, mcpwm_action_on_pwmxb_t action_b)
  236. {
  237. gpio_config_t gp;
  238. gp.intr_type = GPIO_INTR_DISABLE;
  239. gp.mode = GPIO_MODE_OUTPUT;
  240. gp.pin_bit_mask = (1ULL << FAULT_SIG_NUM);
  241. gpio_config(&gp); // gpio configure should be more previous than mcpwm configuration
  242. gpio_set_level(FAULT_SIG_NUM, !input_sig);
  243. pcnt_init(GPIO_PWMA_PCNT_INPUT, PCNT_CTRL_FLOATING_IO1);
  244. pcnt_init(GPIO_PWMB_PCNT_INPUT, PCNT_CTRL_FLOATING_IO2);
  245. mcpwm_basic_config(unit, mcpwm_a, mcpwm_b, timer);
  246. mcpwm_gpio_init(unit, fault_io, GPIO_FAULT_IN);
  247. // cycle mode, it can be triggered more than once
  248. printf("cyc test:\n");
  249. gpio_set_level(FAULT_SIG_NUM, !input_sig);
  250. TEST_ESP_OK(mcpwm_fault_init(unit, input_sig, fault_sig));
  251. TEST_ESP_OK(mcpwm_fault_set_cyc_mode(unit, timer, fault_sig, action_a, action_b));
  252. vTaskDelay(1000 / portTICK_RATE_MS);
  253. gpio_set_level(FAULT_SIG_NUM, input_sig); // trigger the fault event
  254. vTaskDelay(1000 / portTICK_RATE_MS);
  255. get_action_level(input_sig, action_a, action_b, 1000, 5);
  256. TEST_ESP_OK(mcpwm_fault_deinit(unit, fault_sig));
  257. }
  258. static void oneshot_fault_test(mcpwm_unit_t unit, mcpwm_io_signals_t mcpwm_a, mcpwm_io_signals_t mcpwm_b, mcpwm_timer_t timer,
  259. mcpwm_fault_signal_t fault_sig, mcpwm_fault_input_level_t input_sig, mcpwm_io_signals_t fault_io,
  260. mcpwm_action_on_pwmxa_t action_a, mcpwm_action_on_pwmxb_t action_b)
  261. {
  262. gpio_config_t gp;
  263. gp.intr_type = GPIO_INTR_DISABLE;
  264. gp.mode = GPIO_MODE_OUTPUT;
  265. gp.pin_bit_mask = (1ULL << FAULT_SIG_NUM);
  266. gpio_config(&gp); // gpio configure should be more previous than mcpwm configuration
  267. gpio_set_level(FAULT_SIG_NUM, !input_sig);
  268. pcnt_init(GPIO_PWMA_PCNT_INPUT, PCNT_CTRL_FLOATING_IO1);
  269. pcnt_init(GPIO_PWMB_PCNT_INPUT, PCNT_CTRL_FLOATING_IO2);
  270. mcpwm_basic_config(unit, mcpwm_a, mcpwm_b, timer);
  271. mcpwm_gpio_init(unit, fault_io, GPIO_FAULT_IN);
  272. // one shot mode, it just can be triggered once
  273. TEST_ESP_OK(mcpwm_fault_init(unit, input_sig, fault_sig));
  274. TEST_ESP_OK(mcpwm_fault_set_oneshot_mode(unit, timer, fault_sig, action_a, action_b));
  275. vTaskDelay(10/ portTICK_RATE_MS);
  276. // trigger it
  277. gpio_set_level(FAULT_SIG_NUM, input_sig);
  278. vTaskDelay(10/ portTICK_RATE_MS);
  279. get_action_level(input_sig, action_a, action_b, 1000, 5);
  280. TEST_ESP_OK(mcpwm_fault_deinit(unit, fault_sig));
  281. }
  282. // test the sync event
  283. static void sync_test(mcpwm_unit_t unit, mcpwm_io_signals_t mcpwm_a, mcpwm_io_signals_t mcpwm_b, mcpwm_timer_t timer,
  284. mcpwm_sync_signal_t sync_sig, mcpwm_io_signals_t sync_io)
  285. {
  286. gpio_config_t gp;
  287. gp.intr_type = GPIO_INTR_DISABLE;
  288. gp.mode = GPIO_MODE_OUTPUT;
  289. gp.pin_bit_mask = (1ULL << SYN_SIG_NUM);
  290. gpio_config(&gp);
  291. gpio_set_level(SYN_SIG_NUM, 0);
  292. mcpwm_gpio_init(unit, mcpwm_a, GPIO_PWMA_OUT);
  293. mcpwm_gpio_init(unit, mcpwm_b, GPIO_PWMB_OUT);
  294. mcpwm_gpio_init(unit, sync_io, GPIO_SYNC_IN);
  295. mcpwm_config_t pwm_config = {
  296. .frequency = 1000,
  297. .cmpr_a = 50.0, //duty cycle of PWMxA = 50.0%
  298. .cmpr_b = 50.0, //duty cycle of PWMxb = 50.0%
  299. .counter_mode = MCPWM_UP_COUNTER,
  300. .duty_mode = MCPWM_DUTY_MODE_0,
  301. };
  302. mcpwm_init(unit, timer, &pwm_config);
  303. gpio_pulldown_en(GPIO_SYNC_IN);
  304. mcpwm_sync_enable(unit, timer, sync_sig, 200);
  305. gpio_set_level(SYN_SIG_NUM, 1);
  306. vTaskDelay(2000 / portTICK_RATE_MS);
  307. mcpwm_sync_disable(unit, timer);
  308. vTaskDelay(2000 / portTICK_RATE_MS);
  309. }
  310. /**
  311. * use interruption to test the capture event
  312. * there are two kinds of methods to trigger the capture event:
  313. * 1. high level trigger
  314. * 2. low level trigger
  315. */
  316. static volatile int flag = 0;
  317. // once capture event happens, will show it
  318. static void disp_captured_signal(void *arg)
  319. {
  320. uint32_t *current_cap_value = (uint32_t *)malloc(sizeof(uint32_t) * CAP_SIG_NUM);
  321. uint32_t *previous_cap_value = (uint32_t *)malloc(sizeof(uint32_t) * CAP_SIG_NUM);
  322. capture evt;
  323. for (int i=0; i<1000; i++) {
  324. xQueueReceive(cap_queue, &evt, portMAX_DELAY);
  325. if (evt.sel_cap_signal == MCPWM_SELECT_CAP0) {
  326. current_cap_value[0] = evt.capture_signal - previous_cap_value[0];
  327. previous_cap_value[0] = evt.capture_signal;
  328. current_cap_value[0] = (current_cap_value[0] / 10000) * (10000000000 / rtc_clk_apb_freq_get());
  329. printf("CAP0 : %d us\n", current_cap_value[0]);
  330. cap0_times++;
  331. }
  332. if (evt.sel_cap_signal == MCPWM_SELECT_CAP1) {
  333. current_cap_value[1] = evt.capture_signal - previous_cap_value[1];
  334. previous_cap_value[1] = evt.capture_signal;
  335. current_cap_value[1] = (current_cap_value[1] / 10000) * (10000000000 / rtc_clk_apb_freq_get());
  336. printf("CAP1 : %d us\n", current_cap_value[1]);
  337. cap1_times++;
  338. }
  339. if (evt.sel_cap_signal == MCPWM_SELECT_CAP2) {
  340. current_cap_value[2] = evt.capture_signal - previous_cap_value[2];
  341. previous_cap_value[2] = evt.capture_signal;
  342. current_cap_value[2] = (current_cap_value[2] / 10000) * (10000000000 / rtc_clk_apb_freq_get());
  343. printf("CAP2 : %d us\n", current_cap_value[2]);
  344. cap2_times++;
  345. }
  346. }
  347. free(current_cap_value);
  348. free(previous_cap_value);
  349. vTaskDelete(NULL);
  350. }
  351. // mcpwm event
  352. static void IRAM_ATTR isr_handler(void *arg)
  353. {
  354. mcpwm_unit_t unit = (mcpwm_unit_t)arg;
  355. uint32_t mcpwm_intr_status;
  356. capture evt;
  357. mcpwm_intr_status = MCPWM[unit]->int_st.val; //Read interrupt status
  358. if (mcpwm_intr_status & CAP0_INT_EN) { //Check for interrupt on rising edge on CAP0 signal
  359. evt.capture_signal = mcpwm_capture_signal_get_value(unit, MCPWM_SELECT_CAP0); //get capture signal counter value
  360. evt.sel_cap_signal = MCPWM_SELECT_CAP0;
  361. xQueueSendFromISR(cap_queue, &evt, NULL);
  362. }
  363. if (mcpwm_intr_status & CAP1_INT_EN) { //Check for interrupt on rising edge on CAP0 signal
  364. evt.capture_signal = mcpwm_capture_signal_get_value(unit, MCPWM_SELECT_CAP1); //get capture signal counter value
  365. evt.sel_cap_signal = MCPWM_SELECT_CAP1;
  366. xQueueSendFromISR(cap_queue, &evt, NULL);
  367. }
  368. if (mcpwm_intr_status & CAP2_INT_EN) { //Check for interrupt on rising edge on CAP0 signal
  369. evt.capture_signal = mcpwm_capture_signal_get_value(unit, MCPWM_SELECT_CAP2); //get capture signal counter value
  370. evt.sel_cap_signal = MCPWM_SELECT_CAP2;
  371. xQueueSendFromISR(cap_queue, &evt, NULL);
  372. }
  373. MCPWM[unit]->int_clr.val = mcpwm_intr_status;
  374. }
  375. // the produce the capture triggering signal to trigger the capture event
  376. static void gpio_test_signal(void *arg)
  377. {
  378. printf("intializing test signal...\n");
  379. gpio_config_t gp = {};
  380. gp.intr_type = GPIO_INTR_DISABLE;
  381. gp.mode = GPIO_MODE_OUTPUT;
  382. gp.pin_bit_mask = 1ULL << CAP_SIG_NUM;
  383. gpio_config(&gp);
  384. for (int i=0; i<1000; i++) {
  385. //here the period of test signal is 20ms
  386. gpio_set_level(CAP_SIG_NUM, 1); //Set high
  387. vTaskDelay(10); //delay of 10ms
  388. gpio_set_level(CAP_SIG_NUM, 0); //Set low
  389. vTaskDelay(10); //delay of 10ms
  390. }
  391. flag = 1;
  392. vTaskDelete(NULL);
  393. }
  394. // capture event test function
  395. static void capture_test(mcpwm_unit_t unit, mcpwm_io_signals_t mcpwm_a, mcpwm_io_signals_t mcpwm_b, mcpwm_io_signals_t cap_io, mcpwm_timer_t timer,
  396. mcpwm_capture_signal_t cap_sig, mcpwm_capture_on_edge_t cap_edge)
  397. {
  398. // initialize the capture times
  399. cap0_times = 0;
  400. cap1_times = 0;
  401. cap2_times = 0;
  402. mcpwm_gpio_init(unit, cap_io, GPIO_CAP_IN);
  403. cap_queue = xQueueCreate(1, sizeof(capture));
  404. xTaskCreate(disp_captured_signal, "mcpwm_config", 4096, (void *)unit, 5, NULL);
  405. xTaskCreate(gpio_test_signal, "gpio_test_signal", 4096, NULL, 5, NULL);
  406. mcpwm_capture_enable(unit, cap_sig, cap_edge, 0);
  407. MCPWM[unit]->int_ena.val = CAP0_INT_EN | CAP1_INT_EN | CAP2_INT_EN; //Enable interrupt on CAP0, CAP1 and CAP2 signal
  408. mcpwm_isr_register(unit, isr_handler, (void *)unit, ESP_INTR_FLAG_IRAM, NULL);
  409. while(flag != 1) {
  410. vTaskDelay(10 / portTICK_RATE_MS);
  411. }
  412. if(cap_sig == MCPWM_SELECT_CAP0) {
  413. TEST_ASSERT(1000 == cap0_times);
  414. } else if(cap_sig == MCPWM_SELECT_CAP1) {
  415. TEST_ASSERT(1000 == cap1_times);
  416. }else {
  417. TEST_ASSERT(1000 == cap2_times);
  418. }
  419. flag = 0; // set flag to 0 that it can be used in other case
  420. mcpwm_capture_disable(unit, cap_sig);
  421. }
  422. /**
  423. * duty test:
  424. * 1. mcpwm_set_duty
  425. * 2. mcpwm_get_duty
  426. *
  427. * This case's phenomenon should be viewed by logic analyzer
  428. * so set it ignore
  429. */
  430. TEST_CASE("MCPWM timer0 duty test and each timer works or not test(logic analyzer)", "[mcpwm][ignore]")
  431. {
  432. timer_duty_test(MCPWM_UNIT_0, MCPWM0A, MCPWM0B, MCPWM_TIMER_0);
  433. timer_duty_test(MCPWM_UNIT_1, MCPWM0A, MCPWM0B, MCPWM_TIMER_0);
  434. }
  435. TEST_CASE("MCPWM timer1 duty test and each timer works or not test(logic analyzer)", "[mcpwm][ignore]")
  436. {
  437. timer_duty_test(MCPWM_UNIT_0, MCPWM1A, MCPWM1B, MCPWM_TIMER_1);
  438. timer_duty_test(MCPWM_UNIT_1, MCPWM1A, MCPWM1B, MCPWM_TIMER_1);
  439. }
  440. TEST_CASE("MCPWM timer2 duty test and each timer works or not test(logic analyzer)", "[mcpwm][ignore]")
  441. {
  442. timer_duty_test(MCPWM_UNIT_0, MCPWM2A, MCPWM2B, MCPWM_TIMER_2);
  443. timer_duty_test(MCPWM_UNIT_1, MCPWM2A, MCPWM2B, MCPWM_TIMER_2);
  444. }
  445. // the deadtime configuration test
  446. // use the logic analyzer to make sure it goes right
  447. TEST_CASE("MCPWM timer0 deadtime configuration(logic analyzer)", "[mcpwm][ignore]")
  448. {
  449. deadtime_test(MCPWM_UNIT_0, MCPWM0A, MCPWM0B, MCPWM_TIMER_0);
  450. deadtime_test(MCPWM_UNIT_1, MCPWM0A, MCPWM0B, MCPWM_TIMER_0);
  451. }
  452. TEST_CASE("MCPWM timer1 deadtime configuration(logic analyzer)", "[mcpwm][ignore]")
  453. {
  454. deadtime_test(MCPWM_UNIT_0, MCPWM1A, MCPWM1B, MCPWM_TIMER_1);
  455. deadtime_test(MCPWM_UNIT_1, MCPWM1A, MCPWM1B, MCPWM_TIMER_1);
  456. }
  457. TEST_CASE("MCPWM timer2 deadtime configuration(logic analyzer)", "[mcpwm][ignore]")
  458. {
  459. deadtime_test(MCPWM_UNIT_0, MCPWM2A, MCPWM2B, MCPWM_TIMER_2);
  460. deadtime_test(MCPWM_UNIT_1, MCPWM2A, MCPWM2B, MCPWM_TIMER_2);
  461. }
  462. TEST_CASE("MCPWM timer0 start and stop test", "[mcpwm][test_env=UT_T1_MCPWM]")
  463. {
  464. start_stop_test(MCPWM_UNIT_0, MCPWM0A, MCPWM0B, MCPWM_TIMER_0);
  465. start_stop_test(MCPWM_UNIT_1, MCPWM0A, MCPWM0B, MCPWM_TIMER_0);
  466. }
  467. // mcpwm start and stop test
  468. TEST_CASE("MCPWM timer1 start and stop test", "[mcpwm][test_env=UT_T1_MCPWM]")
  469. {
  470. start_stop_test(MCPWM_UNIT_0, MCPWM1A, MCPWM1B, MCPWM_TIMER_1);
  471. start_stop_test(MCPWM_UNIT_1, MCPWM1A, MCPWM1B, MCPWM_TIMER_1);
  472. }
  473. TEST_CASE("MCPWM timer2 start and stop test", "[mcpwm][test_env=UT_T1_MCPWM]")
  474. {
  475. start_stop_test(MCPWM_UNIT_0, MCPWM2A, MCPWM2B, MCPWM_TIMER_2);
  476. start_stop_test(MCPWM_UNIT_1, MCPWM2A, MCPWM2B, MCPWM_TIMER_2);
  477. }
  478. TEST_CASE("MCPWM timer0 carrier test with set function", "[mcpwm][test_env=UT_T1_MCPWM]")
  479. {
  480. carrier_with_set_function_test(MCPWM_UNIT_0, MCPWM0A, MCPWM0B, MCPWM_TIMER_0,
  481. MCPWM_CARRIER_OUT_IVT_DIS, 6, 3, 3);
  482. carrier_with_set_function_test(MCPWM_UNIT_0, MCPWM0A, MCPWM0B, MCPWM_TIMER_0,
  483. MCPWM_CARRIER_OUT_IVT_EN, 6, 3, 3);
  484. carrier_with_set_function_test(MCPWM_UNIT_1, MCPWM0A, MCPWM0B, MCPWM_TIMER_0,
  485. MCPWM_CARRIER_OUT_IVT_DIS, 6, 3, 3);
  486. carrier_with_set_function_test(MCPWM_UNIT_1, MCPWM0A, MCPWM0B, MCPWM_TIMER_0,
  487. MCPWM_CARRIER_OUT_IVT_EN, 6, 3, 3);
  488. }
  489. TEST_CASE("MCPWM timer1 carrier test with set function", "[mcpwm][test_env=UT_T1_MCPWM]")
  490. {
  491. carrier_with_set_function_test(MCPWM_UNIT_0, MCPWM1A, MCPWM1B, MCPWM_TIMER_1,
  492. MCPWM_CARRIER_OUT_IVT_DIS, 6, 3, 3);
  493. carrier_with_set_function_test(MCPWM_UNIT_0, MCPWM1A, MCPWM1B, MCPWM_TIMER_1,
  494. MCPWM_CARRIER_OUT_IVT_EN, 6, 3, 3);
  495. carrier_with_set_function_test(MCPWM_UNIT_1, MCPWM1A, MCPWM1B, MCPWM_TIMER_1,
  496. MCPWM_CARRIER_OUT_IVT_DIS, 6, 3, 3);
  497. carrier_with_set_function_test(MCPWM_UNIT_1, MCPWM1A, MCPWM1B, MCPWM_TIMER_1,
  498. MCPWM_CARRIER_OUT_IVT_EN, 6, 3, 3);
  499. }
  500. TEST_CASE("MCPWM timer2 carrier test with set function", "[mcpwm][test_env=UT_T1_MCPWM]")
  501. {
  502. carrier_with_set_function_test(MCPWM_UNIT_0, MCPWM2A, MCPWM2B, MCPWM_TIMER_2,
  503. MCPWM_CARRIER_OUT_IVT_DIS, 6, 3, 3);
  504. carrier_with_set_function_test(MCPWM_UNIT_0, MCPWM2A, MCPWM2B, MCPWM_TIMER_2,
  505. MCPWM_CARRIER_OUT_IVT_EN, 6, 3, 3);
  506. carrier_with_set_function_test(MCPWM_UNIT_1, MCPWM2A, MCPWM2B, MCPWM_TIMER_2,
  507. MCPWM_CARRIER_OUT_IVT_DIS, 6, 3, 3);
  508. carrier_with_set_function_test(MCPWM_UNIT_1, MCPWM2A, MCPWM2B, MCPWM_TIMER_2,
  509. MCPWM_CARRIER_OUT_IVT_EN, 6, 3, 3);
  510. }
  511. TEST_CASE("MCPWM timer0 carrier test with configuration function", "[mcpwm][test_env=UT_T1_MCPWM][timeout=120]")
  512. {
  513. mcpwm_carrier_os_t oneshot[2] = {MCPWM_ONESHOT_MODE_DIS, MCPWM_ONESHOT_MODE_EN};
  514. mcpwm_carrier_out_ivt_t invert[2] = {MCPWM_CARRIER_OUT_IVT_DIS, MCPWM_CARRIER_OUT_IVT_EN};
  515. for(int i=0; i<2; i++){
  516. for(int j=0; j<2; j++) {
  517. printf("i=%d, j=%d\n", i, j);
  518. carrier_with_configuration_test(MCPWM_UNIT_0, MCPWM0A, MCPWM0B, MCPWM_TIMER_0,
  519. oneshot[i], invert[j], 6, 3, 3);
  520. carrier_with_configuration_test(MCPWM_UNIT_1, MCPWM0A, MCPWM0B, MCPWM_TIMER_0,
  521. oneshot[i], invert[j], 6, 3, 3);
  522. }
  523. }
  524. }
  525. TEST_CASE("MCPWM timer1 carrier test with configuration function", "[mcpwm][test_env=UT_T1_MCPWM][timeout=120]")
  526. {
  527. mcpwm_carrier_os_t oneshot[2] = {MCPWM_ONESHOT_MODE_DIS, MCPWM_ONESHOT_MODE_EN};
  528. mcpwm_carrier_out_ivt_t invert[2] = {MCPWM_CARRIER_OUT_IVT_DIS, MCPWM_CARRIER_OUT_IVT_EN};
  529. for(int i=0; i<2; i++){
  530. for(int j=0; j<2; j++) {
  531. carrier_with_configuration_test(MCPWM_UNIT_0, MCPWM1A, MCPWM1B, MCPWM_TIMER_1,
  532. oneshot[i], invert[j], 6, 3, 3);
  533. carrier_with_configuration_test(MCPWM_UNIT_1, MCPWM1A, MCPWM1B, MCPWM_TIMER_1,
  534. oneshot[i], invert[j], 6, 3, 3);
  535. }
  536. }
  537. }
  538. TEST_CASE("MCPWM timer2 carrier test with configuration function", "[mcpwm][test_env=UT_T1_MCPWM][timeout=120]")
  539. {
  540. mcpwm_carrier_os_t oneshot[2] = {MCPWM_ONESHOT_MODE_DIS, MCPWM_ONESHOT_MODE_EN};
  541. mcpwm_carrier_out_ivt_t invert[2] = {MCPWM_CARRIER_OUT_IVT_DIS, MCPWM_CARRIER_OUT_IVT_EN};
  542. for(int i=0; i<2; i++){
  543. for(int j=0; j<2; j++) {
  544. carrier_with_configuration_test(MCPWM_UNIT_0, MCPWM2A, MCPWM2B, MCPWM_TIMER_2,
  545. oneshot[i], invert[j], 6, 3, 3);
  546. carrier_with_configuration_test(MCPWM_UNIT_1, MCPWM2A, MCPWM2B, MCPWM_TIMER_2,
  547. oneshot[i], invert[j], 6, 3, 3);
  548. }
  549. }
  550. }
  551. /**
  552. * Fault event:
  553. * Just support high level triggering
  554. * There are two types fault event:
  555. * 1. one-shot: it just can be triggered once, its effect is forever and it will never be changed although the fault signal change
  556. * 2. cycle: it can be triggered more than once, it will changed just as the fault signal changes. If set it triggered by high level,
  557. * when the fault signal is high level, the event will be triggered. But the event will disappear as the fault signal disappears
  558. */
  559. TEST_CASE("MCPWM timer0 cycle fault test", "[mcpwm][test_env=UT_T1_MCPWM][timeout=180]")
  560. {
  561. // API just supports the high level trigger now, so comment it
  562. // mcpwm_fault_input_level_t fault_input[2] = {MCPWM_LOW_LEVEL_TGR, MCPWM_HIGH_LEVEL_TGR};
  563. mcpwm_action_on_pwmxa_t action_a[4] = {MCPWM_NO_CHANGE_IN_MCPWMXA, MCPWM_FORCE_MCPWMXA_LOW, MCPWM_FORCE_MCPWMXA_HIGH, MCPWM_TOG_MCPWMXA};
  564. mcpwm_action_on_pwmxb_t action_b[4] = {MCPWM_NO_CHANGE_IN_MCPWMXB, MCPWM_FORCE_MCPWMXB_LOW, MCPWM_FORCE_MCPWMXB_HIGH, MCPWM_TOG_MCPWMXB};
  565. for(int i=0; i<4; i++){
  566. for(int j=0; j<4; j++) {
  567. printf("i=%d, j=%d\n",i, j);
  568. cycle_fault_test(MCPWM_UNIT_0, MCPWM0A, MCPWM0B, MCPWM_TIMER_0,
  569. MCPWM_SELECT_F0, MCPWM_HIGH_LEVEL_TGR, MCPWM_FAULT_0,
  570. action_a[i], action_b[j]);
  571. cycle_fault_test(MCPWM_UNIT_1, MCPWM0A, MCPWM0B, MCPWM_TIMER_0,
  572. MCPWM_SELECT_F0, MCPWM_HIGH_LEVEL_TGR, MCPWM_FAULT_0,
  573. action_a[i], action_b[j]);
  574. }
  575. }
  576. }
  577. TEST_CASE("MCPWM timer1 cycle fault test", "[mcpwm][test_env=UT_T1_MCPWM][timeout=180]")
  578. {
  579. // API just supports the high level trigger now, so comment it
  580. // mcpwm_fault_input_level_t fault_input[2] = {MCPWM_LOW_LEVEL_TGR, MCPWM_HIGH_LEVEL_TGR};
  581. mcpwm_action_on_pwmxa_t action_a[4] = {MCPWM_NO_CHANGE_IN_MCPWMXA, MCPWM_FORCE_MCPWMXA_LOW, MCPWM_FORCE_MCPWMXA_HIGH, MCPWM_TOG_MCPWMXA};
  582. mcpwm_action_on_pwmxb_t action_b[4] = {MCPWM_NO_CHANGE_IN_MCPWMXB, MCPWM_FORCE_MCPWMXB_LOW, MCPWM_FORCE_MCPWMXB_HIGH, MCPWM_TOG_MCPWMXB};
  583. for(int i=0; i<4; i++){
  584. for(int j=0; j<4; j++) {
  585. cycle_fault_test(MCPWM_UNIT_0, MCPWM1A, MCPWM1B, MCPWM_TIMER_1,
  586. MCPWM_SELECT_F1, MCPWM_HIGH_LEVEL_TGR, MCPWM_FAULT_1,
  587. action_a[i], action_b[j]);
  588. cycle_fault_test(MCPWM_UNIT_1, MCPWM1A, MCPWM1B, MCPWM_TIMER_1,
  589. MCPWM_SELECT_F1, MCPWM_HIGH_LEVEL_TGR, MCPWM_FAULT_1,
  590. action_a[i], action_b[j]);
  591. }
  592. }
  593. }
  594. TEST_CASE("MCPWM timer2 cycle fault test", "[mcpwm][test_env=UT_T1_MCPWM][timeout=180]")
  595. {
  596. // API just supports the high level trigger now, so comment it
  597. // mcpwm_fault_input_level_t fault_input[2] = {MCPWM_LOW_LEVEL_TGR, MCPWM_HIGH_LEVEL_TGR};
  598. mcpwm_action_on_pwmxa_t action_a[4] = {MCPWM_NO_CHANGE_IN_MCPWMXA, MCPWM_FORCE_MCPWMXA_LOW, MCPWM_FORCE_MCPWMXA_HIGH, MCPWM_TOG_MCPWMXA};
  599. mcpwm_action_on_pwmxb_t action_b[4] = {MCPWM_NO_CHANGE_IN_MCPWMXB, MCPWM_FORCE_MCPWMXB_LOW, MCPWM_FORCE_MCPWMXB_HIGH, MCPWM_TOG_MCPWMXB};
  600. for(int i=0; i<4; i++){
  601. for(int j=0; j<4; j++) {
  602. cycle_fault_test(MCPWM_UNIT_0, MCPWM2A, MCPWM2B, MCPWM_TIMER_2,
  603. MCPWM_SELECT_F2, MCPWM_HIGH_LEVEL_TGR, MCPWM_FAULT_2,
  604. action_a[i], action_b[j]);
  605. cycle_fault_test(MCPWM_UNIT_1, MCPWM2A, MCPWM2B, MCPWM_TIMER_2,
  606. MCPWM_SELECT_F2, MCPWM_HIGH_LEVEL_TGR, MCPWM_FAULT_2,
  607. action_a[i], action_b[j]);
  608. }
  609. }
  610. }
  611. TEST_CASE("MCPWM timer0 one shot fault test", "[mcpwm][test_env=UT_T1_MCPWM][timeout=60]")
  612. {
  613. // API just supports the high level trigger now, so comment it
  614. // mcpwm_fault_input_level_t fault_input[2] = {MCPWM_LOW_LEVEL_TGR, MCPWM_HIGH_LEVEL_TGR};
  615. mcpwm_action_on_pwmxa_t action_a[4] = {MCPWM_NO_CHANGE_IN_MCPWMXA, MCPWM_FORCE_MCPWMXA_LOW, MCPWM_FORCE_MCPWMXA_HIGH, MCPWM_TOG_MCPWMXA};
  616. mcpwm_action_on_pwmxb_t action_b[4] = {MCPWM_NO_CHANGE_IN_MCPWMXB, MCPWM_FORCE_MCPWMXB_LOW, MCPWM_FORCE_MCPWMXB_HIGH, MCPWM_TOG_MCPWMXB};
  617. for(int i=0; i<4; i++){
  618. for(int j=0; j<4; j++) {
  619. printf("i=%d, j=%d\n",i, j);
  620. oneshot_fault_test(MCPWM_UNIT_0, MCPWM0A, MCPWM0B, MCPWM_TIMER_0,
  621. MCPWM_SELECT_F0, MCPWM_HIGH_LEVEL_TGR, MCPWM_FAULT_0,
  622. action_a[i], action_b[j]);
  623. oneshot_fault_test(MCPWM_UNIT_1, MCPWM0A, MCPWM0B, MCPWM_TIMER_0,
  624. MCPWM_SELECT_F0, MCPWM_HIGH_LEVEL_TGR, MCPWM_FAULT_0,
  625. action_a[i], action_b[j]);
  626. }
  627. }
  628. }
  629. TEST_CASE("MCPWM timer1 one shot fault test", "[mcpwm][test_env=UT_T1_MCPWM][timeout=60]")
  630. {
  631. // API just supports the high level trigger now, so comment it
  632. // mcpwm_fault_input_level_t fault_input[2] = {MCPWM_LOW_LEVEL_TGR, MCPWM_HIGH_LEVEL_TGR};
  633. mcpwm_action_on_pwmxa_t action_a[4] = {MCPWM_NO_CHANGE_IN_MCPWMXA, MCPWM_FORCE_MCPWMXA_LOW, MCPWM_FORCE_MCPWMXA_HIGH, MCPWM_TOG_MCPWMXA};
  634. mcpwm_action_on_pwmxb_t action_b[4] = {MCPWM_NO_CHANGE_IN_MCPWMXB, MCPWM_FORCE_MCPWMXB_LOW, MCPWM_FORCE_MCPWMXB_HIGH, MCPWM_TOG_MCPWMXB};
  635. for(int i=0; i<4; i++){
  636. for(int j=0; j<4; j++) {
  637. oneshot_fault_test(MCPWM_UNIT_0, MCPWM1A, MCPWM1B, MCPWM_TIMER_1,
  638. MCPWM_SELECT_F1, MCPWM_HIGH_LEVEL_TGR, MCPWM_FAULT_1,
  639. action_a[i], action_b[j]);
  640. oneshot_fault_test(MCPWM_UNIT_1, MCPWM1A, MCPWM1B, MCPWM_TIMER_1,
  641. MCPWM_SELECT_F1, MCPWM_HIGH_LEVEL_TGR, MCPWM_FAULT_1,
  642. action_a[i], action_b[j]);
  643. }
  644. }
  645. }
  646. TEST_CASE("MCPWM timer2 one shot fault test", "[mcpwm][test_env=UT_T1_MCPWM][timeout=60]")
  647. {
  648. // API just supports the high level trigger now, so comment it
  649. // mcpwm_fault_input_level_t fault_input[2] = {MCPWM_LOW_LEVEL_TGR, MCPWM_HIGH_LEVEL_TGR};
  650. mcpwm_action_on_pwmxa_t action_a[4] = {MCPWM_NO_CHANGE_IN_MCPWMXA, MCPWM_FORCE_MCPWMXA_LOW, MCPWM_FORCE_MCPWMXA_HIGH, MCPWM_TOG_MCPWMXA};
  651. mcpwm_action_on_pwmxb_t action_b[4] = {MCPWM_NO_CHANGE_IN_MCPWMXB, MCPWM_FORCE_MCPWMXB_LOW, MCPWM_FORCE_MCPWMXB_HIGH, MCPWM_TOG_MCPWMXB};
  652. for(int i=0; i<4; i++){
  653. for(int j=0; j<4; j++) {
  654. oneshot_fault_test(MCPWM_UNIT_0, MCPWM2A, MCPWM2B, MCPWM_TIMER_2,
  655. MCPWM_SELECT_F2, MCPWM_HIGH_LEVEL_TGR, MCPWM_FAULT_2,
  656. action_a[i], action_b[j]);
  657. oneshot_fault_test(MCPWM_UNIT_1, MCPWM2A, MCPWM2B, MCPWM_TIMER_2,
  658. MCPWM_SELECT_F2, MCPWM_HIGH_LEVEL_TGR, MCPWM_FAULT_2,
  659. action_a[i], action_b[j]);
  660. }
  661. }
  662. }
  663. // need to view its phenomenon in logic analyzer
  664. // set it ignore
  665. TEST_CASE("MCPWM timer0 sync test(logic analyzer)", "[mcpwm][ignore]")
  666. {
  667. sync_test(MCPWM_UNIT_0, MCPWM0A, MCPWM0B, MCPWM_TIMER_0, MCPWM_SELECT_SYNC0, MCPWM_SYNC_0);
  668. TEST_ESP_OK(mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_0)); // make sure can view the next sync signal clearly
  669. vTaskDelay(1000 / portTICK_RATE_MS);
  670. TEST_ESP_OK(mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_0));
  671. sync_test(MCPWM_UNIT_1, MCPWM0A, MCPWM0B, MCPWM_TIMER_0, MCPWM_SELECT_SYNC0, MCPWM_SYNC_0);
  672. }
  673. // need to view its phenomenon in logic analyzer
  674. // set it ignore
  675. TEST_CASE("MCPWM timer1 sync test(logic analyzer)", "[mcpwm][ignore]")
  676. {
  677. sync_test(MCPWM_UNIT_0, MCPWM1A, MCPWM1B, MCPWM_TIMER_1, MCPWM_SELECT_SYNC1, MCPWM_SYNC_1);
  678. TEST_ESP_OK(mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_1)); // make sure can view the next sync signal clearly
  679. vTaskDelay(1000 / portTICK_RATE_MS);
  680. TEST_ESP_OK(mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_1));
  681. sync_test(MCPWM_UNIT_1, MCPWM1A, MCPWM1B, MCPWM_TIMER_1, MCPWM_SELECT_SYNC1, MCPWM_SYNC_1);
  682. }
  683. // need to view its phenomenon in logic analyzer
  684. // set it ignore
  685. TEST_CASE("MCPWM timer2 sync test(logic analyzer)", "[mcpwm][ignore]")
  686. {
  687. sync_test(MCPWM_UNIT_0, MCPWM2A, MCPWM2B, MCPWM_TIMER_2, MCPWM_SELECT_SYNC2, MCPWM_SYNC_2);
  688. TEST_ESP_OK(mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_2)); // make sure can view the next sync signal clearly
  689. vTaskDelay(1000 / portTICK_RATE_MS);
  690. TEST_ESP_OK(mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_2));
  691. sync_test(MCPWM_UNIT_1, MCPWM2A, MCPWM2B, MCPWM_TIMER_2, MCPWM_SELECT_SYNC2, MCPWM_SYNC_2);
  692. }
  693. TEST_CASE("MCPWM unit0, timer0 capture test", "[mcpwm][test_env=UT_T1_MCPWM][timeout=60]")
  694. {
  695. capture_test(MCPWM_UNIT_0, MCPWM0A, MCPWM0B, MCPWM_CAP_0, MCPWM_TIMER_0, MCPWM_SELECT_CAP0, MCPWM_POS_EDGE);
  696. }
  697. TEST_CASE("MCPWM uni0, timer1 capture test", "[mcpwm][test_env=UT_T1_MCPWM][timeout=60]")
  698. {
  699. capture_test(MCPWM_UNIT_0, MCPWM1A, MCPWM1B, MCPWM_CAP_1, MCPWM_TIMER_1, MCPWM_SELECT_CAP1, MCPWM_POS_EDGE);
  700. }
  701. TEST_CASE("MCPWM unit0, timer2 capture test", "[mcpwm][test_env=UT_T1_MCPWM][timeout=60]")
  702. {
  703. capture_test(MCPWM_UNIT_0, MCPWM2A, MCPWM2B, MCPWM_CAP_2, MCPWM_TIMER_2, MCPWM_SELECT_CAP2, MCPWM_POS_EDGE);
  704. }
  705. TEST_CASE("MCPWM unit1, timer0 capture test", "[mcpwm][test_env=UT_T1_MCPWM][timeout=60]")
  706. {
  707. capture_test(MCPWM_UNIT_1, MCPWM0A, MCPWM0B, MCPWM_CAP_0, MCPWM_TIMER_0, MCPWM_SELECT_CAP0, MCPWM_NEG_EDGE);
  708. }
  709. TEST_CASE("MCPWM unit1, timer1 capture test", "[mcpwm][test_env=UT_T1_MCPWM][timeout=60]")
  710. {
  711. capture_test(MCPWM_UNIT_1, MCPWM1A, MCPWM1B, MCPWM_CAP_1, MCPWM_TIMER_1, MCPWM_SELECT_CAP1, MCPWM_POS_EDGE);
  712. }
  713. TEST_CASE("MCPWM unit1, timer2 capture test", "[mcpwm][test_env=UT_T1_MCPWM][timeout=60]")
  714. {
  715. capture_test(MCPWM_UNIT_1, MCPWM2A, MCPWM2B, MCPWM_CAP_2, MCPWM_TIMER_2, MCPWM_SELECT_CAP2, MCPWM_POS_EDGE);
  716. }