@@ -75,6 +75,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
75
75
obj -> pin = pin ;
76
76
obj -> period = 0 ;
77
77
obj -> pulse = 0 ;
78
+ obj -> prescaler = 1 ;
78
79
79
80
pwmout_period_us (obj , 20000 ); // 20 ms per default
80
81
}
@@ -101,7 +102,7 @@ void pwmout_write(pwmout_t* obj, float value) {
101
102
102
103
// Configure channels
103
104
sConfig .OCMode = TIM_OCMODE_PWM1 ;
104
- sConfig .Pulse = obj -> pulse ;
105
+ sConfig .Pulse = obj -> pulse / obj -> prescaler ;
105
106
sConfig .OCPolarity = TIM_OCPOLARITY_HIGH ;
106
107
sConfig .OCNPolarity = TIM_OCNPOLARITY_HIGH ;
107
108
sConfig .OCFastMode = TIM_OCFAST_DISABLE ;
@@ -265,18 +266,39 @@ void pwmout_period_us(pwmout_t* obj, int us) {
265
266
// Update the SystemCoreClock variable
266
267
SystemCoreClockUpdate ();
267
268
268
- TimHandle .Init .Period = us - 1 ;
269
- TimHandle .Init .Prescaler = (uint16_t )(SystemCoreClock / 1000000 ) - 1 ; // 1 µs tick
269
+ /* To make it simple, we use to possible prescaler values which lead to:
270
+ * pwm unit = 1us, period/pulse can be from 1us to 65535us
271
+ * or
272
+ * pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
273
+ * Be careful that all the channels of a PWM shares the same prescaler
274
+ */
275
+ if (us > 0xFFFF ) {
276
+ obj -> prescaler = 500 ;
277
+ } else {
278
+ obj -> prescaler = 1 ;
279
+ }
280
+ TimHandle .Init .Prescaler = ((SystemCoreClock / 1000000 ) * obj -> prescaler ) - 1 ;
281
+
282
+ if (TimHandle .Init .Prescaler > 0xFFFF )
283
+ error ("PWM: out of range prescaler" );
284
+
285
+ TimHandle .Init .Period = (us - 1 ) / obj -> prescaler ;
286
+ if (TimHandle .Init .Period > 0xFFFF )
287
+ error ("PWM: out of range period" );
288
+
270
289
TimHandle .Init .ClockDivision = 0 ;
271
290
TimHandle .Init .CounterMode = TIM_COUNTERMODE_UP ;
272
- HAL_TIM_PWM_Init (& TimHandle );
273
291
274
- // Set duty cycle again
275
- pwmout_write (obj , dc );
292
+ if (HAL_TIM_PWM_Init (& TimHandle ) != HAL_OK ) {
293
+ error ("Cannot initialize PWM" );
294
+ }
276
295
277
296
// Save for future use
278
297
obj -> period = us ;
279
298
299
+ // Set duty cycle again
300
+ pwmout_write (obj , dc );
301
+
280
302
__HAL_TIM_ENABLE (& TimHandle );
281
303
}
282
304
0 commit comments