optimisation: calculate steps per unit reciprocal at compile time

Using the reciprocal allows us to use multiplication instead of division at runtime.

This commit removes 7 divison operations at run time.

Change in memory:
Flash: -210 bytes
SRAM: 0 bytes
pull/336/head
Guðni Már Gilbert 2024-12-22 12:50:59 +00:00
parent 4ab07d627a
commit 87a1862161
3 changed files with 9 additions and 4 deletions

View File

@ -28,6 +28,7 @@ struct AxisConfig {
uint8_t iHold; ///< holding current uint8_t iHold; ///< holding current
bool stealth; ///< Default to Stealth mode bool stealth; ///< Default to Stealth mode
long double stepsPerUnit; ///< steps per unit long double stepsPerUnit; ///< steps per unit
long double stepsPerUnitReciprocal; ///< reciprocal of step per unit (used to avoid divisions)
int8_t sg_thrs; /// @todo 7bit two's complement for the sg_thrs int8_t sg_thrs; /// @todo 7bit two's complement for the sg_thrs
}; };

View File

@ -115,6 +115,7 @@ static constexpr AxisConfig pulley = {
.iHold = 0, /// 17mA in SpreadCycle, freewheel in StealthChop .iHold = 0, /// 17mA in SpreadCycle, freewheel in StealthChop
.stealth = false, .stealth = false,
.stepsPerUnit = (200 * 8 / 19.147274), .stepsPerUnit = (200 * 8 / 19.147274),
.stepsPerUnitReciprocal = 1 / ((200 * 8 / 19.147274)),
.sg_thrs = 8, .sg_thrs = 8,
}; };
@ -140,6 +141,7 @@ static constexpr AxisConfig selector = {
.iHold = 0, /// 17mA in SpreadCycle, freewheel in StealthChop .iHold = 0, /// 17mA in SpreadCycle, freewheel in StealthChop
.stealth = false, .stealth = false,
.stepsPerUnit = (200 * 8 / 8.), .stepsPerUnit = (200 * 8 / 8.),
.stepsPerUnitReciprocal = 1 / ((200 * 8 / 8.)),
.sg_thrs = 3, .sg_thrs = 3,
}; };
@ -190,6 +192,7 @@ static constexpr AxisConfig idler = {
.iHold = 5, /// 99mA - parked current .iHold = 5, /// 99mA - parked current
.stealth = false, .stealth = false,
.stepsPerUnit = (200 * 16 / 360.), .stepsPerUnit = (200 * 16 / 360.),
.stepsPerUnitReciprocal = 1 / ((200 * 16 / 360.)),
.sg_thrs = 7, .sg_thrs = 7,
}; };

View File

@ -94,12 +94,13 @@ constexpr AxisUnit<T, A, U> operator*(const long double f, const AxisUnit<T, A,
struct AxisScale { struct AxisScale {
unit::UnitBase base; unit::UnitBase base;
long double stepsPerUnit; long double stepsPerUnit;
long double stepsPerUnitReciprocal;
}; };
static constexpr AxisScale axisScale[config::NUM_AXIS] = { static constexpr AxisScale axisScale[config::NUM_AXIS] = {
{ config::pulleyLimits.base, config::pulley.stepsPerUnit }, { config::pulleyLimits.base, config::pulley.stepsPerUnit, config::pulley.stepsPerUnitReciprocal },
{ config::selectorLimits.base, config::selector.stepsPerUnit }, { config::selectorLimits.base, config::selector.stepsPerUnit, config::selector.stepsPerUnitReciprocal },
{ config::idlerLimits.base, config::idler.stepsPerUnit }, { config::idlerLimits.base, config::idler.stepsPerUnit, config::idler.stepsPerUnitReciprocal },
}; };
/// Convert a unit::Unit to AxisUnit. /// Convert a unit::Unit to AxisUnit.
@ -126,7 +127,7 @@ template <typename U, typename AU, typename T = int32_t>
static constexpr T axisUnitToTruncatedUnit(AU v, long double mul = 1.) { static constexpr T axisUnitToTruncatedUnit(AU v, long double mul = 1.) {
static_assert(AU::unit == U::unit, "incorrect unit type conversion"); static_assert(AU::unit == U::unit, "incorrect unit type conversion");
static_assert(U::base == axisScale[AU::axis].base, "incorrect unit base conversion"); static_assert(U::base == axisScale[AU::axis].base, "incorrect unit base conversion");
return { ((T)v.v / (T)(axisScale[AU::axis].stepsPerUnit / mul)) }; return { ((T)v.v * (T)(axisScale[AU::axis].stepsPerUnitReciprocal * mul)) };
} }
/// Truncate an Unit type to an integer (normally int32_t) /// Truncate an Unit type to an integer (normally int32_t)