From 5fff8d148bd50bf2791ee809932dfad6d2a480b1 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Sun, 25 Sep 2016 06:32:58 -0500
Subject: [PATCH] Clean up digital pots and microsteps

---
 Marlin/Conditionals_post.h |   5 +-
 Marlin/Marlin_main.cpp     |  21 +--
 Marlin/stepper.cpp         | 276 ++++++++++++++++++++-----------------
 Marlin/stepper.h           |  18 ++-
 4 files changed, 178 insertions(+), 142 deletions(-)

diff --git a/Marlin/Conditionals_post.h b/Marlin/Conditionals_post.h
index 1b5e4188ec9..d23c82299e3 100644
--- a/Marlin/Conditionals_post.h
+++ b/Marlin/Conditionals_post.h
@@ -462,10 +462,13 @@
   #define HAS_SOLENOID_1 (PIN_EXISTS(SOL1))
   #define HAS_SOLENOID_2 (PIN_EXISTS(SOL2))
   #define HAS_SOLENOID_3 (PIN_EXISTS(SOL3))
-  #define HAS_MICROSTEPS (PIN_EXISTS(X_MS1))
+  #define HAS_MICROSTEPS_X (PIN_EXISTS(X_MS1))
+  #define HAS_MICROSTEPS_Y (PIN_EXISTS(Y_MS1))
+  #define HAS_MICROSTEPS_Z (PIN_EXISTS(Z_MS1))
   #define HAS_MICROSTEPS_E0 (PIN_EXISTS(E0_MS1))
   #define HAS_MICROSTEPS_E1 (PIN_EXISTS(E1_MS1))
   #define HAS_MICROSTEPS_E2 (PIN_EXISTS(E2_MS1))
+  #define HAS_MICROSTEPS (HAS_MICROSTEPS_X || HAS_MICROSTEPS_Y || HAS_MICROSTEPS_Z || HAS_MICROSTEPS_E0 || HAS_MICROSTEPS_E1 || HAS_MICROSTEPS_E2)
   #define HAS_STEPPER_RESET (PIN_EXISTS(STEPPER_RESET))
   #define HAS_X_ENABLE (PIN_EXISTS(X_ENABLE))
   #define HAS_X2_ENABLE (PIN_EXISTS(X2_ENABLE))
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 1b3550d48cf..ced90647226 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -6514,18 +6514,19 @@ inline void gcode_M503() {
 inline void gcode_M907() {
   #if HAS_DIGIPOTSS
     LOOP_XYZE(i)
-      if (code_seen(axis_codes[i])) stepper.digipot_current(i, code_value_int());
+    if (code_seen(axis_codes[i])) stepper.digipot_current(i, code_value_int());
     if (code_seen('B')) stepper.digipot_current(4, code_value_int());
     if (code_seen('S')) for (int i = 0; i <= 4; i++) stepper.digipot_current(i, code_value_int());
-  #endif
-  #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
-    if (code_seen('X')) stepper.digipot_current(0, code_value_int());
-  #endif
-  #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
-    if (code_seen('Z')) stepper.digipot_current(1, code_value_int());
-  #endif
-  #if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
-    if (code_seen('E')) stepper.digipot_current(2, code_value_int());
+  #elif HAS_MOTOR_CURRENT_PWM
+    #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
+      if (code_seen('X')) stepper.digipot_current(0, code_value_int());
+    #endif
+    #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
+      if (code_seen('Z')) stepper.digipot_current(1, code_value_int());
+    #endif
+    #if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
+      if (code_seen('E')) stepper.digipot_current(2, code_value_int());
+    #endif
   #endif
   #if ENABLED(DIGIPOT_I2C)
     // this one uses actual amps in floating point
diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index f0c4f27fe9e..06183a7f5fe 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -733,19 +733,27 @@ void Stepper::isr() {
 
 void Stepper::init() {
 
-  digipot_init(); //Initialize Digipot Motor Current
-  microstep_init(); //Initialize Microstepping Pins
+  // Init Digipot Motor Current
+  #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM
+    digipot_init();
+  #endif
 
-  // initialise TMC Steppers
+  // Init Microstepping Pins
+  #if HAS_MICROSTEPS
+    microstep_init();
+  #endif
+
+  // Init TMC Steppers
   #if ENABLED(HAVE_TMCDRIVER)
     tmc_init();
   #endif
-    // initialise L6470 Steppers
+
+  // Init L6470 Steppers
   #if ENABLED(HAVE_L6470DRIVER)
     L6470_init();
   #endif
 
-  // Initialize Dir Pins
+  // Init Dir Pins
   #if HAS_X_DIR
     X_DIR_INIT;
   #endif
@@ -777,8 +785,7 @@ void Stepper::init() {
     E3_DIR_INIT;
   #endif
 
-  //Initialize Enable Pins - steppers default to disabled.
-
+  // Init Enable Pins - steppers default to disabled.
   #if HAS_X_ENABLE
     X_ENABLE_INIT;
     if (!X_ENABLE_ON) X_ENABLE_WRITE(HIGH);
@@ -787,7 +794,6 @@ void Stepper::init() {
       if (!X_ENABLE_ON) X2_ENABLE_WRITE(HIGH);
     #endif
   #endif
-
   #if HAS_Y_ENABLE
     Y_ENABLE_INIT;
     if (!Y_ENABLE_ON) Y_ENABLE_WRITE(HIGH);
@@ -796,7 +802,6 @@ void Stepper::init() {
       if (!Y_ENABLE_ON) Y2_ENABLE_WRITE(HIGH);
     #endif
   #endif
-
   #if HAS_Z_ENABLE
     Z_ENABLE_INIT;
     if (!Z_ENABLE_ON) Z_ENABLE_WRITE(HIGH);
@@ -805,7 +810,6 @@ void Stepper::init() {
       if (!Z_ENABLE_ON) Z2_ENABLE_WRITE(HIGH);
     #endif
   #endif
-
   #if HAS_E0_ENABLE
     E0_ENABLE_INIT;
     if (!E_ENABLE_ON) E0_ENABLE_WRITE(HIGH);
@@ -823,9 +827,7 @@ void Stepper::init() {
     if (!E_ENABLE_ON) E3_ENABLE_WRITE(HIGH);
   #endif
 
-  //
-  // Init endstops and pullups here
-  //
+  // Init endstops and pullups
   endstops.init();
 
   #define _STEP_INIT(AXIS) AXIS ##_STEP_INIT
@@ -839,7 +841,7 @@ void Stepper::init() {
 
   #define E_AXIS_INIT(NUM) AXIS_INIT(e## NUM, E## NUM, E)
 
-  // Initialize Step Pins
+  // Init Step Pins
   #if HAS_X_STEP
     #if ENABLED(X_DUAL_STEPPER_DRIVERS) || ENABLED(DUAL_X_CARRIAGE)
       X2_STEP_INIT;
@@ -1164,134 +1166,158 @@ void Stepper::report_positions() {
 
 #endif //HAS_DIGIPOTSS
 
-void Stepper::digipot_init() {
-  #if HAS_DIGIPOTSS
-    const uint8_t digipot_motor_current[] = DIGIPOT_MOTOR_CURRENT;
+#if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM
 
-    SPI.begin();
-    pinMode(DIGIPOTSS_PIN, OUTPUT);
-    for (uint8_t i = 0; i < COUNT(digipot_motor_current); i++) {
-      //digitalPotWrite(digipot_ch[i], digipot_motor_current[i]);
-      digipot_current(i, digipot_motor_current[i]);
-    }
-  #endif
-  #if HAS_MOTOR_CURRENT_PWM
-    #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
-      pinMode(MOTOR_CURRENT_PWM_XY_PIN, OUTPUT);
-      digipot_current(0, motor_current_setting[0]);
-    #endif
-    #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
-      pinMode(MOTOR_CURRENT_PWM_Z_PIN, OUTPUT);
-      digipot_current(1, motor_current_setting[1]);
-    #endif
-    #if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
-      pinMode(MOTOR_CURRENT_PWM_E_PIN, OUTPUT);
-      digipot_current(2, motor_current_setting[2]);
-    #endif
-    //Set timer5 to 31khz so the PWM of the motor power is as constant as possible. (removes a buzzing noise)
-    TCCR5B = (TCCR5B & ~(_BV(CS50) | _BV(CS51) | _BV(CS52))) | _BV(CS50);
-  #endif
-}
-
-void Stepper::digipot_current(uint8_t driver, int current) {
-  #if HAS_DIGIPOTSS
-    const uint8_t digipot_ch[] = DIGIPOT_CHANNELS;
-    digitalPotWrite(digipot_ch[driver], current);
-  #elif HAS_MOTOR_CURRENT_PWM
-    #define _WRITE_CURRENT_PWM(P) analogWrite(P, 255L * current / (MOTOR_CURRENT_PWM_RANGE))
-    switch (driver) {
+  void Stepper::digipot_init() {
+    #if HAS_DIGIPOTSS
+      static const uint8_t digipot_motor_current[] = DIGIPOT_MOTOR_CURRENT;
+      SPI.begin();
+      SET_OUTPUT(DIGIPOTSS_PIN);
+      for (uint8_t i = 0; i < COUNT(digipot_motor_current); i++) {
+        //digitalPotWrite(digipot_ch[i], digipot_motor_current[i]);
+        digipot_current(i, digipot_motor_current[i]);
+      }
+    #elif HAS_MOTOR_CURRENT_PWM
       #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
-        case 0: _WRITE_CURRENT_PWM(MOTOR_CURRENT_PWM_XY_PIN); break;
+        SET_OUTPUT(MOTOR_CURRENT_PWM_XY_PIN);
+        digipot_current(0, motor_current_setting[0]);
       #endif
       #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
-        case 1: _WRITE_CURRENT_PWM(MOTOR_CURRENT_PWM_Z_PIN); break;
+        SET_OUTPUT(MOTOR_CURRENT_PWM_Z_PIN);
+        digipot_current(1, motor_current_setting[1]);
       #endif
       #if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
-        case 2: _WRITE_CURRENT_PWM(MOTOR_CURRENT_PWM_E_PIN); break;
+        SET_OUTPUT(MOTOR_CURRENT_PWM_E_PIN);
+        digipot_current(2, motor_current_setting[2]);
       #endif
-    }
-  #else
-    UNUSED(driver);
-    UNUSED(current);
-  #endif
-}
+      //Set timer5 to 31khz so the PWM of the motor power is as constant as possible. (removes a buzzing noise)
+      TCCR5B = (TCCR5B & ~(_BV(CS50) | _BV(CS51) | _BV(CS52))) | _BV(CS50);
+    #endif
+  }
 
-void Stepper::microstep_init() {
-  #if HAS_MICROSTEPS_E1
-    pinMode(E1_MS1_PIN, OUTPUT);
-    pinMode(E1_MS2_PIN, OUTPUT);
-  #endif
+  void Stepper::digipot_current(uint8_t driver, int current) {
+    #if HAS_DIGIPOTSS
+      const uint8_t digipot_ch[] = DIGIPOT_CHANNELS;
+      digitalPotWrite(digipot_ch[driver], current);
+    #elif HAS_MOTOR_CURRENT_PWM
+      #define _WRITE_CURRENT_PWM(P) analogWrite(P, 255L * current / (MOTOR_CURRENT_PWM_RANGE))
+      switch (driver) {
+        #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
+          case 0: _WRITE_CURRENT_PWM(MOTOR_CURRENT_PWM_XY_PIN); break;
+        #endif
+        #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
+          case 1: _WRITE_CURRENT_PWM(MOTOR_CURRENT_PWM_Z_PIN); break;
+        #endif
+        #if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
+          case 2: _WRITE_CURRENT_PWM(MOTOR_CURRENT_PWM_E_PIN); break;
+        #endif
+      }
+    #endif
+  }
 
-  #if HAS_MICROSTEPS
-    pinMode(X_MS1_PIN, OUTPUT);
-    pinMode(X_MS2_PIN, OUTPUT);
-    pinMode(Y_MS1_PIN, OUTPUT);
-    pinMode(Y_MS2_PIN, OUTPUT);
-    pinMode(Z_MS1_PIN, OUTPUT);
-    pinMode(Z_MS2_PIN, OUTPUT);
-    pinMode(E0_MS1_PIN, OUTPUT);
-    pinMode(E0_MS2_PIN, OUTPUT);
-    const uint8_t microstep_modes[] = MICROSTEP_MODES;
+#endif
+
+#if HAS_MICROSTEPS
+
+  /**
+   * Software-controlled Microstepping
+   */
+
+  void Stepper::microstep_init() {
+    SET_OUTPUT(X_MS1_PIN);
+    SET_OUTPUT(X_MS2_PIN);
+    #if HAS_MICROSTEPS_Y
+      SET_OUTPUT(Y_MS1_PIN);
+      SET_OUTPUT(Y_MS2_PIN);
+    #endif
+    #if HAS_MICROSTEPS_Z
+      SET_OUTPUT(Z_MS1_PIN);
+      SET_OUTPUT(Z_MS2_PIN);
+    #endif
+    #if HAS_MICROSTEPS_E0
+      SET_OUTPUT(E0_MS1_PIN);
+      SET_OUTPUT(E0_MS2_PIN);
+    #endif
+    #if HAS_MICROSTEPS_E1
+      SET_OUTPUT(E1_MS1_PIN);
+      SET_OUTPUT(E1_MS2_PIN);
+    #endif
+    static const uint8_t microstep_modes[] = MICROSTEP_MODES;
     for (uint16_t i = 0; i < COUNT(microstep_modes); i++)
       microstep_mode(i, microstep_modes[i]);
-  #endif
-}
+  }
 
-/**
- * Software-controlled Microstepping
- */
+  void Stepper::microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) {
+    if (ms1 >= 0) switch (driver) {
+      case 0: digitalWrite(X_MS1_PIN, ms1); break;
+      #if HAS_MICROSTEPS_Y
+        case 1: digitalWrite(Y_MS1_PIN, ms1); break;
+      #endif
+      #if HAS_MICROSTEPS_Z
+        case 2: digitalWrite(Z_MS1_PIN, ms1); break;
+      #endif
+      #if HAS_MICROSTEPS_E0
+        case 3: digitalWrite(E0_MS1_PIN, ms1); break;
+      #endif
+      #if HAS_MICROSTEPS_E1
+        case 4: digitalWrite(E1_MS1_PIN, ms1); break;
+      #endif
+    }
+    if (ms2 >= 0) switch (driver) {
+      case 0: digitalWrite(X_MS2_PIN, ms2); break;
+      #if HAS_MICROSTEPS_Y
+        case 1: digitalWrite(Y_MS2_PIN, ms2); break;
+      #endif
+      #if HAS_MICROSTEPS_Z
+        case 2: digitalWrite(Z_MS2_PIN, ms2); break;
+      #endif
+      #if HAS_MICROSTEPS_E0
+        case 3: digitalWrite(E0_MS2_PIN, ms2); break;
+      #endif
+      #if HAS_MICROSTEPS_E1
+        case 4: digitalWrite(E1_MS2_PIN, ms2); break;
+      #endif
+    }
+  }
 
-void Stepper::microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) {
-  if (ms1 >= 0) switch (driver) {
-    case 0: digitalWrite(X_MS1_PIN, ms1); break;
-    case 1: digitalWrite(Y_MS1_PIN, ms1); break;
-    case 2: digitalWrite(Z_MS1_PIN, ms1); break;
-    case 3: digitalWrite(E0_MS1_PIN, ms1); break;
+  void Stepper::microstep_mode(uint8_t driver, uint8_t stepping_mode) {
+    switch (stepping_mode) {
+      case 1: microstep_ms(driver, MICROSTEP1); break;
+      case 2: microstep_ms(driver, MICROSTEP2); break;
+      case 4: microstep_ms(driver, MICROSTEP4); break;
+      case 8: microstep_ms(driver, MICROSTEP8); break;
+      case 16: microstep_ms(driver, MICROSTEP16); break;
+    }
+  }
+
+  void Stepper::microstep_readings() {
+    SERIAL_PROTOCOLLNPGM("MS1,MS2 Pins");
+    SERIAL_PROTOCOLPGM("X: ");
+    SERIAL_PROTOCOL(READ(X_MS1_PIN));
+    SERIAL_PROTOCOLLN(READ(X_MS2_PIN));
+    #if HAS_MICROSTEPS_Y
+      SERIAL_PROTOCOLPGM("Y: ");
+      SERIAL_PROTOCOL(READ(Y_MS1_PIN));
+      SERIAL_PROTOCOLLN(READ(Y_MS2_PIN));
+    #endif
+    #if HAS_MICROSTEPS_Z
+      SERIAL_PROTOCOLPGM("Z: ");
+      SERIAL_PROTOCOL(READ(Z_MS1_PIN));
+      SERIAL_PROTOCOLLN(READ(Z_MS2_PIN));
+    #endif
+    #if HAS_MICROSTEPS_E0
+      SERIAL_PROTOCOLPGM("E0: ");
+      SERIAL_PROTOCOL(READ(E0_MS1_PIN));
+      SERIAL_PROTOCOLLN(READ(E0_MS2_PIN));
+    #endif
     #if HAS_MICROSTEPS_E1
-      case 4: digitalWrite(E1_MS1_PIN, ms1); break;
+      SERIAL_PROTOCOLPGM("E1: ");
+      SERIAL_PROTOCOL(READ(E1_MS1_PIN));
+      SERIAL_PROTOCOLLN(READ(E1_MS2_PIN));
     #endif
   }
-  if (ms2 >= 0) switch (driver) {
-    case 0: digitalWrite(X_MS2_PIN, ms2); break;
-    case 1: digitalWrite(Y_MS2_PIN, ms2); break;
-    case 2: digitalWrite(Z_MS2_PIN, ms2); break;
-    case 3: digitalWrite(E0_MS2_PIN, ms2); break;
-    #if PIN_EXISTS(E1_MS2)
-      case 4: digitalWrite(E1_MS2_PIN, ms2); break;
-    #endif
-  }
-}
 
-void Stepper::microstep_mode(uint8_t driver, uint8_t stepping_mode) {
-  switch (stepping_mode) {
-    case 1: microstep_ms(driver, MICROSTEP1); break;
-    case 2: microstep_ms(driver, MICROSTEP2); break;
-    case 4: microstep_ms(driver, MICROSTEP4); break;
-    case 8: microstep_ms(driver, MICROSTEP8); break;
-    case 16: microstep_ms(driver, MICROSTEP16); break;
-  }
-}
-
-void Stepper::microstep_readings() {
-  SERIAL_PROTOCOLLNPGM("MS1,MS2 Pins");
-  SERIAL_PROTOCOLPGM("X: ");
-  SERIAL_PROTOCOL(READ(X_MS1_PIN));
-  SERIAL_PROTOCOLLN(READ(X_MS2_PIN));
-  SERIAL_PROTOCOLPGM("Y: ");
-  SERIAL_PROTOCOL(READ(Y_MS1_PIN));
-  SERIAL_PROTOCOLLN(READ(Y_MS2_PIN));
-  SERIAL_PROTOCOLPGM("Z: ");
-  SERIAL_PROTOCOL(READ(Z_MS1_PIN));
-  SERIAL_PROTOCOLLN(READ(Z_MS2_PIN));
-  SERIAL_PROTOCOLPGM("E0: ");
-  SERIAL_PROTOCOL(READ(E0_MS1_PIN));
-  SERIAL_PROTOCOLLN(READ(E0_MS2_PIN));
-  #if HAS_MICROSTEPS_E1
-    SERIAL_PROTOCOLPGM("E1: ");
-    SERIAL_PROTOCOL(READ(E1_MS1_PIN));
-    SERIAL_PROTOCOLLN(READ(E1_MS2_PIN));
-  #endif
-}
+#endif // HAS_MICROSTEPS
 
 #if ENABLED(LIN_ADVANCE)
 
diff --git a/Marlin/stepper.h b/Marlin/stepper.h
index 995aaea82c8..a1c62fe9416 100644
--- a/Marlin/stepper.h
+++ b/Marlin/stepper.h
@@ -239,13 +239,16 @@ class Stepper {
     //
     static FORCE_INLINE bool motor_direction(AxisEnum axis) { return TEST(last_direction_bits, axis); }
 
-    #if HAS_DIGIPOTSS
+    #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM
       static void digitalPotWrite(int address, int value);
+      static void digipot_current(uint8_t driver, int current);
+    #endif
+
+    #if HAS_MICROSTEPS
+      static void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2);
+      static void microstep_mode(uint8_t driver, uint8_t stepping);
+      static void microstep_readings();
     #endif
-    static void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2);
-    static void digipot_current(uint8_t driver, int current);
-    static void microstep_mode(uint8_t driver, uint8_t stepping);
-    static void microstep_readings();
 
     #if ENABLED(Z_DUAL_ENDSTOPS)
       static FORCE_INLINE void set_homing_flag(bool state) { performing_homing = state; }
@@ -380,7 +383,10 @@ class Stepper {
     }
 
     static void digipot_init();
-    static void microstep_init();
+
+    #if HAS_MICROSTEPS
+      static void microstep_init();
+    #endif
 
 };