@@ -77,6 +77,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
7777 obj -> pin = pin ;
7878 obj -> period = 0 ;
7979 obj -> pulse = 0 ;
80+ obj -> prescaler = 1 ;
8081
8182 pwmout_period_us (obj , 20000 ); // 20 ms per default
8283}
@@ -104,7 +105,7 @@ void pwmout_write(pwmout_t* obj, float value)
104105
105106 // Configure channels
106107 sConfig .OCMode = TIM_OCMODE_PWM1 ;
107- sConfig .Pulse = obj -> pulse ;
108+ sConfig .Pulse = obj -> pulse / obj -> prescaler ;
108109 sConfig .OCPolarity = TIM_OCPOLARITY_HIGH ;
109110 sConfig .OCNPolarity = TIM_OCNPOLARITY_HIGH ;
110111 sConfig .OCFastMode = TIM_OCFAST_ENABLE ;
@@ -168,22 +169,39 @@ void pwmout_period_us(pwmout_t* obj, int us)
168169
169170 SystemCoreClockUpdate ();
170171
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 ;
176194
177195 if (HAL_TIM_PWM_Init (& TimHandle ) != HAL_OK ) {
178196 error ("Cannot initialize PWM\n" );
179197 }
180198
181- // Set duty cycle again
182- pwmout_write (obj , dc );
183-
184199 // Save for future use
185200 obj -> period = us ;
186201
202+ // Set duty cycle again
203+ pwmout_write (obj , dc );
204+
187205 __HAL_TIM_ENABLE (& TimHandle );
188206}
189207
0 commit comments