Skip to content

RP2040 driver improvements, StepDirListener fix #209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Aug 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/communication/StepDirListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ void StepDirListener::init(){
}

void StepDirListener::enableInterrupt(void (*doA)()){
attachInterrupt(digitalPinToInterrupt(pin_step), doA, CHANGE);
attachInterrupt(digitalPinToInterrupt(pin_step), doA, polarity);
}

void StepDirListener::attach(float* variable){
Expand All @@ -22,15 +22,15 @@ void StepDirListener::attach(float* variable){

void StepDirListener::handle(){
// read step status
bool step = digitalRead(pin_step);
//bool step = digitalRead(pin_step);
// update counter only on rising edge
if(step && step != step_active){
if(digitalRead(pin_dir))
//if(step && step != step_active){
if(digitalRead(pin_dir))
count++;
else
else
count--;
}
step_active = step;
//}
//step_active = step;
// if attached variable update it
if(attached_variable) *attached_variable = getValue();
}
Expand Down
10 changes: 9 additions & 1 deletion src/communication/StepDirListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
#include "Arduino.h"
#include "../common/foc_utils.h"


#if defined(_STM32_DEF_) || defined(ESP_H) || defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_SAM_DUE)
#define PinStatus int
#endif


/**
* Step/Dir listenner class for easier interraction with this communication interface.
*/
Expand Down Expand Up @@ -47,11 +53,13 @@ class StepDirListener
int pin_step; //!< step pin
int pin_dir; //!< direction pin
long count; //!< current counter value - should be set to 0 for homing
PinStatus polarity = RISING; //!< polarity of the step pin

private:
float* attached_variable = nullptr; //!< pointer to the attached variable
float counter_to_value; //!< step counter to value
bool step_active = 0; //!< current step pin status (HIGH/LOW) - debouncing variable
//bool step_active = 0; //!< current step pin status (HIGH/LOW) - debouncing variable

};

#endif
84 changes: 53 additions & 31 deletions src/drivers/hardware_specific/rp2040_mcu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,31 @@

#define SIMPLEFOC_DEBUG_RP2040

#include "../hardware_api.h"

#ifdef SIMPLEFOC_DEBUG_RP2040

#ifndef SIMPLEFOC_RP2040_DEBUG_SERIAL
#define SIMPLEFOC_RP2040_DEBUG_SERIAL Serial
#endif
// these defines determine the polarity of the PWM output. Normally, the polarity is active-high,
// i.e. a high-level PWM output is expected to switch on the MOSFET. But should your driver design
// require inverted polarity, you can change the defines below, or set them via your build environment
// or board definition files.

// used for 2-PWM, 3-PWM, and 4-PWM modes
#ifndef SIMPLEFOC_PWM_ACTIVE_HIGH
#define SIMPLEFOC_PWM_ACTIVE_HIGH true
#endif
// used fof 6-PWM mode, high-side
#ifndef SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH
#define SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH true
#endif
// used fof 6-PWM mode, low-side
#ifndef SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH
#define SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH true
#endif

#include "Arduino.h"

#define _PWM_FREQUENCY 24000
#define _PWM_FREQUENCY_MAX 66000
#define _PWM_FREQUENCY_MIN 5000


typedef struct RP2040DriverParams {
Expand Down Expand Up @@ -46,18 +60,18 @@ void setupPWM(int pin, long pwm_frequency, bool invert, RP2040DriverParams* para
pwm_set_phase_correct(slice, true);
uint16_t wrapvalue = ((125L * 1000L * 1000L) / pwm_frequency) / 2L - 1L;
if (wrapvalue < 999) wrapvalue = 999; // 66kHz, resolution 1000
if (wrapvalue > 3299) wrapvalue = 3299; // 20kHz, resolution 3300
if (wrapvalue > 12499) wrapvalue = 12499; // 20kHz, resolution 12500
#ifdef SIMPLEFOC_DEBUG_RP2040
SIMPLEFOC_RP2040_DEBUG_SERIAL.print("Configuring pin ");
SIMPLEFOC_RP2040_DEBUG_SERIAL.print(pin);
SIMPLEFOC_RP2040_DEBUG_SERIAL.print(" slice ");
SIMPLEFOC_RP2040_DEBUG_SERIAL.print(slice);
SIMPLEFOC_RP2040_DEBUG_SERIAL.print(" channel ");
SIMPLEFOC_RP2040_DEBUG_SERIAL.print(chan);
SIMPLEFOC_RP2040_DEBUG_SERIAL.print(" frequency ");
SIMPLEFOC_RP2040_DEBUG_SERIAL.print(pwm_frequency);
SIMPLEFOC_RP2040_DEBUG_SERIAL.print(" top value ");
SIMPLEFOC_RP2040_DEBUG_SERIAL.println(wrapvalue);
SimpleFOCDebug::print("Configuring pin ");
SimpleFOCDebug::print(pin);
SimpleFOCDebug::print(" slice ");
SimpleFOCDebug::print((int)slice);
SimpleFOCDebug::print(" channel ");
SimpleFOCDebug::print((int)chan);
SimpleFOCDebug::print(" frequency ");
SimpleFOCDebug::print((int)pwm_frequency);
SimpleFOCDebug::print(" top value ");
SimpleFOCDebug::println(wrapvalue);
#endif
pwm_set_wrap(slice, wrapvalue);
wrapvalues[slice] = wrapvalue;
Expand All @@ -83,9 +97,11 @@ void syncSlices() {

void* _configure2PWM(long pwm_frequency, const int pinA, const int pinB) {
RP2040DriverParams* params = new RP2040DriverParams();
if( !pwm_frequency || !_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY;
else pwm_frequency = _constrain(pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX);
params->pwm_frequency = pwm_frequency;
setupPWM(pinA, pwm_frequency, false, params, 0);
setupPWM(pinB, pwm_frequency, false, params, 1);
setupPWM(pinA, pwm_frequency, !SIMPLEFOC_PWM_ACTIVE_HIGH, params, 0);
setupPWM(pinB, pwm_frequency, !SIMPLEFOC_PWM_ACTIVE_HIGH, params, 1);
syncSlices();
return params;
}
Expand All @@ -94,10 +110,12 @@ void* _configure2PWM(long pwm_frequency, const int pinA, const int pinB) {

void* _configure3PWM(long pwm_frequency, const int pinA, const int pinB, const int pinC) {
RP2040DriverParams* params = new RP2040DriverParams();
if( !pwm_frequency || !_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY;
else pwm_frequency = _constrain(pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX);
params->pwm_frequency = pwm_frequency;
setupPWM(pinA, pwm_frequency, false, params, 0);
setupPWM(pinB, pwm_frequency, false, params, 1);
setupPWM(pinC, pwm_frequency, false, params, 2);
setupPWM(pinA, pwm_frequency, !SIMPLEFOC_PWM_ACTIVE_HIGH, params, 0);
setupPWM(pinB, pwm_frequency, !SIMPLEFOC_PWM_ACTIVE_HIGH, params, 1);
setupPWM(pinC, pwm_frequency, !SIMPLEFOC_PWM_ACTIVE_HIGH, params, 2);
syncSlices();
return params;
}
Expand All @@ -107,11 +125,13 @@ void* _configure3PWM(long pwm_frequency, const int pinA, const int pinB, const i

void* _configure4PWM(long pwm_frequency, const int pin1A, const int pin1B, const int pin2A, const int pin2B) {
RP2040DriverParams* params = new RP2040DriverParams();
if( !pwm_frequency || !_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY;
else pwm_frequency = _constrain(pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX);
params->pwm_frequency = pwm_frequency;
setupPWM(pin1A, pwm_frequency, false, params, 0);
setupPWM(pin1B, pwm_frequency, false, params, 1);
setupPWM(pin2A, pwm_frequency, false, params, 2);
setupPWM(pin2B, pwm_frequency, false, params, 3);
setupPWM(pin1A, pwm_frequency, !SIMPLEFOC_PWM_ACTIVE_HIGH, params, 0);
setupPWM(pin1B, pwm_frequency, !SIMPLEFOC_PWM_ACTIVE_HIGH, params, 1);
setupPWM(pin2A, pwm_frequency, !SIMPLEFOC_PWM_ACTIVE_HIGH, params, 2);
setupPWM(pin2B, pwm_frequency, !SIMPLEFOC_PWM_ACTIVE_HIGH, params, 3);
syncSlices();
return params;
}
Expand All @@ -120,14 +140,16 @@ void* _configure4PWM(long pwm_frequency, const int pin1A, const int pin1B, const
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) {
// non-PIO solution...
RP2040DriverParams* params = new RP2040DriverParams();
if( !pwm_frequency || !_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY;
else pwm_frequency = _constrain(pwm_frequency, _PWM_FREQUENCY_MIN, _PWM_FREQUENCY_MAX);
params->pwm_frequency = pwm_frequency;
params->dead_zone = dead_zone;
setupPWM(pinA_h, pwm_frequency, false, params, 0);
setupPWM(pinB_h, pwm_frequency, false, params, 2);
setupPWM(pinC_h, pwm_frequency, false, params, 4);
setupPWM(pinA_l, pwm_frequency, true, params, 1);
setupPWM(pinB_l, pwm_frequency, true, params, 3);
setupPWM(pinC_l, pwm_frequency, true, params, 5);
setupPWM(pinA_h, pwm_frequency, !SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, params, 0);
setupPWM(pinB_h, pwm_frequency, !SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, params, 2);
setupPWM(pinC_h, pwm_frequency, !SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, params, 4);
setupPWM(pinA_l, pwm_frequency, SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH, params, 1);
setupPWM(pinB_l, pwm_frequency, SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH, params, 3);
setupPWM(pinC_l, pwm_frequency, SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH, params, 5);
syncSlices();
return params;
}
Expand Down
3 changes: 3 additions & 0 deletions src/drivers/hardware_specific/stm32_mcu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ void _startTimers(HardwareTimer **timers_to_start, int timer_num)
for (int i=0; i < timer_num; i++) {
if(timers_to_start[i] == NP) return;
timers_to_start[i]->resume();
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-DRV: Starting timer ", getTimerNumber(get_timer_index(timers_to_start[i]->getHandle()->Instance)));
#endif
}
}

Expand Down