@@ -66,6 +66,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
6666 obj -> pin = pin ;
6767 obj -> period = 0 ;
6868 obj -> pulse = 0 ;
69+ obj -> prescaler = 1 ;
6970
7071 pwmout_period_us (obj , 20000 ); // 20 ms per default
7172}
@@ -93,7 +94,7 @@ void pwmout_write(pwmout_t* obj, float value)
9394
9495 // Configure channels
9596 sConfig .OCMode = TIM_OCMODE_PWM1 ;
96- sConfig .Pulse = obj -> pulse ;
97+ sConfig .Pulse = obj -> pulse / obj -> prescaler ;
9798 sConfig .OCPolarity = TIM_OCPOLARITY_HIGH ;
9899 sConfig .OCFastMode = TIM_OCFAST_ENABLE ;
99100
@@ -148,21 +149,39 @@ void pwmout_period_us(pwmout_t* obj, int us)
148149
149150 __HAL_TIM_DISABLE (& TimHandle );
150151
151- TimHandle .Init .Period = us - 1 ;
152- TimHandle .Init .Prescaler = (uint16_t )(SystemCoreClock / 1000000 ) - 1 ; // 1 us tick
152+ /* To make it simple, we use to possible prescaler values which lead to:
153+ * pwm unit = 1us, period/pulse can be from 1us to 65535us
154+ * or
155+ * pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
156+ * Be careful that all the channels of a PWM shares the same prescaler
157+ */
158+ if (us > 0xFFFF ) {
159+ obj -> prescaler = 500 ;
160+ } else {
161+ obj -> prescaler = 1 ;
162+ }
163+ TimHandle .Init .Prescaler = ((SystemCoreClock / 1000000 ) * obj -> prescaler ) - 1 ;
164+
165+ if (TimHandle .Init .Prescaler > 0xFFFF )
166+ error ("PWM: out of range prescaler" );
167+
168+ TimHandle .Init .Period = (us - 1 ) / obj -> prescaler ;
169+ if (TimHandle .Init .Period > 0xFFFF )
170+ error ("PWM: out of range period" );
171+
153172 TimHandle .Init .ClockDivision = 0 ;
154173 TimHandle .Init .CounterMode = TIM_COUNTERMODE_UP ;
155174
156175 if (HAL_TIM_PWM_Init (& TimHandle ) != HAL_OK ) {
157176 error ("Cannot initialize PWM" );
158177 }
159178
160- // Set duty cycle again
161- pwmout_write (obj , dc );
162-
163179 // Save for future use
164180 obj -> period = us ;
165181
182+ // Set duty cycle again
183+ pwmout_write (obj , dc );
184+
166185 __HAL_TIM_ENABLE (& TimHandle );
167186}
168187
0 commit comments