@@ -94,6 +94,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
94
94
obj -> pin = pin ;
95
95
obj -> period = 0 ;
96
96
obj -> pulse = 0 ;
97
+ obj -> prescaler = 1 ;
97
98
98
99
pwmout_period_us (obj , 20000 ); // 20 ms per default
99
100
}
@@ -121,7 +122,7 @@ void pwmout_write(pwmout_t* obj, float value)
121
122
122
123
// Configure channels
123
124
sConfig .OCMode = TIM_OCMODE_PWM1 ;
124
- sConfig .Pulse = obj -> pulse ;
125
+ sConfig .Pulse = obj -> pulse / obj -> prescaler ;
125
126
sConfig .OCPolarity = TIM_OCPOLARITY_HIGH ;
126
127
sConfig .OCNPolarity = TIM_OCNPOLARITY_HIGH ;
127
128
sConfig .OCFastMode = TIM_OCFAST_DISABLE ;
@@ -240,26 +241,45 @@ void pwmout_period_us(pwmout_t* obj, int us)
240
241
default :
241
242
return ;
242
243
}
243
-
244
- TimHandle .Init .Period = us - 1 ;
244
+
245
+ /* To make it simple, we use to possible prescaler values which lead to:
246
+ * pwm unit = 1us, period/pulse can be from 1us to 65535us
247
+ * or
248
+ * pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
249
+ * Be careful that all the channels of a PWM shares the same prescaler
250
+ */
251
+ if (us > 0xFFFF ) {
252
+ obj -> prescaler = 500 ;
253
+ } else {
254
+ obj -> prescaler = 1 ;
255
+ }
256
+
245
257
// TIMxCLK = PCLKx when the APB prescaler = 1 else TIMxCLK = 2 * PCLKx
246
258
if (APBxCLKDivider == RCC_HCLK_DIV1 )
247
- TimHandle .Init .Prescaler = (uint16_t )((PclkFreq ) / 1000000 ) - 1 ; // 1 us tick
259
+ TimHandle .Init .Prescaler = (uint16_t )((( PclkFreq ) / 1000000 ) * obj -> prescaler ) - 1 ; // 1 us tick
248
260
else
249
- TimHandle .Init .Prescaler = (uint16_t )((PclkFreq * 2 ) / 1000000 ) - 1 ; // 1 us tick
261
+ TimHandle .Init .Prescaler = (uint16_t )(((PclkFreq * 2 ) / 1000000 ) * obj -> prescaler ) - 1 ; // 1 us tick
262
+
263
+ if (TimHandle .Init .Prescaler > 0xFFFF )
264
+ error ("PWM: out of range prescaler" );
265
+
266
+ TimHandle .Init .Period = (us - 1 ) / obj -> prescaler ;
267
+ if (TimHandle .Init .Period > 0xFFFF )
268
+ error ("PWM: out of range period" );
269
+
250
270
TimHandle .Init .ClockDivision = 0 ;
251
271
TimHandle .Init .CounterMode = TIM_COUNTERMODE_UP ;
252
-
272
+
253
273
if (HAL_TIM_PWM_Init (& TimHandle ) != HAL_OK ) {
254
274
error ("Cannot initialize PWM\n" );
255
275
}
256
276
257
- // Set duty cycle again
258
- pwmout_write (obj , dc );
259
-
260
277
// Save for future use
261
278
obj -> period = us ;
262
279
280
+ // Set duty cycle again
281
+ pwmout_write (obj , dc );
282
+
263
283
__HAL_TIM_ENABLE (& TimHandle );
264
284
}
265
285
@@ -276,6 +296,7 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
276
296
void pwmout_pulsewidth_us (pwmout_t * obj , int us )
277
297
{
278
298
float value = (float )us / (float )obj -> period ;
299
+ printf ("pwmout_pulsewidth_us: period=%d, us=%d, dc=%d%%\r\n" , obj -> period , us , (int ) (value * 100 ));
279
300
pwmout_write (obj , value );
280
301
}
281
302
0 commit comments