10
10
#define _EMPTY_SLOT -20
11
11
#define _TAKEN_SLOT -21
12
12
13
+ // ABI bus frequency - would be better to take it from somewhere
14
+ // but I did nto find a good exposed variable
15
+ #define _MCPWM_FREQ 160e6
16
+
17
+ // preferred pwm resolution default
18
+ #define _PWM_RES_DEF 2048
19
+ // min resolution
20
+ #define _PWM_RES_MIN 1500
21
+ // max resolution
22
+ #define _PWM_RES_MAX 3000
23
+
13
24
// structure containing motor slot configuration
14
25
// this library supports up to 4 motors
15
26
typedef struct {
@@ -73,23 +84,61 @@ bldc_6pwm_motor_slots_t esp32_bldc_6pwm_motor_slots[2] = {
73
84
void _configureTimerFrequency (long pwm_frequency, mcpwm_dev_t * mcpwm_num, mcpwm_unit_t mcpwm_unit, float dead_zone = NOT_SET){
74
85
75
86
mcpwm_config_t pwm_config;
76
- pwm_config.frequency = pwm_frequency; // frequency
77
87
pwm_config.counter_mode = MCPWM_UP_DOWN_COUNTER; // Up-down counter (triangle wave)
78
88
pwm_config.duty_mode = MCPWM_DUTY_MODE_0; // Active HIGH
79
89
mcpwm_init (mcpwm_unit, MCPWM_TIMER_0, &pwm_config); // Configure PWM0A & PWM0B with above settings
80
90
mcpwm_init (mcpwm_unit, MCPWM_TIMER_1, &pwm_config); // Configure PWM0A & PWM0B with above settings
81
91
mcpwm_init (mcpwm_unit, MCPWM_TIMER_2, &pwm_config); // Configure PWM0A & PWM0B with above settings
82
-
92
+
83
93
if (dead_zone != NOT_SET){
84
- // dead zone is configured in dead_time x 100 nanoseconds
85
- float dead_time = (float )(1e7 / pwm_frequency) * dead_zone;
86
- mcpwm_deadtime_enable (mcpwm_unit, MCPWM_TIMER_0, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, dead_time, dead_time);
87
- mcpwm_deadtime_enable (mcpwm_unit, MCPWM_TIMER_1, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, dead_time, dead_time);
88
- mcpwm_deadtime_enable (mcpwm_unit, MCPWM_TIMER_2, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, dead_time, dead_time);
94
+ // dead zone is configured
95
+ float dead_time = (float )(_MCPWM_FREQ / ( pwm_frequency) ) * dead_zone;
96
+ mcpwm_deadtime_enable (mcpwm_unit, MCPWM_TIMER_0, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, dead_time/ 2 , dead_time/ 2 );
97
+ mcpwm_deadtime_enable (mcpwm_unit, MCPWM_TIMER_1, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, dead_time/ 2 , dead_time/ 2 );
98
+ mcpwm_deadtime_enable (mcpwm_unit, MCPWM_TIMER_2, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, dead_time/ 2 , dead_time/ 2 );
89
99
}
90
-
91
100
_delay (100 );
92
101
102
+ mcpwm_stop (mcpwm_unit, MCPWM_TIMER_0);
103
+ mcpwm_stop (mcpwm_unit, MCPWM_TIMER_1);
104
+ mcpwm_stop (mcpwm_unit, MCPWM_TIMER_2);
105
+
106
+ // manual configuration due to the lack of config flexibility in mcpwm_init()
107
+ mcpwm_num->clk_cfg .prescale = 0 ;
108
+ // calculate prescaler and period
109
+ // step 1: calculate the prescaler using the default pwm resolution
110
+ // prescaler = bus_freq / (pwm_freq * default_pwm_res) - 1
111
+ int prescaler = ceil (_MCPWM_FREQ / _PWM_RES_DEF / 2.0 / pwm_frequency) - 1 ;
112
+ // constrain prescaler
113
+ prescaler = _constrain (prescaler, 0 , 128 );
114
+ // now calculate the real resolution timer period necessary (pwm resolution)
115
+ // pwm_res = bus_freq / (pwm_freq * (prescaler + 1))
116
+ int resolution_corrected = _MCPWM_FREQ / 2.0 / pwm_frequency / (prescaler + 1 );
117
+ // if pwm resolution too low lower the prescaler
118
+ if (resolution_corrected < _PWM_RES_MIN && prescaler > 0 )
119
+ resolution_corrected = _MCPWM_FREQ / 2.0 / pwm_frequency / (--prescaler + 1 );
120
+ resolution_corrected = _constrain (resolution_corrected, _PWM_RES_MIN, _PWM_RES_MAX);
121
+
122
+ // set prescaler
123
+ mcpwm_num->timer [0 ].period .prescale = prescaler;
124
+ mcpwm_num->timer [1 ].period .prescale = prescaler;
125
+ mcpwm_num->timer [2 ].period .prescale = prescaler;
126
+ _delay (1 );
127
+ // set period
128
+ mcpwm_num->timer [0 ].period .period = resolution_corrected;
129
+ mcpwm_num->timer [1 ].period .period = resolution_corrected;
130
+ mcpwm_num->timer [2 ].period .period = resolution_corrected;
131
+ _delay (1 );
132
+ mcpwm_num->timer [0 ].period .upmethod = 0 ;
133
+ mcpwm_num->timer [1 ].period .upmethod = 0 ;
134
+ mcpwm_num->timer [2 ].period .upmethod = 0 ;
135
+ _delay (1 );
136
+ // restart the timers
137
+ mcpwm_start (mcpwm_unit, MCPWM_TIMER_0);
138
+ mcpwm_start (mcpwm_unit, MCPWM_TIMER_1);
139
+ mcpwm_start (mcpwm_unit, MCPWM_TIMER_2);
140
+ _delay (1 );
141
+
93
142
mcpwm_sync_enable (mcpwm_unit, MCPWM_TIMER_0, MCPWM_SELECT_SYNC_INT0, 0 );
94
143
mcpwm_sync_enable (mcpwm_unit, MCPWM_TIMER_1, MCPWM_SELECT_SYNC_INT0, 0 );
95
144
mcpwm_sync_enable (mcpwm_unit, MCPWM_TIMER_2, MCPWM_SELECT_SYNC_INT0, 0 );
@@ -106,8 +155,8 @@ void _configureTimerFrequency(long pwm_frequency, mcpwm_dev_t* mcpwm_num, mcpwm
106
155
// supports Arudino/ATmega328, STM32 and ESP32
107
156
void _configure3PWM (long pwm_frequency,const int pinA, const int pinB, const int pinC) {
108
157
109
- if (!pwm_frequency || pwm_frequency == NOT_SET) pwm_frequency = 40000 ; // default frequency 20khz - centered pwm has twice lower frequency
110
- else pwm_frequency = _constrain (2 * pwm_frequency, 0 , 100000 ); // constrain to 50kHz max - centered pwm has twice lower frequency
158
+ if (!pwm_frequency || pwm_frequency == NOT_SET) pwm_frequency = 20000 ; // default frequency 20khz - centered pwm has twice lower frequency
159
+ else pwm_frequency = _constrain (pwm_frequency, 0 , 40000 ); // constrain to 40kHz max - centered pwm has twice lower frequency
111
160
112
161
bldc_3pwm_motor_slots_t m_slot = {};
113
162
@@ -149,8 +198,8 @@ void _configure3PWM(long pwm_frequency,const int pinA, const int pinB, const int
149
198
// - hardware speciffic
150
199
void _configure4PWM (long pwm_frequency,const int pinA, const int pinB, const int pinC, const int pinD) {
151
200
152
- if (!pwm_frequency || pwm_frequency == NOT_SET) pwm_frequency = 40000 ; // default frequency 20khz - centered pwm has twice lower frequency
153
- else pwm_frequency = _constrain (2 * pwm_frequency, 0 , 100000 ); // constrain to 50kHz max - centered pwm has twice lower frequency
201
+ if (!pwm_frequency || pwm_frequency == NOT_SET) pwm_frequency = 20000 ; // default frequency 20khz - centered pwm has twice lower frequency
202
+ else pwm_frequency = _constrain (pwm_frequency, 0 , 40000 ); // constrain to 50kHz max - centered pwm has twice lower frequency
154
203
stepper_motor_slots_t m_slot = {};
155
204
// determine which motor are we connecting
156
205
// and set the appropriate configuration parameters
@@ -229,8 +278,8 @@ void _writeDutyCycle4PWM(float dc_1a, float dc_1b, float dc_2a, float dc_2b, in
229
278
// - hardware specific
230
279
int _configure6PWM (long pwm_frequency, float dead_zone, const int pinA_h, const int pinA_l, const int pinB_h, const int pinB_l, const int pinC_h, const int pinC_l){
231
280
232
- if (!pwm_frequency || pwm_frequency == NOT_SET) pwm_frequency = 40000 ; // default frequency 20khz - centered pwm has twice lower frequency
233
- else pwm_frequency = _constrain (2 * pwm_frequency, 0 , 60000 ); // constrain to 30kHz max - centered pwm has twice lower frequency
281
+ if (!pwm_frequency || pwm_frequency == NOT_SET) pwm_frequency = 20000 ; // default frequency 20khz - centered pwm has twice lower frequency
282
+ else pwm_frequency = _constrain (pwm_frequency, 0 , 40000 ); // constrain to 40kHz max - centered pwm has twice lower frequency
234
283
bldc_6pwm_motor_slots_t m_slot = {};
235
284
// determine which motor are we connecting
236
285
// and set the appropriate configuration parameters
0 commit comments