1
6
7
13
14
15
16
22
23
24
25
26
27
28
29
30
31
35
36
37
38
39
45
46
47
48
53
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
77
78
79
80
85
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
114
115
116
117
122
123
124
127
128
129
130
131
132
133
134
135
136
137
144
147
148
149
150
153
156
157
158
161
162
163
164
167
172
173
174
175
176
177
181
182
183
184
185
186
187
188
189
190
191
192
193
198
199
200
201
202
205
206
207
208
209
210
214
215
/* ... */
#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
#define EXAMPLE_TIMER_PERIOD 1000
#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_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_num = EXAMPLE_SYNC_GPIO,
.flags.pull_down = true,
.flags.active_neg = false,
}{...};
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
#if CONFIG_EXAMPLE_SYNC_FROM_TEZ
static void example_setup_sync_strategy(mcpwm_timer_handle_t timers[])
{
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,
}{...};
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
#if CONFIG_EXAMPLE_SYNC_FROM_SOFT
static void example_setup_sync_strategy(mcpwm_timer_handle_t timers[])
{
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
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,
}{...};
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]));
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],
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],
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));
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) {
ESP_ERROR_CHECK(mcpwm_generator_set_force_level(generators[i], -1, true));
}{...}
vTaskDelay(pdMS_TO_TICKS(100));
}{ ... }