@@ -30,11 +30,12 @@ void setupPWM(int pin, long pwm_frequency, bool invert, RP2040DriverParams* para
3030 params->pins [index] = pin;
3131 params->slice [index] = slice;
3232 params->chan [index] = chan;
33- pwm_set_clkdiv_int_frac (slice, 1 , 0 ); // fastest pwm we can get
34- pwm_set_phase_correct (slice, true );
35- uint16_t wrapvalue = ((125L * 1000L * 1000L ) / pwm_frequency) / 2L - 1L ;
36- if (wrapvalue < 999 ) wrapvalue = 999 ; // 66kHz, resolution 1000
37- if (wrapvalue > 12499 ) wrapvalue = 12499 ; // 20kHz, resolution 12500
33+ uint32_t sysclock_hz = machine.freq ();
34+ uint32_t factor = 4096 * 2 * pwm_frequency;
35+ uint32_t div = sysclock_hz / factor;
36+ if (sysclock_hz % factor !=0 ) div+=1 ;
37+ if (div < 16 ) div = 16 ;
38+ uint32_t wrapvalue = sysclock_hz *16 / div / pwm_frequency - 1 ;
3839#ifdef SIMPLEFOC_DEBUG_RP2040
3940 SimpleFOCDebug::print (" Configuring pin " );
4041 SimpleFOCDebug::print (pin);
@@ -44,9 +45,17 @@ void setupPWM(int pin, long pwm_frequency, bool invert, RP2040DriverParams* para
4445 SimpleFOCDebug::print ((int )chan);
4546 SimpleFOCDebug::print (" frequency " );
4647 SimpleFOCDebug::print ((int )pwm_frequency);
48+ SimpleFOCDebug::print (" divisor " );
49+ SimpleFOCDebug::print ((int )(div>>4 ));
50+ SimpleFOCDebug::print (" ." );
51+ SimpleFOCDebug::print ((int )(div&0xF ));
4752 SimpleFOCDebug::print (" top value " );
4853 SimpleFOCDebug::println (wrapvalue);
4954#endif
55+ if (wrapvalue < 999 )
56+ SimpleFOCDebug::println (" Warning: PWM resolution is low." );
57+ pwm_set_clkdiv_int_frac (slice, div>>4 , div&0xF );
58+ pwm_set_phase_correct (slice, true );
5059 pwm_set_wrap (slice, wrapvalue);
5160 wrapvalues[slice] = wrapvalue;
5261 if (invert) {
0 commit comments