Skip to content

Commit 1f0bba3

Browse files
committed
FOCDriver: Replace divisions in the hot PWM code paths with reciprocal multiplications
To reduce time of execution of the SetPWM member function. Signed-off-by: Felipe Neves <[email protected]>
1 parent c4e8470 commit 1f0bba3

File tree

5 files changed

+26
-14
lines changed

5 files changed

+26
-14
lines changed

src/common/base_classes/FOCDriver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class FOCDriver{
3535
long pwm_frequency; //!< pwm frequency value in hertz
3636
float voltage_power_supply; //!< power supply voltage
3737
float voltage_limit; //!< limiting voltage set to the motor
38+
float inverse_power_supply //!< inverse of the power supply, very useful to replace divisions with reciprocal multiply which is faster
3839

3940
bool initialized = false; //!< true if driver was successfully initialized
4041
void* params = 0; //!< pointer to hardware specific parameters of driver

src/drivers/BLDCDriver3PWM.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ BLDCDriver3PWM::BLDCDriver3PWM(int phA, int phB, int phC, int en1, int en2, int
1515
voltage_power_supply = DEF_POWER_SUPPLY;
1616
voltage_limit = NOT_SET;
1717
pwm_frequency = NOT_SET;
18-
18+
inverse_power_supply = 1.0f / voltage_power_supply;
1919
}
2020

2121
// enable motor driver
@@ -53,6 +53,8 @@ int BLDCDriver3PWM::init() {
5353

5454
// sanity check for the voltage limit configuration
5555
if(!_isset(voltage_limit) || voltage_limit > voltage_power_supply) voltage_limit = voltage_power_supply;
56+
inverse_power_supply = 1.0f / voltage_power_supply;
57+
5658

5759
// Set the pwm frequency to the pins
5860
// hardware specific function - depending on driver and mcu
@@ -82,9 +84,9 @@ void BLDCDriver3PWM::setPwm(float Ua, float Ub, float Uc) {
8284
Uc = _constrain(Uc, 0.0f, voltage_limit);
8385
// calculate duty cycle
8486
// limited in [0,1]
85-
dc_a = _constrain(Ua / voltage_power_supply, 0.0f , 1.0f );
86-
dc_b = _constrain(Ub / voltage_power_supply, 0.0f , 1.0f );
87-
dc_c = _constrain(Uc / voltage_power_supply, 0.0f , 1.0f );
87+
dc_a = _constrain(Ua * inverse_power_supply, 0.0f , 1.0f );
88+
dc_b = _constrain(Ub * inverse_power_supply, 0.0f , 1.0f );
89+
dc_c = _constrain(Uc * inverse_power_supply, 0.0f , 1.0f );
8890

8991
// hardware specific writing
9092
// hardware specific function - depending on driver and mcu

src/drivers/BLDCDriver6PWM.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ BLDCDriver6PWM::BLDCDriver6PWM(int phA_h,int phA_l,int phB_h,int phB_l,int phC_h
1616
voltage_power_supply = DEF_POWER_SUPPLY;
1717
voltage_limit = NOT_SET;
1818
pwm_frequency = NOT_SET;
19+
inverse_power_supply = 1.0f / voltage_power_supply;
1920

2021
// dead zone initial - 2%
2122
dead_zone = 0.02f;
@@ -60,6 +61,8 @@ int BLDCDriver6PWM::init() {
6061
// sanity check for the voltage limit configuration
6162
if( !_isset(voltage_limit) || voltage_limit > voltage_power_supply) voltage_limit = voltage_power_supply;
6263

64+
inverse_power_supply = 1.0f / voltage_power_supply;
65+
6366
// set phase state to disabled
6467
phase_state[0] = PhaseState::PHASE_OFF;
6568
phase_state[1] = PhaseState::PHASE_OFF;
@@ -84,9 +87,9 @@ void BLDCDriver6PWM::setPwm(float Ua, float Ub, float Uc) {
8487
Uc = _constrain(Uc, 0, voltage_limit);
8588
// calculate duty cycle
8689
// limited in [0,1]
87-
dc_a = _constrain(Ua / voltage_power_supply, 0.0f , 1.0f );
88-
dc_b = _constrain(Ub / voltage_power_supply, 0.0f , 1.0f );
89-
dc_c = _constrain(Uc / voltage_power_supply, 0.0f , 1.0f );
90+
dc_a = _constrain(Ua * inverse_power_supply, 0.0f , 1.0f );
91+
dc_b = _constrain(Ub * inverse_power_supply, 0.0f , 1.0f );
92+
dc_c = _constrain(Uc * inverse_power_supply, 0.0f , 1.0f );
9093
// hardware specific writing
9194
// hardware specific function - depending on driver and mcu
9295
_writeDutyCycle6PWM(dc_a, dc_b, dc_c, phase_state, params);

src/drivers/StepperDriver2PWM.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ StepperDriver2PWM::StepperDriver2PWM(int _pwm1, int* _in1, int _pwm2, int* _in2,
1717
voltage_power_supply = DEF_POWER_SUPPLY;
1818
voltage_limit = NOT_SET;
1919
pwm_frequency = NOT_SET;
20+
inverse_power_supply = 1.0f / voltage_power_supply;
2021

2122
}
2223

@@ -77,6 +78,8 @@ int StepperDriver2PWM::init() {
7778
// sanity check for the voltage limit configuration
7879
if( !_isset(voltage_limit) || voltage_limit > voltage_power_supply) voltage_limit = voltage_power_supply;
7980

81+
inverse_power_supply = 1.0f / voltage_power_supply;
82+
8083
// Set the pwm frequency to the pins
8184
// hardware specific function - depending on driver and mcu
8285
params = _configure2PWM(pwm_frequency, pwm1, pwm2);
@@ -100,8 +103,8 @@ void StepperDriver2PWM::setPwm(float Ua, float Ub) {
100103
Ua = _constrain(Ua, -voltage_limit, voltage_limit);
101104
Ub = _constrain(Ub, -voltage_limit, voltage_limit);
102105
// hardware specific writing
103-
duty_cycle1 = _constrain(abs(Ua)/voltage_power_supply,0.0f,1.0f);
104-
duty_cycle2 = _constrain(abs(Ub)/voltage_power_supply,0.0f,1.0f);
106+
duty_cycle1 = _constrain(abs(Ua)* inverse_power_supply,0.0f,1.0f);
107+
duty_cycle2 = _constrain(abs(Ub)* inverse_power_supply,0.0f,1.0f);
105108

106109
// phase 1 direction
107110
digitalWrite(dir1a, Ua >= 0 ? LOW : HIGH);

src/drivers/StepperDriver4PWM.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ StepperDriver4PWM::StepperDriver4PWM(int ph1A,int ph1B,int ph2A,int ph2B,int en1
1515
voltage_power_supply = DEF_POWER_SUPPLY;
1616
voltage_limit = NOT_SET;
1717
pwm_frequency = NOT_SET;
18+
inverse_power_supply = 1.0f / voltage_power_supply;
1819

1920
}
2021

@@ -52,10 +53,12 @@ int StepperDriver4PWM::init() {
5253
// sanity check for the voltage limit configuration
5354
if( !_isset(voltage_limit) || voltage_limit > voltage_power_supply) voltage_limit = voltage_power_supply;
5455

56+
inverse_power_supply = 1.0f / voltage_power_supply;
57+
5558
// Set the pwm frequency to the pins
5659
// hardware specific function - depending on driver and mcu
5760
params = _configure4PWM(pwm_frequency, pwm1A, pwm1B, pwm2A, pwm2B);
58-
initialized = (params!=SIMPLEFOC_DRIVER_INIT_FAILED);
61+
initialized = (params!=SIMPLEFOC_DRIVER_INIT_FAILED);
5962
return params!=SIMPLEFOC_DRIVER_INIT_FAILED;
6063
}
6164

@@ -77,14 +80,14 @@ void StepperDriver4PWM::setPwm(float Ualpha, float Ubeta) {
7780
Ubeta = _constrain(Ubeta, -voltage_limit, voltage_limit);
7881
// hardware specific writing
7982
if( Ualpha > 0 )
80-
duty_cycle1B = _constrain(abs(Ualpha)/voltage_power_supply,0.0f,1.0f);
83+
duty_cycle1B = _constrain(abs(Ualpha) * inverse_power_supply,0.0f,1.0f);
8184
else
82-
duty_cycle1A = _constrain(abs(Ualpha)/voltage_power_supply,0.0f,1.0f);
85+
duty_cycle1A = _constrain(abs(Ualpha) * inverse_power_supply,0.0f,1.0f);
8386

8487
if( Ubeta > 0 )
85-
duty_cycle2B = _constrain(abs(Ubeta)/voltage_power_supply,0.0f,1.0f);
88+
duty_cycle2B = _constrain(abs(Ubeta) * inverse_power_supply,0.0f,1.0f);
8689
else
87-
duty_cycle2A = _constrain(abs(Ubeta)/voltage_power_supply,0.0f,1.0f);
90+
duty_cycle2A = _constrain(abs(Ubeta) * inverse_power_supply,0.0f,1.0f);
8891
// write to hardware
8992
_writeDutyCycle4PWM(duty_cycle1A, duty_cycle1B, duty_cycle2A, duty_cycle2B, params);
9093
}

0 commit comments

Comments
 (0)