9#if defined(TARGET_RP2040) || defined(TARGET_RP2350)
13#pragma message("SimpleFOC: compiling for RP2040/RP2350")
16#if !defined(SIMPLEFOC_DEBUG_RP2040)
17#define SIMPLEFOC_DEBUG_RP2040
20#include "../../hardware_api.h"
21#include "hardware/pwm.h"
22#include "hardware/clocks.h"
23#if defined(USE_ARDUINO_PINOUT)
24#include <pinDefinitions.h>
27#define _PWM_FREQUENCY 24000
28#define _PWM_FREQUENCY_MAX 66000
29#define _PWM_FREQUENCY_MIN 1
35uint16_t wrapvalues[NUM_PWM_SLICES];
40void setupPWM(
int pin_nr,
long pwm_frequency,
bool invert, RP2040DriverParams*
params, uint8_t index) {
41 #if defined(USE_ARDUINO_PINOUT)
42 uint pin = (uint)digitalPinToPinName(pin_nr);
44 uint pin = (uint)pin_nr;
46 gpio_set_function(pin, GPIO_FUNC_PWM);
47 uint slice = pwm_gpio_to_slice_num(pin);
48 uint chan = pwm_gpio_to_channel(pin);
50 params->slice[index] = slice;
51 params->chan[index] = chan;
52 uint32_t sysclock_hz = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS) * 1000;
53 uint32_t factor = 4096 * 2 * pwm_frequency;
54 uint32_t div = sysclock_hz / factor;
55 if (sysclock_hz % factor !=0) div+=1;
56 if (div < 16) div = 16;
57 uint32_t wrapvalue = (sysclock_hz * 8) / div / pwm_frequency - 1;
58#if defined(SIMPLEFOC_DEBUG_RP2040) && !defined(SIMPLEFOC_DISABLE_DEBUG)
76 pwm_set_clkdiv_int_frac(slice, div>>4, div&0xF);
77 pwm_set_phase_correct(slice,
true);
78 pwm_set_wrap(slice, wrapvalue);
79 wrapvalues[slice] = wrapvalue;
82 hw_write_masked(&pwm_hw->slice[slice].csr, 0x1 << PWM_CH0_CSR_A_INV_LSB, PWM_CH0_CSR_A_INV_BITS);
84 hw_write_masked(&pwm_hw->slice[slice].csr, 0x1 << PWM_CH0_CSR_B_INV_LSB, PWM_CH0_CSR_B_INV_BITS);
86 pwm_set_chan_level(slice, chan, 0);
91 for (uint i=0;i<NUM_PWM_SLICES;i++) {
92 pwm_set_enabled(i,
false);
93 pwm_set_counter(i, 0);
96 pwm_set_mask_enabled(0xFFF);
102 RP2040DriverParams*
params =
new RP2040DriverParams();
103 if( !pwm_frequency || !
_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY;
104 else pwm_frequency =
_constrain(pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX);
105 params->pwm_frequency = pwm_frequency;
114 RP2040DriverParams*
params =
new RP2040DriverParams();
115 if( !pwm_frequency || !
_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY;
116 else pwm_frequency =
_constrain(pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX);
117 params->pwm_frequency = pwm_frequency;
127 RP2040DriverParams*
params =
new RP2040DriverParams();
128 if( !pwm_frequency || !
_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY;
129 else pwm_frequency =
_constrain(pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX);
130 params->pwm_frequency = pwm_frequency;
142 RP2040DriverParams*
params =
new RP2040DriverParams();
143 if( !pwm_frequency || !
_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY;
144 else pwm_frequency =
_constrain(pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX);
145 params->pwm_frequency = pwm_frequency;
157 RP2040DriverParams*
params =
new RP2040DriverParams();
158 if( !pwm_frequency || !
_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY;
159 else pwm_frequency =
_constrain(pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX);
160 params->pwm_frequency = pwm_frequency;
176void writeDutyCycle(
float val, uint slice, uint chan) {
177 pwm_set_chan_level(slice, chan, (wrapvalues[slice]+1) * val);
184 writeDutyCycle(dc_a, ((RP2040DriverParams*)
params)->slice[0], ((RP2040DriverParams*)
params)->chan[0]);
191 writeDutyCycle(dc_a, ((RP2040DriverParams*)
params)->slice[0], ((RP2040DriverParams*)
params)->chan[0]);
192 writeDutyCycle(
dc_b, ((RP2040DriverParams*)
params)->slice[1], ((RP2040DriverParams*)
params)->chan[1]);
198 writeDutyCycle(dc_a, ((RP2040DriverParams*)
params)->slice[0], ((RP2040DriverParams*)
params)->chan[0]);
199 writeDutyCycle(
dc_b, ((RP2040DriverParams*)
params)->slice[1], ((RP2040DriverParams*)
params)->chan[1]);
200 writeDutyCycle(
dc_c, ((RP2040DriverParams*)
params)->slice[2], ((RP2040DriverParams*)
params)->chan[2]);
206 writeDutyCycle(dc_1a, ((RP2040DriverParams*)
params)->slice[0], ((RP2040DriverParams*)
params)->chan[0]);
207 writeDutyCycle(
dc_1b, ((RP2040DriverParams*)
params)->slice[1], ((RP2040DriverParams*)
params)->chan[1]);
208 writeDutyCycle(
dc_2a, ((RP2040DriverParams*)
params)->slice[2], ((RP2040DriverParams*)
params)->chan[2]);
209 writeDutyCycle(
dc_2b, ((RP2040DriverParams*)
params)->slice[3], ((RP2040DriverParams*)
params)->chan[3]);
212inline float swDti(
float val,
float dt) {
214 if (ret>1.0) ret = 1.0f;
220 writeDutyCycle(dc_a, ((RP2040DriverParams*)
params)->slice[0], ((RP2040DriverParams*)
params)->chan[0]);
222 writeDutyCycle(0.0f, ((RP2040DriverParams*)
params)->slice[0], ((RP2040DriverParams*)
params)->chan[0]);
224 writeDutyCycle(swDti(dc_a, ((RP2040DriverParams*)
params)->
dead_zone), ((RP2040DriverParams*)
params)->slice[1], ((RP2040DriverParams*)
params)->chan[1]);
226 writeDutyCycle(0.0f, ((RP2040DriverParams*)
params)->slice[1], ((RP2040DriverParams*)
params)->chan[1]);
229 writeDutyCycle(
dc_b, ((RP2040DriverParams*)
params)->slice[2], ((RP2040DriverParams*)
params)->chan[2]);
231 writeDutyCycle(0.0f, ((RP2040DriverParams*)
params)->slice[2], ((RP2040DriverParams*)
params)->chan[2]);
233 writeDutyCycle(swDti(
dc_b, ((RP2040DriverParams*)
params)->
dead_zone), ((RP2040DriverParams*)
params)->slice[3], ((RP2040DriverParams*)
params)->chan[3]);
235 writeDutyCycle(0.0f, ((RP2040DriverParams*)
params)->slice[3], ((RP2040DriverParams*)
params)->chan[3]);
238 writeDutyCycle(
dc_c, ((RP2040DriverParams*)
params)->slice[4], ((RP2040DriverParams*)
params)->chan[4]);
240 writeDutyCycle(0.0f, ((RP2040DriverParams*)
params)->slice[4], ((RP2040DriverParams*)
params)->chan[4]);
242 writeDutyCycle(swDti(
dc_c, ((RP2040DriverParams*)
params)->
dead_zone), ((RP2040DriverParams*)
params)->slice[5], ((RP2040DriverParams*)
params)->chan[5]);
244 writeDutyCycle(0.0f, ((RP2040DriverParams*)
params)->slice[5], ((RP2040DriverParams*)
params)->chan[5]);
static void print(const char *msg)
const int const int const int pinC
GenericCurrentSenseParams * params
#define SIMPLEFOC_PWM_ACTIVE_HIGH
void * _configure4PWM(long pwm_frequency, const int pin1A, const int pin1B, const int pin2A, const int pin2B)
void * _configure6PWM(long pwm_frequency, float dead_zone, const int pinA_h, const int pinA_l, const int pinB_h, const int pinB_l, const int pinC_h, const int pinC_l)
void * _configure2PWM(long pwm_frequency, const int pinA, const int pinB)
void _writeDutyCycle2PWM(float dc_a, float dc_b, void *params)
void _writeDutyCycle1PWM(float dc_a, void *params)
void _writeDutyCycle4PWM(float dc_1a, float dc_1b, float dc_2a, float dc_2b, void *params)
void * _configure3PWM(long pwm_frequency, const int pinA, const int pinB, const int pinC)
#define SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH
void _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, PhaseState *phase_state, void *params)
void * _configure1PWM(long pwm_frequency, const int pinA)
#define SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH
void _writeDutyCycle3PWM(float dc_a, float dc_b, float dc_c, void *params)
float const int const int const int pinB_h
float const int const int const int const int pinB_l
const int const int pin1B
const int const int const int pin2A
float const int const int const int const int const int pinC_h
float float PhaseState * phase_state
float const int const int const int const int const int const int pinC_l
float const int const int pinA_l
const int const int const int const int pin2B
#define _constrain(amt, low, high)