From 8b55b25028e7a4f31b6555df59136a12472d089f Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Fri, 3 Mar 2023 11:59:51 +0100 Subject: [PATCH] Allow cutting current >31 Needs reinitialization of the axis (Selector) because the TMC driver needs to set another register to double the current level. --- src/hal/tmc2130.cpp | 66 ++++++++++++++++++++++---- src/logic/cut_filament.cpp | 5 +- src/modules/motion.cpp | 7 ++- src/modules/motion.h | 1 + tests/unit/logic/stubs/stub_motion.cpp | 5 ++ 5 files changed, 70 insertions(+), 14 deletions(-) diff --git a/src/hal/tmc2130.cpp b/src/hal/tmc2130.cpp index 3a6218f..bb32dac 100644 --- a/src/hal/tmc2130.cpp +++ b/src/hal/tmc2130.cpp @@ -83,7 +83,7 @@ namespace tmc2130 { static constexpr uint8_t TOFF_DEFAULT = 3U, TOFF_MASK = 0xFU; -bool TMC2130::Init(const MotorParams ¶ms, const MotorCurrents ¤ts, MotorMode mode) { +bool __attribute__((noinline)) TMC2130::Init(const MotorParams ¶ms, const MotorCurrents ¤ts, MotorMode mode) { initialized = false; // sg_filter_threshold = (1 << (8 - params.mRes)); @@ -108,15 +108,61 @@ bool TMC2130::Init(const MotorParams ¶ms, const MotorCurrents ¤ts, Mot ReadRegister(params, Registers::GSTAT); /// apply chopper parameters - const uint32_t chopconf = (uint32_t)(TOFF_DEFAULT & TOFF_MASK) << 0U // toff - | (uint32_t)(5U & 0x07U) << 4U // hstrt - | (uint32_t)(1U & 0x0FU) << 7U // hend - | (uint32_t)(2U & 0x03U) << 15U // tbl - | (uint32_t)(currents.vSense & 0x01U) << 17U // vsense - | (uint32_t)(params.mRes & 0x0FU) << 24U // mres - | (uint32_t)(1U & 0x01) << 28U // intpol (always true) - | (uint32_t)(1U & 0x01) << 29U; // dedge (always true) - WriteRegister(params, Registers::CHOPCONF, chopconf); + // const uint32_t chopconf = (uint32_t)(TOFF_DEFAULT & TOFF_MASK) << 0U // toff + // | (uint32_t)(5U & 0x07U) << 4U // hstrt + // | (uint32_t)(1U & 0x0FU) << 7U // hend + // | (uint32_t)(2U & 0x03U) << 15U // tbl + // | (uint32_t)(currents.vSense & 0x01U) << 17U // vsense + // | (uint32_t)(params.mRes & 0x0FU) << 24U // mres + // | (uint32_t)(1U & 0x01) << 28U // intpol (always true) + // | (uint32_t)(1U & 0x01) << 29U; // dedge (always true) + // this ugly union/bit structure saves 34B over the previous implementation + union ChopConfU { + struct __attribute__((packed)) S { + uint8_t toff : 4; + uint8_t hstrt : 3; + uint8_t hend : 4; + uint8_t fd : 1; + uint8_t disfdcc : 1; + uint8_t rndtf : 1; + uint8_t chm : 1; + uint8_t tbl : 2; + uint8_t vsense : 1; + uint8_t vhighfs : 1; + uint8_t vhighchm : 1; + uint8_t sync : 4; + uint8_t mres : 4; + uint8_t intpol : 1; + uint8_t dedge : 1; + uint8_t diss2g : 1; + uint8_t reserved : 1; + constexpr S(bool vsense, uint8_t mres) + : toff(TOFF_DEFAULT) + , hstrt(5) + , hend(1) + , fd(0) + , disfdcc(0) + , rndtf(0) + , chm(0) + , tbl(2) + , vsense(vsense) + , vhighfs(0) + , vhighchm(0) + , sync(0) + , mres(mres) + , intpol(1) + , dedge(1) + , diss2g(0) + , reserved(0) {} + } s; + uint32_t dw; + constexpr ChopConfU(bool vsense, uint8_t mres) + : s(vsense, mres) {} + }; + static_assert(sizeof(ChopConfU::S) == 4); + static_assert(sizeof(ChopConfU) == 4); + + WriteRegister(params, Registers::CHOPCONF, ChopConfU(currents.vSense, params.mRes).dw); /// apply currents SetCurrents(params, currents); diff --git a/src/logic/cut_filament.cpp b/src/logic/cut_filament.cpp index 926639b..1cdd853 100644 --- a/src/logic/cut_filament.cpp +++ b/src/logic/cut_filament.cpp @@ -107,7 +107,8 @@ bool CutFilament::StepInner() { if (mi::idler.Disengaged()) { state = ProgressCode::PerformingCut; // set highest available current for the Selector - ms::selector.SetCurrents(mg::globals.CutIRunCurrent(), config::selector.iHold); + // Since we probably need to change the vSense bit (to double the current), we must reinit the axis + mm::motion.InitAxis(mm::Selector, mm::MotorCurrents(mg::globals.CutIRunCurrent(), config::selector.iHold)); // lower move speed savedSelectorFeedRate_mm_s = mg::globals.SelectorFeedrate_mm_s().v; mg::globals.SetSelectorFeedrate_mm_s(mg::globals.SelectorHomingFeedrate_mm_s().v); @@ -118,7 +119,7 @@ bool CutFilament::StepInner() { if (ms::selector.Slot() == cutSlot) { // this may not be necessary if we want the selector and pulley move at once state = ProgressCode::ReturningSelector; // revert current to Selector's normal value - ms::selector.SetCurrents(config::selector.iRun, config::selector.iHold); + mm::motion.InitAxis(mm::Selector, mm::MotorCurrents(config::selector.iRun, config::selector.iHold)); // revert move speed mg::globals.SetSelectorFeedrate_mm_s(savedSelectorFeedRate_mm_s); ms::selector.InvalidateHoming(); diff --git a/src/modules/motion.cpp b/src/modules/motion.cpp index 3fa7265..72cba5a 100644 --- a/src/modules/motion.cpp +++ b/src/modules/motion.cpp @@ -56,12 +56,15 @@ public: }; bool Motion::InitAxis(Axis axis) { + return InitAxis(axis, axisData[axis].currents); +} + +bool Motion::InitAxis(config::Axis axis, MotorCurrents mc) { // disable the axis and re-init the driver: this will clear the internal // StallGuard data as a result without special handling Disable(axis); - // Init also applies the currently pre-set StallGuard threshold into the TMC driver - return axisData[axis].drv.Init(axisParams[axis].params, axisData[axis].currents, axisParams[axis].mode); + return axisData[axis].drv.Init(axisParams[axis].params, mc, axisParams[axis].mode); } void Motion::SetEnabled(Axis axis, bool enabled) { diff --git a/src/modules/motion.h b/src/modules/motion.h index 4e91f10..235a198 100644 --- a/src/modules/motion.h +++ b/src/modules/motion.h @@ -77,6 +77,7 @@ public: /// state especially when the TMC may get randomly reset (deinited) /// @returns true if the init was successful (TMC2130 responded ok) bool InitAxis(Axis axis); + bool InitAxis(Axis axis, MotorCurrents mc); /// Return the axis power status. bool Enabled(Axis axis) const { return axisData[axis].enabled; } diff --git a/tests/unit/logic/stubs/stub_motion.cpp b/tests/unit/logic/stubs/stub_motion.cpp index bbd8f83..26ec7ff 100644 --- a/tests/unit/logic/stubs/stub_motion.cpp +++ b/tests/unit/logic/stubs/stub_motion.cpp @@ -20,6 +20,11 @@ bool Motion::InitAxis(Axis axis) { return true; } +bool Motion::InitAxis(Axis axis, MotorCurrents /*mc*/) { + SetEnabled(axis, true); + return true; +} + void Motion::SetEnabled(Axis axis, bool enabled) { axisData[axis].enabled = axes[axis].enabled = enabled; }