@@ -69,6 +69,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
69
69
obj -> pin = pin ;
70
70
obj -> period = 0 ;
71
71
obj -> pulse = 0 ;
72
+ obj -> prescaler = 1 ;
72
73
73
74
pwmout_period_us (obj , 20000 ); // 20 ms per default
74
75
}
@@ -96,7 +97,7 @@ void pwmout_write(pwmout_t* obj, float value)
96
97
97
98
// Configure channels
98
99
sConfig .OCMode = TIM_OCMODE_PWM1 ;
99
- sConfig .Pulse = obj -> pulse ;
100
+ sConfig .Pulse = obj -> pulse / obj -> prescaler ;
100
101
sConfig .OCPolarity = TIM_OCPOLARITY_HIGH ;
101
102
sConfig .OCNPolarity = TIM_OCNPOLARITY_HIGH ;
102
103
sConfig .OCFastMode = TIM_OCFAST_DISABLE ;
@@ -192,25 +193,44 @@ void pwmout_period_us(pwmout_t* obj, int us)
192
193
return ;
193
194
}
194
195
195
- TimHandle .Init .Period = us - 1 ;
196
+ /* To make it simple, we use to possible prescaler values which lead to:
197
+ * pwm unit = 1us, period/pulse can be from 1us to 65535us
198
+ * or
199
+ * pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
200
+ * Be careful that all the channels of a PWM shares the same prescaler
201
+ */
202
+ if (us > 0xFFFF ) {
203
+ obj -> prescaler = 500 ;
204
+ } else {
205
+ obj -> prescaler = 1 ;
206
+ }
207
+
196
208
// TIMxCLK = PCLKx when the APB prescaler = 1 else TIMxCLK = 2 * PCLKx
197
209
if (APBxCLKDivider == RCC_HCLK_DIV1 )
198
- TimHandle .Init .Prescaler = (uint16_t )((PclkFreq ) / 1000000 ) - 1 ; // 1 µs tick
210
+ TimHandle .Init .Prescaler = (uint16_t )((( PclkFreq ) / 1000000 ) * obj -> prescaler ) - 1 ; // 1 us tick
199
211
else
200
- TimHandle .Init .Prescaler = (uint16_t )((PclkFreq * 2 ) / 1000000 ) - 1 ; // 1 µs tick
212
+ TimHandle .Init .Prescaler = (uint16_t )(((PclkFreq * 2 ) / 1000000 ) * obj -> prescaler ) - 1 ; // 1 us tick
213
+
214
+ if (TimHandle .Init .Prescaler > 0xFFFF )
215
+ error ("PWM: out of range prescaler" );
216
+
217
+ TimHandle .Init .Period = (us - 1 ) / obj -> prescaler ;
218
+ if (TimHandle .Init .Period > 0xFFFF )
219
+ error ("PWM: out of range period" );
220
+
201
221
TimHandle .Init .ClockDivision = 0 ;
202
222
TimHandle .Init .CounterMode = TIM_COUNTERMODE_UP ;
203
223
204
224
if (HAL_TIM_PWM_Init (& TimHandle ) != HAL_OK ) {
205
225
error ("Cannot initialize PWM\n" );
206
226
}
207
227
208
- // Set duty cycle again
209
- pwmout_write (obj , dc );
210
-
211
228
// Save for future use
212
229
obj -> period = us ;
213
230
231
+ // Set duty cycle again
232
+ pwmout_write (obj , dc );
233
+
214
234
__HAL_TIM_ENABLE (& TimHandle );
215
235
}
216
236
0 commit comments