35
35
#include "stm32f4xx_hal.h"
36
36
#include "common-hal/microcontroller/Pin.h"
37
37
38
- #define PULSE_RESOLUTION 256 //8 bit
39
38
#define ALL_CLOCKS 0xFFFF
40
39
41
40
STATIC uint8_t reserved_tim [TIM_BANK_ARRAY_LEN ];
@@ -183,12 +182,21 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
183
182
}
184
183
185
184
uint32_t source_freq = timer_get_source_freq (self -> tim -> tim_index );
186
- if (frequency == 0 || frequency * PULSE_RESOLUTION > (source_freq )) {
185
+ uint32_t prescaler = 0 ;
186
+ uint32_t period = 0 ;
187
+
188
+ for (int i = 0 ; i < 32767 ;i ++ ) {
189
+ period = source_freq /(i * frequency );
190
+ if (period <= 65535 && period >=2 ) {
191
+ prescaler = i ;
192
+ break ;
193
+ }
194
+ }
195
+ if (prescaler == 0 ) {
187
196
mp_raise_ValueError (translate ("Invalid frequency supplied" ));
188
197
}
189
- uint32_t prescaler = source_freq /(frequency * PULSE_RESOLUTION );
190
- uint32_t period = PULSE_RESOLUTION ;
191
- uint32_t input = (duty * PULSE_RESOLUTION )/65535 ;
198
+ uint32_t input = (duty * period )/65535 ;
199
+
192
200
//Used for Debugging
193
201
// mp_printf(&mp_plat_print, "Duty:%d, Pulses:%d\n", duty,input);
194
202
// mp_printf(&mp_plat_print, "SysCoreClock: %d\n", SystemCoreClock);
@@ -231,6 +239,7 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
231
239
self -> variable_frequency = variable_frequency ;
232
240
self -> frequency = frequency ;
233
241
self -> duty_cycle = duty ;
242
+ self -> period = period ;
234
243
235
244
return PWMOUT_OK ;
236
245
}
@@ -261,7 +270,7 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
261
270
}
262
271
263
272
void common_hal_pulseio_pwmout_set_duty_cycle (pulseio_pwmout_obj_t * self , uint16_t duty_cycle ) {
264
- uint32_t input = (duty_cycle * PULSE_RESOLUTION )/65535 ;
273
+ uint32_t input = (duty_cycle * self -> period )/65535 ;
265
274
//Used for debugging
266
275
//mp_printf(&mp_plat_print, "duty_cycle %d, Duty: %d, Input %d\n", duty_cycle, duty, input);
267
276
__HAL_TIM_SET_COMPARE (& self -> handle , self -> channel , input );
@@ -277,15 +286,30 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_
277
286
//don't halt setup for the same frequency
278
287
if (frequency == self -> frequency ) return ;
279
288
280
- //calculate new values
281
289
uint32_t source_freq = timer_get_source_freq (self -> tim -> tim_index );
282
- if (frequency == 0 || frequency * PULSE_RESOLUTION > (source_freq )) {
290
+ uint32_t prescaler = 0 ;
291
+ uint32_t period = 0 ;
292
+
293
+ for (int i = 0 ; i < 32767 ;i ++ ) {
294
+ period = source_freq /(i * frequency );
295
+ if (period <= 65535 && period >=2 ) {
296
+ prescaler = i ;
297
+ break ;
298
+ }
299
+ }
300
+ if (prescaler == 0 ) {
283
301
mp_raise_ValueError (translate ("Invalid frequency supplied" ));
284
302
}
285
- uint32_t prescaler = source_freq /(frequency * PULSE_RESOLUTION );
286
- uint32_t period = PULSE_RESOLUTION ;
287
- //this shouldn't ever exceed 0xffff*0xffff = 0xfffe0001, so it won't integer overflow.
288
- uint32_t input = (self -> duty_cycle * PULSE_RESOLUTION )/65535 ;
303
+
304
+ uint32_t input = (self -> duty_cycle * period )/65535 ;
305
+
306
+ //debugging output
307
+ // mp_printf(&mp_plat_print, "Duty:%d, Pulses:%d\n", self->duty_cycle,input);
308
+ // mp_printf(&mp_plat_print, "Period: %d\n", period);
309
+ // mp_printf(&mp_plat_print, "Source Freq: %d\n", source_freq);
310
+ // mp_printf(&mp_plat_print, "Prescaler %d, Timer Freq: %d\n", prescaler, source_freq/prescaler);
311
+ // mp_printf(&mp_plat_print, "Output Freq: %d\n", (source_freq/prescaler)/period);
312
+ // mp_printf(&mp_plat_print, "TIM#:%d CH:%d ALTF:%d\n", self->tim->tim_index, self->tim->channel_index, self->tim->altfn_index);
289
313
290
314
//shut down
291
315
HAL_TIM_PWM_Stop (& self -> handle , self -> channel );
@@ -310,6 +334,7 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_
310
334
311
335
tim_frequencies [self -> tim -> tim_index - 1 ] = frequency ;
312
336
self -> frequency = frequency ;
337
+ self -> period = period ;
313
338
}
314
339
315
340
uint32_t common_hal_pulseio_pwmout_get_frequency (pulseio_pwmout_obj_t * self ) {
0 commit comments