Select one of the symbols to view example projects that use it.
 
Outline
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/mcpwm_prelude.h"
#include "driver/gpio.h"
TAG
#define EXAMPLE_TIMER_RESOLUTION_HZ
#define EXAMPLE_TIMER_PERIOD
#define EXAMPLE_GEN_GPIO0
#define EXAMPLE_GEN_GPIO1
#define EXAMPLE_GEN_GPIO2
#define EXAMPLE_SYNC_GPIO
example_setup_sync_strategy(mcpwm_timer_handle_t *)
app_main()
Files
loading...
SourceVuESP-IDF Framework and Examplesmcpwm_sync samplemain/mcpwm_sync_example_main.c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 *//* ... */ #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "driver/mcpwm_prelude.h" #include "driver/gpio.h"6 includes const static char *TAG = "example"; #define EXAMPLE_TIMER_RESOLUTION_HZ 1000000 // 1MHz, 1us per tick #define EXAMPLE_TIMER_PERIOD 1000 // 1000 ticks, 1ms #define EXAMPLE_GEN_GPIO0 0 #define EXAMPLE_GEN_GPIO1 2 #define EXAMPLE_GEN_GPIO2 4 #define EXAMPLE_SYNC_GPIO 56 defines #if CONFIG_EXAMPLE_SYNC_FROM_GPIO static void example_setup_sync_strategy(mcpwm_timer_handle_t timers[]) { // +----GPIO----+ // | | | // | | | // v v v // timer0 timer1 timer2 gpio_config_t sync_gpio_conf = { .mode = GPIO_MODE_OUTPUT, .pin_bit_mask = BIT(EXAMPLE_SYNC_GPIO), }{...}; ESP_ERROR_CHECK(gpio_config(&sync_gpio_conf)); ESP_LOGI(TAG, "Create GPIO sync source"); mcpwm_sync_handle_t gpio_sync_source = NULL; mcpwm_gpio_sync_src_config_t gpio_sync_config = { .group_id = 0, // GPIO fault should be in the same group of the above timers .gpio_num = EXAMPLE_SYNC_GPIO, .flags.pull_down = true, .flags.active_neg = false, // by default, a posedge pulse can trigger a sync event }{...}; ESP_ERROR_CHECK(mcpwm_new_gpio_sync_src(&gpio_sync_config, &gpio_sync_source)); ESP_LOGI(TAG, "Set timers to sync on the GPIO"); mcpwm_timer_sync_phase_config_t sync_phase_config = { .count_value = 0, .direction = MCPWM_TIMER_DIRECTION_UP, .sync_src = gpio_sync_source, }{...}; for (int i = 0; i < 3; i++) { ESP_ERROR_CHECK(mcpwm_timer_set_phase_on_sync(timers[i], &sync_phase_config)); }{...} ESP_LOGI(TAG, "Trigger a pulse on the GPIO as a sync event"); ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_SYNC_GPIO, 0)); ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_SYNC_GPIO, 1)); ESP_ERROR_CHECK(gpio_reset_pin(EXAMPLE_SYNC_GPIO)); }{ ... } /* ... */#endif // CONFIG_EXAMPLE_SYNC_FROM_GPIO #if CONFIG_EXAMPLE_SYNC_FROM_TEZ static void example_setup_sync_strategy(mcpwm_timer_handle_t timers[]) { // +->timer1 // (TEZ) | // timer0---+ // | // +->timer2 ESP_LOGI(TAG, "Create TEZ sync source from timer0"); mcpwm_sync_handle_t timer_sync_source = NULL; mcpwm_timer_sync_src_config_t timer_sync_config = { .timer_event = MCPWM_TIMER_EVENT_EMPTY, // generate sync event on timer empty }{...}; ESP_ERROR_CHECK(mcpwm_new_timer_sync_src(timers[0], &timer_sync_config, &timer_sync_source)); ESP_LOGI(TAG, "Set other timers sync to the first timer"); mcpwm_timer_sync_phase_config_t sync_phase_config = { .count_value = 0, .direction = MCPWM_TIMER_DIRECTION_UP, .sync_src = timer_sync_source, }{...}; for (int i = 1; i < 3; i++) { ESP_ERROR_CHECK(mcpwm_timer_set_phase_on_sync(timers[i], &sync_phase_config)); }{...} ESP_LOGI(TAG, "Wait some time for the timer TEZ event"); vTaskDelay(pdMS_TO_TICKS(10)); }{...} /* ... */#endif // CONFIG_EXAMPLE_SYNC_FROM_TEZ #if CONFIG_EXAMPLE_SYNC_FROM_SOFT static void example_setup_sync_strategy(mcpwm_timer_handle_t timers[]) { // soft // | // v // +-timer0--+ // | | // v v // timer1 timer2 ESP_LOGI(TAG, "Create software sync source"); mcpwm_sync_handle_t soft_sync_source = NULL; mcpwm_soft_sync_config_t soft_sync_config = {}; ESP_ERROR_CHECK(mcpwm_new_soft_sync_src(&soft_sync_config, &soft_sync_source)); ESP_LOGI(TAG, "Create timer sync source to propagate the sync event"); mcpwm_sync_handle_t timer_sync_source; mcpwm_timer_sync_src_config_t timer_sync_config = { .flags.propagate_input_sync = true, }{...}; ESP_ERROR_CHECK(mcpwm_new_timer_sync_src(timers[0], &timer_sync_config, &timer_sync_source)); ESP_LOGI(TAG, "Set sync phase for timers"); mcpwm_timer_sync_phase_config_t sync_phase_config = { .count_value = 0, .direction = MCPWM_TIMER_DIRECTION_UP, .sync_src = soft_sync_source, }{...}; ESP_ERROR_CHECK(mcpwm_timer_set_phase_on_sync(timers[0], &sync_phase_config)); sync_phase_config.sync_src = timer_sync_source; for (int i = 1; i < 3; ++i) { ESP_ERROR_CHECK(mcpwm_timer_set_phase_on_sync(timers[i], &sync_phase_config)); }{...} ESP_LOGI(TAG, "Trigger the software sync event"); ESP_ERROR_CHECK(mcpwm_soft_sync_activate(soft_sync_source)); }{...} /* ... */#endif // CONFIG_EXAMPLE_SYNC_FROM_SOFT void app_main(void) { ESP_LOGI(TAG, "Create timers"); mcpwm_timer_handle_t timers[3]; mcpwm_timer_config_t timer_config = { .clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT, .group_id = 0, .resolution_hz = EXAMPLE_TIMER_RESOLUTION_HZ, .period_ticks = EXAMPLE_TIMER_PERIOD, .count_mode = MCPWM_TIMER_COUNT_MODE_UP, }{...}; for (int i = 0; i < 3; i++) { ESP_ERROR_CHECK(mcpwm_new_timer(&timer_config, &timers[i])); }{...} ESP_LOGI(TAG, "Create operators"); mcpwm_oper_handle_t operators[3]; mcpwm_operator_config_t operator_config = { .group_id = 0, // operator should be in the same group of the above timers }{...}; for (int i = 0; i < 3; ++i) { ESP_ERROR_CHECK(mcpwm_new_operator(&operator_config, &operators[i])); }{...} ESP_LOGI(TAG, "Connect timers and operators with each other"); for (int i = 0; i < 3; i++) { ESP_ERROR_CHECK(mcpwm_operator_connect_timer(operators[i], timers[i])); }{...} ESP_LOGI(TAG, "Create comparators"); mcpwm_cmpr_handle_t comparators[3]; mcpwm_comparator_config_t compare_config = { .flags.update_cmp_on_tez = true, }{...}; for (int i = 0; i < 3; i++) { ESP_ERROR_CHECK(mcpwm_new_comparator(operators[i], &compare_config, &comparators[i])); // init compare for each comparator ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(comparators[i], 200)); }{...} ESP_LOGI(TAG, "Create generators"); mcpwm_gen_handle_t generators[3]; const int gen_gpios[3] = {EXAMPLE_GEN_GPIO0, EXAMPLE_GEN_GPIO1, EXAMPLE_GEN_GPIO2}; mcpwm_generator_config_t gen_config = {}; for (int i = 0; i < 3; i++) { gen_config.gen_gpio_num = gen_gpios[i]; ESP_ERROR_CHECK(mcpwm_new_generator(operators[i], &gen_config, &generators[i])); }{...} ESP_LOGI(TAG, "Set generator actions on timer and compare event"); for (int i = 0; i < 3; i++) { ESP_ERROR_CHECK(mcpwm_generator_set_action_on_timer_event(generators[i], // when the timer value is zero, and is counting up, set output to high MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH))); ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(generators[i], // when compare event happens, and timer is counting up, set output to low MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, comparators[i], MCPWM_GEN_ACTION_LOW))); }{...} ESP_LOGI(TAG, "Start timers one by one, so they are not synced"); for (int i = 0; i < 3; i++) { ESP_ERROR_CHECK(mcpwm_timer_enable(timers[i])); ESP_ERROR_CHECK(mcpwm_timer_start_stop(timers[i], MCPWM_TIMER_START_NO_STOP)); vTaskDelay(pdMS_TO_TICKS(10)); }{...} vTaskDelay(pdMS_TO_TICKS(100)); // Manually added this "IDLE" phase, which can help us distinguish the wave forms before and after sync ESP_LOGI(TAG, "Force the output level to low, timer still running"); for (int i = 0; i < 3; i++) { ESP_ERROR_CHECK(mcpwm_generator_set_force_level(generators[i], 0, true)); }{...} ESP_LOGI(TAG, "Setup sync strategy"); example_setup_sync_strategy(timers); ESP_LOGI(TAG, "Now the output PWMs should in sync"); for (int i = 0; i < 3; ++i) { // remove the force level on the generator, so that we can see the PWM again ESP_ERROR_CHECK(mcpwm_generator_set_force_level(generators[i], -1, true)); }{...} vTaskDelay(pdMS_TO_TICKS(100)); }{ ... }
Details
Show:
from
Types: Columns:
This file uses the notable symbols shown below. Click anywhere in the file to view more details.