9
9
#include " ../../hardware_api.h"
10
10
#include " ./rp2040_mcu.h"
11
11
#include " hardware/pwm.h"
12
+ #include " hardware/clocks.h"
12
13
13
14
#define _PWM_FREQUENCY 24000
14
15
#define _PWM_FREQUENCY_MAX 66000
15
- #define _PWM_FREQUENCY_MIN 5000
16
+ #define _PWM_FREQUENCY_MIN 1
16
17
17
18
18
19
@@ -30,11 +31,12 @@ void setupPWM(int pin, long pwm_frequency, bool invert, RP2040DriverParams* para
30
31
params->pins [index] = pin;
31
32
params->slice [index] = slice;
32
33
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 ;
38
40
#ifdef SIMPLEFOC_DEBUG_RP2040
39
41
SimpleFOCDebug::print (" Configuring pin " );
40
42
SimpleFOCDebug::print (pin);
@@ -44,9 +46,17 @@ void setupPWM(int pin, long pwm_frequency, bool invert, RP2040DriverParams* para
44
46
SimpleFOCDebug::print ((int )chan);
45
47
SimpleFOCDebug::print (" frequency " );
46
48
SimpleFOCDebug::print ((int )pwm_frequency);
49
+ SimpleFOCDebug::print (" divisor " );
50
+ SimpleFOCDebug::print ((int )(div>>4 ));
51
+ SimpleFOCDebug::print (" ." );
52
+ SimpleFOCDebug::print ((int )(div&0xF ));
47
53
SimpleFOCDebug::print (" top value " );
48
- SimpleFOCDebug::println (wrapvalue);
54
+ SimpleFOCDebug::println (( int ) wrapvalue);
49
55
#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 );
50
60
pwm_set_wrap (slice, wrapvalue);
51
61
wrapvalues[slice] = wrapvalue;
52
62
if (invert) {
0 commit comments