99#include " ../../hardware_api.h"
1010#include " ./rp2040_mcu.h"
1111#include " hardware/pwm.h"
12+ #include " hardware/clocks.h"
1213
1314#define _PWM_FREQUENCY 24000
1415#define _PWM_FREQUENCY_MAX 66000
15- #define _PWM_FREQUENCY_MIN 5000
16+ #define _PWM_FREQUENCY_MIN 1
1617
1718
1819
@@ -30,11 +31,12 @@ void setupPWM(int pin, long pwm_frequency, bool invert, RP2040DriverParams* para
3031 params->pins [index] = pin;
3132 params->slice [index] = slice;
3233 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
34+ uint32_t sysclock_hz = frequency_count_khz (CLOCKS_FC0_SRC_VALUE_CLK_SYS) * 1000 ;
35+ uint32_t factor = 4096 * 2 * pwm_frequency;
36+ uint32_t div = sysclock_hz / factor;
37+ if (sysclock_hz % factor !=0 ) div+=1 ;
38+ if (div < 16 ) div = 16 ;
39+ uint32_t wrapvalue = (sysclock_hz * 8 ) / div / pwm_frequency - 1 ;
3840#ifdef SIMPLEFOC_DEBUG_RP2040
3941 SimpleFOCDebug::print (" Configuring pin " );
4042 SimpleFOCDebug::print (pin);
@@ -44,9 +46,17 @@ void setupPWM(int pin, long pwm_frequency, bool invert, RP2040DriverParams* para
4446 SimpleFOCDebug::print ((int )chan);
4547 SimpleFOCDebug::print (" frequency " );
4648 SimpleFOCDebug::print ((int )pwm_frequency);
49+ SimpleFOCDebug::print (" divisor " );
50+ SimpleFOCDebug::print ((int )(div>>4 ));
51+ SimpleFOCDebug::print (" ." );
52+ SimpleFOCDebug::print ((int )(div&0xF ));
4753 SimpleFOCDebug::print (" top value " );
48- SimpleFOCDebug::println (wrapvalue);
54+ SimpleFOCDebug::println (( int ) wrapvalue);
4955#endif
56+ if (wrapvalue < 999 )
57+ SimpleFOCDebug::println (" Warning: PWM resolution is low." );
58+ pwm_set_clkdiv_int_frac (slice, div>>4 , div&0xF );
59+ pwm_set_phase_correct (slice, true );
5060 pwm_set_wrap (slice, wrapvalue);
5161 wrapvalues[slice] = wrapvalue;
5262 if (invert) {
0 commit comments