Skip to content

Commit a368f67

Browse files
committed
Update esp32_mcpwm.c
1 parent 6911993 commit a368f67

File tree

1 file changed

+158
-15
lines changed

1 file changed

+158
-15
lines changed

ports/esp32/esp32_mcpwm.c

Lines changed: 158 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,52 @@
44
#include "py/binary.h"
55

66
#include <stdio.h>
7-
#include "driver/mcpwm.h"
7+
//#include "driver/mcpwm.h"
8+
#include "driver/mcpwm_prelude.h"
89
#include "mphalport.h"
910
#include "esp_err.h"
11+
#include "esp_check.h"
12+
13+
#if SOC_MCPWM_SUPPORTED | 1
14+
15+
// static const char *TAG = "ESP32_mcpwm";
16+
17+
#define MCPWM_TIMER_MAX SOC_MCPWM_TIMERS_PER_GROUP
18+
#define MCPWM_UNIT_MAX SOC_MCPWM_GROUPS
1019

1120
#define MCPWM_CHANNEL_MAX (MCPWM_TIMER_MAX * MCPWM_UNIT_MAX)
1221

1322
typedef struct _mcpwm_obj_t {
1423
mp_obj_base_t base;
1524
uint8_t id;
1625
gpio_num_t pin_a;
17-
gpio_num_t pin_b;
26+
gpio_num_t pin_a_; // complementary PWM pin
1827

1928
// Derived values for easier IDF API calls.
20-
mcpwm_unit_t unit;
21-
mcpwm_timer_t timer;
29+
//mcpwm_unit_t unit;
30+
int8_t unit; // is group_id
31+
//int8_t group_id;
32+
33+
//mcpwm_timer_t timer;
34+
int8_t timer;
35+
36+
uint32_t pwm_freq_hz;
37+
/*
38+
.pwm_freq_hz = BDC_MCPWM_FREQ_HZ,
39+
.pwma_gpio_num = BDC_MCPWM_GPIO_A,
40+
.pwmb_gpio_num = BDC_MCPWM_GPIO_B,
41+
*/
42+
43+
mcpwm_timer_handle_t timer_;
44+
mcpwm_oper_handle_t oper;
45+
mcpwm_cmpr_handle_t cmpa;
46+
mcpwm_cmpr_handle_t cmpb;
47+
mcpwm_gen_handle_t gena;
48+
mcpwm_gen_handle_t genb;
49+
/*
2250
mcpwm_io_signals_t sig_a;
2351
mcpwm_io_signals_t sig_b;
52+
*/
2453
} mcpwm_obj_t;
2554

2655
// Forward dec'l
@@ -29,6 +58,75 @@ STATIC mp_obj_t _mcpwm_deinit(mp_obj_t self_in);
2958
STATIC mp_obj_t _mcpwm_duty(size_t n_args, const mp_obj_t *args);
3059
STATIC mp_obj_t _mcpwm_freq(size_t n_args, const mp_obj_t *args);
3160

61+
esp_err_t mcpwm_set_frequency(int8_t mcpwm_num, int8_t timer_num, uint32_t frequency) {
62+
63+
return ESP_OK;
64+
}
65+
66+
esp_err_t mcpwm_set_duty(int8_t mcpwm_num, int8_t timer_num, mcpwm_gen_handle_t gen, float duty) {
67+
68+
return ESP_OK;
69+
}
70+
71+
uint32_t mcpwm_get_frequency(int8_t mcpwm_num, int8_t timer_num) {
72+
return 0;
73+
}
74+
75+
float mcpwm_get_duty(int8_t mcpwm_num, int8_t timer_num, mcpwm_gen_handle_t gen) {
76+
return 0;
77+
}
78+
79+
/*
80+
// Dual Edge Symmetric Waveform - Complementary
81+
static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb)
82+
{
83+
check_esp_err(mcpwm_generator_set_actions_on_compare_event(gena,
84+
MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_HIGH),
85+
MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_DOWN, cmpa, MCPWM_GEN_ACTION_LOW),
86+
MCPWM_GEN_COMPARE_EVENT_ACTION_END()));
87+
check_esp_err(mcpwm_generator_set_actions_on_compare_event(genb,
88+
MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpb, MCPWM_GEN_ACTION_LOW),
89+
MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_DOWN, cmpb, MCPWM_GEN_ACTION_HIGH),
90+
MCPWM_GEN_COMPARE_EVENT_ACTION_END()));
91+
}
92+
*/
93+
static void gen_action_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb)
94+
{
95+
check_esp_err(mcpwm_generator_set_action_on_timer_event(gena,
96+
MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH)));
97+
check_esp_err(mcpwm_generator_set_action_on_compare_event(gena,
98+
MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, cmpa, MCPWM_GEN_ACTION_LOW)));
99+
}
100+
101+
// Active High Complementary
102+
static void dead_time_config(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb)
103+
{
104+
mcpwm_dead_time_config_t dead_time_config = {
105+
.posedge_delay_ticks = 50,
106+
.negedge_delay_ticks = 0
107+
};
108+
check_esp_err(mcpwm_generator_set_dead_time(gena, gena, &dead_time_config));
109+
dead_time_config.posedge_delay_ticks = 0;
110+
dead_time_config.negedge_delay_ticks = 150;
111+
dead_time_config.flags.invert_output = true;
112+
check_esp_err(mcpwm_generator_set_dead_time(gena, genb, &dead_time_config));
113+
}
114+
/*
115+
// Active Low, Complementary
116+
static void dead_time_config_low(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb)
117+
{
118+
mcpwm_dead_time_config_t dead_time_config = {
119+
.posedge_delay_ticks = 50,
120+
.negedge_delay_ticks = 0,
121+
.flags.invert_output = true
122+
};
123+
check_esp_err(mcpwm_generator_set_dead_time(gena, gena, &dead_time_config));
124+
dead_time_config.posedge_delay_ticks = 0;
125+
dead_time_config.negedge_delay_ticks = 150;
126+
dead_time_config.flags.invert_output = false;
127+
check_esp_err(mcpwm_generator_set_dead_time(gena, genb, &dead_time_config));
128+
}
129+
*/
32130
STATIC mp_obj_t mcpwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
33131
mp_arg_check_num(n_args, n_kw, 1, 3, true);
34132

@@ -44,9 +142,11 @@ STATIC mp_obj_t mcpwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t
44142

45143
self->timer = self->id % MCPWM_TIMER_MAX;
46144
self->unit = self->id / MCPWM_TIMER_MAX;
145+
/*
47146
self->sig_a = self->timer * 2; // even numbers -> A operators
48147
self->sig_b = self->timer * 2 + 1; // odd numbers -> B operators
49-
148+
*/
149+
/*
50150
mcpwm_config_t config = {
51151
.frequency = 1000, // frequency = 1kHz
52152
.cmpr_a = 50, // duty A = 50%
@@ -57,15 +157,39 @@ STATIC mp_obj_t mcpwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t
57157
58158
mcpwm_init(self->unit, self->timer, &config);
59159
mp_obj_t self_out = MP_OBJ_FROM_PTR(self);
160+
*/
161+
162+
163+
// mcpwm timer
164+
mcpwm_timer_config_t timer_config = {
165+
.group_id = mcpwm_config->group_id,
166+
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
167+
.resolution_hz = mcpwm_config->resolution_hz,
168+
.period_ticks = mcpwm_config->resolution_hz / motor_config->pwm_freq_hz,
169+
.count_mode = MCPWM_TIMER_COUNT_MODE_UP,
170+
};
171+
ESP_GOTO_ON_ERROR(mcpwm_new_timer(&timer_config, &mcpwm_motor->timer), err, TAG, "create MCPWM timer failed");
172+
173+
mcpwm_operator_config_t operator_config = {
174+
.group_id = mcpwm_config->group_id,
175+
};
176+
ESP_GOTO_ON_ERROR(mcpwm_new_operator(&operator_config, &mcpwm_motor->operator), err, TAG, "create MCPWM operator failed");
177+
178+
ESP_GOTO_ON_ERROR(mcpwm_operator_connect_timer(mcpwm_motor->operator, mcpwm_motor->timer), err, TAG, "connect timer and operator failed");
179+
60180

61-
return self_out;
181+
182+
return MP_OBJ_FROM_PTR(self);
62183
}
63184

64185

65186
STATIC void mcpwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
66187
mcpwm_obj_t *self = MP_OBJ_TO_PTR(self_in);
67-
mp_printf(print, "MCPWM(ID=%u. ", self->id);
188+
mp_printf(print, "MCPWM(ID=%u, ", self->id);
68189
mp_printf(print, "pin=%u, ", self->pin_a);
190+
if (self->pin_a_ >= 0) {
191+
mp_printf(print, "complementary_pin=%u, ", self->pin_a_);
192+
}
69193
float duty = mcpwm_get_duty(self->unit, self->timer, MCPWM_OPR_A);
70194
int freq = mcpwm_get_frequency(self->unit, self->timer);
71195
mp_printf(print, "freq=%uHz, duty=%.1f%%", freq, duty);
@@ -74,25 +198,42 @@ STATIC void mcpwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind
74198

75199

76200
// BIND
77-
STATIC mp_obj_t _mcpwm_bind(mp_obj_t self_in, mp_obj_t pin) {
78-
mcpwm_obj_t *self = MP_OBJ_TO_PTR(self_in);
79-
gpio_num_t pin_id = machine_pin_get_id(pin);
80-
mcpwm_gpio_init(self->unit, self->sig_a, pin_id);
201+
//STATIC mp_obj_t _mcpwm_bind(mp_obj_t self_in, mp_obj_t pin) {
202+
STATIC mp_obj_t _mcpwm_bind(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
203+
enum { ARG_complementary_pin };
204+
static const mp_arg_t allowed_args[] = {
205+
{ MP_QSTR_pin_complementary, MP_ARG_INT, {.u_int = -1} },
206+
};
207+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
208+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
209+
MP_ARRAY_SIZE(allowed_args), allowed_args, args);
210+
211+
mcpwm_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
212+
gpio_num_t pin_id = machine_pin_get_id(pos_args[1]);
213+
self->pin_a = pin_id;
214+
self->pin_a_ = args[ARG_complementary_pin].u_int;
215+
216+
// mcpwm_gpio_init(self->unit, self->sig_a, pin_id);
217+
218+
dead_time_config(self->gena, self->genb);
219+
gen_action_config(self->gena, self->genb, self->cmpa, self->cmpb);
81220
return mp_const_none;
82221
}
83-
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mcpwm_bind_obj, _mcpwm_bind);
84-
222+
//STATIC MP_DEFINE_CONST_FUN_OBJ_2(mcpwm_bind_obj, _mcpwm_bind);
223+
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mcpwm_bind_obj, 1, _mcpwm_bind);
85224

86225
// DEINIT
87226
STATIC mp_obj_t _mcpwm_deinit(mp_obj_t self_in) {
88227
mcpwm_obj_t *self = MP_OBJ_TO_PTR(self_in);
89-
mcpwm_stop(self->unit, self->timer);
228+
// mcpwm_stop(self->unit, self->timer);
229+
mcpwm_timer_start_stop(self->timer_, MCPWM_TIMER_STOP_EMPTY);
90230
// mcpwm_set_signal_low(self->unit, self->timer, MCPWM_OPR_A);
231+
check_esp_err(mcpwm_generator_set_force_level(self->gena, 0, true));//, TAG, "set force level for gena failed");
232+
check_esp_err(mcpwm_generator_set_force_level(self->genb, 0, true));//, TAG, "set force level for genb failed");
91233
return mp_const_none;
92234
}
93235
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mcpwm_deinit_obj, _mcpwm_deinit);
94236

95-
96237
// FREQ
97238
STATIC mp_obj_t _mcpwm_freq(size_t n_args, const mp_obj_t *args) {
98239
mcpwm_obj_t *self = MP_OBJ_TO_PTR(args[0]);
@@ -145,3 +286,5 @@ MP_DEFINE_CONST_OBJ_TYPE(
145286
make_new, mcpwm_make_new,
146287
locals_dict, &mcpwm_locals_dict
147288
);
289+
290+
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy