Introduce config::MRes and fix (real) axis units

The parameter config::AxisConfig::uSteps was supposed to be
microstepping resolution, but it's instead being used as the driver's
MRES directly.

To avoid a runtime conversion, rename the field to mRes and define a new
enum listing all the possible (and valid) microstepping resolutions.

This simplifies the code and makes clear the stepsPerUnit scale.

Assign correct stepsPerUnit to all axes as a result, including working
limits.
pull/100/head
Yuri D'Elia 2021-08-24 23:02:36 +02:00 committed by DRracer
parent f7f0df4afa
commit 288e74283d
6 changed files with 47 additions and 33 deletions

View File

@ -6,10 +6,23 @@ namespace config {
using namespace unit; using namespace unit;
/// Available microstepping resolutions
enum MRes : uint8_t {
MRes_256 = 0,
MRes_128 = 1,
MRes_64 = 2,
MRes_32 = 3,
MRes_16 = 4,
MRes_8 = 5,
MRes_4 = 6,
MRes_2 = 7,
MRes_1 = 8
};
/// Axis configuration data /// Axis configuration data
struct AxisConfig { struct AxisConfig {
bool dirOn; ///< direction ON state (for inversion) bool dirOn; ///< direction ON state (for inversion)
uint8_t uSteps; ///< microstepping [0-8, where 0 is x256 and 8 is fullstepping] MRes mRes; ///< microstepping [0-8, where 0 is x256 and 8 is fullstepping]
bool vSense; ///< vSense scaling bool vSense; ///< vSense scaling
uint8_t iRun; ///< running current uint8_t iRun; ///< running current
uint8_t iHold; ///< holding current uint8_t iHold; ///< holding current

View File

@ -70,56 +70,56 @@ static constexpr uint8_t stepTimerQuantum = 16;
/// Pulley axis configuration /// Pulley axis configuration
static constexpr AxisConfig pulley = { static constexpr AxisConfig pulley = {
.dirOn = true, .dirOn = false,
.uSteps = 4, //x16 .mRes = MRes_2,
.vSense = false, .vSense = false,
.iRun = 20, .iRun = 20,
.iHold = 20, .iHold = 20,
.stealth = false, .stealth = false,
.stepsPerUnit = 100, .stepsPerUnit = 161.3,
}; };
/// Pulley motion limits /// Pulley motion limits
static constexpr PulleyLimits pulleyLimits = { static constexpr PulleyLimits pulleyLimits = {
.lenght = 100.0_mm, .lenght = 1000.0_mm, // TODO
.jerk = 10.0_mm_s, .jerk = 4.0_mm_s,
.accel = 1000.0_mm_s2, .accel = 800.0_mm_s2,
}; };
/// Selector configuration /// Selector configuration
static constexpr AxisConfig selector = { static constexpr AxisConfig selector = {
.dirOn = true, .dirOn = true,
.uSteps = 4, //x16 .mRes = MRes_2,
.vSense = false, .vSense = false,
.iRun = 20, .iRun = 20,
.iHold = 20, .iHold = 20,
.stealth = false, .stealth = false,
.stepsPerUnit = 100, .stepsPerUnit = (200 * 2 / 8.),
}; };
/// Selector motion limits /// Selector motion limits
static constexpr SelectorLimits selectorLimits = { static constexpr SelectorLimits selectorLimits = {
.lenght = 100.0_mm, .lenght = 75.0_mm,
.jerk = 10.0_mm_s, .jerk = 1.0_mm_s,
.accel = 1000.0_mm_s2, .accel = 200.0_mm_s2,
}; };
/// Idler configuration /// Idler configuration
static constexpr AxisConfig idler = { static constexpr AxisConfig idler = {
.dirOn = true, .dirOn = true,
.uSteps = 4, //x16 .mRes = MRes_16,
.vSense = false, .vSense = false,
.iRun = 20, .iRun = 20,
.iHold = 20, .iHold = 20,
.stealth = false, .stealth = false,
.stepsPerUnit = 100, .stepsPerUnit = (200 * 16 / 360.),
}; };
/// Idler motion limits /// Idler motion limits
static constexpr IdlerLimits idlerLimits = { static constexpr IdlerLimits idlerLimits = {
.lenght = 360.0_deg, .lenght = 270.0_deg,
.jerk = 10.0_deg_s, .jerk = 0.1_deg_s,
.accel = 1000.0_deg_s2, .accel = 10.0_deg_s2,
}; };
/// Max retries of FeedToBondtech used in LoadFilament /// Max retries of FeedToBondtech used in LoadFilament

View File

@ -26,9 +26,9 @@ bool TMC2130::Init(const MotorParams &params, const MotorCurrents &currents, Mot
| (uint32_t)(1U & 0x0FU) << 7U //hend | (uint32_t)(1U & 0x0FU) << 7U //hend
| (uint32_t)(2U & 0x03U) << 15U //tbl | (uint32_t)(2U & 0x03U) << 15U //tbl
| (uint32_t)(currents.vSense & 0x01U) << 17U //vsense | (uint32_t)(currents.vSense & 0x01U) << 17U //vsense
| (uint32_t)(params.uSteps & 0x0FU) << 24U //mres | (uint32_t)(params.mRes & 0x0FU) << 24U //mres
| (uint32_t)((bool)params.uSteps) << 28U //intpol | (uint32_t)(1U & 0x01) << 28U //intpol (always true)
| (uint32_t)(1U & 0x01) << 29U; //dedge | (uint32_t)(1U & 0x01) << 29U; //dedge (always true)
WriteRegister(params, Registers::CHOPCONF, chopconf); WriteRegister(params, Registers::CHOPCONF, chopconf);
///apply currents ///apply currents
@ -82,7 +82,7 @@ void TMC2130::SetEnabled(const MotorParams &params, bool enabled) {
void TMC2130::ClearStallguard(const MotorParams &params) { void TMC2130::ClearStallguard(const MotorParams &params) {
// @todo: maximum resolution right now is x256/4 (uint8_t / 4) // @todo: maximum resolution right now is x256/4 (uint8_t / 4)
sg_counter = 4 * (1 << (8 - params.uSteps)) - 1; /// one electrical full step (4 steps when fullstepping) sg_counter = 4 * (1 << (8 - params.mRes)) - 1; /// one electrical full step (4 steps when fullstepping)
} }
bool TMC2130::CheckForErrors(const MotorParams &params) { bool TMC2130::CheckForErrors(const MotorParams &params) {
@ -116,7 +116,7 @@ void TMC2130::Isr(const MotorParams &params) {
if (sg_counter) { if (sg_counter) {
if (SampleDiag(params)) if (SampleDiag(params))
sg_counter--; sg_counter--;
else if (sg_counter < (4 * (1 << (8 - params.uSteps)) - 1)) else if (sg_counter < (4 * (1 << (8 - params.mRes)) - 1))
sg_counter++; sg_counter++;
} }
} }

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "../config/config.h"
#include "../hal/gpio.h" #include "../hal/gpio.h"
#include "../hal/shr16.h" #include "../hal/shr16.h"
#include "../hal/spi.h" #include "../hal/spi.h"
@ -23,7 +24,7 @@ struct MotorParams {
gpio::GPIO_pin csPin; ///< CS pin gpio::GPIO_pin csPin; ///< CS pin
gpio::GPIO_pin stepPin; ///< step pin gpio::GPIO_pin stepPin; ///< step pin
gpio::GPIO_pin sgPin; ///< stallguard pin gpio::GPIO_pin sgPin; ///< stallguard pin
uint8_t uSteps; ///< microstep resolution (mres) config::MRes mRes; ///< microstep resolution
}; };
struct MotorCurrents { struct MotorCurrents {

View File

@ -41,7 +41,7 @@ static AxisParams axisParams[NUM_AXIS] = {
// Pulley // Pulley
{ {
.name = 'P', .name = 'P',
.params = { .spi = hal::spi::TmcSpiBus, .idx = Pulley, .dirOn = config::pulley.dirOn, .csPin = PULLEY_CS_PIN, .stepPin = PULLEY_STEP_PIN, .sgPin = PULLEY_SG_PIN, .uSteps = config::pulley.uSteps }, .params = { .spi = hal::spi::TmcSpiBus, .idx = Pulley, .dirOn = config::pulley.dirOn, .csPin = PULLEY_CS_PIN, .stepPin = PULLEY_STEP_PIN, .sgPin = PULLEY_SG_PIN, .mRes = config::pulley.mRes },
.currents = { .vSense = config::pulley.vSense, .iRun = config::pulley.iRun, .iHold = config::pulley.iHold }, .currents = { .vSense = config::pulley.vSense, .iRun = config::pulley.iRun, .iHold = config::pulley.iHold },
.mode = DefaultMotorMode(config::pulley), .mode = DefaultMotorMode(config::pulley),
.jerk = unitToSteps<P_speed_t>(config::pulleyLimits.jerk), .jerk = unitToSteps<P_speed_t>(config::pulleyLimits.jerk),
@ -50,7 +50,7 @@ static AxisParams axisParams[NUM_AXIS] = {
// Selector // Selector
{ {
.name = 'S', .name = 'S',
.params = { .spi = hal::spi::TmcSpiBus, .idx = Selector, .dirOn = config::selector.dirOn, .csPin = SELECTOR_CS_PIN, .stepPin = SELECTOR_STEP_PIN, .sgPin = SELECTOR_SG_PIN, .uSteps = config::selector.uSteps }, .params = { .spi = hal::spi::TmcSpiBus, .idx = Selector, .dirOn = config::selector.dirOn, .csPin = SELECTOR_CS_PIN, .stepPin = SELECTOR_STEP_PIN, .sgPin = SELECTOR_SG_PIN, .mRes = config::selector.mRes },
.currents = { .vSense = config::selector.vSense, .iRun = config::selector.iRun, .iHold = config::selector.iHold }, .currents = { .vSense = config::selector.vSense, .iRun = config::selector.iRun, .iHold = config::selector.iHold },
.mode = DefaultMotorMode(config::selector), .mode = DefaultMotorMode(config::selector),
.jerk = unitToSteps<S_speed_t>(config::selectorLimits.jerk), .jerk = unitToSteps<S_speed_t>(config::selectorLimits.jerk),
@ -59,7 +59,7 @@ static AxisParams axisParams[NUM_AXIS] = {
// Idler // Idler
{ {
.name = 'I', .name = 'I',
.params = { .spi = hal::spi::TmcSpiBus, .idx = Idler, .dirOn = config::idler.dirOn, .csPin = IDLER_CS_PIN, .stepPin = IDLER_STEP_PIN, .sgPin = IDLER_SG_PIN, .uSteps = config::idler.uSteps }, .params = { .spi = hal::spi::TmcSpiBus, .idx = Idler, .dirOn = config::idler.dirOn, .csPin = IDLER_CS_PIN, .stepPin = IDLER_STEP_PIN, .sgPin = IDLER_SG_PIN, .mRes = config::idler.mRes },
.currents = { .vSense = config::idler.vSense, .iRun = config::idler.iRun, .iHold = config::idler.iHold }, .currents = { .vSense = config::idler.vSense, .iRun = config::idler.iRun, .iHold = config::idler.iHold },
.mode = DefaultMotorMode(config::idler), .mode = DefaultMotorMode(config::idler),
.jerk = unitToSteps<I_speed_t>(config::idlerLimits.jerk), .jerk = unitToSteps<I_speed_t>(config::idlerLimits.jerk),

View File

@ -38,7 +38,7 @@ TEST_CASE("pulse_gen::basic", "[pulse_gen]") {
.csPin = IDLER_CS_PIN, .csPin = IDLER_CS_PIN,
.stepPin = IDLER_STEP_PIN, .stepPin = IDLER_STEP_PIN,
.sgPin = IDLER_SG_PIN, .sgPin = IDLER_SG_PIN,
.uSteps = config::idler.uSteps .mRes = config::idler.mRes
}; };
PulseGen pg(10, 100); PulseGen pg(10, 100);
@ -67,7 +67,7 @@ TEST_CASE("pulse_gen::step_dir", "[pulse_gen]") {
.csPin = IDLER_CS_PIN, .csPin = IDLER_CS_PIN,
.stepPin = IDLER_STEP_PIN, .stepPin = IDLER_STEP_PIN,
.sgPin = IDLER_SG_PIN, .sgPin = IDLER_SG_PIN,
.uSteps = config::idler.uSteps .mRes = config::idler.mRes
}; };
PulseGen pg(10, 100); PulseGen pg(10, 100);
@ -102,7 +102,7 @@ TEST_CASE("pulse_gen::step_count", "[pulse_gen]") {
.csPin = IDLER_CS_PIN, .csPin = IDLER_CS_PIN,
.stepPin = IDLER_STEP_PIN, .stepPin = IDLER_STEP_PIN,
.sgPin = IDLER_SG_PIN, .sgPin = IDLER_SG_PIN,
.uSteps = config::idler.uSteps .mRes = config::idler.mRes
}; };
PulseGen pg(10, 100); PulseGen pg(10, 100);
@ -140,7 +140,7 @@ TEST_CASE("pulse_gen::queue_position", "[pulse_gen]") {
.csPin = IDLER_CS_PIN, .csPin = IDLER_CS_PIN,
.stepPin = IDLER_STEP_PIN, .stepPin = IDLER_STEP_PIN,
.sgPin = IDLER_SG_PIN, .sgPin = IDLER_SG_PIN,
.uSteps = config::idler.uSteps .mRes = config::idler.mRes
}; };
PulseGen pg(10, 100); PulseGen pg(10, 100);
@ -208,7 +208,7 @@ TEST_CASE("pulse_gen::queue_step", "[pulse_gen]") {
.csPin = IDLER_CS_PIN, .csPin = IDLER_CS_PIN,
.stepPin = IDLER_STEP_PIN, .stepPin = IDLER_STEP_PIN,
.sgPin = IDLER_SG_PIN, .sgPin = IDLER_SG_PIN,
.uSteps = config::idler.uSteps .mRes = config::idler.mRes
}; };
PulseGen pg(10, 100); PulseGen pg(10, 100);
@ -234,7 +234,7 @@ TEST_CASE("pulse_gen::queue_abort", "[pulse_gen]") {
.csPin = IDLER_CS_PIN, .csPin = IDLER_CS_PIN,
.stepPin = IDLER_STEP_PIN, .stepPin = IDLER_STEP_PIN,
.sgPin = IDLER_SG_PIN, .sgPin = IDLER_SG_PIN,
.uSteps = config::idler.uSteps .mRes = config::idler.mRes
}; };
PulseGen pg(10, 100); PulseGen pg(10, 100);
@ -266,7 +266,7 @@ TEST_CASE("pulse_gen::accel_ramp", "[pulse_gen]") {
.csPin = IDLER_CS_PIN, .csPin = IDLER_CS_PIN,
.stepPin = IDLER_STEP_PIN, .stepPin = IDLER_STEP_PIN,
.sgPin = IDLER_SG_PIN, .sgPin = IDLER_SG_PIN,
.uSteps = config::idler.uSteps .mRes = config::idler.mRes
}; };
// TODO: output ramps still to be checked // TODO: output ramps still to be checked