Add initial Axis configuration static structs
parent
ef7c776461
commit
de88ed4c6b
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace config {
|
||||||
|
|
||||||
|
/// Axis configuration data
|
||||||
|
struct AxisConfig {
|
||||||
|
bool dirOn; ///< direction ON state (for inversion)
|
||||||
|
uint8_t uSteps; ///< microstepping [1-32]
|
||||||
|
bool vSense; ///< vSense scaling
|
||||||
|
uint8_t iRun; ///< running current
|
||||||
|
uint8_t iHold; ///< holding current
|
||||||
|
float scale; ///< Scaling unit (unit/uStepsMaxRes)
|
||||||
|
float accel; ///< Acceleration (unit/s^2)
|
||||||
|
float jerk; ///< Jerk (unit/s)
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace config
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "axis.h"
|
||||||
#include "todo.h"
|
#include "todo.h"
|
||||||
|
|
||||||
/// Wrangler for assorted compile-time configuration and constants.
|
/// Wrangler for assorted compile-time configuration and constants.
|
||||||
|
|
@ -27,4 +28,45 @@ static constexpr const uint16_t buttonsDebounceMs = 100;
|
||||||
static constexpr const uint16_t buttonADCLimits[buttonCount][2] = { { 0, 10 }, { 320, 360 }, { 500, 530 } };
|
static constexpr const uint16_t buttonADCLimits[buttonCount][2] = { { 0, 10 }, { 320, 360 }, { 500, 530 } };
|
||||||
static constexpr const uint8_t buttonsADCIndex = 0; ///< ADC index of buttons input
|
static constexpr const uint8_t buttonsADCIndex = 0; ///< ADC index of buttons input
|
||||||
|
|
||||||
|
/// Maximum microstepping resolution. This defines the effective unit of
|
||||||
|
/// the step intevals on the motion API, independently of the selected
|
||||||
|
/// microstepping interval.
|
||||||
|
static constexpr uint8_t uStepMaxRes = 32;
|
||||||
|
|
||||||
|
/// Idler configuration
|
||||||
|
static constexpr AxisConfig idler = {
|
||||||
|
.dirOn = true,
|
||||||
|
.uSteps = 16,
|
||||||
|
.vSense = false,
|
||||||
|
.iRun = 20,
|
||||||
|
.iHold = 20,
|
||||||
|
.scale = 1.,
|
||||||
|
.accel = 100.,
|
||||||
|
.jerk = 1.,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Pulley configuration
|
||||||
|
static constexpr AxisConfig pulley = {
|
||||||
|
.dirOn = true,
|
||||||
|
.uSteps = 16,
|
||||||
|
.vSense = false,
|
||||||
|
.iRun = 20,
|
||||||
|
.iHold = 20,
|
||||||
|
.scale = 1.,
|
||||||
|
.accel = 100.,
|
||||||
|
.jerk = 1.,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Selector configuration
|
||||||
|
static constexpr AxisConfig selector = {
|
||||||
|
.dirOn = true,
|
||||||
|
.uSteps = 16,
|
||||||
|
.vSense = false,
|
||||||
|
.iRun = 20,
|
||||||
|
.iHold = 20,
|
||||||
|
.scale = 1.,
|
||||||
|
.accel = 100.,
|
||||||
|
.jerk = 1.,
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace config
|
} // namespace config
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,59 @@ namespace modules {
|
||||||
/// home?
|
/// home?
|
||||||
namespace motion {
|
namespace motion {
|
||||||
|
|
||||||
enum Axis {
|
/// Main axis enumeration
|
||||||
|
enum Axis : uint8_t {
|
||||||
Pulley,
|
Pulley,
|
||||||
Selector,
|
Selector,
|
||||||
Idler,
|
Idler,
|
||||||
|
_Axis_Last = Idler
|
||||||
};
|
};
|
||||||
|
|
||||||
enum IdlerMode {
|
static constexpr uint8_t NUM_AXIS = _Axis_Last + 1;
|
||||||
|
|
||||||
|
/// Static axis configuration
|
||||||
|
struct AxisParams {
|
||||||
|
char name;
|
||||||
|
hal::tmc2130::MotorParams params;
|
||||||
|
hal::tmc2130::MotorCurrents currents;
|
||||||
|
float scale;
|
||||||
|
float accel;
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr AxisParams axisParams[NUM_AXIS] = {
|
||||||
|
// Idler
|
||||||
|
{
|
||||||
|
.name = 'I',
|
||||||
|
.params = {
|
||||||
|
.idx = Idler,
|
||||||
|
.dirOn = config::idler.dirOn,
|
||||||
|
.csPin = IDLER_CS_PIN,
|
||||||
|
.stepPin = IDLER_STEP_PIN,
|
||||||
|
.sgPin = IDLER_SG_PIN,
|
||||||
|
.uSteps = config::idler.uSteps },
|
||||||
|
.currents = { .vSense = config::idler.vSense, .iRun = config::idler.iRun, .iHold = config::idler.iHold },
|
||||||
|
.scale = config::idler.scale,
|
||||||
|
.accel = config::idler.accel,
|
||||||
|
},
|
||||||
|
// Pulley
|
||||||
|
{
|
||||||
|
.name = 'P',
|
||||||
|
.params = { .idx = Pulley, .dirOn = config::pulley.dirOn, .csPin = PULLEY_CS_PIN, .stepPin = PULLEY_STEP_PIN, .sgPin = PULLEY_SG_PIN, .uSteps = config::pulley.uSteps },
|
||||||
|
.currents = { .vSense = config::pulley.vSense, .iRun = config::pulley.iRun, .iHold = config::pulley.iHold },
|
||||||
|
.scale = config::pulley.scale,
|
||||||
|
.accel = config::pulley.accel,
|
||||||
|
},
|
||||||
|
// Selector
|
||||||
|
{
|
||||||
|
.name = 'S',
|
||||||
|
.params = { .idx = Selector, .dirOn = config::selector.dirOn, .csPin = SELECTOR_CS_PIN, .stepPin = SELECTOR_STEP_PIN, .sgPin = SELECTOR_SG_PIN, .uSteps = config::selector.uSteps },
|
||||||
|
.currents = { .vSense = config::selector.vSense, .iRun = config::selector.iRun, .iHold = config::selector.iHold },
|
||||||
|
.scale = config::selector.scale,
|
||||||
|
.accel = config::selector.accel,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
enum IdlerMode : uint8_t {
|
||||||
Engage,
|
Engage,
|
||||||
Disengage
|
Disengage
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace speed_table {
|
||||||
|
|
||||||
#if F_CPU == 16000000
|
#if F_CPU == 16000000
|
||||||
|
|
||||||
const uint16_t speed_table_fast[256][2] PROGMEM = {
|
const st_timer_t speed_table_fast[256][2] PROGMEM = {
|
||||||
{ 62500, 55556 }, { 6944, 3268 }, { 3676, 1176 }, { 2500, 607 }, { 1893, 369 }, { 1524, 249 }, { 1275, 179 }, { 1096, 135 },
|
{ 62500, 55556 }, { 6944, 3268 }, { 3676, 1176 }, { 2500, 607 }, { 1893, 369 }, { 1524, 249 }, { 1275, 179 }, { 1096, 135 },
|
||||||
{ 961, 105 }, { 856, 85 }, { 771, 69 }, { 702, 58 }, { 644, 49 }, { 595, 42 }, { 553, 37 }, { 516, 32 },
|
{ 961, 105 }, { 856, 85 }, { 771, 69 }, { 702, 58 }, { 644, 49 }, { 595, 42 }, { 553, 37 }, { 516, 32 },
|
||||||
{ 484, 28 }, { 456, 25 }, { 431, 23 }, { 408, 20 }, { 388, 19 }, { 369, 16 }, { 353, 16 }, { 337, 14 },
|
{ 484, 28 }, { 456, 25 }, { 431, 23 }, { 408, 20 }, { 388, 19 }, { 369, 16 }, { 353, 16 }, { 337, 14 },
|
||||||
|
|
@ -40,7 +40,7 @@ const uint16_t speed_table_fast[256][2] PROGMEM = {
|
||||||
{ 31, 0 }, { 31, 0 }, { 31, 0 }, { 31, 1 }, { 30, 0 }, { 30, 0 }, { 30, 0 }, { 30, 0 }
|
{ 31, 0 }, { 31, 0 }, { 31, 0 }, { 31, 1 }, { 30, 0 }, { 30, 0 }, { 30, 0 }, { 30, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint16_t speed_table_slow[256][2] PROGMEM = {
|
const st_timer_t speed_table_slow[256][2] PROGMEM = {
|
||||||
{ 62500, 12500 }, { 50000, 8334 }, { 41666, 5952 }, { 35714, 4464 }, { 31250, 3473 }, { 27777, 2777 }, { 25000, 2273 }, { 22727, 1894 },
|
{ 62500, 12500 }, { 50000, 8334 }, { 41666, 5952 }, { 35714, 4464 }, { 31250, 3473 }, { 27777, 2777 }, { 25000, 2273 }, { 22727, 1894 },
|
||||||
{ 20833, 1603 }, { 19230, 1373 }, { 17857, 1191 }, { 16666, 1041 }, { 15625, 920 }, { 14705, 817 }, { 13888, 731 }, { 13157, 657 },
|
{ 20833, 1603 }, { 19230, 1373 }, { 17857, 1191 }, { 16666, 1041 }, { 15625, 920 }, { 14705, 817 }, { 13888, 731 }, { 13157, 657 },
|
||||||
{ 12500, 596 }, { 11904, 541 }, { 11363, 494 }, { 10869, 453 }, { 10416, 416 }, { 10000, 385 }, { 9615, 356 }, { 9259, 331 },
|
{ 12500, 596 }, { 11904, 541 }, { 11363, 494 }, { 10869, 453 }, { 10416, 416 }, { 10000, 385 }, { 9615, 356 }, { 9259, 331 },
|
||||||
|
|
@ -77,7 +77,7 @@ const uint16_t speed_table_slow[256][2] PROGMEM = {
|
||||||
|
|
||||||
#elif F_CPU == 20000000
|
#elif F_CPU == 20000000
|
||||||
|
|
||||||
const uint16_t speed_table_fast[256][2] PROGMEM = {
|
const st_timer_t speed_table_fast[256][2] PROGMEM = {
|
||||||
{ 62500, 54055 },
|
{ 62500, 54055 },
|
||||||
{ 8445, 3917 },
|
{ 8445, 3917 },
|
||||||
{ 4528, 1434 },
|
{ 4528, 1434 },
|
||||||
|
|
@ -336,7 +336,7 @@ const uint16_t speed_table_fast[256][2] PROGMEM = {
|
||||||
{ 38, 0 },
|
{ 38, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint16_t speed_table_slow[256][2] PROGMEM = {
|
const st_timer_t speed_table_slow[256][2] PROGMEM = {
|
||||||
{ 62500, 10417 },
|
{ 62500, 10417 },
|
||||||
{ 52083, 7441 },
|
{ 52083, 7441 },
|
||||||
{ 44642, 5580 },
|
{ 44642, 5580 },
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,16 @@ namespace modules {
|
||||||
/// Speed tables for acceleration calculations
|
/// Speed tables for acceleration calculations
|
||||||
namespace speed_table {
|
namespace speed_table {
|
||||||
|
|
||||||
|
typedef uint16_t st_timer_t;
|
||||||
|
|
||||||
/// Lookup table for rates equal or higher than 8*256
|
/// Lookup table for rates equal or higher than 8*256
|
||||||
extern const uint16_t speed_table_fast[256][2] PROGMEM;
|
extern const st_timer_t speed_table_fast[256][2] PROGMEM;
|
||||||
|
|
||||||
/// Lookup table for lower step rates
|
/// Lookup table for lower step rates
|
||||||
extern const uint16_t speed_table_slow[256][2] PROGMEM;
|
extern const st_timer_t speed_table_slow[256][2] PROGMEM;
|
||||||
|
|
||||||
/// Calculate the next timer interval and steps according to current step rate
|
/// Calculate the next timer interval and steps according to current step rate
|
||||||
static inline uint16_t calc_timer(uint16_t step_rate, uint8_t &step_loops) {
|
static inline st_timer_t calc_timer(st_timer_t step_rate, uint8_t &step_loops) {
|
||||||
if (step_rate > MAX_STEP_FREQUENCY)
|
if (step_rate > MAX_STEP_FREQUENCY)
|
||||||
step_rate = MAX_STEP_FREQUENCY;
|
step_rate = MAX_STEP_FREQUENCY;
|
||||||
if (step_rate > 20000) { // If steprate > 20kHz >> step 4 times
|
if (step_rate > 20000) { // If steprate > 20kHz >> step 4 times
|
||||||
|
|
@ -31,7 +33,7 @@ static inline uint16_t calc_timer(uint16_t step_rate, uint8_t &step_loops) {
|
||||||
using modules::math::mulU8X16toH16;
|
using modules::math::mulU8X16toH16;
|
||||||
namespace pm = hal::progmem;
|
namespace pm = hal::progmem;
|
||||||
|
|
||||||
uint16_t timer; // calculated interval
|
st_timer_t timer; // calculated interval
|
||||||
|
|
||||||
if (step_rate < (F_CPU / 500000))
|
if (step_rate < (F_CPU / 500000))
|
||||||
step_rate = (F_CPU / 500000);
|
step_rate = (F_CPU / 500000);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ using namespace modules::speed_table;
|
||||||
// The following reference values are calculated for 16MHz F_CPU
|
// The following reference values are calculated for 16MHz F_CPU
|
||||||
static_assert(F_CPU == 16000000);
|
static_assert(F_CPU == 16000000);
|
||||||
|
|
||||||
static const uint16_t reference[][3] = {
|
static const st_timer_t reference[][3] = {
|
||||||
{ 1, 62500, 1 },
|
{ 1, 62500, 1 },
|
||||||
{ 501, 3992, 1 },
|
{ 501, 3992, 1 },
|
||||||
{ 1001, 1998, 1 },
|
{ 1001, 1998, 1 },
|
||||||
|
|
@ -94,9 +94,9 @@ static const uint16_t reference[][3] = {
|
||||||
TEST_CASE("speed_table::calc_timer", "[speed_table]") {
|
TEST_CASE("speed_table::calc_timer", "[speed_table]") {
|
||||||
// Check the result values of calc_timer against an AVR reference table
|
// Check the result values of calc_timer against an AVR reference table
|
||||||
for (unsigned i = 0; i != sizeof(reference) / sizeof(*reference); ++i) {
|
for (unsigned i = 0; i != sizeof(reference) / sizeof(*reference); ++i) {
|
||||||
uint16_t step_rate = reference[i][0];
|
st_timer_t step_rate = reference[i][0];
|
||||||
uint8_t loops;
|
uint8_t loops;
|
||||||
uint16_t timer = calc_timer(step_rate, loops);
|
st_timer_t timer = calc_timer(step_rate, loops);
|
||||||
|
|
||||||
// allow +/-1 of difference for rounding between the C and ASM versions
|
// allow +/-1 of difference for rounding between the C and ASM versions
|
||||||
REQUIRE(abs((int)timer - (int)reference[i][1]) <= 1);
|
REQUIRE(abs((int)timer - (int)reference[i][1]) <= 1);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue