Skip to content

Commit ca541b7

Browse files
Merge pull request #277 from runger1101001/dev
RP2040 PWM driver now supports pre-scaler
2 parents 2fcc55d + fa637de commit ca541b7

File tree

3 files changed

+20
-8
lines changed

3 files changed

+20
-8
lines changed

src/communication/Commander.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ class Commander
240240
*/
241241
void motion(FOCMotor* motor, char* user_cmd, char* separator = (char *)" ");
242242

243+
bool isSentinel(char ch);
243244
private:
244245
// Subscribed command callback variables
245246
CommandCallback call_list[20];//!< array of command callback pointers - 20 is an arbitrary number
@@ -294,7 +295,6 @@ class Commander
294295

295296

296297
void printError();
297-
bool isSentinel(char ch);
298298
};
299299

300300

src/drivers/hardware_specific/rp2040/rp2040_mcu.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
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) {

src/drivers/hardware_specific/rp2040/rp2040_mcu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#pragma once
44

5+
#include "Arduino.h"
6+
57
#if defined(TARGET_RP2040)
68

79

0 commit comments

Comments
 (0)