@@ -30,11 +30,12 @@ void setupPWM(int pin, long pwm_frequency, bool invert, RP2040DriverParams* para
30
30
params->pins [index] = pin;
31
31
params->slice [index] = slice;
32
32
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 ;
38
39
#ifdef SIMPLEFOC_DEBUG_RP2040
39
40
SimpleFOCDebug::print (" Configuring pin " );
40
41
SimpleFOCDebug::print (pin);
@@ -44,9 +45,17 @@ void setupPWM(int pin, long pwm_frequency, bool invert, RP2040DriverParams* para
44
45
SimpleFOCDebug::print ((int )chan);
45
46
SimpleFOCDebug::print (" frequency " );
46
47
SimpleFOCDebug::print ((int )pwm_frequency);
48
+ SimpleFOCDebug::print (" divisor " );
49
+ SimpleFOCDebug::print ((int )(div>>4 ));
50
+ SimpleFOCDebug::print (" ." );
51
+ SimpleFOCDebug::print ((int )(div&0xF ));
47
52
SimpleFOCDebug::print (" top value " );
48
53
SimpleFOCDebug::println (wrapvalue);
49
54
#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 );
50
59
pwm_set_wrap (slice, wrapvalue);
51
60
wrapvalues[slice] = wrapvalue;
52
61
if (invert) {
0 commit comments