Skip to content

Commit

Permalink
Do BABYSTEPPING in stepper ISR
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkyhead committed Feb 16, 2020
1 parent 64b96f3 commit fefdbed
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 6 deletions.
1 change: 1 addition & 0 deletions Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1447,6 +1447,7 @@
*/
//#define BABYSTEPPING
#if ENABLED(BABYSTEPPING)
//#define INTEGRATED_BABYSTEPPING // EXPERIMENTAL integration of babystepping into the Stepper ISR
//#define BABYSTEP_WITHOUT_HOMING
//#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA!
#define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way
Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/feature/babystep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ void Babystep::add_steps(const AxisEnum axis, const int16_t distance) {
#if ENABLED(BABYSTEP_ALWAYS_AVAILABLE)
gcode.reset_stepper_timeout();
#endif

#if ENABLED(INTEGRATED_BABYSTEPPING)
if (has_steps()) stepper.initiateBabystepping();
#endif
}

#endif // BABYSTEPPING
14 changes: 13 additions & 1 deletion Marlin/src/feature/babystep.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@

#include "../inc/MarlinConfigPre.h"

#if ENABLED(INTEGRATED_BABYSTEPPING)
#define BABYSTEPS_PER_SEC 1000UL
#define BABYSTEP_TICKS ((STEPPER_TIMER_RATE) / (BABYSTEPS_PER_SEC))
#else
#define BABYSTEPS_PER_SEC 976UL
#define BABYSTEP_TICKS ((TEMP_TIMER_RATE) / (BABYSTEPS_PER_SEC))
#endif

#if IS_CORE || EITHER(BABYSTEP_XY, I2C_POSITION_ENCODERS)
#define BS_TODO_AXIS(A) A
#else
Expand Down Expand Up @@ -56,8 +64,12 @@ class Babystep {
static void add_steps(const AxisEnum axis, const int16_t distance);
static void add_mm(const AxisEnum axis, const float &mm);

static inline bool has_steps() {
return steps[BS_TODO_AXIS(X_AXIS)] || steps[BS_TODO_AXIS(Y_AXIS)] || steps[BS_TODO_AXIS(Z_AXIS)];
}

//
// Called by the Temperature ISR to
// Called by the Temperature or Stepper ISR to
// apply accumulated babysteps to the axes.
//
static inline void task() {
Expand Down
45 changes: 42 additions & 3 deletions Marlin/src/module/stepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ uint32_t Stepper::advance_divisor = 0,

#endif // LIN_ADVANCE

#if ENABLED(INTEGRATED_BABYSTEPPING)
uint32_t Stepper::nextBabystepISR = BABYSTEP_NEVER;
#endif

int32_t Stepper::ticks_nominal = -1;
#if DISABLED(S_CURVE_ACCELERATION)
uint32_t Stepper::acc_step_rate; // needed for deceleration start point
Expand Down Expand Up @@ -1358,16 +1362,32 @@ void Stepper::isr() {
if (!nextAdvanceISR) nextAdvanceISR = advance_isr(); // 0 = Do Linear Advance E Stepper pulses
#endif

#if ENABLED(INTEGRATED_BABYSTEPPING)
const bool do_babystep = (nextBabystepISR == 0); // 0 = Do Babystepping (XY)Z pulses
if (do_babystep) nextBabystepISR = babystepping_isr();
#endif

// ^== Time critical. NOTHING besides pulse generation should be above here!!!

if (!nextMainISR) nextMainISR = block_phase_isr(); // Manage acc/deceleration, get next block

#if ENABLED(INTEGRATED_BABYSTEPPING)
if (do_babystep) // Avoid ANY stepping too soon after baby-stepping
NOLESS(nextMainISR, (BABYSTEP_TICKS) / 8) // FULL STOP for 125µs after a baby-step

if (nextBabystepISR != BABYSTEP_NEVER) // Avoid baby-stepping too close to axis Stepping
NOLESS(nextBabystepISR, nextMainISR / 2) // TODO: Only look at axes enabled for baby-stepping
#endif

// Get the interval to the next ISR call
const uint32_t interval = _MIN(
nextMainISR // Time until the next Stepper ISR
nextMainISR // Time until the next Pulse / Block phase
#if ENABLED(LIN_ADVANCE)
, nextAdvanceISR // Come back early for Linear Advance?
#endif
#if ENABLED(INTEGRATED_BABYSTEPPING)
, nextBabystepISR // Come back early for Babystepping?
#endif
, uint32_t(HAL_TIMER_TYPE_MAX) // Come back in a very long time
);

Expand All @@ -1384,6 +1404,10 @@ void Stepper::isr() {
if (nextAdvanceISR != LA_ADV_NEVER) nextAdvanceISR -= interval;
#endif

#if ENABLED(INTEGRATED_BABYSTEPPING)
if (nextBabystepISR != BABYSTEP_NEVER) nextBabystepISR -= interval;
#endif

/**
* This needs to avoid a race-condition caused by interleaving
* of interrupts required by both the LA and Stepper algorithms.
Expand Down Expand Up @@ -2043,6 +2067,16 @@ uint32_t Stepper::block_phase_isr() {

#endif // LIN_ADVANCE

#if ENABLED(INTEGRATED_BABYSTEPPING)

// Timer interrupt for baby-stepping
uint32_t Stepper::babystepping_isr() {
babystep.task();
return babystep.has_steps() ? BABYSTEP_TICKS : BABYSTEP_NEVER;
}

#endif

// Check if the given block is busy or not - Must not be called from ISR contexts
// The current_block could change in the middle of the read by an Stepper ISR, so
// we must explicitly prevent that!
Expand Down Expand Up @@ -2511,7 +2545,10 @@ void Stepper::report_positions() {
// MUST ONLY BE CALLED BY AN ISR,
// No other ISR should ever interrupt this!
void Stepper::babystep(const AxisEnum axis, const bool direction) {
cli();

#if DISABLED(INTEGRATED_BABYSTEPPING)
cli();
#endif

switch (axis) {

Expand Down Expand Up @@ -2594,7 +2631,9 @@ void Stepper::report_positions() {
default: break;
}

sei();
#if DISABLED(INTEGRATED_BABYSTEPPING)
sei();
#endif
}

#endif // BABYSTEPPING
Expand Down
16 changes: 16 additions & 0 deletions Marlin/src/module/stepper.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@ class Stepper {
static bool LA_use_advance_lead;
#endif

#if ENABLED(INTEGRATED_BABYSTEPPING)
static constexpr uint32_t BABYSTEP_NEVER = 0xFFFFFFFF;
static uint32_t nextBabystepISR;
#endif

static int32_t ticks_nominal;
#if DISABLED(S_CURVE_ACCELERATION)
static uint32_t acc_step_rate; // needed for deceleration start point
Expand Down Expand Up @@ -383,6 +388,17 @@ class Stepper {
FORCE_INLINE static void initiateLA() { nextAdvanceISR = 0; }
#endif

#if ENABLED(INTEGRATED_BABYSTEPPING)
// The Babystepping ISR phase
static uint32_t babystepping_isr();
FORCE_INLINE static void initiateBabystepping() {
if (nextBabystepISR == BABYSTEP_NEVER) {
nextBabystepISR = 0;
wake_up();
}
}
#endif

// Check if the given block is busy or not - Must not be called from ISR contexts
static bool is_block_busy(const block_t* const block);

Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/module/temperature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
#include "stepper.h"
#endif

#if ENABLED(BABYSTEPPING)
#if ENABLED(BABYSTEPPING) && DISABLED(INTEGRATED_BABYSTEPPING)
#include "../feature/babystep.h"
#endif

Expand Down Expand Up @@ -3010,7 +3010,7 @@ void Temperature::tick() {
// Additional ~1KHz Tasks
//

#if ENABLED(BABYSTEPPING)
#if ENABLED(BABYSTEPPING) && DISABLED(INTEGRATED_BABYSTEPPING)
babystep.task();
#endif

Expand Down

0 comments on commit fefdbed

Please sign in to comment.