From f9dd484381d9aa53267ecefc8db2e87f9e27c8fa Mon Sep 17 00:00:00 2001
From: Mike La Spina <mike.laspina@shaw.ca>
Date: Wed, 23 Dec 2020 22:50:24 -0600
Subject: [PATCH] Cutter Power in percent format (#20410)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
Co-authored-by: Jason Smith <jason.inet@gmail.com>
Co-authored-by: Luu Lac <45380455+shitcreek@users.noreply.github.com>
---
 Marlin/src/feature/spindle_laser_types.h   | 13 +++++++++----
 Marlin/src/lcd/dogm/status_screen_DOGM.cpp |  1 -
 Marlin/src/lcd/menu/menu_item.h            |  1 +
 Marlin/src/libs/numtostr.cpp               | 16 ++++++++++------
 Marlin/src/libs/numtostr.h                 |  5 ++++-
 buildroot/tests/BIGTREE_SKR_PRO-tests      |  9 +++++++++
 6 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/Marlin/src/feature/spindle_laser_types.h b/Marlin/src/feature/spindle_laser_types.h
index 181c4d73ac0..c2994fd5c95 100644
--- a/Marlin/src/feature/spindle_laser_types.h
+++ b/Marlin/src/feature/spindle_laser_types.h
@@ -39,12 +39,17 @@ typedef IF<(SPEED_POWER_MAX > 255), uint16_t, uint8_t>::type cutter_cpower_t;
 
 #if CUTTER_UNIT_IS(RPM) && SPEED_POWER_MAX > 255
   typedef uint16_t cutter_power_t;
-  #define CUTTER_MENU_POWER_TYPE uint16_5
-  #define cutter_power2str       ui16tostr5rj
+  #define CUTTER_MENU_POWER_TYPE   uint16_5
+  #define cutter_power2str         ui16tostr5rj
 #else
   typedef uint8_t cutter_power_t;
-  #define CUTTER_MENU_POWER_TYPE uint8
-  #define cutter_power2str       ui8tostr3rj
+  #if CUTTER_UNIT_IS(PERCENT)
+    #define CUTTER_MENU_POWER_TYPE percent_3
+    #define cutter_power2str       pcttostrpctrj
+  #else
+    #define CUTTER_MENU_POWER_TYPE uint8
+    #define cutter_power2str       ui8tostr3rj
+  #endif
 #endif
 
 #if ENABLED(MARLIN_DEV_MODE)
diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp
index 751d47da55e..985041ede57 100644
--- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp
+++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp
@@ -618,7 +618,6 @@ void MarlinUI::draw_status_screen() {
       if (cutter.isReady && PAGE_CONTAINS(STATUS_CUTTER_TEXT_Y - INFO_FONT_ASCENT, STATUS_CUTTER_TEXT_Y - 1)) {
         #if CUTTER_UNIT_IS(PERCENT)
           lcd_put_u8str(STATUS_CUTTER_TEXT_X, STATUS_CUTTER_TEXT_Y, cutter_power2str(cutter.unitPower));
-          lcd_put_wchar('%');
         #elif CUTTER_UNIT_IS(RPM)
           lcd_put_u8str(STATUS_CUTTER_TEXT_X - 2, STATUS_CUTTER_TEXT_Y, ftostr51rj(float(cutter.unitPower) / 1000));
           lcd_put_wchar('K');
diff --git a/Marlin/src/lcd/menu/menu_item.h b/Marlin/src/lcd/menu/menu_item.h
index 6430021223c..188463c6c66 100644
--- a/Marlin/src/lcd/menu/menu_item.h
+++ b/Marlin/src/lcd/menu/menu_item.h
@@ -122,6 +122,7 @@ class TMenuEditItem : MenuEditItemBase {
 
 //                         NAME         TYPE      STRFUNC          SCALE         +ROUND
 DEFINE_MENU_EDIT_ITEM_TYPE(percent     ,uint8_t  ,ui8tostr4pctrj  , 100.f/255.f, 0.5f);  // 100%   right-justified
+DEFINE_MENU_EDIT_ITEM_TYPE(percent_3   ,uint8_t  ,pcttostrpctrj   ,   1     );   // 100%   right-justified
 DEFINE_MENU_EDIT_ITEM_TYPE(int3        ,int16_t  ,i16tostr3rj     ,   1     );   // 123, -12   right-justified
 DEFINE_MENU_EDIT_ITEM_TYPE(int4        ,int16_t  ,i16tostr4signrj ,   1     );   // 1234, -123 right-justified
 DEFINE_MENU_EDIT_ITEM_TYPE(int8        ,int8_t   ,i8tostr3rj      ,   1     );   // 123, -12   right-justified
diff --git a/Marlin/src/libs/numtostr.cpp b/Marlin/src/libs/numtostr.cpp
index c3efb2b25a8..90696e9ad3c 100644
--- a/Marlin/src/libs/numtostr.cpp
+++ b/Marlin/src/libs/numtostr.cpp
@@ -34,16 +34,20 @@ char conv[8] = { 0 };
 #define INTFLOAT(V,N) (((V) * 10 * pow(10, N) + ((V) < 0 ? -5: 5)) / 10)      // pow10?
 #define UINTFLOAT(V,N) INTFLOAT((V) < 0 ? -(V) : (V), N)
 
-// Convert a full-range unsigned 8bit int to a percentage
-const char* ui8tostr4pctrj(const uint8_t i) {
-  const uint8_t n = ui8_to_percent(i);
-  conv[3] = RJDIGIT(n, 100);
-  conv[4] = RJDIGIT(n, 10);
-  conv[5] = DIGIMOD(n, 1);
+// Format uint8_t (0-100) as rj string with 123% / _12% / __1% format
+const char* pcttostrpctrj(const uint8_t i) {
+  conv[3] = RJDIGIT(i, 100);
+  conv[4] = RJDIGIT(i, 10);
+  conv[5] = DIGIMOD(i, 1);
   conv[6] = '%';
   return &conv[3];
 }
 
+// Convert uint8_t (0-255) to a percentage, format as above
+const char* ui8tostr4pctrj(const uint8_t i) {
+  return pcttostrpctrj(ui8_to_percent(i));
+}
+
 // Convert unsigned 8bit int to string 123 format
 const char* ui8tostr3rj(const uint8_t i) {
   conv[4] = RJDIGIT(i, 100);
diff --git a/Marlin/src/libs/numtostr.h b/Marlin/src/libs/numtostr.h
index e7c1e67e12d..40c298af425 100644
--- a/Marlin/src/libs/numtostr.h
+++ b/Marlin/src/libs/numtostr.h
@@ -23,7 +23,10 @@
 
 #include <stdint.h>
 
-// Convert a full-range unsigned 8bit int to a percentage
+// Format uint8_t (0-100) as rj string with 123% / _12% / __1% format
+const char* pcttostrpctrj(const uint8_t i);
+
+// Convert uint8_t (0-255) to a percentage, format as above
 const char* ui8tostr4pctrj(const uint8_t i);
 
 // Convert uint8_t to string with 12 format
diff --git a/buildroot/tests/BIGTREE_SKR_PRO-tests b/buildroot/tests/BIGTREE_SKR_PRO-tests
index ff4a8d734e7..8dc433deb27 100755
--- a/buildroot/tests/BIGTREE_SKR_PRO-tests
+++ b/buildroot/tests/BIGTREE_SKR_PRO-tests
@@ -28,5 +28,14 @@ opt_set Y_DRIVER_TYPE TMC2130
 opt_enable BLTOUCH EEPROM_SETTINGS AUTO_BED_LEVELING_3POINT Z_SAFE_HOMING PINS_DEBUGGING
 exec_test $1 $2 "BigTreeTech SKR Pro 3 Extruders, Auto-Fan, BLTOUCH, mixed TMC drivers" "$3"
 
+restore_configs
+opt_set MOTHERBOARD BOARD_BTT_SKR_PRO_V1_1
+opt_set SERIAL_PORT -1
+opt_enable LASER_FEATURE REPRAP_DISCOUNT_SMART_CONTROLLER
+opt_set CUTTER_POWER_UNIT PERCENT
+opt_add SPINDLE_LASER_PWM_PIN HEATER_1_PIN
+opt_add SPINDLE_LASER_ENA_PIN HEATER_2_PIN
+exec_test $1 $2 "Laser, LCD, PERCENT power unit" "$3"
+
 # clean up
 restore_configs