mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2025-07-24 07:03:55 -06:00
🧑💻 FxdTiCtrl => FTMotion
This commit is contained in:
parent
a7a3abb9bf
commit
e7e77d9612
12 changed files with 186 additions and 205 deletions
|
@ -862,7 +862,7 @@ void idle(const bool no_stepper_sleep/*=false*/) {
|
|||
TERN_(HAS_TFT_LVGL_UI, LV_TASK_HANDLER());
|
||||
|
||||
// Manage Fixed-time Motion Control
|
||||
TERN_(FT_MOTION, fxdTiCtrl.loop());
|
||||
TERN_(FT_MOTION, ftMotion.loop());
|
||||
|
||||
IDLE_DONE:
|
||||
TERN_(MARLIN_DEV_MODE, idle_depth--);
|
||||
|
@ -1632,7 +1632,7 @@ void setup() {
|
|||
#endif
|
||||
|
||||
#if ENABLED(FT_MOTION)
|
||||
SETUP_RUN(fxdTiCtrl.init());
|
||||
SETUP_RUN(ftMotion.init());
|
||||
#endif
|
||||
|
||||
marlin_state = MF_RUNNING;
|
||||
|
|
|
@ -29,13 +29,13 @@
|
|||
|
||||
void say_shaping() {
|
||||
// FT Enabled
|
||||
SERIAL_ECHO_TERNARY(fxdTiCtrl.cfg.mode, "Fixed-Time Motion ", "en", "dis", "abled");
|
||||
SERIAL_ECHO_TERNARY(ftMotion.cfg.mode, "Fixed-Time Motion ", "en", "dis", "abled");
|
||||
|
||||
// FT Shaping
|
||||
#if HAS_X_AXIS
|
||||
if (fxdTiCtrl.cfg.mode > ftMotionMode_ENABLED) {
|
||||
if (ftMotion.cfg.mode > ftMotionMode_ENABLED) {
|
||||
SERIAL_ECHOPGM(" with ");
|
||||
switch (fxdTiCtrl.cfg.mode) {
|
||||
switch (ftMotion.cfg.mode) {
|
||||
default: break;
|
||||
case ftMotionMode_ZV: SERIAL_ECHOPGM("ZV"); break;
|
||||
case ftMotionMode_ZVD: SERIAL_ECHOPGM("ZVD"); break;
|
||||
|
@ -51,15 +51,15 @@ void say_shaping() {
|
|||
#endif
|
||||
SERIAL_ECHOLNPGM(".");
|
||||
|
||||
const bool z_based = TERN0(HAS_DYNAMIC_FREQ_MM, fxdTiCtrl.cfg.dynFreqMode == dynFreqMode_Z_BASED),
|
||||
g_based = TERN0(HAS_DYNAMIC_FREQ_G, fxdTiCtrl.cfg.dynFreqMode == dynFreqMode_MASS_BASED),
|
||||
const bool z_based = TERN0(HAS_DYNAMIC_FREQ_MM, ftMotion.cfg.dynFreqMode == dynFreqMode_Z_BASED),
|
||||
g_based = TERN0(HAS_DYNAMIC_FREQ_G, ftMotion.cfg.dynFreqMode == dynFreqMode_MASS_BASED),
|
||||
dynamic = z_based || g_based;
|
||||
|
||||
// FT Dynamic Frequency Mode
|
||||
if (fxdTiCtrl.cfg.modeHasShaper()) {
|
||||
if (ftMotion.cfg.modeHasShaper()) {
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
SERIAL_ECHOPGM("Dynamic Frequency Mode ");
|
||||
switch (fxdTiCtrl.cfg.dynFreqMode) {
|
||||
switch (ftMotion.cfg.dynFreqMode) {
|
||||
default:
|
||||
case dynFreqMode_DISABLED: SERIAL_ECHOPGM("disabled"); break;
|
||||
#if HAS_DYNAMIC_FREQ_MM
|
||||
|
@ -74,32 +74,32 @@ void say_shaping() {
|
|||
|
||||
#if HAS_X_AXIS
|
||||
SERIAL_ECHO_TERNARY(dynamic, "X/A ", "base dynamic", "static", " compensator frequency: ");
|
||||
SERIAL_ECHO(p_float_t(fxdTiCtrl.cfg.baseFreq[X_AXIS], 2), F("Hz"));
|
||||
SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq[X_AXIS], 2), F("Hz"));
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
if (dynamic) SERIAL_ECHO(" scaling: ", p_float_t(fxdTiCtrl.cfg.dynFreqK[X_AXIS], 8), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
if (dynamic) SERIAL_ECHO(" scaling: ", p_float_t(ftMotion.cfg.dynFreqK[X_AXIS], 8), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
SERIAL_ECHO_TERNARY(dynamic, "Y/B ", "base dynamic", "static", " compensator frequency: ");
|
||||
SERIAL_ECHO(p_float_t(fxdTiCtrl.cfg.baseFreq[Y_AXIS], 2), F(" Hz"));
|
||||
SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq[Y_AXIS], 2), F(" Hz"));
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(fxdTiCtrl.cfg.dynFreqK[Y_AXIS], 8), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(ftMotion.cfg.dynFreqK[Y_AXIS], 8), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
SERIAL_ECHO_TERNARY(fxdTiCtrl.cfg.linearAdvEna, "Linear Advance ", "en", "dis", "abled");
|
||||
SERIAL_ECHOLN(F(". Gain: "), p_float_t(fxdTiCtrl.cfg.linearAdvK, 5));
|
||||
SERIAL_ECHO_TERNARY(ftMotion.cfg.linearAdvEna, "Linear Advance ", "en", "dis", "abled");
|
||||
SERIAL_ECHOLN(F(". Gain: "), p_float_t(ftMotion.cfg.linearAdvK, 5));
|
||||
#endif
|
||||
}
|
||||
|
||||
void GcodeSuite::M493_report(const bool forReplay/*=true*/) {
|
||||
report_heading_etc(forReplay, F(STR_FT_MOTION));
|
||||
const ft_config_t &c = fxdTiCtrl.cfg;
|
||||
const ft_config_t &c = ftMotion.cfg;
|
||||
SERIAL_ECHOPGM(" M493 S", c.mode);
|
||||
#if HAS_X_AXIS
|
||||
SERIAL_ECHOPGM(" A", c.baseFreq[X_AXIS]);
|
||||
|
@ -160,7 +160,7 @@ void GcodeSuite::M493() {
|
|||
|
||||
// Parse 'S' mode parameter.
|
||||
if (parser.seenval('S')) {
|
||||
const ftMotionMode_t oldmm = fxdTiCtrl.cfg.mode,
|
||||
const ftMotionMode_t oldmm = ftMotion.cfg.mode,
|
||||
newmm = (ftMotionMode_t)parser.value_byte();
|
||||
|
||||
if (newmm != oldmm) {
|
||||
|
@ -179,7 +179,7 @@ void GcodeSuite::M493() {
|
|||
#endif
|
||||
case ftMotionMode_DISABLED:
|
||||
case ftMotionMode_ENABLED:
|
||||
fxdTiCtrl.cfg.mode = newmm;
|
||||
ftMotion.cfg.mode = newmm;
|
||||
flag.report_h = true;
|
||||
if (oldmm == ftMotionMode_DISABLED) flag.reset_ft = true;
|
||||
break;
|
||||
|
@ -192,7 +192,7 @@ void GcodeSuite::M493() {
|
|||
// Pressure control (linear advance) parameter.
|
||||
if (parser.seen('P')) {
|
||||
const bool val = parser.value_bool();
|
||||
fxdTiCtrl.cfg.linearAdvEna = val;
|
||||
ftMotion.cfg.linearAdvEna = val;
|
||||
SERIAL_ECHO_TERNARY(val, "Linear Advance ", "en", "dis", "abled.\n");
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,7 @@ void GcodeSuite::M493() {
|
|||
if (parser.seenval('K')) {
|
||||
const float val = parser.value_float();
|
||||
if (val >= 0.0f) {
|
||||
fxdTiCtrl.cfg.linearAdvK = val;
|
||||
ftMotion.cfg.linearAdvK = val;
|
||||
flag.report_h = true;
|
||||
}
|
||||
else // Value out of range.
|
||||
|
@ -213,22 +213,22 @@ void GcodeSuite::M493() {
|
|||
|
||||
// Dynamic frequency mode parameter.
|
||||
if (parser.seenval('D')) {
|
||||
if (fxdTiCtrl.cfg.modeHasShaper()) {
|
||||
if (ftMotion.cfg.modeHasShaper()) {
|
||||
const dynFreqMode_t val = dynFreqMode_t(parser.value_byte());
|
||||
switch (val) {
|
||||
case dynFreqMode_DISABLED:
|
||||
fxdTiCtrl.cfg.dynFreqMode = val;
|
||||
ftMotion.cfg.dynFreqMode = val;
|
||||
flag.report_h = true;
|
||||
break;
|
||||
#if HAS_DYNAMIC_FREQ_MM
|
||||
case dynFreqMode_Z_BASED:
|
||||
fxdTiCtrl.cfg.dynFreqMode = val;
|
||||
ftMotion.cfg.dynFreqMode = val;
|
||||
flag.report_h = true;
|
||||
break;
|
||||
#endif
|
||||
#if HAS_DYNAMIC_FREQ_G
|
||||
case dynFreqMode_MASS_BASED:
|
||||
fxdTiCtrl.cfg.dynFreqMode = val;
|
||||
ftMotion.cfg.dynFreqMode = val;
|
||||
flag.report_h = true;
|
||||
break;
|
||||
#endif
|
||||
|
@ -243,8 +243,8 @@ void GcodeSuite::M493() {
|
|||
}
|
||||
|
||||
const bool modeUsesDynFreq = (
|
||||
TERN0(HAS_DYNAMIC_FREQ_MM, fxdTiCtrl.cfg.dynFreqMode == dynFreqMode_Z_BASED)
|
||||
|| TERN0(HAS_DYNAMIC_FREQ_G, fxdTiCtrl.cfg.dynFreqMode == dynFreqMode_MASS_BASED)
|
||||
TERN0(HAS_DYNAMIC_FREQ_MM, ftMotion.cfg.dynFreqMode == dynFreqMode_Z_BASED)
|
||||
|| TERN0(HAS_DYNAMIC_FREQ_G, ftMotion.cfg.dynFreqMode == dynFreqMode_MASS_BASED)
|
||||
);
|
||||
|
||||
#endif // HAS_DYNAMIC_FREQ
|
||||
|
@ -253,11 +253,11 @@ void GcodeSuite::M493() {
|
|||
|
||||
// Parse frequency parameter (X axis).
|
||||
if (parser.seenval('A')) {
|
||||
if (fxdTiCtrl.cfg.modeHasShaper()) {
|
||||
if (ftMotion.cfg.modeHasShaper()) {
|
||||
const float val = parser.value_float();
|
||||
// TODO: Frequency minimum is dependent on the shaper used; the above check isn't always correct.
|
||||
if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) {
|
||||
fxdTiCtrl.cfg.baseFreq[X_AXIS] = val;
|
||||
ftMotion.cfg.baseFreq[X_AXIS] = val;
|
||||
flag.update_n = flag.reset_ft = flag.report_h = true;
|
||||
}
|
||||
else // Frequency out of range.
|
||||
|
@ -271,7 +271,7 @@ void GcodeSuite::M493() {
|
|||
// Parse frequency scaling parameter (X axis).
|
||||
if (parser.seenval('F')) {
|
||||
if (modeUsesDynFreq) {
|
||||
fxdTiCtrl.cfg.dynFreqK[X_AXIS] = parser.value_float();
|
||||
ftMotion.cfg.dynFreqK[X_AXIS] = parser.value_float();
|
||||
flag.report_h = true;
|
||||
}
|
||||
else
|
||||
|
@ -285,10 +285,10 @@ void GcodeSuite::M493() {
|
|||
|
||||
// Parse frequency parameter (Y axis).
|
||||
if (parser.seenval('B')) {
|
||||
if (fxdTiCtrl.cfg.modeHasShaper()) {
|
||||
if (ftMotion.cfg.modeHasShaper()) {
|
||||
const float val = parser.value_float();
|
||||
if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) {
|
||||
fxdTiCtrl.cfg.baseFreq[Y_AXIS] = val;
|
||||
ftMotion.cfg.baseFreq[Y_AXIS] = val;
|
||||
flag.update_n = flag.reset_ft = flag.report_h = true;
|
||||
}
|
||||
else // Frequency out of range.
|
||||
|
@ -302,7 +302,7 @@ void GcodeSuite::M493() {
|
|||
// Parse frequency scaling parameter (Y axis).
|
||||
if (parser.seenval('H')) {
|
||||
if (modeUsesDynFreq) {
|
||||
fxdTiCtrl.cfg.dynFreqK[Y_AXIS] = parser.value_float();
|
||||
ftMotion.cfg.dynFreqK[Y_AXIS] = parser.value_float();
|
||||
flag.report_h = true;
|
||||
}
|
||||
else
|
||||
|
@ -313,10 +313,10 @@ void GcodeSuite::M493() {
|
|||
#endif // HAS_Y_AXIS
|
||||
|
||||
#if HAS_X_AXIS
|
||||
if (flag.update_n) fxdTiCtrl.refreshShapingN();
|
||||
if (flag.update_a) fxdTiCtrl.updateShapingA();
|
||||
if (flag.update_n) ftMotion.refreshShapingN();
|
||||
if (flag.update_a) ftMotion.updateShapingA();
|
||||
#endif
|
||||
if (flag.reset_ft) fxdTiCtrl.reset();
|
||||
if (flag.reset_ft) ftMotion.reset();
|
||||
if (flag.report_h) say_shaping();
|
||||
|
||||
}
|
||||
|
|
|
@ -319,13 +319,13 @@ void menu_move() {
|
|||
#include "../../gcode/gcode.h"
|
||||
|
||||
void ftm_menu_setShaping(const ftMotionMode_t s) {
|
||||
fxdTiCtrl.cfg.mode = s;
|
||||
fxdTiCtrl.refreshShapingN();
|
||||
ftMotion.cfg.mode = s;
|
||||
ftMotion.refreshShapingN();
|
||||
ui.go_back();
|
||||
}
|
||||
|
||||
inline void menu_ftm_mode() {
|
||||
const ftMotionMode_t mode = fxdTiCtrl.cfg.mode;
|
||||
const ftMotionMode_t mode = ftMotion.cfg.mode;
|
||||
|
||||
START_MENU();
|
||||
BACK_ITEM(MSG_FIXED_TIME_MOTION);
|
||||
|
@ -349,17 +349,17 @@ void menu_move() {
|
|||
#if HAS_DYNAMIC_FREQ
|
||||
|
||||
inline void menu_ftm_dyn_mode() {
|
||||
const dynFreqMode_t dmode = fxdTiCtrl.cfg.dynFreqMode;
|
||||
const dynFreqMode_t dmode = ftMotion.cfg.dynFreqMode;
|
||||
|
||||
START_MENU();
|
||||
BACK_ITEM(MSG_FIXED_TIME_MOTION);
|
||||
|
||||
if (dmode != dynFreqMode_DISABLED) ACTION_ITEM(MSG_LCD_OFF, []{ fxdTiCtrl.cfg.dynFreqMode = dynFreqMode_DISABLED; ui.go_back(); });
|
||||
if (dmode != dynFreqMode_DISABLED) ACTION_ITEM(MSG_LCD_OFF, []{ ftMotion.cfg.dynFreqMode = dynFreqMode_DISABLED; ui.go_back(); });
|
||||
#if HAS_DYNAMIC_FREQ_MM
|
||||
if (dmode != dynFreqMode_Z_BASED) ACTION_ITEM(MSG_FTM_Z_BASED, []{ fxdTiCtrl.cfg.dynFreqMode = dynFreqMode_Z_BASED; ui.go_back(); });
|
||||
if (dmode != dynFreqMode_Z_BASED) ACTION_ITEM(MSG_FTM_Z_BASED, []{ ftMotion.cfg.dynFreqMode = dynFreqMode_Z_BASED; ui.go_back(); });
|
||||
#endif
|
||||
#if HAS_DYNAMIC_FREQ_G
|
||||
if (dmode != dynFreqMode_MASS_BASED) ACTION_ITEM(MSG_FTM_MASS_BASED, []{ fxdTiCtrl.cfg.dynFreqMode = dynFreqMode_MASS_BASED; ui.go_back(); });
|
||||
if (dmode != dynFreqMode_MASS_BASED) ACTION_ITEM(MSG_FTM_MASS_BASED, []{ ftMotion.cfg.dynFreqMode = dynFreqMode_MASS_BASED; ui.go_back(); });
|
||||
#endif
|
||||
|
||||
END_MENU();
|
||||
|
@ -368,7 +368,7 @@ void menu_move() {
|
|||
#endif // HAS_DYNAMIC_FREQ
|
||||
|
||||
void menu_ft_motion() {
|
||||
ft_config_t &c = fxdTiCtrl.cfg;
|
||||
ft_config_t &c = ftMotion.cfg;
|
||||
|
||||
FSTR_P ftmode;
|
||||
switch (c.mode) {
|
||||
|
@ -403,16 +403,16 @@ void menu_move() {
|
|||
|
||||
if (c.modeHasShaper()) {
|
||||
#if HAS_X_AXIS
|
||||
EDIT_ITEM_FAST_N(float42_52, X_AXIS, MSG_FTM_BASE_FREQ_N, &c.baseFreq[X_AXIS], FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2, fxdTiCtrl.refreshShapingN);
|
||||
EDIT_ITEM_FAST_N(float42_52, X_AXIS, MSG_FTM_BASE_FREQ_N, &c.baseFreq[X_AXIS], FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2, ftMotion.refreshShapingN);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
EDIT_ITEM_FAST_N(float42_52, Y_AXIS, MSG_FTM_BASE_FREQ_N, &c.baseFreq[Y_AXIS], FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2, fxdTiCtrl.refreshShapingN);
|
||||
EDIT_ITEM_FAST_N(float42_52, Y_AXIS, MSG_FTM_BASE_FREQ_N, &c.baseFreq[Y_AXIS], FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2, ftMotion.refreshShapingN);
|
||||
#endif
|
||||
|
||||
EDIT_ITEM_FAST(float42_52, MSG_FTM_ZETA, &c.zeta, 0.0f, 1.0f, fxdTiCtrl.refreshShapingN);
|
||||
EDIT_ITEM_FAST(float42_52, MSG_FTM_ZETA, &c.zeta, 0.0f, 1.0f, ftMotion.refreshShapingN);
|
||||
|
||||
if (WITHIN(c.mode, ftMotionMode_EI, ftMotionMode_3HEI))
|
||||
EDIT_ITEM_FAST(float42_52, MSG_FTM_VTOL, &c.vtol, 0.0f, 1.0f, fxdTiCtrl.refreshShapingN);
|
||||
EDIT_ITEM_FAST(float42_52, MSG_FTM_VTOL, &c.vtol, 0.0f, 1.0f, ftMotion.refreshShapingN);
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
SUBMENU(MSG_FTM_DYN_MODE, menu_ftm_dyn_mode);
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "ft_motion.h"
|
||||
#include "stepper.h" // Access stepper block queue function and abort status.
|
||||
|
||||
FxdTiCtrl fxdTiCtrl;
|
||||
FTMotion ftMotion;
|
||||
|
||||
#if !HAS_X_AXIS
|
||||
static_assert(FTM_DEFAULT_MODE == ftMotionMode_ZV, "ftMotionMode_ZV requires at least one linear axis.");
|
||||
|
@ -50,66 +50,67 @@ FxdTiCtrl fxdTiCtrl;
|
|||
|
||||
// Public variables.
|
||||
|
||||
ft_config_t FxdTiCtrl::cfg;
|
||||
ft_command_t FxdTiCtrl::stepperCmdBuff[FTM_STEPPERCMD_BUFF_SIZE] = {0U}; // Buffer of stepper commands.
|
||||
hal_timer_t FxdTiCtrl::stepperCmdBuff_StepRelativeTi[FTM_STEPPERCMD_BUFF_SIZE] = {0U}; // Buffer of the stepper command timing.
|
||||
uint8_t FxdTiCtrl::stepperCmdBuff_ApplyDir[FTM_STEPPERCMD_DIR_SIZE] = {0U}; // Buffer of whether DIR needs to be updated.
|
||||
uint32_t FxdTiCtrl::stepperCmdBuff_produceIdx = 0, // Index of next stepper command write to the buffer.
|
||||
FxdTiCtrl::stepperCmdBuff_consumeIdx = 0; // Index of next stepper command read from the buffer.
|
||||
ft_config_t FTMotion::cfg;
|
||||
bool FTMotion::busy; // = false
|
||||
ft_command_t FTMotion::stepperCmdBuff[FTM_STEPPERCMD_BUFF_SIZE] = {0U}; // Buffer of stepper commands.
|
||||
hal_timer_t FTMotion::stepperCmdBuff_StepRelativeTi[FTM_STEPPERCMD_BUFF_SIZE] = {0U}; // Buffer of the stepper command timing.
|
||||
uint8_t FTMotion::stepperCmdBuff_ApplyDir[FTM_STEPPERCMD_DIR_SIZE] = {0U}; // Buffer of whether DIR needs to be updated.
|
||||
uint32_t FTMotion::stepperCmdBuff_produceIdx = 0, // Index of next stepper command write to the buffer.
|
||||
FTMotion::stepperCmdBuff_consumeIdx = 0; // Index of next stepper command read from the buffer.
|
||||
|
||||
bool FxdTiCtrl::sts_stepperBusy = false; // The stepper buffer has items and is in use.
|
||||
bool FTMotion::sts_stepperBusy = false; // The stepper buffer has items and is in use.
|
||||
|
||||
// Private variables.
|
||||
// NOTE: These are sized for Ulendo FBS use.
|
||||
xyze_trajectory_t FxdTiCtrl::traj; // = {0.0f} Storage for fixed-time-based trajectory.
|
||||
xyze_trajectoryMod_t FxdTiCtrl::trajMod; // = {0.0f} Storage for modified fixed-time-based trajectory.
|
||||
xyze_trajectory_t FTMotion::traj; // = {0.0f} Storage for fixed-time-based trajectory.
|
||||
xyze_trajectoryMod_t FTMotion::trajMod; // = {0.0f} Storage for modified fixed-time-based trajectory.
|
||||
|
||||
block_t* FxdTiCtrl::current_block_cpy = nullptr; // Pointer to current block being processed.
|
||||
bool FxdTiCtrl::blockProcRdy = false, // Indicates a block is ready to be processed.
|
||||
FxdTiCtrl::blockProcRdy_z1 = false, // Storage for the previous indicator.
|
||||
FxdTiCtrl::blockProcDn = false; // Indicates current block is done being processed.
|
||||
bool FxdTiCtrl::batchRdy = false; // Indicates a batch of the fixed time trajectory
|
||||
// has been generated, is now available in the upper -
|
||||
// half of traj.x[], y, z ... e vectors, and is ready to be
|
||||
// post processed, if applicable, then interpolated.
|
||||
bool FxdTiCtrl::batchRdyForInterp = false; // Indicates the batch is done being post processed,
|
||||
// if applicable, and is ready to be converted to step commands.
|
||||
bool FxdTiCtrl::runoutEna = false; // True if runout of the block hasn't been done and is allowed.
|
||||
bool FxdTiCtrl::runout = false; // Indicates if runout is in progress.
|
||||
block_t* FTMotion::current_block_cpy = nullptr; // Pointer to current block being processed.
|
||||
bool FTMotion::blockProcRdy = false, // Indicates a block is ready to be processed.
|
||||
FTMotion::blockProcRdy_z1 = false, // Storage for the previous indicator.
|
||||
FTMotion::blockProcDn = false; // Indicates current block is done being processed.
|
||||
bool FTMotion::batchRdy = false; // Indicates a batch of the fixed time trajectory
|
||||
// has been generated, is now available in the upper -
|
||||
// half of traj.x[], y, z ... e vectors, and is ready to be
|
||||
// post processed, if applicable, then interpolated.
|
||||
bool FTMotion::batchRdyForInterp = false; // Indicates the batch is done being post processed,
|
||||
// if applicable, and is ready to be converted to step commands.
|
||||
bool FTMotion::runoutEna = false; // True if runout of the block hasn't been done and is allowed.
|
||||
bool FTMotion::runout = false; // Indicates if runout is in progress.
|
||||
|
||||
// Trapezoid data variables.
|
||||
xyze_pos_t FxdTiCtrl::startPosn, // (mm) Start position of block
|
||||
FxdTiCtrl::endPosn_prevBlock = { 0.0f }; // (mm) End position of previous block
|
||||
xyze_float_t FxdTiCtrl::ratio; // (ratio) Axis move ratio of block
|
||||
float FxdTiCtrl::accel_P, // Acceleration prime of block. [mm/sec/sec]
|
||||
FxdTiCtrl::decel_P, // Deceleration prime of block. [mm/sec/sec]
|
||||
FxdTiCtrl::F_P, // Feedrate prime of block. [mm/sec]
|
||||
FxdTiCtrl::f_s, // Starting feedrate of block. [mm/sec]
|
||||
FxdTiCtrl::s_1e, // Position after acceleration phase of block.
|
||||
FxdTiCtrl::s_2e; // Position after acceleration and coasting phase of block.
|
||||
xyze_pos_t FTMotion::startPosn, // (mm) Start position of block
|
||||
FTMotion::endPosn_prevBlock = { 0.0f }; // (mm) End position of previous block
|
||||
xyze_float_t FTMotion::ratio; // (ratio) Axis move ratio of block
|
||||
float FTMotion::accel_P, // Acceleration prime of block. [mm/sec/sec]
|
||||
FTMotion::decel_P, // Deceleration prime of block. [mm/sec/sec]
|
||||
FTMotion::F_P, // Feedrate prime of block. [mm/sec]
|
||||
FTMotion::f_s, // Starting feedrate of block. [mm/sec]
|
||||
FTMotion::s_1e, // Position after acceleration phase of block.
|
||||
FTMotion::s_2e; // Position after acceleration and coasting phase of block.
|
||||
|
||||
uint32_t FxdTiCtrl::N1, // Number of data points in the acceleration phase.
|
||||
FxdTiCtrl::N2, // Number of data points in the coasting phase.
|
||||
FxdTiCtrl::N3; // Number of data points in the deceleration phase.
|
||||
uint32_t FTMotion::N1, // Number of data points in the acceleration phase.
|
||||
FTMotion::N2, // Number of data points in the coasting phase.
|
||||
FTMotion::N3; // Number of data points in the deceleration phase.
|
||||
|
||||
uint32_t FxdTiCtrl::max_intervals; // Total number of data points that will be generated from block.
|
||||
uint32_t FTMotion::max_intervals; // Total number of data points that will be generated from block.
|
||||
|
||||
// Make vector variables.
|
||||
uint32_t FxdTiCtrl::makeVector_idx = 0, // Index of fixed time trajectory generation of the overall block.
|
||||
FxdTiCtrl::makeVector_idx_z1 = 0, // Storage for the previously calculated index above.
|
||||
FxdTiCtrl::makeVector_batchIdx = FTM_BATCH_SIZE; // Index of fixed time trajectory generation within the batch.
|
||||
uint32_t FTMotion::makeVector_idx = 0, // Index of fixed time trajectory generation of the overall block.
|
||||
FTMotion::makeVector_idx_z1 = 0, // Storage for the previously calculated index above.
|
||||
FTMotion::makeVector_batchIdx = FTM_BATCH_SIZE; // Index of fixed time trajectory generation within the batch.
|
||||
|
||||
// Interpolation variables.
|
||||
xyze_long_t FxdTiCtrl::steps = { 0 }; // Step count accumulator.
|
||||
xyze_stepDir_t FxdTiCtrl::dirState = LOGICAL_AXIS_ARRAY_1(stepDirState_NOT_SET); // Memory of the currently set step direction of the axis.
|
||||
xyze_long_t FTMotion::steps = { 0 }; // Step count accumulator.
|
||||
xyze_stepDir_t FTMotion::dirState = LOGICAL_AXIS_ARRAY_1(stepDirState_NOT_SET); // Memory of the currently set step direction of the axis.
|
||||
|
||||
uint32_t FxdTiCtrl::interpIdx = 0, // Index of current data point being interpolated.
|
||||
FxdTiCtrl::interpIdx_z1 = 0; // Storage for the previously calculated index above.
|
||||
hal_timer_t FxdTiCtrl::nextStepTicks = FTM_MIN_TICKS; // Accumulator for the next step time (in ticks).
|
||||
uint32_t FTMotion::interpIdx = 0, // Index of current data point being interpolated.
|
||||
FTMotion::interpIdx_z1 = 0; // Storage for the previously calculated index above.
|
||||
hal_timer_t FTMotion::nextStepTicks = FTM_MIN_TICKS; // Accumulator for the next step time (in ticks).
|
||||
|
||||
// Shaping variables.
|
||||
#if HAS_X_AXIS
|
||||
FxdTiCtrl::shaping_t FxdTiCtrl::shaping = {
|
||||
FTMotion::shaping_t FTMotion::shaping = {
|
||||
0, 0,
|
||||
x:{ { 0.0f }, { 0.0f }, { 0 } }, // d_zi, Ai, Ni
|
||||
#if HAS_Y_AXIS
|
||||
|
@ -120,8 +121,8 @@ hal_timer_t FxdTiCtrl::nextStepTicks = FTM_MIN_TICKS; // Accumulator for the nex
|
|||
|
||||
#if HAS_EXTRUDERS
|
||||
// Linear advance variables.
|
||||
float FxdTiCtrl::e_raw_z1 = 0.0f; // (ms) Unit delay of raw extruder position.
|
||||
float FxdTiCtrl::e_advanced_z1 = 0.0f; // (ms) Unit delay of advanced extruder position.
|
||||
float FTMotion::e_raw_z1 = 0.0f; // (ms) Unit delay of raw extruder position.
|
||||
float FTMotion::e_advanced_z1 = 0.0f; // (ms) Unit delay of advanced extruder position.
|
||||
#endif
|
||||
|
||||
constexpr uint32_t last_batchIdx = (FTM_WINDOW_SIZE) - (FTM_BATCH_SIZE);
|
||||
|
@ -133,15 +134,15 @@ constexpr uint32_t last_batchIdx = (FTM_WINDOW_SIZE) - (FTM_BATCH_SIZE);
|
|||
// Public functions.
|
||||
|
||||
// Sets controller states to begin processing a block.
|
||||
void FxdTiCtrl::startBlockProc(block_t * const current_block) {
|
||||
void FTMotion::startBlockProc(block_t * const current_block) {
|
||||
current_block_cpy = current_block;
|
||||
blockProcRdy = true;
|
||||
blockProcDn = false;
|
||||
runoutEna = true;
|
||||
}
|
||||
|
||||
// Moves any free data points to the stepper buffer even if a full batch isn't ready.
|
||||
void FxdTiCtrl::runoutBlock() {
|
||||
// Move any free data points to the stepper buffer even if a full batch isn't ready.
|
||||
void FTMotion::runoutBlock() {
|
||||
|
||||
if (runoutEna && !batchRdy) { // If the window is full already (block intervals was a multiple of
|
||||
// the batch size), or runout is not enabled, no runout is needed.
|
||||
|
@ -170,7 +171,7 @@ void FxdTiCtrl::runoutBlock() {
|
|||
}
|
||||
|
||||
// Controller main, to be invoked from non-isr task.
|
||||
void FxdTiCtrl::loop() {
|
||||
void FTMotion::loop() {
|
||||
|
||||
if (!cfg.mode) return;
|
||||
|
||||
|
@ -188,7 +189,7 @@ void FxdTiCtrl::loop() {
|
|||
}
|
||||
|
||||
// Planner processing and block conversion.
|
||||
if (!blockProcRdy && !runout) stepper.fxdTiCtrl_BlockQueueUpdate();
|
||||
if (!blockProcRdy && !runout) stepper.ftMotion_BlockQueueUpdate();
|
||||
|
||||
if (blockProcRdy) {
|
||||
if (!blockProcRdy_z1) loadBlockData(current_block_cpy); // One-shot.
|
||||
|
@ -264,7 +265,7 @@ void FxdTiCtrl::loop() {
|
|||
}
|
||||
|
||||
// Report busy status to planner.
|
||||
planner.fxdTiCtrl_busy = (sts_stepperBusy || ((!blockProcDn && blockProcRdy) || batchRdy || batchRdyForInterp || runoutEna));
|
||||
busy = (sts_stepperBusy || ((!blockProcDn && blockProcRdy) || batchRdy || batchRdyForInterp || runoutEna));
|
||||
|
||||
blockProcRdy_z1 = blockProcRdy;
|
||||
makeVector_idx_z1 = makeVector_idx;
|
||||
|
@ -276,7 +277,7 @@ void FxdTiCtrl::loop() {
|
|||
// Refresh the gains used by shaping functions.
|
||||
// To be called on init or mode or zeta change.
|
||||
|
||||
void FxdTiCtrl::Shaping::updateShapingA(const_float_t zeta/*=cfg.zeta*/, const_float_t vtol/*=cfg.vtol*/) {
|
||||
void FTMotion::Shaping::updateShapingA(const_float_t zeta/*=cfg.zeta*/, const_float_t vtol/*=cfg.vtol*/) {
|
||||
|
||||
const float K = exp(-zeta * M_PI / sqrt(1.0f - sq(zeta))),
|
||||
K2 = sq(K);
|
||||
|
@ -345,14 +346,14 @@ void FxdTiCtrl::loop() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void FxdTiCtrl::updateShapingA(const_float_t zeta/*=cfg.zeta*/, const_float_t vtol/*=cfg.vtol*/) {
|
||||
void FTMotion::updateShapingA(const_float_t zeta/*=cfg.zeta*/, const_float_t vtol/*=cfg.vtol*/) {
|
||||
shaping.updateShapingA(zeta, vtol);
|
||||
}
|
||||
|
||||
// Refresh the indices used by shaping functions.
|
||||
// To be called when frequencies change.
|
||||
|
||||
void FxdTiCtrl::AxisShaping::updateShapingN(const_float_t f, const_float_t df) {
|
||||
void FTMotion::AxisShaping::updateShapingN(const_float_t f, const_float_t df) {
|
||||
// Protections omitted for DBZ and for index exceeding array length.
|
||||
switch (cfg.mode) {
|
||||
case ftMotionMode_ZV:
|
||||
|
@ -382,7 +383,7 @@ void FxdTiCtrl::loop() {
|
|||
}
|
||||
}
|
||||
|
||||
void FxdTiCtrl::updateShapingN(const_float_t xf OPTARG(HAS_Y_AXIS, const_float_t yf), const_float_t zeta/*=cfg.zeta*/) {
|
||||
void FTMotion::updateShapingN(const_float_t xf OPTARG(HAS_Y_AXIS, const_float_t yf), const_float_t zeta/*=cfg.zeta*/) {
|
||||
const float df = sqrt(1.0f - sq(zeta));
|
||||
shaping.x.updateShapingN(xf, df);
|
||||
TERN_(HAS_Y_AXIS, shaping.y.updateShapingN(yf, df));
|
||||
|
@ -391,12 +392,12 @@ void FxdTiCtrl::loop() {
|
|||
#endif // HAS_X_AXIS
|
||||
|
||||
// Reset all trajectory processing variables.
|
||||
void FxdTiCtrl::reset() {
|
||||
void FTMotion::reset() {
|
||||
|
||||
stepperCmdBuff_produceIdx = stepperCmdBuff_consumeIdx = 0;
|
||||
|
||||
traj.reset(); // Reset trajectory history
|
||||
trajMod.reset(); // Reset modified trajectory history
|
||||
traj.reset(); // Reset trajectory history
|
||||
trajMod.reset(); // Reset modified trajectory history
|
||||
|
||||
blockProcRdy = blockProcRdy_z1 = blockProcDn = false;
|
||||
batchRdy = batchRdyForInterp = false;
|
||||
|
@ -424,13 +425,13 @@ void FxdTiCtrl::reset() {
|
|||
|
||||
// Private functions.
|
||||
// Auxiliary function to get number of step commands in the buffer.
|
||||
uint32_t FxdTiCtrl::stepperCmdBuffItems() {
|
||||
uint32_t FTMotion::stepperCmdBuffItems() {
|
||||
const uint32_t udiff = stepperCmdBuff_produceIdx - stepperCmdBuff_consumeIdx;
|
||||
return stepperCmdBuff_produceIdx < stepperCmdBuff_consumeIdx ? (FTM_STEPPERCMD_BUFF_SIZE) + udiff : udiff;
|
||||
}
|
||||
|
||||
// Initializes storage variables before startup.
|
||||
void FxdTiCtrl::init() {
|
||||
void FTMotion::init() {
|
||||
#if HAS_X_AXIS
|
||||
refreshShapingN();
|
||||
updateShapingA();
|
||||
|
@ -439,7 +440,7 @@ void FxdTiCtrl::init() {
|
|||
}
|
||||
|
||||
// Loads / converts block data from planner to fixed-time control variables.
|
||||
void FxdTiCtrl::loadBlockData(block_t * const current_block) {
|
||||
void FTMotion::loadBlockData(block_t * const current_block) {
|
||||
|
||||
const float totalLength = current_block->millimeters,
|
||||
oneOverLength = 1.0f / totalLength;
|
||||
|
@ -489,6 +490,7 @@ void FxdTiCtrl::loadBlockData(block_t * const current_block) {
|
|||
const float fdiff = feSqByTwoD - fsSqByTwoA, // (mm) Coasting distance if nominal speed is reached
|
||||
odiff = oneby2a - oneby2d, // (i.e., oneby2a * 2) (mm/s) Change in speed for one second of acceleration
|
||||
ldiff = totalLength - fdiff; // (mm) Distance to travel if nominal speed is reached
|
||||
|
||||
float T2 = (1.0f / F_n) * (ldiff - odiff * sq(F_n)); // (s) Coasting duration after nominal speed reached
|
||||
if (T2 < 0.0f) {
|
||||
T2 = 0.0f;
|
||||
|
@ -496,7 +498,6 @@ void FxdTiCtrl::loadBlockData(block_t * const current_block) {
|
|||
}
|
||||
|
||||
const float T1 = (F_n - f_s) / a, // (s) Accel Time = difference in feedrate over acceleration
|
||||
T3 = (F_n - f_e) / a; // (s) Decel Time = difference in feedrate over acceleration
|
||||
|
||||
N1 = ceil(T1 * (FTM_FS)); // Accel datapoints based on Hz frequency
|
||||
N2 = ceil(T2 * (FTM_FS)); // Coast
|
||||
|
@ -536,7 +537,7 @@ void FxdTiCtrl::loadBlockData(block_t * const current_block) {
|
|||
}
|
||||
|
||||
// Generate data points of the trajectory.
|
||||
void FxdTiCtrl::makeVector() {
|
||||
void FTMotion::makeVector() {
|
||||
float accel_k = 0.0f; // (mm/s^2) Acceleration K factor
|
||||
float tau = (makeVector_idx + 1) * (FTM_TS); // (s) Time since start of block
|
||||
float dist = 0.0f; // (mm) Distance traveled
|
||||
|
@ -653,7 +654,7 @@ void FxdTiCtrl::makeVector() {
|
|||
}
|
||||
|
||||
// Interpolates single data point to stepper commands.
|
||||
void FxdTiCtrl::convertToSteps(const uint32_t idx) {
|
||||
void FTMotion::convertToSteps(const uint32_t idx) {
|
||||
xyze_long_t err_P = { 0 };
|
||||
|
||||
//#define STEPS_ROUNDING
|
||||
|
|
|
@ -64,12 +64,13 @@ typedef struct FTConfig {
|
|||
#endif
|
||||
} ft_config_t;
|
||||
|
||||
class FxdTiCtrl {
|
||||
class FTMotion {
|
||||
|
||||
public:
|
||||
|
||||
// Public variables
|
||||
static ft_config_t cfg;
|
||||
static bool busy;
|
||||
|
||||
static void set_defaults() {
|
||||
cfg.mode = FTM_DEFAULT_MODE;
|
||||
|
@ -77,8 +78,8 @@ class FxdTiCtrl {
|
|||
TERN_(HAS_X_AXIS, cfg.baseFreq[X_AXIS] = FTM_SHAPING_DEFAULT_X_FREQ);
|
||||
TERN_(HAS_Y_AXIS, cfg.baseFreq[Y_AXIS] = FTM_SHAPING_DEFAULT_Y_FREQ);
|
||||
|
||||
cfg.zeta = FTM_SHAPING_ZETA;
|
||||
cfg.vtol = FTM_SHAPING_V_TOL;
|
||||
cfg.zeta = FTM_SHAPING_ZETA; // Damping factor
|
||||
cfg.vtol = FTM_SHAPING_V_TOL; // Vibration Level
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
cfg.dynFreqMode = FTM_DEFAULT_DYNFREQ_MODE;
|
||||
|
@ -114,7 +115,6 @@ class FxdTiCtrl {
|
|||
static void runoutBlock(); // Move any free data points to the stepper buffer even if a full batch isn't ready.
|
||||
static void loop(); // Controller main, to be invoked from non-isr task.
|
||||
|
||||
|
||||
#if HAS_X_AXIS
|
||||
// Refresh the gains used by shaping functions.
|
||||
// To be called on init or mode or zeta change.
|
||||
|
@ -168,6 +168,7 @@ class FxdTiCtrl {
|
|||
|
||||
static hal_timer_t nextStepTicks;
|
||||
|
||||
// Shaping variables.
|
||||
#if HAS_X_AXIS
|
||||
|
||||
typedef struct AxisShaping {
|
||||
|
@ -202,10 +203,10 @@ class FxdTiCtrl {
|
|||
|
||||
// Private methods
|
||||
static uint32_t stepperCmdBuffItems();
|
||||
static void loadBlockData(block_t * const current_block);
|
||||
static void loadBlockData(block_t *const current_block);
|
||||
static void makeVector();
|
||||
static void convertToSteps(const uint32_t idx);
|
||||
|
||||
}; // class fxdTiCtrl
|
||||
}; // class FTMotion
|
||||
|
||||
extern FxdTiCtrl fxdTiCtrl;
|
||||
extern FTMotion ftMotion;
|
||||
|
|
|
@ -56,15 +56,9 @@ typedef struct XYZEval<stepDirState_t> xyze_stepDir_t;
|
|||
enum {
|
||||
LIST_N(DOUBLE(LOGICAL_AXES),
|
||||
FT_BIT_DIR_E, FT_BIT_STEP_E,
|
||||
FT_BIT_DIR_X, FT_BIT_STEP_X,
|
||||
FT_BIT_DIR_Y, FT_BIT_STEP_Y,
|
||||
FT_BIT_DIR_Z, FT_BIT_STEP_Z,
|
||||
FT_BIT_DIR_I, FT_BIT_STEP_I,
|
||||
FT_BIT_DIR_J, FT_BIT_STEP_J,
|
||||
FT_BIT_DIR_K, FT_BIT_STEP_K,
|
||||
FT_BIT_DIR_U, FT_BIT_STEP_U,
|
||||
FT_BIT_DIR_V, FT_BIT_STEP_V,
|
||||
FT_BIT_DIR_W, FT_BIT_STEP_W
|
||||
FT_BIT_DIR_X, FT_BIT_STEP_X, FT_BIT_DIR_Y, FT_BIT_STEP_Y, FT_BIT_DIR_Z, FT_BIT_STEP_Z,
|
||||
FT_BIT_DIR_I, FT_BIT_STEP_I, FT_BIT_DIR_J, FT_BIT_STEP_J, FT_BIT_DIR_K, FT_BIT_STEP_K,
|
||||
FT_BIT_DIR_U, FT_BIT_STEP_U, FT_BIT_DIR_V, FT_BIT_STEP_V, FT_BIT_DIR_W, FT_BIT_STEP_W
|
||||
),
|
||||
FT_BIT_COUNT
|
||||
};
|
||||
|
|
|
@ -2100,12 +2100,12 @@ void prepare_line_to_destination() {
|
|||
struct OnExit {
|
||||
ftMotionMode_t oldmm;
|
||||
OnExit() {
|
||||
oldmm = fxdTiCtrl.cfg.mode;
|
||||
fxdTiCtrl.cfg.mode = ftMotionMode_DISABLED;
|
||||
oldmm = ftMotion.cfg.mode;
|
||||
ftMotion.cfg.mode = ftMotionMode_DISABLED;
|
||||
}
|
||||
~OnExit() {
|
||||
fxdTiCtrl.cfg.mode = oldmm;
|
||||
fxdTiCtrl.init();
|
||||
ftMotion.cfg.mode = oldmm;
|
||||
ftMotion.init();
|
||||
}
|
||||
} on_exit;
|
||||
#endif
|
||||
|
|
|
@ -229,10 +229,6 @@ float Planner::previous_nominal_speed;
|
|||
int32_t Planner::xy_freq_min_interval_us = LROUND(1000000.0f / (XY_FREQUENCY_LIMIT));
|
||||
#endif
|
||||
|
||||
#if ENABLED(FT_MOTION)
|
||||
bool Planner::fxdTiCtrl_busy = false;
|
||||
#endif
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
float Planner::extruder_advance_K[DISTINCT_E]; // Initialized by settings.load()
|
||||
#endif
|
||||
|
@ -1692,7 +1688,7 @@ void Planner::quick_stop() {
|
|||
// Restart the block delay for the first movement - As the queue was
|
||||
// forced to empty, there's no risk the ISR will touch this.
|
||||
|
||||
delay_before_delivering = TERN_(FT_MOTION, fxdTiCtrl.cfg.mode ? BLOCK_DELAY_NONE :) BLOCK_DELAY_FOR_1ST_MOVE;
|
||||
delay_before_delivering = TERN_(FT_MOTION, ftMotion.cfg.mode ? BLOCK_DELAY_NONE :) BLOCK_DELAY_FOR_1ST_MOVE;
|
||||
|
||||
TERN_(HAS_WIRED_LCD, clear_block_buffer_runtime()); // Clear the accumulated runtime
|
||||
|
||||
|
@ -1738,7 +1734,7 @@ bool Planner::busy() {
|
|||
return (has_blocks_queued() || cleaning_buffer_counter
|
||||
|| TERN0(EXTERNAL_CLOSED_LOOP_CONTROLLER, CLOSED_LOOP_WAITING())
|
||||
|| TERN0(HAS_ZV_SHAPING, stepper.input_shaping_busy())
|
||||
|| TERN0(FT_MOTION, fxdTiCtrl_busy)
|
||||
|| TERN0(FT_MOTION, ftMotion.busy)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1851,7 +1847,7 @@ bool Planner::_buffer_steps(const xyze_long_t &target
|
|||
// As there are no queued movements, the Stepper ISR will not touch this
|
||||
// variable, so there is no risk setting this here (but it MUST be done
|
||||
// before the following line!!)
|
||||
delay_before_delivering = TERN_(FT_MOTION, fxdTiCtrl.cfg.mode ? BLOCK_DELAY_NONE :) BLOCK_DELAY_FOR_1ST_MOVE;
|
||||
delay_before_delivering = TERN_(FT_MOTION, ftMotion.cfg.mode ? BLOCK_DELAY_NONE :) BLOCK_DELAY_FOR_1ST_MOVE;
|
||||
}
|
||||
|
||||
// Move buffer head
|
||||
|
@ -2924,7 +2920,7 @@ void Planner::buffer_sync_block(const BlockFlagBit sync_flag/*=BLOCK_BIT_SYNC_PO
|
|||
// As there are no queued movements, the Stepper ISR will not touch this
|
||||
// variable, so there is no risk setting this here (but it MUST be done
|
||||
// before the following line!!)
|
||||
delay_before_delivering = TERN_(FT_MOTION, fxdTiCtrl.cfg.mode ? BLOCK_DELAY_NONE :) BLOCK_DELAY_FOR_1ST_MOVE;
|
||||
delay_before_delivering = TERN_(FT_MOTION, ftMotion.cfg.mode ? BLOCK_DELAY_NONE :) BLOCK_DELAY_FOR_1ST_MOVE;
|
||||
}
|
||||
|
||||
block_buffer_head = next_buffer_head;
|
||||
|
@ -3217,7 +3213,7 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s
|
|||
// As there are no queued movements, the Stepper ISR will not touch this
|
||||
// variable, so there is no risk setting this here (but it MUST be done
|
||||
// before the following line!!)
|
||||
delay_before_delivering = TERN_(FT_MOTION, fxdTiCtrl.cfg.mode ? BLOCK_DELAY_NONE :) BLOCK_DELAY_FOR_1ST_MOVE;
|
||||
delay_before_delivering = TERN_(FT_MOTION, ftMotion.cfg.mode ? BLOCK_DELAY_NONE :) BLOCK_DELAY_FOR_1ST_MOVE;
|
||||
}
|
||||
|
||||
// Move buffer head
|
||||
|
|
|
@ -529,10 +529,6 @@ class Planner {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if ENABLED(FT_MOTION)
|
||||
static bool fxdTiCtrl_busy;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
|
|
@ -612,7 +612,7 @@ typedef struct SettingsDataStruct {
|
|||
// Fixed-Time Motion
|
||||
//
|
||||
#if ENABLED(FT_MOTION)
|
||||
ft_config_t fxdTiCtrl_cfg; // M493
|
||||
ft_config_t ftMotion_cfg; // M493
|
||||
#endif
|
||||
|
||||
//
|
||||
|
@ -1711,8 +1711,8 @@ void MarlinSettings::postprocess() {
|
|||
// Fixed-Time Motion
|
||||
//
|
||||
#if ENABLED(FT_MOTION)
|
||||
_FIELD_TEST(fxdTiCtrl_cfg);
|
||||
EEPROM_WRITE(fxdTiCtrl.cfg);
|
||||
_FIELD_TEST(ftMotion_cfg);
|
||||
EEPROM_WRITE(ftMotion.cfg);
|
||||
#endif
|
||||
|
||||
//
|
||||
|
@ -2785,8 +2785,8 @@ void MarlinSettings::postprocess() {
|
|||
// Fixed-Time Motion
|
||||
//
|
||||
#if ENABLED(FT_MOTION)
|
||||
_FIELD_TEST(fxdTiCtrl_cfg);
|
||||
EEPROM_READ(fxdTiCtrl.cfg);
|
||||
_FIELD_TEST(ftMotion_cfg);
|
||||
EEPROM_READ(ftMotion.cfg);
|
||||
#endif
|
||||
|
||||
//
|
||||
|
@ -3614,7 +3614,7 @@ void MarlinSettings::reset() {
|
|||
//
|
||||
// Fixed-Time Motion
|
||||
//
|
||||
TERN_(FT_MOTION, fxdTiCtrl.set_defaults());
|
||||
TERN_(FT_MOTION, ftMotion.set_defaults());
|
||||
|
||||
//
|
||||
// Nonlinear Extrusion
|
||||
|
|
|
@ -1492,11 +1492,14 @@ void Stepper::isr() {
|
|||
uint8_t max_loops = 10;
|
||||
|
||||
#if ENABLED(FT_MOTION)
|
||||
static bool fxdTiCtrl_stepCmdRdy = false; // Indicates a step command was loaded from the
|
||||
// buffers and is ready to be output.
|
||||
static bool fxdTiCtrl_applyDir = false; // Indicates the DIR output should be set.
|
||||
static ft_command_t fxdTiCtrl_stepCmd = 0U; // Storage for the step command to be output.
|
||||
static uint32_t fxdTiCtrl_nextAuxISR = 0U; // Storage for the next ISR of the auxilliary tasks.
|
||||
static bool ftMotion_stepCmdRdy = false; // Indicates a step command was loaded from the
|
||||
// buffers and is ready to be output.
|
||||
static bool ftMotion_applyDir = false; // Indicates the DIR output should be set.
|
||||
static ft_command_t ftMotion_stepCmd = 0U; // Storage for the step command to be output.
|
||||
static uint32_t ftMotion_nextAuxISR = 0U; // Storage for the next ISR of the auxilliary tasks.
|
||||
const bool using_ftMotion = ftMotion.cfg.mode;
|
||||
#else
|
||||
constexpr bool using_ftMotion = false;
|
||||
#endif
|
||||
|
||||
// We need this variable here to be able to use it in the following loop
|
||||
|
@ -1509,64 +1512,58 @@ void Stepper::isr() {
|
|||
|
||||
#if ENABLED(FT_MOTION)
|
||||
|
||||
// NOTE STEPPER_TIMER_RATE is equal to 2000000, not what VSCode shows
|
||||
const bool using_fxtictrl = fxdTiCtrl.cfg.mode;
|
||||
if (using_fxtictrl) {
|
||||
if (using_ftMotion) {
|
||||
if (!nextMainISR) {
|
||||
if (abort_current_block) {
|
||||
fxdTiCtrl_stepCmdRdy = false; // If a command was ready, cancel it.
|
||||
fxdTiCtrl.sts_stepperBusy = false; // Set busy false to allow a reset.
|
||||
ftMotion_stepCmdRdy = false; // If a command was ready, cancel it.
|
||||
ftMotion.sts_stepperBusy = false; // Set busy false to allow a reset.
|
||||
nextMainISR = 0.01f * (STEPPER_TIMER_RATE); // Come back in 10 msec.
|
||||
}
|
||||
else { // !(abort_current_block)
|
||||
if (fxdTiCtrl_stepCmdRdy) {
|
||||
fxdTiCtrl_stepper(fxdTiCtrl_applyDir, fxdTiCtrl_stepCmd);
|
||||
fxdTiCtrl_stepCmdRdy = false;
|
||||
if (ftMotion_stepCmdRdy) {
|
||||
ftMotion_stepper(ftMotion_applyDir, ftMotion_stepCmd);
|
||||
ftMotion_stepCmdRdy = false;
|
||||
}
|
||||
// Check if there is data in the buffers.
|
||||
if (fxdTiCtrl.stepperCmdBuff_produceIdx != fxdTiCtrl.stepperCmdBuff_consumeIdx) {
|
||||
if (ftMotion.stepperCmdBuff_produceIdx != ftMotion.stepperCmdBuff_consumeIdx) {
|
||||
|
||||
fxdTiCtrl.sts_stepperBusy = true;
|
||||
ftMotion.sts_stepperBusy = true;
|
||||
|
||||
// "Pop" one command from the command buffer.
|
||||
fxdTiCtrl_stepCmd = fxdTiCtrl.stepperCmdBuff[fxdTiCtrl.stepperCmdBuff_consumeIdx];
|
||||
const uint8_t dir_index = fxdTiCtrl.stepperCmdBuff_consumeIdx >> 3,
|
||||
dir_bit = fxdTiCtrl.stepperCmdBuff_consumeIdx & 0x7;
|
||||
fxdTiCtrl_applyDir = TEST(fxdTiCtrl.stepperCmdBuff_ApplyDir[dir_index], dir_bit);
|
||||
nextMainISR = fxdTiCtrl.stepperCmdBuff_StepRelativeTi[fxdTiCtrl.stepperCmdBuff_consumeIdx];
|
||||
fxdTiCtrl_stepCmdRdy = true;
|
||||
ftMotion_stepCmd = ftMotion.stepperCmdBuff[ftMotion.stepperCmdBuff_consumeIdx];
|
||||
const uint8_t dir_index = ftMotion.stepperCmdBuff_consumeIdx >> 3,
|
||||
dir_bit = ftMotion.stepperCmdBuff_consumeIdx & 0x7;
|
||||
ftMotion_applyDir = TEST(ftMotion.stepperCmdBuff_ApplyDir[dir_index], dir_bit);
|
||||
nextMainISR = ftMotion.stepperCmdBuff_StepRelativeTi[ftMotion.stepperCmdBuff_consumeIdx];
|
||||
ftMotion_stepCmdRdy = true;
|
||||
|
||||
if (++fxdTiCtrl.stepperCmdBuff_consumeIdx == (FTM_STEPPERCMD_BUFF_SIZE))
|
||||
fxdTiCtrl.stepperCmdBuff_consumeIdx = 0;
|
||||
if (++ftMotion.stepperCmdBuff_consumeIdx == (FTM_STEPPERCMD_BUFF_SIZE))
|
||||
ftMotion.stepperCmdBuff_consumeIdx = 0;
|
||||
|
||||
}
|
||||
else { // Buffer empty.
|
||||
fxdTiCtrl.sts_stepperBusy = false;
|
||||
ftMotion.sts_stepperBusy = false;
|
||||
nextMainISR = 0.01f * (STEPPER_TIMER_RATE); // Come back in 10 msec.
|
||||
}
|
||||
} // !(abort_current_block)
|
||||
} // if (!nextMainISR)
|
||||
|
||||
// Define 2.5 msec task for auxilliary functions.
|
||||
if (!fxdTiCtrl_nextAuxISR) {
|
||||
// Define 2.5 msec task for auxiliary functions.
|
||||
if (!ftMotion_nextAuxISR) {
|
||||
endstops.update();
|
||||
TERN_(BABYSTEPPING, if (babystep.has_steps()) babystepping_isr());
|
||||
fxdTiCtrl_refreshAxisDidMove();
|
||||
fxdTiCtrl_nextAuxISR = 0.0025f * (STEPPER_TIMER_RATE);
|
||||
ftMotion_refreshAxisDidMove();
|
||||
ftMotion_nextAuxISR = 0.0025f * (STEPPER_TIMER_RATE);
|
||||
}
|
||||
|
||||
interval = _MIN(nextMainISR, fxdTiCtrl_nextAuxISR);
|
||||
interval = _MIN(nextMainISR, ftMotion_nextAuxISR);
|
||||
nextMainISR -= interval;
|
||||
fxdTiCtrl_nextAuxISR -= interval;
|
||||
ftMotion_nextAuxISR -= interval;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
constexpr bool using_fxtictrl = false;
|
||||
|
||||
#endif
|
||||
|
||||
if (!using_fxtictrl) {
|
||||
if (!using_ftMotion) {
|
||||
|
||||
TERN_(HAS_ZV_SHAPING, shaping_isr()); // Do Shaper stepping, if needed
|
||||
|
||||
|
@ -3436,12 +3433,8 @@ void Stepper::report_a_position(const xyz_long_t &pos) {
|
|||
TERN(SAYS_A, PSTR(STR_COUNT_A), PSTR(STR_COUNT_X)), pos.x,
|
||||
TERN(SAYS_B, PSTR("B:"), SP_Y_LBL), pos.y,
|
||||
TERN(SAYS_C, PSTR("C:"), SP_Z_LBL), pos.z,
|
||||
SP_I_LBL, pos.i,
|
||||
SP_J_LBL, pos.j,
|
||||
SP_K_LBL, pos.k,
|
||||
SP_U_LBL, pos.u,
|
||||
SP_V_LBL, pos.v,
|
||||
SP_W_LBL, pos.w
|
||||
SP_I_LBL, pos.i, SP_J_LBL, pos.j, SP_K_LBL, pos.k,
|
||||
SP_U_LBL, pos.u, SP_V_LBL, pos.v, SP_W_LBL, pos.w
|
||||
)
|
||||
);
|
||||
#endif
|
||||
|
@ -3466,7 +3459,7 @@ void Stepper::report_positions() {
|
|||
#if ENABLED(FT_MOTION)
|
||||
|
||||
// Set stepper I/O for fixed time controller.
|
||||
void Stepper::fxdTiCtrl_stepper(const bool applyDir, const ft_command_t command) {
|
||||
void Stepper::ftMotion_stepper(const bool applyDir, const ft_command_t command) {
|
||||
|
||||
USING_TIMED_PULSE();
|
||||
|
||||
|
@ -3558,13 +3551,13 @@ void Stepper::report_positions() {
|
|||
if (axis_step.w) W_APPLY_STEP(!STEP_STATE_W, false)
|
||||
);
|
||||
|
||||
} // Stepper::fxdTiCtrl_stepper
|
||||
} // Stepper::ftMotion_stepper
|
||||
|
||||
void Stepper::fxdTiCtrl_BlockQueueUpdate() {
|
||||
void Stepper::ftMotion_BlockQueueUpdate() {
|
||||
|
||||
if (current_block) {
|
||||
// If the current block is not done processing, return right away
|
||||
if (!fxdTiCtrl.getBlockProcDn()) return;
|
||||
if (!ftMotion.getBlockProcDn()) return;
|
||||
|
||||
axis_did_move.reset();
|
||||
current_block = nullptr;
|
||||
|
@ -3591,21 +3584,21 @@ void Stepper::report_positions() {
|
|||
// update it here, even though it will may be out of sync with step commands
|
||||
last_direction_bits = current_block->direction_bits;
|
||||
|
||||
fxdTiCtrl.startBlockProc(current_block);
|
||||
ftMotion.startBlockProc(current_block);
|
||||
|
||||
}
|
||||
else {
|
||||
fxdTiCtrl.runoutBlock();
|
||||
ftMotion.runoutBlock();
|
||||
return; // No queued blocks
|
||||
}
|
||||
|
||||
} // if (!current_block)
|
||||
|
||||
} // Stepper::fxdTiCtrl_BlockQueueUpdate()
|
||||
} // Stepper::ftMotion_BlockQueueUpdate()
|
||||
|
||||
// Debounces the axis move indication to account for potential
|
||||
// delay between the block information and the stepper commands
|
||||
void Stepper::fxdTiCtrl_refreshAxisDidMove() {
|
||||
void Stepper::ftMotion_refreshAxisDidMove() {
|
||||
|
||||
// Set the debounce time in seconds.
|
||||
#define AXIS_DID_MOVE_DEB 5 // TODO: The debounce time should be calculated if possible,
|
||||
|
|
|
@ -294,7 +294,7 @@ constexpr ena_mask_t enable_overlap[] = {
|
|||
//
|
||||
class Stepper {
|
||||
friend class Max7219;
|
||||
friend class FxdTiCtrl;
|
||||
friend class FTMotion;
|
||||
friend void stepperTask(void *);
|
||||
|
||||
public:
|
||||
|
@ -535,7 +535,7 @@ class Stepper {
|
|||
if (current_block->is_page()) page_manager.free_page(current_block->page_idx);
|
||||
#endif
|
||||
current_block = nullptr;
|
||||
axis_did_move = 0;
|
||||
axis_did_move.reset();
|
||||
planner.release_current_block();
|
||||
TERN_(LIN_ADVANCE, la_interval = nextAdvanceISR = LA_ADV_NEVER);
|
||||
}
|
||||
|
@ -654,7 +654,7 @@ class Stepper {
|
|||
|
||||
#if ENABLED(FT_MOTION)
|
||||
// Manage the planner
|
||||
static void fxdTiCtrl_BlockQueueUpdate();
|
||||
static void ftMotion_BlockQueueUpdate();
|
||||
#endif
|
||||
|
||||
#if HAS_ZV_SHAPING
|
||||
|
@ -693,8 +693,8 @@ class Stepper {
|
|||
#endif
|
||||
|
||||
#if ENABLED(FT_MOTION)
|
||||
static void fxdTiCtrl_stepper(const bool applyDir, const ft_command_t command);
|
||||
static void fxdTiCtrl_refreshAxisDidMove();
|
||||
static void ftMotion_stepper(const bool applyDir, const ft_command_t command);
|
||||
static void ftMotion_refreshAxisDidMove();
|
||||
#endif
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue