From 470d5ac09f5b5fa54b3961944e9ba0ae2bbbbefa Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 26 May 2016 11:22:51 -0700
Subject: [PATCH 1/2] Apply static to Planner class

---
 Marlin/planner.cpp |  58 +++++++++++++++++++++++
 Marlin/planner.h   | 116 ++++++++++++++++++++++++---------------------
 2 files changed, 120 insertions(+), 54 deletions(-)

diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp
index 05a3c7174e..3627f27612 100644
--- a/Marlin/planner.cpp
+++ b/Marlin/planner.cpp
@@ -71,6 +71,64 @@
 
 Planner planner;
 
+  // public:
+
+/**
+ * A ring buffer of moves described in steps
+ */
+block_t Planner::block_buffer[BLOCK_BUFFER_SIZE];
+volatile uint8_t Planner::block_buffer_head = 0;           // Index of the next block to be pushed
+volatile uint8_t Planner::block_buffer_tail = 0;
+
+float Planner::max_feedrate[NUM_AXIS]; // Max speeds in mm per minute
+float Planner::axis_steps_per_unit[NUM_AXIS];
+unsigned long Planner::axis_steps_per_sqr_second[NUM_AXIS];
+unsigned long Planner::max_acceleration_units_per_sq_second[NUM_AXIS]; // Use M201 to override by software
+
+millis_t Planner::min_segment_time;
+float Planner::min_feedrate;
+float Planner::acceleration;         // Normal acceleration mm/s^2  DEFAULT ACCELERATION for all printing moves. M204 SXXXX
+float Planner::retract_acceleration; // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX
+float Planner::travel_acceleration;  // Travel acceleration mm/s^2  DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX
+float Planner::max_xy_jerk;          // The largest speed change requiring no acceleration
+float Planner::max_z_jerk;
+float Planner::max_e_jerk;
+float Planner::min_travel_feedrate;
+
+#if ENABLED(AUTO_BED_LEVELING_FEATURE)
+  matrix_3x3 Planner::bed_level_matrix; // Transform to compensate for bed level
+#endif
+
+#if ENABLED(AUTOTEMP)
+  float Planner::autotemp_max = 250;
+  float Planner::autotemp_min = 210;
+  float Planner::autotemp_factor = 0.1;
+  bool Planner::autotemp_enabled = false;
+#endif
+
+// private:
+
+long Planner::position[NUM_AXIS] = { 0 };
+
+float Planner::previous_speed[NUM_AXIS];
+
+float Planner::previous_nominal_speed;
+
+#if ENABLED(DISABLE_INACTIVE_EXTRUDER)
+  uint8_t Planner::g_uc_extruder_last_move[EXTRUDERS] = { 0 };
+#endif // DISABLE_INACTIVE_EXTRUDER
+
+#ifdef XY_FREQUENCY_LIMIT
+  // Old direction bits. Used for speed calculations
+  unsigned char Planner::old_direction_bits = 0;
+  // Segment times (in µs). Used for speed calculations
+  long Planner::axis_segment_time[2][3] = { {MAX_FREQ_TIME + 1, 0, 0}, {MAX_FREQ_TIME + 1, 0, 0} };
+#endif
+
+/**
+ * Class and Instance Methods
+ */
+
 Planner::Planner() {
   #if ENABLED(AUTO_BED_LEVELING_FEATURE)
     bed_level_matrix.set_to_identity();
diff --git a/Marlin/planner.h b/Marlin/planner.h
index f62398397a..580bf765dc 100644
--- a/Marlin/planner.h
+++ b/Marlin/planner.h
@@ -108,27 +108,27 @@ class Planner {
     /**
      * A ring buffer of moves described in steps
      */
-    block_t block_buffer[BLOCK_BUFFER_SIZE];
-    volatile uint8_t block_buffer_head = 0;           // Index of the next block to be pushed
-    volatile uint8_t block_buffer_tail = 0;
+    static block_t block_buffer[BLOCK_BUFFER_SIZE];
+    static volatile uint8_t block_buffer_head;           // Index of the next block to be pushed
+    static volatile uint8_t block_buffer_tail;
 
-    float max_feedrate[NUM_AXIS]; // Max speeds in mm per minute
-    float axis_steps_per_unit[NUM_AXIS];
-    unsigned long axis_steps_per_sqr_second[NUM_AXIS];
-    unsigned long max_acceleration_units_per_sq_second[NUM_AXIS]; // Use M201 to override by software
+    static float max_feedrate[NUM_AXIS]; // Max speeds in mm per minute
+    static float axis_steps_per_unit[NUM_AXIS];
+    static unsigned long axis_steps_per_sqr_second[NUM_AXIS];
+    static unsigned long max_acceleration_units_per_sq_second[NUM_AXIS]; // Use M201 to override by software
 
-    millis_t min_segment_time;
-    float min_feedrate;
-    float acceleration;         // Normal acceleration mm/s^2  DEFAULT ACCELERATION for all printing moves. M204 SXXXX
-    float retract_acceleration; // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX
-    float travel_acceleration;  // Travel acceleration mm/s^2  DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX
-    float max_xy_jerk;          // The largest speed change requiring no acceleration
-    float max_z_jerk;
-    float max_e_jerk;
-    float min_travel_feedrate;
+    static millis_t min_segment_time;
+    static float min_feedrate;
+    static float acceleration;         // Normal acceleration mm/s^2  DEFAULT ACCELERATION for all printing moves. M204 SXXXX
+    static float retract_acceleration; // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX
+    static float travel_acceleration;  // Travel acceleration mm/s^2  DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX
+    static float max_xy_jerk;          // The largest speed change requiring no acceleration
+    static float max_z_jerk;
+    static float max_e_jerk;
+    static float min_travel_feedrate;
 
     #if ENABLED(AUTO_BED_LEVELING_FEATURE)
-      matrix_3x3 bed_level_matrix; // Transform to compensate for bed level
+      static matrix_3x3 bed_level_matrix; // Transform to compensate for bed level
     #endif
 
   private:
@@ -137,49 +137,57 @@ class Planner {
      * The current position of the tool in absolute steps
      * Reclculated if any axis_steps_per_unit are changed by gcode
      */
-    long position[NUM_AXIS] = { 0 };
+    static long position[NUM_AXIS];
 
     /**
      * Speed of previous path line segment
      */
-    float previous_speed[NUM_AXIS];
+    static float previous_speed[NUM_AXIS];
 
     /**
      * Nominal speed of previous path line segment
      */
-    float previous_nominal_speed;
+    static float previous_nominal_speed;
 
     #if ENABLED(DISABLE_INACTIVE_EXTRUDER)
       /**
        * Counters to manage disabling inactive extruders
        */
-      uint8_t g_uc_extruder_last_move[EXTRUDERS] = { 0 };
+      static uint8_t g_uc_extruder_last_move[EXTRUDERS];
     #endif // DISABLE_INACTIVE_EXTRUDER
 
     #ifdef XY_FREQUENCY_LIMIT
       // Used for the frequency limit
-      #define MAX_FREQ_TIME (1000000.0/XY_FREQUENCY_LIMIT)
+      #define MAX_FREQ_TIME long(1000000.0/XY_FREQUENCY_LIMIT)
       // Old direction bits. Used for speed calculations
-      static unsigned char old_direction_bits = 0;
+      static unsigned char old_direction_bits;
       // Segment times (in µs). Used for speed calculations
-      static long axis_segment_time[2][3] = { {MAX_FREQ_TIME + 1, 0, 0}, {MAX_FREQ_TIME + 1, 0, 0} };
+      static long axis_segment_time[2][3];
     #endif
 
   public:
 
+    /**
+     * Instance Methods
+     */
+
     Planner();
 
     void init();
 
-    void reset_acceleration_rates();
+    /**
+     * Static (class) Methods
+     */
+
+    static void reset_acceleration_rates();
 
     // Manage fans, paste pressure, etc.
-    void check_axes_activity();
+    static void check_axes_activity();
 
     /**
      * Number of moves currently in the planner
      */
-    FORCE_INLINE uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail + BLOCK_BUFFER_SIZE); }
+    static FORCE_INLINE uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail + BLOCK_BUFFER_SIZE); }
 
     #if ENABLED(AUTO_BED_LEVELING_FEATURE) || ENABLED(MESH_BED_LEVELING)
 
@@ -187,7 +195,7 @@ class Planner {
         /**
          * The corrected position, applying the bed level matrix
          */
-        vector_3 adjusted_position();
+        static vector_3 adjusted_position();
       #endif
 
       /**
@@ -197,7 +205,7 @@ class Planner {
        *  feed_rate - (target) speed of the move
        *  extruder  - target extruder
        */
-      void buffer_line(float x, float y, float z, const float& e, float feed_rate, const uint8_t extruder);
+      static void buffer_line(float x, float y, float z, const float& e, float feed_rate, const uint8_t extruder);
 
       /**
        * Set the planner.position and individual stepper positions.
@@ -208,30 +216,30 @@ class Planner {
        *
        * Clears previous speed values.
        */
-      void set_position(float x, float y, float z, const float& e);
+      static void set_position(float x, float y, float z, const float& e);
 
     #else
 
-      void buffer_line(const float& x, const float& y, const float& z, const float& e, float feed_rate, const uint8_t extruder);
-      void set_position(const float& x, const float& y, const float& z, const float& e);
+      static void buffer_line(const float& x, const float& y, const float& z, const float& e, float feed_rate, const uint8_t extruder);
+      static void set_position(const float& x, const float& y, const float& z, const float& e);
 
     #endif // AUTO_BED_LEVELING_FEATURE || MESH_BED_LEVELING
 
     /**
      * Set the E position (mm) of the planner (and the E stepper)
      */
-    void set_e_position(const float& e);
+    static void set_e_position(const float& e);
 
     /**
      * Does the buffer have any blocks queued?
      */
-    FORCE_INLINE bool blocks_queued() { return (block_buffer_head != block_buffer_tail); }
+    static FORCE_INLINE bool blocks_queued() { return (block_buffer_head != block_buffer_tail); }
 
     /**
      * "Discards" the block and "releases" the memory.
      * Called when the current block is no longer needed.
      */
-    FORCE_INLINE void discard_current_block() {
+    static FORCE_INLINE void discard_current_block() {
       if (blocks_queued())
         block_buffer_tail = BLOCK_MOD(block_buffer_tail + 1);
     }
@@ -240,7 +248,7 @@ class Planner {
      * The current block. NULL if the buffer is empty.
      * This also marks the block as busy.
      */
-    FORCE_INLINE block_t* get_current_block() {
+    static FORCE_INLINE block_t* get_current_block() {
       if (blocks_queued()) {
         block_t* block = &block_buffer[block_buffer_tail];
         block->busy = true;
@@ -251,12 +259,12 @@ class Planner {
     }
 
     #if ENABLED(AUTOTEMP)
-      float autotemp_max = 250;
-      float autotemp_min = 210;
-      float autotemp_factor = 0.1;
-      bool autotemp_enabled = false;
-      void getHighESpeed();
-      void autotemp_M109();
+      static float autotemp_max;
+      static float autotemp_min;
+      static float autotemp_factor;
+      static bool autotemp_enabled;
+      static void getHighESpeed();
+      static void autotemp_M109();
     #endif
 
   private:
@@ -264,14 +272,14 @@ class Planner {
     /**
      * Get the index of the next / previous block in the ring buffer
      */
-    FORCE_INLINE int8_t next_block_index(int8_t block_index) { return BLOCK_MOD(block_index + 1); }
-    FORCE_INLINE int8_t prev_block_index(int8_t block_index) { return BLOCK_MOD(block_index - 1); }
+    static FORCE_INLINE int8_t next_block_index(int8_t block_index) { return BLOCK_MOD(block_index + 1); }
+    static FORCE_INLINE int8_t prev_block_index(int8_t block_index) { return BLOCK_MOD(block_index - 1); }
 
     /**
      * Calculate the distance (not time) it takes to accelerate
      * from initial_rate to target_rate using the given acceleration:
      */
-    FORCE_INLINE float estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) {
+    static FORCE_INLINE float estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) {
       if (acceleration == 0) return 0; // acceleration was 0, set acceleration distance to 0
       return (target_rate * target_rate - initial_rate * initial_rate) / (acceleration * 2);
     }
@@ -284,7 +292,7 @@ class Planner {
      * This is used to compute the intersection point between acceleration and deceleration
      * in cases where the "trapezoid" has no plateau (i.e., never reaches maximum speed)
      */
-    FORCE_INLINE float intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) {
+    static FORCE_INLINE float intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) {
       if (acceleration == 0) return 0; // acceleration was 0, set intersection distance to 0
       return (acceleration * 2 * distance - initial_rate * initial_rate + final_rate * final_rate) / (acceleration * 4);
     }
@@ -294,21 +302,21 @@ class Planner {
      * to reach 'target_velocity' using 'acceleration' within a given
      * 'distance'.
      */
-    FORCE_INLINE float max_allowable_speed(float acceleration, float target_velocity, float distance) {
+    static FORCE_INLINE float max_allowable_speed(float acceleration, float target_velocity, float distance) {
       return sqrt(target_velocity * target_velocity - 2 * acceleration * distance);
     }
 
-    void calculate_trapezoid_for_block(block_t* block, float entry_factor, float exit_factor);
+    static void calculate_trapezoid_for_block(block_t* block, float entry_factor, float exit_factor);
 
-    void reverse_pass_kernel(block_t* previous, block_t* current, block_t* next);
-    void forward_pass_kernel(block_t* previous, block_t* current, block_t* next);
+    static void reverse_pass_kernel(block_t* previous, block_t* current, block_t* next);
+    static void forward_pass_kernel(block_t* previous, block_t* current, block_t* next);
 
-    void reverse_pass();
-    void forward_pass();
+    static void reverse_pass();
+    static void forward_pass();
 
-    void recalculate_trapezoids();
+    static void recalculate_trapezoids();
 
-    void recalculate();
+    static void recalculate();
 
 };
 

From ff53819856f45e036c483e9435f8e8257dee15f2 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Mon, 30 May 2016 17:18:28 -0700
Subject: [PATCH 2/2] Drop FORCE_INLINE in planner.h

This change actually does increase the binary size by about 12 bytes,
but how does it affect performance?
---
 Marlin/planner.h | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/Marlin/planner.h b/Marlin/planner.h
index 580bf765dc..b263e2dfa0 100644
--- a/Marlin/planner.h
+++ b/Marlin/planner.h
@@ -187,7 +187,7 @@ class Planner {
     /**
      * Number of moves currently in the planner
      */
-    static FORCE_INLINE uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail + BLOCK_BUFFER_SIZE); }
+    static uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail + BLOCK_BUFFER_SIZE); }
 
     #if ENABLED(AUTO_BED_LEVELING_FEATURE) || ENABLED(MESH_BED_LEVELING)
 
@@ -233,13 +233,13 @@ class Planner {
     /**
      * Does the buffer have any blocks queued?
      */
-    static FORCE_INLINE bool blocks_queued() { return (block_buffer_head != block_buffer_tail); }
+    static bool blocks_queued() { return (block_buffer_head != block_buffer_tail); }
 
     /**
      * "Discards" the block and "releases" the memory.
      * Called when the current block is no longer needed.
      */
-    static FORCE_INLINE void discard_current_block() {
+    static void discard_current_block() {
       if (blocks_queued())
         block_buffer_tail = BLOCK_MOD(block_buffer_tail + 1);
     }
@@ -248,7 +248,7 @@ class Planner {
      * The current block. NULL if the buffer is empty.
      * This also marks the block as busy.
      */
-    static FORCE_INLINE block_t* get_current_block() {
+    static block_t* get_current_block() {
       if (blocks_queued()) {
         block_t* block = &block_buffer[block_buffer_tail];
         block->busy = true;
@@ -272,14 +272,14 @@ class Planner {
     /**
      * Get the index of the next / previous block in the ring buffer
      */
-    static FORCE_INLINE int8_t next_block_index(int8_t block_index) { return BLOCK_MOD(block_index + 1); }
-    static FORCE_INLINE int8_t prev_block_index(int8_t block_index) { return BLOCK_MOD(block_index - 1); }
+    static int8_t next_block_index(int8_t block_index) { return BLOCK_MOD(block_index + 1); }
+    static int8_t prev_block_index(int8_t block_index) { return BLOCK_MOD(block_index - 1); }
 
     /**
      * Calculate the distance (not time) it takes to accelerate
      * from initial_rate to target_rate using the given acceleration:
      */
-    static FORCE_INLINE float estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) {
+    static float estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) {
       if (acceleration == 0) return 0; // acceleration was 0, set acceleration distance to 0
       return (target_rate * target_rate - initial_rate * initial_rate) / (acceleration * 2);
     }
@@ -292,7 +292,7 @@ class Planner {
      * This is used to compute the intersection point between acceleration and deceleration
      * in cases where the "trapezoid" has no plateau (i.e., never reaches maximum speed)
      */
-    static FORCE_INLINE float intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) {
+    static float intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) {
       if (acceleration == 0) return 0; // acceleration was 0, set intersection distance to 0
       return (acceleration * 2 * distance - initial_rate * initial_rate + final_rate * final_rate) / (acceleration * 4);
     }
@@ -302,7 +302,7 @@ class Planner {
      * to reach 'target_velocity' using 'acceleration' within a given
      * 'distance'.
      */
-    static FORCE_INLINE float max_allowable_speed(float acceleration, float target_velocity, float distance) {
+    static float max_allowable_speed(float acceleration, float target_velocity, float distance) {
       return sqrt(target_velocity * target_velocity - 2 * acceleration * distance);
     }