Merge pull request #382 from wolfmanjm/upstreamedge
[clinton/Smoothieware.git] / src / modules / tools / endstops / Endstops.cpp
index b65b0f8..8afda5a 100644 (file)
 #include "libs/Pin.h"
 #include "libs/StepperMotor.h"
 #include "wait_api.h" // mbed.h lib
+#include "Robot.h"
+#include "Stepper.h"
+#include "Config.h"
+#include "SlowTicker.h"
+#include "Planner.h"
+#include "checksumm.h"
+#include "utils.h"
+#include "ConfigValue.h"
 
 #define ALPHA_AXIS 0
 #define BETA_AXIS  1
@@ -98,7 +106,7 @@ Endstops::Endstops()
 void Endstops::on_module_loaded()
 {
     // Do not do anything if not enabled
-    if ( this->kernel->config->value( endstops_module_enable_checksum )->by_default(true)->as_bool() == false ) {
+    if ( THEKERNEL->config->value( endstops_module_enable_checksum )->by_default(true)->as_bool() == false ) {
         return;
     }
 
@@ -106,79 +114,80 @@ void Endstops::on_module_loaded()
     this->register_for_event(ON_GCODE_RECEIVED);
 
     // Take StepperMotor objects from Robot and keep them here
-    this->steppers[0] = this->kernel->robot->alpha_stepper_motor;
-    this->steppers[1] = this->kernel->robot->beta_stepper_motor;
-    this->steppers[2] = this->kernel->robot->gamma_stepper_motor;
+    this->steppers[0] = THEKERNEL->robot->alpha_stepper_motor;
+    this->steppers[1] = THEKERNEL->robot->beta_stepper_motor;
+    this->steppers[2] = THEKERNEL->robot->gamma_stepper_motor;
+    THEKERNEL->slow_ticker->attach( THEKERNEL->stepper->acceleration_ticks_per_second , this, &Endstops::acceleration_tick );
 
     // Settings
     this->on_config_reload(this);
-
 }
 
 // Get config
 void Endstops::on_config_reload(void *argument)
 {
-    this->pins[0].from_string(         this->kernel->config->value(alpha_min_endstop_checksum          )->by_default("nc" )->as_string())->as_input();
-    this->pins[1].from_string(         this->kernel->config->value(beta_min_endstop_checksum           )->by_default("nc" )->as_string())->as_input();
-    this->pins[2].from_string(         this->kernel->config->value(gamma_min_endstop_checksum          )->by_default("nc" )->as_string())->as_input();
-    this->pins[3].from_string(         this->kernel->config->value(alpha_max_endstop_checksum          )->by_default("nc" )->as_string())->as_input();
-    this->pins[4].from_string(         this->kernel->config->value(beta_max_endstop_checksum           )->by_default("nc" )->as_string())->as_input();
-    this->pins[5].from_string(         this->kernel->config->value(gamma_max_endstop_checksum          )->by_default("nc" )->as_string())->as_input();
+    this->pins[0].from_string(         THEKERNEL->config->value(alpha_min_endstop_checksum          )->by_default("nc" )->as_string())->as_input();
+    this->pins[1].from_string(         THEKERNEL->config->value(beta_min_endstop_checksum           )->by_default("nc" )->as_string())->as_input();
+    this->pins[2].from_string(         THEKERNEL->config->value(gamma_min_endstop_checksum          )->by_default("nc" )->as_string())->as_input();
+    this->pins[3].from_string(         THEKERNEL->config->value(alpha_max_endstop_checksum          )->by_default("nc" )->as_string())->as_input();
+    this->pins[4].from_string(         THEKERNEL->config->value(beta_max_endstop_checksum           )->by_default("nc" )->as_string())->as_input();
+    this->pins[5].from_string(         THEKERNEL->config->value(gamma_max_endstop_checksum          )->by_default("nc" )->as_string())->as_input();
 
     // we need to know steps per mm for M206, also use them for all settings
-    this->steps_per_mm[0]           =  this->kernel->config->value(alpha_steps_per_mm_checksum         )->as_number();
-    this->steps_per_mm[1]           =  this->kernel->config->value(beta_steps_per_mm_checksum          )->as_number();
-    this->steps_per_mm[2]           =  this->kernel->config->value(gamma_steps_per_mm_checksum         )->as_number();
-
-    this->fast_rates[0]             =  this->kernel->config->value(alpha_fast_homing_rate_checksum     )->by_default(4000 )->as_number();
-    this->fast_rates[1]             =  this->kernel->config->value(beta_fast_homing_rate_checksum      )->by_default(4000 )->as_number();
-    this->fast_rates[2]             =  this->kernel->config->value(gamma_fast_homing_rate_checksum     )->by_default(6400 )->as_number();
-    this->slow_rates[0]             =  this->kernel->config->value(alpha_slow_homing_rate_checksum     )->by_default(2000 )->as_number();
-    this->slow_rates[1]             =  this->kernel->config->value(beta_slow_homing_rate_checksum      )->by_default(2000 )->as_number();
-    this->slow_rates[2]             =  this->kernel->config->value(gamma_slow_homing_rate_checksum     )->by_default(3200 )->as_number();
-    this->retract_steps[0]          =  this->kernel->config->value(alpha_homing_retract_checksum       )->by_default(400  )->as_number();
-    this->retract_steps[1]          =  this->kernel->config->value(beta_homing_retract_checksum        )->by_default(400  )->as_number();
-    this->retract_steps[2]          =  this->kernel->config->value(gamma_homing_retract_checksum       )->by_default(1600 )->as_number();
+    this->steps_per_mm[0]           =  THEKERNEL->config->value(alpha_steps_per_mm_checksum         )->as_number();
+    this->steps_per_mm[1]           =  THEKERNEL->config->value(beta_steps_per_mm_checksum          )->as_number();
+    this->steps_per_mm[2]           =  THEKERNEL->config->value(gamma_steps_per_mm_checksum         )->as_number();
+
+    //These are the old ones in steps still here for backwards compatibility
+    this->fast_rates[0]             =  THEKERNEL->config->value(alpha_fast_homing_rate_checksum     )->by_default(4000 )->as_number();
+    this->fast_rates[1]             =  THEKERNEL->config->value(beta_fast_homing_rate_checksum      )->by_default(4000 )->as_number();
+    this->fast_rates[2]             =  THEKERNEL->config->value(gamma_fast_homing_rate_checksum     )->by_default(6400 )->as_number();
+    this->slow_rates[0]             =  THEKERNEL->config->value(alpha_slow_homing_rate_checksum     )->by_default(2000 )->as_number();
+    this->slow_rates[1]             =  THEKERNEL->config->value(beta_slow_homing_rate_checksum      )->by_default(2000 )->as_number();
+    this->slow_rates[2]             =  THEKERNEL->config->value(gamma_slow_homing_rate_checksum     )->by_default(3200 )->as_number();
+    this->retract_steps[0]          =  THEKERNEL->config->value(alpha_homing_retract_checksum       )->by_default(400  )->as_number();
+    this->retract_steps[1]          =  THEKERNEL->config->value(beta_homing_retract_checksum        )->by_default(400  )->as_number();
+    this->retract_steps[2]          =  THEKERNEL->config->value(gamma_homing_retract_checksum       )->by_default(1600 )->as_number();
 
     // newer mm based config values override the old ones, convert to steps/mm and steps, defaults to what was set in the older config settings above
-    this->fast_rates[0] =    this->kernel->config->value(alpha_fast_homing_rate_mm_checksum )->by_default(this->fast_rates[0]  / steps_per_mm[0])->as_number() * steps_per_mm[0];
-    this->fast_rates[1] =    this->kernel->config->value(beta_fast_homing_rate_mm_checksum  )->by_default(this->fast_rates[1]  / steps_per_mm[1])->as_number() * steps_per_mm[1];
-    this->fast_rates[2] =    this->kernel->config->value(gamma_fast_homing_rate_mm_checksum )->by_default(this->fast_rates[2]  / steps_per_mm[2])->as_number() * steps_per_mm[2];
-    this->slow_rates[0] =    this->kernel->config->value(alpha_slow_homing_rate_mm_checksum )->by_default(this->slow_rates[0]  / steps_per_mm[0])->as_number() * steps_per_mm[0];
-    this->slow_rates[1] =    this->kernel->config->value(beta_slow_homing_rate_mm_checksum  )->by_default(this->slow_rates[1]  / steps_per_mm[1])->as_number() * steps_per_mm[1];
-    this->slow_rates[2] =    this->kernel->config->value(gamma_slow_homing_rate_mm_checksum )->by_default(this->slow_rates[2]  / steps_per_mm[2])->as_number() * steps_per_mm[2];
-    this->retract_steps[0] = this->kernel->config->value(alpha_homing_retract_mm_checksum   )->by_default(this->retract_steps[0] / steps_per_mm[0])->as_number() * steps_per_mm[0];
-    this->retract_steps[1] = this->kernel->config->value(beta_homing_retract_mm_checksum    )->by_default(this->retract_steps[1] / steps_per_mm[1])->as_number() * steps_per_mm[1];
-    this->retract_steps[2] = this->kernel->config->value(gamma_homing_retract_mm_checksum   )->by_default(this->retract_steps[2] / steps_per_mm[2])->as_number() * steps_per_mm[2];
+    this->fast_rates[0] =    THEKERNEL->config->value(alpha_fast_homing_rate_mm_checksum )->by_default(this->fast_rates[0]  / steps_per_mm[0])->as_number() * steps_per_mm[0];
+    this->fast_rates[1] =    THEKERNEL->config->value(beta_fast_homing_rate_mm_checksum  )->by_default(this->fast_rates[1]  / steps_per_mm[1])->as_number() * steps_per_mm[1];
+    this->fast_rates[2] =    THEKERNEL->config->value(gamma_fast_homing_rate_mm_checksum )->by_default(this->fast_rates[2]  / steps_per_mm[2])->as_number() * steps_per_mm[2];
+    this->slow_rates[0] =    THEKERNEL->config->value(alpha_slow_homing_rate_mm_checksum )->by_default(this->slow_rates[0]  / steps_per_mm[0])->as_number() * steps_per_mm[0];
+    this->slow_rates[1] =    THEKERNEL->config->value(beta_slow_homing_rate_mm_checksum  )->by_default(this->slow_rates[1]  / steps_per_mm[1])->as_number() * steps_per_mm[1];
+    this->slow_rates[2] =    THEKERNEL->config->value(gamma_slow_homing_rate_mm_checksum )->by_default(this->slow_rates[2]  / steps_per_mm[2])->as_number() * steps_per_mm[2];
+    this->retract_steps[0] = THEKERNEL->config->value(alpha_homing_retract_mm_checksum   )->by_default(this->retract_steps[0] / steps_per_mm[0])->as_number() * steps_per_mm[0];
+    this->retract_steps[1] = THEKERNEL->config->value(beta_homing_retract_mm_checksum    )->by_default(this->retract_steps[1] / steps_per_mm[1])->as_number() * steps_per_mm[1];
+    this->retract_steps[2] = THEKERNEL->config->value(gamma_homing_retract_mm_checksum   )->by_default(this->retract_steps[2] / steps_per_mm[2])->as_number() * steps_per_mm[2];
 
-    this->debounce_count  = this->kernel->config->value(endstop_debounce_count_checksum    )->by_default(0)->as_number();
+    this->debounce_count  = THEKERNEL->config->value(endstop_debounce_count_checksum    )->by_default(0)->as_number();
 
 
     // get homing direction and convert to boolean where true is home to min, and false is home to max
-    int home_dir                    = get_checksum(this->kernel->config->value(alpha_homing_direction_checksum)->by_default("home_to_min")->as_string());
+    int home_dir                    = get_checksum(THEKERNEL->config->value(alpha_homing_direction_checksum)->by_default("home_to_min")->as_string());
     this->home_direction[0]         = home_dir != home_to_max_checksum;
 
-    home_dir                        = get_checksum(this->kernel->config->value(beta_homing_direction_checksum)->by_default("home_to_min")->as_string());
+    home_dir                        = get_checksum(THEKERNEL->config->value(beta_homing_direction_checksum)->by_default("home_to_min")->as_string());
     this->home_direction[1]         = home_dir != home_to_max_checksum;
 
-    home_dir                        = get_checksum(this->kernel->config->value(gamma_homing_direction_checksum)->by_default("home_to_min")->as_string());
+    home_dir                        = get_checksum(THEKERNEL->config->value(gamma_homing_direction_checksum)->by_default("home_to_min")->as_string());
     this->home_direction[2]         = home_dir != home_to_max_checksum;
 
-    this->homing_position[0]        =  this->home_direction[0] ? this->kernel->config->value(alpha_min_checksum)->by_default(0)->as_number() : this->kernel->config->value(alpha_max_checksum)->by_default(200)->as_number();
-    this->homing_position[1]        =  this->home_direction[1] ? this->kernel->config->value(beta_min_checksum )->by_default(0)->as_number() : this->kernel->config->value(beta_max_checksum )->by_default(200)->as_number();;
-    this->homing_position[2]        =  this->home_direction[2] ? this->kernel->config->value(gamma_min_checksum)->by_default(0)->as_number() : this->kernel->config->value(gamma_max_checksum)->by_default(200)->as_number();;
+    this->homing_position[0]        =  this->home_direction[0] ? THEKERNEL->config->value(alpha_min_checksum)->by_default(0)->as_number() : THEKERNEL->config->value(alpha_max_checksum)->by_default(200)->as_number();
+    this->homing_position[1]        =  this->home_direction[1] ? THEKERNEL->config->value(beta_min_checksum )->by_default(0)->as_number() : THEKERNEL->config->value(beta_max_checksum )->by_default(200)->as_number();;
+    this->homing_position[2]        =  this->home_direction[2] ? THEKERNEL->config->value(gamma_min_checksum)->by_default(0)->as_number() : THEKERNEL->config->value(gamma_max_checksum)->by_default(200)->as_number();;
 
-    this->is_corexy                 =  this->kernel->config->value(corexy_homing_checksum)->by_default(false)->as_bool();
-    this->is_delta                  =  this->kernel->config->value(delta_homing_checksum)->by_default(false)->as_bool();
+    this->is_corexy                 =  THEKERNEL->config->value(corexy_homing_checksum)->by_default(false)->as_bool();
+    this->is_delta                  =  THEKERNEL->config->value(delta_homing_checksum)->by_default(false)->as_bool();
 
     // endstop trim used by deltas to do soft adjusting, in mm, convert to steps, and negate depending on homing direction
     // eg on a delta homing to max, a negative trim value will move the carriage down, and a positive will move it up
     int dirx = (this->home_direction[0] ? 1 : -1);
     int diry = (this->home_direction[1] ? 1 : -1);
     int dirz = (this->home_direction[2] ? 1 : -1);
-    this->trim[0] = this->kernel->config->value(alpha_trim_checksum )->by_default(0  )->as_number() * steps_per_mm[0] * dirx;
-    this->trim[1] = this->kernel->config->value(beta_trim_checksum  )->by_default(0  )->as_number() * steps_per_mm[1] * diry;
-    this->trim[2] = this->kernel->config->value(gamma_trim_checksum )->by_default(0  )->as_number() * steps_per_mm[2] * dirz;
+    this->trim[0] = THEKERNEL->config->value(alpha_trim_checksum )->by_default(0  )->as_number() * steps_per_mm[0] * dirx;
+    this->trim[1] = THEKERNEL->config->value(beta_trim_checksum  )->by_default(0  )->as_number() * steps_per_mm[1] * diry;
+    this->trim[2] = THEKERNEL->config->value(gamma_trim_checksum )->by_default(0  )->as_number() * steps_per_mm[2] * dirz;
 }
 
 void Endstops::wait_for_homed(char axes_to_move)
@@ -187,7 +196,7 @@ void Endstops::wait_for_homed(char axes_to_move)
     unsigned int debounce[3] = {0, 0, 0};
     while (running) {
         running = false;
-        this->kernel->call_event(ON_IDLE);
+        THEKERNEL->call_event(ON_IDLE);
         for ( char c = 'X'; c <= 'Z'; c++ ) {
             if ( ( axes_to_move >> ( c - 'X' ) ) & 1 ) {
                 if ( this->pins[c - 'X' + (this->home_direction[c - 'X'] ? 0 : 3)].get() ) {
@@ -214,7 +223,8 @@ void Endstops::do_homing(char axes_to_move)
     this->status = MOVING_TO_ORIGIN_FAST;
     for ( char c = 'X'; c <= 'Z'; c++ ) {
         if ( ( axes_to_move >> ( c - 'X' ) ) & 1 ) {
-            this->steppers[c - 'X']->set_speed(this->fast_rates[c - 'X']);
+            this->feed_rate[c - 'X']= this->fast_rates[c - 'X'];
+            this->steppers[c - 'X']->set_speed(0);
             this->steppers[c - 'X']->move(this->home_direction[c - 'X'], 10000000);
         }
     }
@@ -228,7 +238,8 @@ void Endstops::do_homing(char axes_to_move)
     for ( char c = 'X'; c <= 'Z'; c++ ) {
         if ( ( axes_to_move >> ( c - 'X' ) ) & 1 ) {
             inverted_dir = !this->home_direction[c - 'X'];
-            this->steppers[c - 'X']->set_speed(this->slow_rates[c - 'X']);
+            this->feed_rate[c - 'X']= this->slow_rates[c - 'X'];
+            this->steppers[c - 'X']->set_speed(0);
             this->steppers[c - 'X']->move(inverted_dir, this->retract_steps[c - 'X']);
         }
     }
@@ -237,7 +248,7 @@ void Endstops::do_homing(char axes_to_move)
     for ( char c = 'X'; c <= 'Z'; c++ ) {
         if (  ( axes_to_move >> ( c - 'X' ) ) & 1 ) {
             while ( this->steppers[c - 'X']->moving ) {
-                this->kernel->call_event(ON_IDLE);
+                THEKERNEL->call_event(ON_IDLE);
             }
         }
     }
@@ -246,7 +257,8 @@ void Endstops::do_homing(char axes_to_move)
     this->status = MOVING_TO_ORIGIN_SLOW;
     for ( char c = 'X'; c <= 'Z'; c++ ) {
         if ( ( axes_to_move >> ( c - 'X' ) ) & 1 ) {
-            this->steppers[c - 'X']->set_speed(this->slow_rates[c - 'X']);
+            this->feed_rate[c - 'X']= this->slow_rates[c - 'X'];
+            this->steppers[c - 'X']->set_speed(0);
             this->steppers[c - 'X']->move(this->home_direction[c - 'X'], 10000000);
         }
     }
@@ -262,17 +274,18 @@ void Endstops::do_homing(char axes_to_move)
                 inverted_dir = !this->home_direction[c - 'X'];
                 // move up or down depending on sign of trim
                 if (this->trim[c - 'X'] < 0) inverted_dir = !inverted_dir;
-                this->steppers[c - 'X']->set_speed(this->slow_rates[c - 'X']);
-                this->steppers[c - 'X']->move(inverted_dir, this->trim[c - 'X']);
+                this->feed_rate[c - 'X']= this->slow_rates[c - 'X'];
+                this->steppers[c - 'X']->set_speed(0);
+                this->steppers[c - 'X']->move(inverted_dir, abs(this->trim[c - 'X']));
             }
         }
 
         // Wait for moves to be done
         for ( char c = 'X'; c <= 'Z'; c++ ) {
             if (  ( axes_to_move >> ( c - 'X' ) ) & 1 ) {
-                //this->kernel->streams->printf("axis %c \r\n", c );
+                //THEKERNEL->streams->printf("axis %c \r\n", c );
                 while ( this->steppers[c - 'X']->moving ) {
-                    this->kernel->call_event(ON_IDLE);
+                    THEKERNEL->call_event(ON_IDLE);
                 }
             }
         }
@@ -288,7 +301,7 @@ void Endstops::wait_for_homed_corexy(int axis)
     unsigned int debounce[3] = {0, 0, 0};
     while (running) {
         running = false;
-        this->kernel->call_event(ON_IDLE);
+        THEKERNEL->call_event(ON_IDLE);
         if ( this->pins[axis + (this->home_direction[axis] ? 0 : 3)].get() ) {
             if ( debounce[axis] < debounce_count ) {
                 debounce[axis] ++;
@@ -306,12 +319,14 @@ void Endstops::wait_for_homed_corexy(int axis)
     }
 }
 
-void Endstops::corexy_home(int home_axis, bool dirx, bool diry, double fast_rate, double slow_rate, unsigned int retract_steps)
+void Endstops::corexy_home(int home_axis, bool dirx, bool diry, float fast_rate, float slow_rate, unsigned int retract_steps)
 {
     this->status = MOVING_TO_ORIGIN_FAST;
-    this->steppers[X_AXIS]->set_speed(fast_rate);
+    this->feed_rate[X_AXIS]= fast_rate;
+    this->steppers[X_AXIS]->set_speed(0);
     this->steppers[X_AXIS]->move(dirx, 10000000);
-    this->steppers[Y_AXIS]->set_speed(fast_rate);
+    this->feed_rate[Y_AXIS]= fast_rate;
+    this->steppers[Y_AXIS]->set_speed(0);
     this->steppers[Y_AXIS]->move(diry, 10000000);
 
     // wait for primary axis
@@ -319,21 +334,25 @@ void Endstops::corexy_home(int home_axis, bool dirx, bool diry, double fast_rate
 
     // Move back a small distance
     this->status = MOVING_BACK;
-    this->steppers[X_AXIS]->set_speed(slow_rate);
+    this->feed_rate[X_AXIS]= slow_rate;
+    this->steppers[X_AXIS]->set_speed(0);
     this->steppers[X_AXIS]->move(!dirx, retract_steps);
-    this->steppers[Y_AXIS]->set_speed(slow_rate);
+    this->feed_rate[Y_AXIS]= slow_rate;
+    this->steppers[Y_AXIS]->set_speed(0);
     this->steppers[Y_AXIS]->move(!diry, retract_steps);
 
     // wait until done
     while ( this->steppers[X_AXIS]->moving || this->steppers[Y_AXIS]->moving) {
-        this->kernel->call_event(ON_IDLE);
+        THEKERNEL->call_event(ON_IDLE);
     }
 
     // Start moving the axes to the origin slowly
     this->status = MOVING_TO_ORIGIN_SLOW;
-    this->steppers[X_AXIS]->set_speed(slow_rate);
+    this->feed_rate[X_AXIS]= slow_rate;
+    this->steppers[X_AXIS]->set_speed(0);
     this->steppers[X_AXIS]->move(dirx, 10000000);
-    this->steppers[Y_AXIS]->set_speed(slow_rate);
+    this->feed_rate[Y_AXIS]= slow_rate;
+    this->steppers[Y_AXIS]->set_speed(0);
     this->steppers[Y_AXIS]->move(diry, 10000000);
 
     // wait for primary axis
@@ -343,9 +362,9 @@ void Endstops::corexy_home(int home_axis, bool dirx, bool diry, double fast_rate
 // this homing works for HBots/CoreXY
 void Endstops::do_homing_corexy(char axes_to_move)
 {
-    // TODO should really make order configurable, and selectr whether to allow XY to home at the same time, diagonally
+    // TODO should really make order configurable, and select whether to allow XY to home at the same time, diagonally
     // To move XY at the same time only one motor needs to turn, determine which motor and which direction based on min or max directions
-    // allow to move until an endstop triggers, then stop that motor.
+    // allow to move until an endstop triggers, then stop that motor. Speed up when moving diagonally to match X or Y speed
     // continue moving in the direction not yet triggered (which means two motors turning) until endstop hit
 
     if((axes_to_move & 0x03) == 0x03) { // both X and Y need Homing
@@ -370,12 +389,13 @@ void Endstops::do_homing_corexy(char axes_to_move)
 
         // then move both X and Y until one hits the endstop
         this->status = MOVING_TO_ORIGIN_FAST;
-        this->steppers[motor]->set_speed(this->fast_rates[motor]);
+        this->feed_rate[motor]= this->fast_rates[motor]*1.4142;
+        this->steppers[motor]->set_speed(0); // need to allow for more ground covered when moving diagonally
         this->steppers[motor]->move(dir, 10000000);
         // wait until either X or Y hits the endstop
         bool running= true;
         while (running) {
-            this->kernel->call_event(ON_IDLE);
+            THEKERNEL->call_event(ON_IDLE);
             for(int m=X_AXIS;m<=Y_AXIS;m++) {
                 if(this->pins[m + (this->home_direction[m] ? 0 : 3)].get()) {
                     // turn off motor
@@ -416,7 +436,7 @@ void Endstops::on_gcode_received(void *argument)
             // G28 is received, we have homing to do
 
             // First wait for the queue to be empty
-            this->kernel->conveyor->wait_for_empty_queue();
+            THEKERNEL->conveyor->wait_for_empty_queue();
 
             // Do we move select axes or all of them
             char axes_to_move = 0;
@@ -430,7 +450,7 @@ void Endstops::on_gcode_received(void *argument)
             }
 
             // Enable the motors
-            this->kernel->stepper->turn_enable_pins_on();
+            THEKERNEL->stepper->turn_enable_pins_on();
 
             // do the actual homing
             if (is_corexy)
@@ -441,7 +461,7 @@ void Endstops::on_gcode_received(void *argument)
             // Zero the ax(i/e)s position, add in the home offset
             for ( int c = 0; c <= 2; c++ ) {
                 if ( (axes_to_move >> c)  & 1 ) {
-                    this->kernel->robot->reset_axis_position(this->homing_position[c] + this->home_offset[c], c);
+                    THEKERNEL->robot->reset_axis_position(this->homing_position[c] + this->home_offset[c], c);
                 }
             }
         }
@@ -456,7 +476,8 @@ void Endstops::on_gcode_received(void *argument)
                 const char *my = this->home_direction[1] ? "min" : "max";
                 const char *mz = this->home_direction[2] ? "min" : "max";
 
-                gcode->stream->printf("X %s:%d Y %s:%d Z %s:%d\n", mx, this->pins[px].get(), my, this->pins[py].get(), mz, this->pins[pz].get());
+                gcode->stream->printf("X %s:%d Y %s:%d Z %s:%d", mx, this->pins[px].get(), my, this->pins[py].get(), mz, this->pins[pz].get());
+                gcode->add_nl= true;
                 gcode->mark_as_taken();
             }
             break;
@@ -473,7 +494,7 @@ void Endstops::on_gcode_received(void *argument)
             case 503: // print settings
                 gcode->stream->printf(";Home offset (mm):\nM206 X%1.2f Y%1.2f Z%1.2f\n", home_offset[0], home_offset[1], home_offset[2]);
                 if (is_delta) {
-                    double mm[3];
+                    float mm[3];
                     trim2mm(mm);
                     gcode->stream->printf(";Trim (mm):\nM666 X%1.2f Y%1.2f Z%1.2f\n", mm[0], mm[1], mm[2]);
                     gcode->stream->printf(";Max Z\nM665 Z%1.2f\n", this->homing_position[2]);
@@ -483,7 +504,7 @@ void Endstops::on_gcode_received(void *argument)
 
             case 665: { // M665 - set max gamma/z height
                 gcode->mark_as_taken();
-                double gamma_max = this->homing_position[2];
+                float gamma_max = this->homing_position[2];
                 if (gcode->has_letter('Z')) {
                     this->homing_position[2] = gamma_max = gcode->get_value('Z');
                 }
@@ -493,8 +514,8 @@ void Endstops::on_gcode_received(void *argument)
             break;
 
 
-            case 666: { // M666 - set trim for each axis in mm
-                double mm[3];
+            case 666: { // M666 - set trim for each axis in mm, NB negative mm and positive steps trim is down
+                float mm[3];
                 trim2mm(mm);
 
                 if (gcode->has_letter('X')) mm[0] = gcode->get_value('X');
@@ -541,7 +562,7 @@ void Endstops::on_gcode_received(void *argument)
     }
 }
 
-void Endstops::trim2mm(double *mm)
+void Endstops::trim2mm(float *mm)
 {
     int dirx = (this->home_direction[0] ? 1 : -1);
     int diry = (this->home_direction[1] ? 1 : -1);
@@ -552,3 +573,28 @@ void Endstops::trim2mm(double *mm)
     mm[2] = this->trim[2] / this->steps_per_mm[2] * dirz;
 }
 
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+// Called periodically to change the speed to match acceleration
+uint32_t Endstops::acceleration_tick(uint32_t dummy)
+{
+    if(this->status == NOT_HOMING) return(0); // nothing to do
+
+    // foreach stepper that is moving
+    for ( int c = X_AXIS; c <= Z_AXIS; c++ ) {
+        if( !this->steppers[c]->moving ) continue;
+
+        uint32_t current_rate = this->steppers[c]->steps_per_second;
+        uint32_t target_rate = int(floor(this->feed_rate[c]));
+
+        if( current_rate < target_rate ){
+            uint32_t rate_increase = int(floor((THEKERNEL->planner->acceleration/THEKERNEL->stepper->acceleration_ticks_per_second)*this->steps_per_mm[c]));
+            current_rate = min( target_rate, current_rate + rate_increase );
+        }
+        if( current_rate > target_rate ){ current_rate = target_rate; }
+
+        // steps per second
+        this->steppers[c]->set_speed(max(current_rate, THEKERNEL->stepper->minimum_steps_per_second));
+    }
+
+    return 0;
+}