4
4
#include "py/binary.h"
5
5
6
6
#include <stdio.h>
7
- #include "driver/mcpwm.h"
7
+ //#include "driver/mcpwm.h"
8
+ #include "driver/mcpwm_prelude.h"
8
9
#include "mphalport.h"
9
10
#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
10
19
11
20
#define MCPWM_CHANNEL_MAX (MCPWM_TIMER_MAX * MCPWM_UNIT_MAX)
12
21
13
22
typedef struct _mcpwm_obj_t {
14
23
mp_obj_base_t base ;
15
24
uint8_t id ;
16
25
gpio_num_t pin_a ;
17
- gpio_num_t pin_b ;
26
+ gpio_num_t pin_a_ ; // complementary PWM pin
18
27
19
28
// 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
+ /*
22
50
mcpwm_io_signals_t sig_a;
23
51
mcpwm_io_signals_t sig_b;
52
+ */
24
53
} mcpwm_obj_t ;
25
54
26
55
// Forward dec'l
@@ -29,6 +58,75 @@ STATIC mp_obj_t _mcpwm_deinit(mp_obj_t self_in);
29
58
STATIC mp_obj_t _mcpwm_duty (size_t n_args , const mp_obj_t * args );
30
59
STATIC mp_obj_t _mcpwm_freq (size_t n_args , const mp_obj_t * args );
31
60
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
+ */
32
130
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 ) {
33
131
mp_arg_check_num (n_args , n_kw , 1 , 3 , true);
34
132
@@ -44,9 +142,11 @@ STATIC mp_obj_t mcpwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t
44
142
45
143
self -> timer = self -> id % MCPWM_TIMER_MAX ;
46
144
self -> unit = self -> id / MCPWM_TIMER_MAX ;
145
+ /*
47
146
self->sig_a = self->timer * 2; // even numbers -> A operators
48
147
self->sig_b = self->timer * 2 + 1; // odd numbers -> B operators
49
-
148
+ */
149
+ /*
50
150
mcpwm_config_t config = {
51
151
.frequency = 1000, // frequency = 1kHz
52
152
.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
57
157
58
158
mcpwm_init(self->unit, self->timer, &config);
59
159
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
+
60
180
61
- return self_out ;
181
+
182
+ return MP_OBJ_FROM_PTR (self );
62
183
}
63
184
64
185
65
186
STATIC void mcpwm_print (const mp_print_t * print , mp_obj_t self_in , mp_print_kind_t kind ) {
66
187
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 );
68
189
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
+ }
69
193
float duty = mcpwm_get_duty (self -> unit , self -> timer , MCPWM_OPR_A );
70
194
int freq = mcpwm_get_frequency (self -> unit , self -> timer );
71
195
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
74
198
75
199
76
200
// 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 );
81
220
return mp_const_none ;
82
221
}
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 );
85
224
86
225
// DEINIT
87
226
STATIC mp_obj_t _mcpwm_deinit (mp_obj_t self_in ) {
88
227
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 );
90
230
// 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");
91
233
return mp_const_none ;
92
234
}
93
235
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (mcpwm_deinit_obj , _mcpwm_deinit );
94
236
95
-
96
237
// FREQ
97
238
STATIC mp_obj_t _mcpwm_freq (size_t n_args , const mp_obj_t * args ) {
98
239
mcpwm_obj_t * self = MP_OBJ_TO_PTR (args [0 ]);
@@ -145,3 +286,5 @@ MP_DEFINE_CONST_OBJ_TYPE(
145
286
make_new , mcpwm_make_new ,
146
287
locals_dict , & mcpwm_locals_dict
147
288
);
289
+
290
+ #endif
0 commit comments