@@ -116,7 +116,7 @@ STATIC int set_freq(int newval, ledc_timer_config_t *timer) {
116
116
return 1 ;
117
117
}
118
118
119
- STATIC int found_timer (int freq ) {
119
+ STATIC int found_timer (int freq , bool same_freq_only ) {
120
120
int free_timer_found = -1 ;
121
121
int timer ;
122
122
// Find a free PWM Timer using the same freq
@@ -125,7 +125,7 @@ STATIC int found_timer(int freq) {
125
125
// A timer already use the same freq. Use it now.
126
126
return timer ;
127
127
}
128
- if ((free_timer_found == -1 ) && (timers [timer ].freq_hz == -1 )) {
128
+ if (! same_freq_only && (free_timer_found == -1 ) && (timers [timer ].freq_hz == -1 )) {
129
129
free_timer_found = timer ;
130
130
// Continue to check if a channel with the same freq is in used.
131
131
}
@@ -134,25 +134,18 @@ STATIC int found_timer(int freq) {
134
134
return free_timer_found ;
135
135
}
136
136
137
- // If the timer is no longer used, clean it
138
- STATIC void cleanup_timer (int prev_channel , int timer ) {
137
+ // return if the timer is in use in addition to curr_channel
138
+ STATIC bool is_timer_in_use (int curr_channel , int timer ) {
139
139
bool used = false;
140
140
int i ;
141
141
for (i = 0 ; i < LEDC_CHANNEL_MAX ; ++ i ) {
142
- if (i != prev_channel && chan_timer [i ] == timer ) {
142
+ if (i != curr_channel && chan_timer [i ] == timer ) {
143
143
used = true;
144
144
break ;
145
145
}
146
146
}
147
147
148
- // If timer is not used, clean it
149
- if (!used ) {
150
- ledc_timer_pause (PWMODE , timer );
151
-
152
- // Flag it unused
153
- timers [timer ].freq_hz = -1 ;
154
- chan_timer [prev_channel ] = -1 ;
155
- }
148
+ return used ;
156
149
}
157
150
158
151
/******************************************************************************/
@@ -204,13 +197,13 @@ STATIC void esp32_pwm_init_helper(esp32_pwm_obj_t *self,
204
197
int timer ;
205
198
int freq = args [ARG_freq ].u_int ;
206
199
207
- //Check if freq wasn't passed as an argument
200
+ // Check if freq wasn't passed as an argument
208
201
if (freq == -1 ) {
209
202
// Check if already set, otherwise use the defaut freq
210
203
freq = chan_timer [self -> channel ] != -1 ? timers [chan_timer [self -> channel ]].freq_hz : PWFREQ ;
211
204
}
212
205
213
- timer = found_timer (freq );
206
+ timer = found_timer (freq , false );
214
207
215
208
if (timer == -1 ) {
216
209
mp_raise_ValueError (MP_ERROR_TEXT ("out of PWM timers" ));
@@ -289,7 +282,12 @@ STATIC mp_obj_t esp32_pwm_deinit(mp_obj_t self_in) {
289
282
// Valid channel?
290
283
if ((chan >= 0 ) && (chan < LEDC_CHANNEL_MAX )) {
291
284
// Clean up timer if necessary
292
- cleanup_timer (chan , chan_timer [self -> channel ]);
285
+ if (!is_timer_in_use (chan , chan_timer [chan ])) {
286
+ ledc_timer_rst (PWMODE , chan_timer [chan ]);
287
+ // Flag it unused
288
+ timers [chan_timer [chan ]].freq_hz = -1 ;
289
+ chan_timer [chan ] = -1 ;
290
+ }
293
291
294
292
// Mark it unused, and tell the hardware to stop routing
295
293
chan_gpio [chan ] = -1 ;
@@ -311,24 +309,52 @@ STATIC mp_obj_t esp32_pwm_freq(size_t n_args, const mp_obj_t *args) {
311
309
312
310
// set
313
311
int tval = mp_obj_get_int (args [1 ]);
314
- cleanup_timer (self -> channel , chan_timer [self -> channel ]);
315
312
316
- // Check if a timer already use the new freq, or grab a new one
317
- int new_timer = found_timer (tval );
313
+ if (tval == timers [chan_timer [self -> channel ]].freq_hz ) {
314
+ return mp_const_none ;
315
+ }
316
+
317
+ int current_timer = chan_timer [self -> channel ];
318
+ int new_timer = -1 ;
319
+ bool current_in_use = is_timer_in_use (self -> channel , current_timer );
318
320
319
- if (new_timer == -1 ) {
320
- mp_raise_ValueError (MP_ERROR_TEXT ("out of PWM timers" ));
321
+ // Check if an already running with the same freq is running
322
+ new_timer = found_timer (tval , true);
323
+
324
+ // If no existing timer was found, and the current one is in use, then find a new one
325
+ if (new_timer == -1 && current_in_use ) {
326
+ // Have to found a new timer
327
+ new_timer = found_timer (tval , false);
328
+
329
+ if (new_timer == -1 ) {
330
+ mp_raise_ValueError (MP_ERROR_TEXT ("out of PWM timers" ));
331
+ }
321
332
}
322
333
323
- chan_timer [self -> channel ] = new_timer ;
334
+ if (new_timer != -1 && new_timer != current_timer ) {
335
+ // Bind the channel to the new timer
336
+ chan_timer [self -> channel ] = new_timer ;
337
+
338
+ if (ledc_bind_channel_timer (PWMODE , self -> channel , new_timer ) != ESP_OK ) {
339
+ mp_raise_msg_varg (& mp_type_ValueError , MP_ERROR_TEXT ("Failed to bind timer to channel" ));
340
+ }
341
+
342
+ if (!current_in_use ) {
343
+ // Free the old timer
344
+ ledc_timer_rst (PWMODE , current_timer );
324
345
325
- if (ledc_bind_channel_timer (PWMODE , self -> channel , new_timer ) != ESP_OK ) {
326
- mp_raise_msg_varg (& mp_type_ValueError , MP_ERROR_TEXT ("Failed to bind timer to channel" ));
346
+ // Flag it unused
347
+ timers [current_timer ].freq_hz = -1 ;
348
+ }
349
+
350
+ current_timer = new_timer ;
327
351
}
328
352
329
- if (!set_freq (tval , & timers [new_timer ])) {
353
+ // Set the freq
354
+ if (!set_freq (tval , & timers [current_timer ])) {
330
355
mp_raise_msg_varg (& mp_type_ValueError , MP_ERROR_TEXT ("bad frequency %d" ), tval );
331
356
}
357
+
332
358
return mp_const_none ;
333
359
}
334
360
0 commit comments