@@ -77,6 +77,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
77
77
obj -> pin = pin ;
78
78
obj -> period = 0 ;
79
79
obj -> pulse = 0 ;
80
+ obj -> prescaler = 1 ;
80
81
81
82
pwmout_period_us (obj , 20000 ); // 20 ms per default
82
83
}
@@ -104,7 +105,7 @@ void pwmout_write(pwmout_t* obj, float value)
104
105
105
106
// Configure channels
106
107
sConfig .OCMode = TIM_OCMODE_PWM1 ;
107
- sConfig .Pulse = obj -> pulse ;
108
+ sConfig .Pulse = obj -> pulse / obj -> prescaler ;
108
109
sConfig .OCPolarity = TIM_OCPOLARITY_HIGH ;
109
110
sConfig .OCNPolarity = TIM_OCNPOLARITY_HIGH ;
110
111
sConfig .OCFastMode = TIM_OCFAST_ENABLE ;
@@ -168,22 +169,39 @@ void pwmout_period_us(pwmout_t* obj, int us)
168
169
169
170
SystemCoreClockUpdate ();
170
171
171
- TimHandle .Init .Period = us - 1 ;
172
- TimHandle .Init .Prescaler = (uint16_t )(SystemCoreClock / 1000000 ) - 1 ; // 1 us tick
173
- TimHandle .Init .ClockDivision = 0 ;
174
- TimHandle .Init .CounterMode = TIM_COUNTERMODE_UP ;
175
- TimHandle .Init .RepetitionCounter = 0 ;
172
+ /* To make it simple, we use to possible prescaler values which lead to:
173
+ * pwm unit = 1us, period/pulse can be from 1us to 65535us
174
+ * or
175
+ * pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
176
+ * Be careful that all the channels of a PWM shares the same prescaler
177
+ */
178
+ if (us > 0xFFFF ) {
179
+ obj -> prescaler = 500 ;
180
+ } else {
181
+ obj -> prescaler = 1 ;
182
+ }
183
+ TimHandle .Init .Prescaler = ((SystemCoreClock / 1000000 ) * obj -> prescaler ) - 1 ;
184
+
185
+ if (TimHandle .Init .Prescaler > 0xFFFF )
186
+ error ("PWM: out of range prescaler" );
187
+
188
+ TimHandle .Init .Period = (us - 1 ) / obj -> prescaler ;
189
+ if (TimHandle .Init .Period > 0xFFFF )
190
+ error ("PWM: out of range period" );
191
+
192
+ TimHandle .Init .ClockDivision = 0 ;
193
+ TimHandle .Init .CounterMode = TIM_COUNTERMODE_UP ;
176
194
177
195
if (HAL_TIM_PWM_Init (& TimHandle ) != HAL_OK ) {
178
196
error ("Cannot initialize PWM\n" );
179
197
}
180
198
181
- // Set duty cycle again
182
- pwmout_write (obj , dc );
183
-
184
199
// Save for future use
185
200
obj -> period = us ;
186
201
202
+ // Set duty cycle again
203
+ pwmout_write (obj , dc );
204
+
187
205
__HAL_TIM_ENABLE (& TimHandle );
188
206
}
189
207
0 commit comments