From 0bc66bf22ceaa2a3a06d657893372f00b2d99f75 Mon Sep 17 00:00:00 2001
From: dot-bob <robfrommendon@gmail.com>
Date: Sat, 10 Jun 2017 00:02:15 -0600
Subject: [PATCH 1/4] PCA9632 PWM color LED support

Add support for the PCA9632 PWM color LED driver used on the Ultimaker 2 and Wanhao Duplicator 6.
---
 .travis.yml                                   |   6 +
 Marlin/Conditionals_LCD.h                     |   2 +-
 Marlin/Configuration.h                        |   5 +-
 Marlin/Marlin_main.cpp                        |  21 +++-
 Marlin/SanityCheck.h                          |   8 +-
 .../CL-260/Configuration.h                    |   5 +-
 .../Cartesio/Configuration.h                  |   5 +-
 .../Felix/Configuration.h                     |   5 +-
 .../Felix/DUAL/Configuration.h                |   5 +-
 .../FolgerTech-i3-2020/Configuration.h        |   5 +-
 .../Hephestos/Configuration.h                 |   5 +-
 .../Hephestos_2/Configuration.h               |   5 +-
 .../K8200/Configuration.h                     |   5 +-
 .../K8400/Configuration.h                     |   5 +-
 .../K8400/Dual-head/Configuration.h           |   5 +-
 .../M150/Configuration.h                      |   5 +-
 .../RepRapWorld/Megatronics/Configuration.h   |   5 +-
 .../RigidBot/Configuration.h                  |   5 +-
 .../SCARA/Configuration.h                     |   5 +-
 .../TAZ4/Configuration.h                      |   5 +-
 .../TinyBoy2/Configuration.h                  |   5 +-
 .../WITBOX/Configuration.h                    |   5 +-
 .../adafruit/ST7565/Configuration.h           |   5 +-
 .../FLSUN/auto_calibrate/Configuration.h      |   5 +-
 .../delta/FLSUN/kossel_mini/Configuration.h   |   5 +-
 .../delta/generic/Configuration.h             |   5 +-
 .../delta/kossel_mini/Configuration.h         |   5 +-
 .../delta/kossel_pro/Configuration.h          |   5 +-
 .../delta/kossel_xl/Configuration.h           |   5 +-
 .../gCreate_gMax1.5+/Configuration.h          |   5 +-
 .../makibox/Configuration.h                   |   5 +-
 .../tvrrug/Round2/Configuration.h             |   5 +-
 .../wt150/Configuration.h                     |   5 +-
 Marlin/pca9632.cpp                            | 115 ++++++++++++++++++
 Marlin/pca9632.h                              |  36 ++++++
 35 files changed, 292 insertions(+), 41 deletions(-)
 create mode 100644 Marlin/pca9632.cpp
 create mode 100644 Marlin/pca9632.h

diff --git a/.travis.yml b/.travis.yml
index 03f7585d0c..643517a447 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -291,6 +291,12 @@ script:
   - opt_enable ULTIMAKERCONTROLLER
   - build_marlin
   #
+  # PCA9632
+  #
+  - restore_configs
+  - opt_enable PCA9632
+  - build_marlin
+  #
   # MAKRPANEL
   # Needs to use Melzi and Sanguino hardware
   #
diff --git a/Marlin/Conditionals_LCD.h b/Marlin/Conditionals_LCD.h
index b33499e6bf..48cc0141a5 100644
--- a/Marlin/Conditionals_LCD.h
+++ b/Marlin/Conditionals_LCD.h
@@ -398,6 +398,6 @@
 
   #define HAS_SOFTWARE_ENDSTOPS (ENABLED(MIN_SOFTWARE_ENDSTOPS) || ENABLED(MAX_SOFTWARE_ENDSTOPS))
   #define HAS_RESUME_CONTINUE (ENABLED(NEWPANEL) || ENABLED(EMERGENCY_PARSER))
-  #define HAS_COLOR_LEDS (ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED))
+  #define HAS_COLOR_LEDS (ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632))
 
 #endif // CONDITIONALS_LCD_H
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index cc422b6525..7d6c4a5614 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -1482,6 +1482,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1519,7 +1522,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 35a9f3e5dd..da3bf1a12c 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -138,7 +138,7 @@
  * M140 - Set bed target temp. S<temp>
  * M145 - Set heatup values for materials on the LCD. H<hotend> B<bed> F<fan speed> for S<material> (0=PLA, 1=ABS)
  * M149 - Set temperature units. (Requires TEMPERATURE_UNITS_SUPPORT)
- * M150 - Set Status LED Color as R<red> U<green> B<blue>. Values 0-255. (Requires BLINKM or RGB_LED)
+ * M150 - Set Status LED Color as R<red> U<green> B<blue>. Values 0-255. (Requires BLINKM, RGB_LED, RGBW_LED, or PCA9632)
  * M155 - Auto-report temperatures with interval of S<seconds>. (Requires AUTO_REPORT_TEMPERATURES)
  * M163 - Set a single proportion for a mixing extruder. (Requires MIXING_EXTRUDER)
  * M164 - Save the mix as a virtual extruder. (Requires MIXING_EXTRUDER and MIXING_VIRTUAL_TOOLS)
@@ -280,6 +280,10 @@
   #include "Wire.h"
 #endif
 
+#if ENABLED(PCA9632)
+  #include "pca9632.h"
+#endif
+
 #if HAS_SERVOS
   #include "servo.h"
 #endif
@@ -986,7 +990,9 @@ void servo_init() {
       // This variant uses i2c to send the RGB components to the device.
       SendColors(r, g, b);
 
-    #else
+    #endif
+
+    #if ENABLED(RGB_LED) || ENABLED(RGBW_LED)
 
       // This variant uses 3 separate pins for the RGB components.
       // If the pins can do PWM then their intensity will be set.
@@ -1003,6 +1009,11 @@ void servo_init() {
       #endif
 
     #endif
+
+    #if ENABLED(PCA9632)
+      // Update I2C LED driver
+      PCA9632_SetColor(r, g, b);
+    #endif
   }
 
 #endif // HAS_COLOR_LEDS
@@ -5893,7 +5904,7 @@ inline void gcode_M17() {
 
     if (!DEBUGGING(DRYRUN) && unload_length != 0) {
       #if ENABLED(PREVENT_COLD_EXTRUSION)
-        if (!thermalManager.allow_cold_extrude && 
+        if (!thermalManager.allow_cold_extrude &&
             thermalManager.degTargetHotend(active_extruder) < thermalManager.extrude_min_temp) {
           SERIAL_ERROR_START();
           SERIAL_ERRORLNPGM(MSG_TOO_COLD_FOR_M600);
@@ -8013,7 +8024,7 @@ inline void gcode_M121() { endstops.enable_globally(false); }
     );
   }
 
-#endif // BLINKM || RGB_LED
+#endif // HAS_COLOR_LEDS
 
 /**
  * M200: Set filament diameter and set E axis units to cubic units
@@ -10621,7 +10632,7 @@ void process_next_command() {
           gcode_M150();
           break;
 
-      #endif // BLINKM
+      #endif // HAS_COLOR_LEDS
 
       #if ENABLED(MIXING_EXTRUDER)
         case 163: // M163: Set a component weight for mixing extruder
diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index f975733361..de4f550d2b 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -1027,17 +1027,13 @@ static_assert(1 >= 0
     #error "RGB_LED requires RGB_LED_R_PIN, RGB_LED_G_PIN, and RGB_LED_B_PIN."
   #elif ENABLED(RGBW_LED)
     #error "Please enable only one of RGB_LED and RGBW_LED."
-  #elif ENABLED(BLINKM)
-    #error "RGB_LED and BLINKM are currently incompatible (both use M150)."
   #endif
 #elif ENABLED(RGBW_LED)
   #if !(_RGB_TEST && PIN_EXISTS(RGB_LED_W))
     #error "RGBW_LED requires RGB_LED_R_PIN, RGB_LED_G_PIN, RGB_LED_B_PIN, and RGB_LED_W_PIN."
-  #elif ENABLED(BLINKM)
-    #error "RGBW_LED and BLINKM are currently incompatible (both use M150)."
   #endif
-#elif DISABLED(BLINKM) && ENABLED(PRINTER_EVENT_LEDS)
-  #error "PRINTER_EVENT_LEDS requires BLINKM, RGB_LED, or RGBW_LED."
+#elif ENABLED(PRINTER_EVENT_LEDS) && DISABLED(BLINKM) && DISABLED(PCA9632)
+  #error "PRINTER_EVENT_LEDS requires BLINKM, PCA9632, RGB_LED, or RGBW_LED."
 #endif
 
 /**
diff --git a/Marlin/example_configurations/CL-260/Configuration.h b/Marlin/example_configurations/CL-260/Configuration.h
index 8be2b4427b..fe024c71b5 100644
--- a/Marlin/example_configurations/CL-260/Configuration.h
+++ b/Marlin/example_configurations/CL-260/Configuration.h
@@ -1482,6 +1482,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1519,7 +1522,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/Cartesio/Configuration.h b/Marlin/example_configurations/Cartesio/Configuration.h
index 13929a9543..38fd64f429 100644
--- a/Marlin/example_configurations/Cartesio/Configuration.h
+++ b/Marlin/example_configurations/Cartesio/Configuration.h
@@ -1479,6 +1479,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1516,7 +1519,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/Felix/Configuration.h b/Marlin/example_configurations/Felix/Configuration.h
index d2fd786a5d..d4c3f07381 100644
--- a/Marlin/example_configurations/Felix/Configuration.h
+++ b/Marlin/example_configurations/Felix/Configuration.h
@@ -1463,6 +1463,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1500,7 +1503,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/Felix/DUAL/Configuration.h b/Marlin/example_configurations/Felix/DUAL/Configuration.h
index 5189616aad..863b725e9a 100644
--- a/Marlin/example_configurations/Felix/DUAL/Configuration.h
+++ b/Marlin/example_configurations/Felix/DUAL/Configuration.h
@@ -1463,6 +1463,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1500,7 +1503,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/FolgerTech-i3-2020/Configuration.h b/Marlin/example_configurations/FolgerTech-i3-2020/Configuration.h
index 8d72fcc27c..1f464ee041 100644
--- a/Marlin/example_configurations/FolgerTech-i3-2020/Configuration.h
+++ b/Marlin/example_configurations/FolgerTech-i3-2020/Configuration.h
@@ -1485,6 +1485,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1522,7 +1525,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/Hephestos/Configuration.h b/Marlin/example_configurations/Hephestos/Configuration.h
index ae0e3a89a5..44cc30e42e 100644
--- a/Marlin/example_configurations/Hephestos/Configuration.h
+++ b/Marlin/example_configurations/Hephestos/Configuration.h
@@ -1471,6 +1471,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1508,7 +1511,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/Hephestos_2/Configuration.h b/Marlin/example_configurations/Hephestos_2/Configuration.h
index aab15d09a7..04dd6842cc 100644
--- a/Marlin/example_configurations/Hephestos_2/Configuration.h
+++ b/Marlin/example_configurations/Hephestos_2/Configuration.h
@@ -1474,6 +1474,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1511,7 +1514,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/K8200/Configuration.h b/Marlin/example_configurations/K8200/Configuration.h
index 2efae18109..86304303e4 100644
--- a/Marlin/example_configurations/K8200/Configuration.h
+++ b/Marlin/example_configurations/K8200/Configuration.h
@@ -1515,6 +1515,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1552,7 +1555,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/K8400/Configuration.h b/Marlin/example_configurations/K8400/Configuration.h
index 8c2ed2be9f..8152f2d619 100644
--- a/Marlin/example_configurations/K8400/Configuration.h
+++ b/Marlin/example_configurations/K8400/Configuration.h
@@ -1481,6 +1481,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1518,7 +1521,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/K8400/Dual-head/Configuration.h b/Marlin/example_configurations/K8400/Dual-head/Configuration.h
index 7236ab4968..735ac65718 100644
--- a/Marlin/example_configurations/K8400/Dual-head/Configuration.h
+++ b/Marlin/example_configurations/K8400/Dual-head/Configuration.h
@@ -1481,6 +1481,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1518,7 +1521,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/M150/Configuration.h b/Marlin/example_configurations/M150/Configuration.h
index 7b5321be9e..75c4f4c129 100644
--- a/Marlin/example_configurations/M150/Configuration.h
+++ b/Marlin/example_configurations/M150/Configuration.h
@@ -1508,6 +1508,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1545,7 +1548,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
index 409684ed8c..fd0fedc30a 100644
--- a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
+++ b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
@@ -1481,6 +1481,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1518,7 +1521,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/RigidBot/Configuration.h b/Marlin/example_configurations/RigidBot/Configuration.h
index ef09f47067..77fa6469bf 100644
--- a/Marlin/example_configurations/RigidBot/Configuration.h
+++ b/Marlin/example_configurations/RigidBot/Configuration.h
@@ -1481,6 +1481,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1518,7 +1521,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/SCARA/Configuration.h b/Marlin/example_configurations/SCARA/Configuration.h
index 9af3cecde5..6f92b4f892 100644
--- a/Marlin/example_configurations/SCARA/Configuration.h
+++ b/Marlin/example_configurations/SCARA/Configuration.h
@@ -1496,6 +1496,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1533,7 +1536,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/TAZ4/Configuration.h b/Marlin/example_configurations/TAZ4/Configuration.h
index 4660946752..845c758d2f 100644
--- a/Marlin/example_configurations/TAZ4/Configuration.h
+++ b/Marlin/example_configurations/TAZ4/Configuration.h
@@ -1500,6 +1500,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1537,7 +1540,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/TinyBoy2/Configuration.h b/Marlin/example_configurations/TinyBoy2/Configuration.h
index 4fefe85d6c..0326daf299 100644
--- a/Marlin/example_configurations/TinyBoy2/Configuration.h
+++ b/Marlin/example_configurations/TinyBoy2/Configuration.h
@@ -1537,6 +1537,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1574,7 +1577,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/WITBOX/Configuration.h b/Marlin/example_configurations/WITBOX/Configuration.h
index 187fb948a6..d090f55065 100644
--- a/Marlin/example_configurations/WITBOX/Configuration.h
+++ b/Marlin/example_configurations/WITBOX/Configuration.h
@@ -1471,6 +1471,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1508,7 +1511,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/adafruit/ST7565/Configuration.h b/Marlin/example_configurations/adafruit/ST7565/Configuration.h
index 0f608c7a1d..04c62167b0 100644
--- a/Marlin/example_configurations/adafruit/ST7565/Configuration.h
+++ b/Marlin/example_configurations/adafruit/ST7565/Configuration.h
@@ -1481,6 +1481,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1518,7 +1521,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h
index df495943d6..840287c96f 100644
--- a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h
+++ b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h
@@ -1602,6 +1602,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1639,7 +1642,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h
index 453b0a603f..b7fe4eed91 100644
--- a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h
+++ b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h
@@ -1603,6 +1603,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1640,7 +1643,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/delta/generic/Configuration.h b/Marlin/example_configurations/delta/generic/Configuration.h
index d005b0876b..39500de3f9 100644
--- a/Marlin/example_configurations/delta/generic/Configuration.h
+++ b/Marlin/example_configurations/delta/generic/Configuration.h
@@ -1592,6 +1592,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1629,7 +1632,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
index edc6ca7905..4e3a7ebb69 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
@@ -1595,6 +1595,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1632,7 +1635,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration.h b/Marlin/example_configurations/delta/kossel_pro/Configuration.h
index 42675f9fff..eabdc13574 100644
--- a/Marlin/example_configurations/delta/kossel_pro/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_pro/Configuration.h
@@ -1600,6 +1600,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1637,7 +1640,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration.h b/Marlin/example_configurations/delta/kossel_xl/Configuration.h
index 1427f5adbb..acbc9e58d8 100644
--- a/Marlin/example_configurations/delta/kossel_xl/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_xl/Configuration.h
@@ -1658,6 +1658,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1695,7 +1698,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/gCreate_gMax1.5+/Configuration.h b/Marlin/example_configurations/gCreate_gMax1.5+/Configuration.h
index 63a698a6c3..67eb606e09 100644
--- a/Marlin/example_configurations/gCreate_gMax1.5+/Configuration.h
+++ b/Marlin/example_configurations/gCreate_gMax1.5+/Configuration.h
@@ -1497,6 +1497,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1534,7 +1537,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/makibox/Configuration.h b/Marlin/example_configurations/makibox/Configuration.h
index a13bb2ed53..ae07c775bd 100644
--- a/Marlin/example_configurations/makibox/Configuration.h
+++ b/Marlin/example_configurations/makibox/Configuration.h
@@ -1484,6 +1484,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1521,7 +1524,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration.h b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
index 046a8a5e2b..57a66e1756 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
@@ -1476,6 +1476,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 /**
  * RGB LED / LED Strip Control
  *
@@ -1513,7 +1516,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/example_configurations/wt150/Configuration.h b/Marlin/example_configurations/wt150/Configuration.h
index 52fa225197..80addd741b 100644
--- a/Marlin/example_configurations/wt150/Configuration.h
+++ b/Marlin/example_configurations/wt150/Configuration.h
@@ -1486,6 +1486,9 @@
 //define BlinkM/CyzRgb Support
 //#define BLINKM
 
+//define PCA9632 PWM LED driver Support
+//#define PCA9632
+
 // Support for an RGB LED using 3 separate pins with optional PWM
 //#define RGB_LED
 //#define RGBW_LED
@@ -1507,7 +1510,7 @@
  *  - Change to green once print has finished
  *  - Turn off after the print has finished and the user has pushed a button
  */
-#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED)
+#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632)
   #define PRINTER_EVENT_LEDS
 #endif
 
diff --git a/Marlin/pca9632.cpp b/Marlin/pca9632.cpp
new file mode 100644
index 0000000000..d8853c4650
--- /dev/null
+++ b/Marlin/pca9632.cpp
@@ -0,0 +1,115 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * Driver for the Philips PCA9632 LED driver.
+ * Written by Robert Mendon Feb 2017.
+ */
+
+#include "MarlinConfig.h"
+
+#if ENABLED(PCA9632)
+
+#include "pca9632.h"
+
+#define PCA9632_MODE1_VALUE   0b00000001 //(ALLCALL)
+#define PCA9632_MODE2_VALUE   0b00010101 //(DIMMING, INVERT, CHANGE ON STOP,TOTEM)
+#define PCA9632_LEDOUT_VALUE  0b00101010
+
+
+/* Register addresses */
+#define PCA9632_MODE1       0x00
+#define PCA9632_MODE2       0x01
+#define PCA9632_PWM0        0x02
+#define PCA9632_PWM1        0x03
+#define PCA9632_PWM2        0x04
+#define PCA9632_PWM3        0x05
+#define PCA9632_GRPPWM      0x06
+#define PCA9632_GRPFREQ     0x07
+#define PCA9632_LEDOUT      0X08
+#define PCA9632_SUBADR1     0x09
+#define PCA9632_SUBADR2     0x0A
+#define PCA9632_SUBADR3     0x0B
+#define PCA9632_ALLCALLADDR 0x0C
+
+#define PCA9632_NO_AUTOINC  0x00
+#define PCA9632_AUTO_ALL    0x80
+#define PCA9632_AUTO_IND    0xA0
+#define PCA9632_AUTOGLO     0xC0
+#define PCA9632_AUTOGI      0xE0
+
+// Red   LED0
+// Green LED1
+// Blue  LED2
+#define PCA9632_RED     0x00
+#define PCA9632_GRN     0x02
+#define PCA9632_BLU     0x04
+
+#define LED_OFF   0x00
+#define LED_ON    0x01
+#define LED_PWM   0x02
+
+#define PCA9632_ADDRESS 0b01100000
+
+byte PCA_init = 0;
+
+static void PCA9632_WriteRegister(const byte addr, const byte regadd, const byte value) {
+  Wire.beginTransmission(addr);
+  Wire.write(regadd);
+  Wire.write(value);
+  Wire.endTransmission();
+}
+
+static void PCA9632_WriteAllRegisters(const byte addr, const byte regadd, const byte value1, const byte value2, const byte value3) {
+  Wire.beginTransmission(addr);
+  Wire.write(PCA9632_AUTO_IND | regadd);
+  Wire.write(value1);
+  Wire.write(value2);
+  Wire.write(value3);
+  Wire.endTransmission();
+}
+
+static byte PCA9632_ReadRegister(const byte addr, const byte regadd) {
+  Wire.beginTransmission(addr);
+  Wire.write(regadd);
+  const byte value = Wire.read();
+  Wire.endTransmission();
+  return value;
+}
+
+void PCA9632_SetColor(const byte r, const byte g, const byte b) {
+  if (!PCA_init) {
+    PCA_init = 1;
+    Wire.begin();
+    PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE1, PCA9632_MODE1_VALUE);
+    PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE2, PCA9632_MODE2_VALUE);
+  }
+
+  const byte LEDOUT = (r ? LED_PWM << PCA9632_RED : 0)
+                    | (g ? LED_PWM << PCA9632_GRN : 0)
+                    | (b ? LED_PWM << PCA9632_BLU : 0);
+
+  PCA9632_WriteAllRegisters(PCA9632_ADDRESS,PCA9632_PWM0, r, g, b);
+  PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_LEDOUT, LEDOUT);
+}
+
+#endif // PCA9632
diff --git a/Marlin/pca9632.h b/Marlin/pca9632.h
new file mode 100644
index 0000000000..b8c78f065d
--- /dev/null
+++ b/Marlin/pca9632.h
@@ -0,0 +1,36 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * Driver for the Philips PCA9632 LED driver.
+ * Written by Robert Mendon Feb 2017.
+ */
+
+#ifndef __PCA9632_H__
+#define __PCA9632_H__
+
+#include "Arduino.h"
+#include "Wire.h"
+
+void PCA9632_SetColor(const byte r, const byte g, const byte  b);
+
+#endif // __PCA9632_H__

From 570722a0fed7dc25a39271c062fe7c1cbb50efc1 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Sun, 11 Jun 2017 22:49:35 -0500
Subject: [PATCH 2/4] Combine Travis tests to shorten required time

---
 .travis.yml | 146 ++++++++++++----------------------------------------
 1 file changed, 33 insertions(+), 113 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 643517a447..127faef496 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -71,48 +71,15 @@ script:
   #
   - build_marlin
   #
-  # Test heated bed temperature sensor
-  #
-  - opt_set TEMP_SENSOR_BED 1
-  - build_marlin
-  #
-  # Test 2 extruders on basic RAMPS 1.4
+  # Test 2 extruders (one MAX6675) and heated bed on basic RAMPS 1.4
+  #  plus a "Fix Mounted" Probe with Safe Homing
   #
   - opt_set MOTHERBOARD BOARD_RAMPS_14_EEB
   - opt_set EXTRUDERS 2
-  - opt_set TEMP_SENSOR_1 1
-  - build_marlin
-  #
-  # Test 5 extruders on AZTEEG_X3_PRO (can use any board with >=5 extruders defined)
-  # Include a test for LIN_ADVANCE here also
-  #
-  - opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO
-  - opt_set EXTRUDERS 5
-  - opt_set TEMP_SENSOR_1 1
-  - opt_set TEMP_SENSOR_2 5
-  - opt_set TEMP_SENSOR_3 20
-  - opt_set TEMP_SENSOR_4 999
-  - opt_set TEMP_SENSOR_BED 1
-  - opt_enable_adv LIN_ADVANCE
-  - build_marlin
-  #
-  # Test PIDTEMPBED
-  #
-  - restore_configs
-  - opt_set TEMP_SENSOR_BED 1
-  - opt_enable PIDTEMPBED
-  - build_marlin
-  #
-  # Test MAX6675
-  #
-  - restore_configs
   - opt_set TEMP_SENSOR_0 -2
-  - build_marlin
-  #
-  # Test a "Fix Mounted" Probe along with Safe Homing
-  #
-  - restore_configs
-  - opt_enable FIX_MOUNTED_PROBE Z_SAFE_HOMING
+  - opt_set TEMP_SENSOR_1 1
+  - opt_set TEMP_SENSOR_BED 1
+  - opt_enable PIDTEMPBED FIX_MOUNTED_PROBE Z_SAFE_HOMING
   - build_marlin
   #
   # ...with AUTO_BED_LEVELING_LINEAR, Z_MIN_PROBE_REPEATABILITY_TEST, and DEBUG_LEVELING_FEATURE
@@ -151,17 +118,27 @@ script:
   - opt_enable MESH_BED_LEVELING MESH_G28_REST_ORIGIN LCD_BED_LEVELING ULTIMAKERCONTROLLER
   - build_marlin
   #
-  # Test PROBE_MANUALLY feature, with LCD support
+  # Test PROBE_MANUALLY feature, with LCD support,
+  #      EEPROM_SETTINGS, EEPROM_CHITCHAT, M100_FREE_MEMORY_WATCHER,
+  #      INCH_MODE_SUPPORT, TEMPERATURE_UNITS_SUPPORT
   #
   - restore_configs
+  - opt_set MOTHERBOARD BOARD_MINIRAMBO
   - opt_enable PROBE_MANUALLY AUTO_BED_LEVELING_BILINEAR LCD_BED_LEVELING ULTIMAKERCONTROLLER
+  - opt_enable EEPROM_SETTINGS EEPROM_CHITCHAT M100_FREE_MEMORY_WATCHER M100_FREE_MEMORY_DUMPER M100_FREE_MEMORY_CORRUPTOR INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT
   - build_marlin
   #
-  # Test EEPROM_SETTINGS, EEPROM_CHITCHAT, M100_FREE_MEMORY_WATCHER,
-  #   INCH_MODE_SUPPORT, TEMPERATURE_UNITS_SUPPORT
+  # Test 5 extruders on AZTEEG_X3_PRO (can use any board with >=5 extruders defined)
+  # Include a test for LIN_ADVANCE here also
   #
-  - restore_configs
-  - opt_enable EEPROM_SETTINGS EEPROM_CHITCHAT M100_FREE_MEMORY_WATCHER M100_FREE_MEMORY_DUMPER M100_FREE_MEMORY_CORRUPTOR INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT
+  - opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO
+  - opt_set EXTRUDERS 5
+  - opt_set TEMP_SENSOR_1 1
+  - opt_set TEMP_SENSOR_2 5
+  - opt_set TEMP_SENSOR_3 20
+  - opt_set TEMP_SENSOR_4 999
+  - opt_set TEMP_SENSOR_BED 1
+  - opt_enable_adv LIN_ADVANCE
   - build_marlin
   #
   # Mixing Extruder with 5 steppers
@@ -202,34 +179,19 @@ script:
   - build_marlin
   #
   # Test MINIRAMBO for PWM_MOTOR_CURRENT
+  #      ULTIMAKERCONTROLLER, FILAMENT_LCD_DISPLAY, FILAMENT_WIDTH_SENSOR,
+  #      PRINTCOUNTER, NOZZLE_PARK_FEATURE, NOZZLE_CLEAN_FEATURE, PCA9632,
+  #      Z_DUAL_STEPPER_DRIVERS, Z_DUAL_ENDSTOPS, BEZIER_CURVE_SUPPORT, EXPERIMENTAL_I2CBUS,
+  #      FILAMENT_CHANGE_FEATURE, PARK_HEAD_ON_PAUSE, LCD_INFO_MENU,
   #
   - restore_configs
-  - opt_set MOTHERBOARD BOARD_MINIRAMBO
-  - build_marlin
-  #
-  # Test FILAMENT_CHANGE_FEATURE, PARK_HEAD_ON_PAUSE, and LCD_INFO_MENU
-  #
-  - restore_configs
-  - opt_enable ULTIMAKERCONTROLLER
-  - opt_enable_adv FILAMENT_CHANGE_FEATURE PARK_HEAD_ON_PAUSE LCD_INFO_MENU
-  - build_marlin
-  #
-  # Enable filament sensor
-  #
-  - restore_configs
-  - opt_enable FILAMENT_WIDTH_SENSOR
-  - build_marlin
-  #
-  # Enable filament sensor with LCD display
-  #
-  - opt_enable ULTIMAKERCONTROLLER FILAMENT_LCD_DISPLAY
-  - build_marlin
-  #
-  # Enable BEZIER_CURVE_SUPPORT, EXPERIMENTAL_I2CBUS, and I2C_SLAVE_ADDRESS
-  #
-  - restore_configs
-  - opt_enable_adv BEZIER_CURVE_SUPPORT EXPERIMENTAL_I2CBUS
+  - opt_enable ULTIMAKERCONTROLLER FILAMENT_LCD_DISPLAY FILAMENT_WIDTH_SENSOR SDSUPPORT
+  - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632
+  - opt_enable_adv Z_DUAL_STEPPER_DRIVERS Z_DUAL_ENDSTOPS BEZIER_CURVE_SUPPORT EXPERIMENTAL_I2CBUS
   - opt_set_adv I2C_SLAVE_ADDRESS 63
+  - opt_enable_adv FILAMENT_CHANGE_FEATURE PARK_HEAD_ON_PAUSE LCD_INFO_MENU
+  - pins_set RAMPS X_MAX_PIN -1
+  - opt_set_adv Z2_MAX_PIN 2
   - build_marlin
   #
   # Enable COREXY
@@ -244,34 +206,8 @@ script:
   - opt_enable COREYX
   - build_marlin
   #
-  # Enable Z_DUAL_STEPPER_DRIVERS, Z_DUAL_ENDSTOPS
   #
-  - restore_configs
-  - opt_enable_adv Z_DUAL_STEPPER_DRIVERS Z_DUAL_ENDSTOPS
-  - pins_set RAMPS X_MAX_PIN -1
-  - opt_set_adv Z2_MAX_PIN 2
-  - build_marlin
-  #
-  # Test PRINTCOUNTER
-  #
-  - restore_configs
-  - opt_enable PRINTCOUNTER
-  - build_marlin
-  #
-  # Test NOZZLE_PARK_FEATURE
-  #
-  - restore_configs
-  - opt_enable NOZZLE_PARK_FEATURE
-  - build_marlin
-  #
-  # Test NOZZLE_CLEAN_FEATURE
-  #
-  - restore_configs
-  - opt_enable NOZZLE_CLEAN_FEATURE
-  - build_marlin
-  #
-  #
-  ######## STANDARD LCD/PANELS ##############
+  ######## Other Standard LCD/Panels ##############
   #
   # ULTRA_LCD
   #
@@ -285,18 +221,6 @@ script:
   - opt_enable DOGLCD
   - build_marlin
   #
-  # ULTIMAKERCONTROLLER
-  #
-  - restore_configs
-  - opt_enable ULTIMAKERCONTROLLER
-  - build_marlin
-  #
-  # PCA9632
-  #
-  - restore_configs
-  - opt_enable PCA9632
-  - build_marlin
-  #
   # MAKRPANEL
   # Needs to use Melzi and Sanguino hardware
   #
@@ -310,15 +234,11 @@ script:
   - opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT BABYSTEPPING
   - build_marlin
   #
-  # G3D_PANEL
+  # G3D_PANEL with SDCARD_SORT_ALPHA and STATUS_MESSAGE_SCROLLING
   #
   - restore_configs
   - opt_enable G3D_PANEL SDSUPPORT
-  - build_marlin
-  #
-  # Add SDCARD_SORT_ALPHA, test G3D_PANEL again
-  #
-  - opt_enable_adv SDCARD_SORT_ALPHA
+  - opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING
   - opt_set_adv SDSORT_GCODE true
   - opt_set_adv SDSORT_USES_RAM true
   - opt_set_adv SDSORT_USES_STACK true

From 699aa35df6ada555b5319d38e0eb6035ff436387 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Mon, 12 Jun 2017 01:25:40 -0500
Subject: [PATCH 3/4] Code cleanup for G33

---
 Marlin/Marlin_main.cpp | 84 ++++++++++++++++--------------------------
 1 file changed, 31 insertions(+), 53 deletions(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index da3bf1a12c..0a573af8a3 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -3529,7 +3529,7 @@ inline void gcode_G4() {
       if (leveling_is_active()) {
         SERIAL_ECHOLNPGM(" (enabled)");
         #if ABL_PLANAR
-          float diff[XYZ] = {
+          const float diff[XYZ] = {
             stepper.get_axis_position_mm(X_AXIS) - current_position[X_AXIS],
             stepper.get_axis_position_mm(Y_AXIS) - current_position[Y_AXIS],
             stepper.get_axis_position_mm(Z_AXIS) - current_position[Z_AXIS]
@@ -5094,6 +5094,15 @@ void home_all_axes() { gcode_G28(true); }
      *
      *   E   Engage the probe for each point
      */
+
+    void print_signed_float(const char * const prefix, const float &f) {
+      SERIAL_PROTOCOLPGM("  ");
+      serialprintPGM(prefix);
+      SERIAL_PROTOCOLCHAR(':');
+      if (f >= 0) SERIAL_CHAR('+');
+      SERIAL_PROTOCOL_F(f, 2);
+    }
+
     inline void gcode_G33() {
 
       const int8_t probe_points = parser.seen('P') ? parser.value_int() : DELTA_CALIBRATION_DEFAULT_POINTS;
@@ -5115,7 +5124,7 @@ void home_all_axes() { gcode_G28(true); }
       }
 
       const bool towers_set = !parser.seen('T'),
-                 stow_after_each = parser.seen('E'),
+                 stow_after_each      = parser.seen('E') && parser.value_bool(),
                  _1p_calibration      = probe_points == 1,
                  _4p_calibration      = probe_points == 2,
                  _4p_towers_points    = _4p_calibration && towers_set,
@@ -5183,25 +5192,16 @@ void home_all_axes() { gcode_G28(true); }
 
       SERIAL_PROTOCOLPAIR(".Height:", DELTA_HEIGHT + home_offset[Z_AXIS]);
       if (!_1p_calibration) {
-        SERIAL_PROTOCOLPGM("    Ex:");
-        if (endstop_adj[A_AXIS] >= 0) SERIAL_CHAR('+');
-        SERIAL_PROTOCOL_F(endstop_adj[A_AXIS], 2);
-        SERIAL_PROTOCOLPGM("  Ey:");
-        if (endstop_adj[B_AXIS] >= 0) SERIAL_CHAR('+');
-        SERIAL_PROTOCOL_F(endstop_adj[B_AXIS], 2);
-        SERIAL_PROTOCOLPGM("  Ez:");
-        if (endstop_adj[C_AXIS] >= 0) SERIAL_CHAR('+');
-        SERIAL_PROTOCOL_F(endstop_adj[C_AXIS], 2);
+        print_signed_float(PSTR("  Ex"), endstop_adj[A_AXIS]);
+        print_signed_float(PSTR("Ey"), endstop_adj[B_AXIS]);
+        print_signed_float(PSTR("Ez"), endstop_adj[C_AXIS]);
         SERIAL_PROTOCOLPAIR("    Radius:", delta_radius);
       }
       SERIAL_EOL();
       if (_7p_calibration && towers_set) {
-        SERIAL_PROTOCOLPGM(".Tower angle :    Tx:");
-        if (delta_tower_angle_trim[A_AXIS] >= 0) SERIAL_CHAR('+');
-        SERIAL_PROTOCOL_F(delta_tower_angle_trim[A_AXIS], 2);
-        SERIAL_PROTOCOLPGM("  Ty:");
-        if (delta_tower_angle_trim[B_AXIS] >= 0) SERIAL_CHAR('+');
-        SERIAL_PROTOCOL_F(delta_tower_angle_trim[B_AXIS], 2);
+        SERIAL_PROTOCOLPGM(".Tower angle :  ");
+        print_signed_float(PSTR("Tx"), delta_tower_angle_trim[A_AXIS]);
+        print_signed_float(PSTR("Ty"), delta_tower_angle_trim[B_AXIS]);
         SERIAL_PROTOCOLPGM("  Tz:+0.00");
         SERIAL_EOL();
       }
@@ -5351,19 +5351,12 @@ void home_all_axes() { gcode_G28(true); }
          // print report
 
         if (verbose_level != 1) {
-          SERIAL_PROTOCOLPGM(".      c:");
-          if (z_at_pt[0] > 0) SERIAL_CHAR('+');
-          SERIAL_PROTOCOL_F(z_at_pt[0], 2);
+          SERIAL_PROTOCOLPGM(".    ");
+          print_signed_float(PSTR("c"), z_at_pt[0]);
           if (_4p_towers_points || _7p_calibration) {
-            SERIAL_PROTOCOLPGM("     x:");
-            if (z_at_pt[1] >= 0) SERIAL_CHAR('+');
-            SERIAL_PROTOCOL_F(z_at_pt[1], 2);
-            SERIAL_PROTOCOLPGM("   y:");
-            if (z_at_pt[5] >= 0) SERIAL_CHAR('+');
-            SERIAL_PROTOCOL_F(z_at_pt[5], 2);
-            SERIAL_PROTOCOLPGM("   z:");
-            if (z_at_pt[9] >= 0) SERIAL_CHAR('+');
-            SERIAL_PROTOCOL_F(z_at_pt[9], 2);
+            print_signed_float(PSTR("   x"), z_at_pt[1]);
+            print_signed_float(PSTR(" y"), z_at_pt[5]);
+            print_signed_float(PSTR(" z"), z_at_pt[9]);
           }
           if (!_4p_opposite_points) SERIAL_EOL();
           if ((_4p_opposite_points) || _7p_calibration) {
@@ -5371,15 +5364,9 @@ void home_all_axes() { gcode_G28(true); }
               SERIAL_CHAR('.');
               SERIAL_PROTOCOL_SP(13);
             }
-            SERIAL_PROTOCOLPGM("    yz:");
-            if (z_at_pt[7] >= 0) SERIAL_CHAR('+');
-            SERIAL_PROTOCOL_F(z_at_pt[7], 2);
-            SERIAL_PROTOCOLPGM("  zx:");
-            if (z_at_pt[11] >= 0) SERIAL_CHAR('+');
-            SERIAL_PROTOCOL_F(z_at_pt[11], 2);
-            SERIAL_PROTOCOLPGM("  xy:");
-            if (z_at_pt[3] >= 0) SERIAL_CHAR('+');
-            SERIAL_PROTOCOL_F(z_at_pt[3], 2);
+            print_signed_float(PSTR("  yz"), z_at_pt[7]);
+            print_signed_float(PSTR("zx"), z_at_pt[11]);
+            print_signed_float(PSTR("xy"), z_at_pt[3]);
             SERIAL_EOL();
           }
         }
@@ -5409,25 +5396,16 @@ void home_all_axes() { gcode_G28(true); }
           }
           SERIAL_PROTOCOLPAIR(".Height:", DELTA_HEIGHT + home_offset[Z_AXIS]);
           if (!_1p_calibration) {
-            SERIAL_PROTOCOLPGM("    Ex:");
-            if (endstop_adj[A_AXIS] >= 0) SERIAL_CHAR('+');
-            SERIAL_PROTOCOL_F(endstop_adj[A_AXIS], 2);
-            SERIAL_PROTOCOLPGM("  Ey:");
-            if (endstop_adj[B_AXIS] >= 0) SERIAL_CHAR('+');
-            SERIAL_PROTOCOL_F(endstop_adj[B_AXIS], 2);
-            SERIAL_PROTOCOLPGM("  Ez:");
-            if (endstop_adj[C_AXIS] >= 0) SERIAL_CHAR('+');
-            SERIAL_PROTOCOL_F(endstop_adj[C_AXIS], 2);
+            print_signed_float(PSTR("  Ex"), endstop_adj[A_AXIS]);
+            print_signed_float(PSTR("Ey"), endstop_adj[B_AXIS]);
+            print_signed_float(PSTR("Ez"), endstop_adj[C_AXIS]);
             SERIAL_PROTOCOLPAIR("    Radius:", delta_radius);
           }
           SERIAL_EOL();
           if (_7p_calibration && towers_set) {
-            SERIAL_PROTOCOLPGM(".Tower angle :    Tx:");
-            if (delta_tower_angle_trim[A_AXIS] >= 0) SERIAL_CHAR('+');
-            SERIAL_PROTOCOL_F(delta_tower_angle_trim[A_AXIS], 2);
-            SERIAL_PROTOCOLPGM("  Ty:");
-            if (delta_tower_angle_trim[B_AXIS] >= 0) SERIAL_CHAR('+');
-            SERIAL_PROTOCOL_F(delta_tower_angle_trim[B_AXIS], 2);
+            SERIAL_PROTOCOLPGM(".Tower angle :  ");
+            print_signed_float(PSTR("Tx"), delta_tower_angle_trim[A_AXIS]);
+            print_signed_float(PSTR("Ty"), delta_tower_angle_trim[B_AXIS]);
             SERIAL_PROTOCOLPGM("  Tz:+0.00");
             SERIAL_EOL();
           }

From 445227c8071242af919b34b18965c484304f95b0 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Mon, 12 Jun 2017 01:28:52 -0500
Subject: [PATCH 4/4] Fix missing LCD_STR_REFRESH

---
 Marlin/Conditionals_LCD.h      | 2 +-
 Marlin/ultralcd_impl_HD44780.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Marlin/Conditionals_LCD.h b/Marlin/Conditionals_LCD.h
index 48cc0141a5..d51d6a353d 100644
--- a/Marlin/Conditionals_LCD.h
+++ b/Marlin/Conditionals_LCD.h
@@ -245,7 +245,7 @@
     #define LCD_DEGREE_CHAR      0x01
     #define LCD_STR_THERMOMETER "\x02" // Still used with string concatenation
     #define LCD_UPLEVEL_CHAR     0x03
-    #define LCD_REFRESH_CHAR     0x04
+    #define LCD_STR_REFRESH     "\x04"
     #define LCD_STR_FOLDER      "\x05"
     #define LCD_FEEDRATE_CHAR    0x06
     #define LCD_CLOCK_CHAR       0x07
diff --git a/Marlin/ultralcd_impl_HD44780.h b/Marlin/ultralcd_impl_HD44780.h
index 7bc901854e..8adbaf8843 100644
--- a/Marlin/ultralcd_impl_HD44780.h
+++ b/Marlin/ultralcd_impl_HD44780.h
@@ -341,13 +341,13 @@ static void lcd_set_custom_characters(
         }
         else { // Custom characters for submenus
           createChar_P(LCD_UPLEVEL_CHAR, uplevel);
-          createChar_P(LCD_REFRESH_CHAR, refresh);
+          createChar_P(LCD_STR_REFRESH[0], refresh);
           createChar_P(LCD_STR_FOLDER[0], folder);
         }
       }
     #else
       createChar_P(LCD_UPLEVEL_CHAR, uplevel);
-      createChar_P(LCD_REFRESH_CHAR, refresh);
+      createChar_P(LCD_STR_REFRESH[0], refresh);
       createChar_P(LCD_STR_FOLDER[0], folder);
     #endif