From 0ebf3093beded17e18941887026367fc940c0f67 Mon Sep 17 00:00:00 2001
From: ellensp <ellensp@hotmsil.com>
Date: Thu, 28 Jan 2021 15:32:46 +1300
Subject: [PATCH 01/10] make report_state reply on initiating serial port.

---
 Marlin/src/feature/meatpack.cpp | 17 +++++++++--------
 Marlin/src/feature/meatpack.h   |  8 ++++----
 Marlin/src/gcode/queue.cpp      |  2 +-
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/Marlin/src/feature/meatpack.cpp b/Marlin/src/feature/meatpack.cpp
index 7dd856c8a7dc..7bc579128dc6 100644
--- a/Marlin/src/feature/meatpack.cpp
+++ b/Marlin/src/feature/meatpack.cpp
@@ -68,13 +68,13 @@ uint8_t meatPackLookupTable[16] = {
 
 TERN_(MP_DEBUG, uint8_t chars_decoded = 0); // Log the first 64 bytes after each reset
 
-void MeatPack::reset_state() {
+void MeatPack::reset_state(const uint8_t serial_num) {
   state = 0;
   cmd_is_next = false;
   second_char = 0;
   cmd_count = full_char_count = char_out_count = 0;
   TERN_(MP_DEBUG, chars_decoded = 0);
-  report_state();
+  report_state(serial_num);
 }
 
 /**
@@ -159,13 +159,13 @@ void MeatPack::handle_output_char(const uint8_t c) {
  * Process a MeatPack command byte to update the state.
  * Report the new state to serial.
  */
-void MeatPack::handle_command(const MeatPack_Command c) {
+void MeatPack::handle_command(const MeatPack_Command c, const uint8_t serial_num) {
   switch (c) {
     case MPCommand_QueryConfig:     break;
     case MPCommand_EnablePacking:   SBI(state, MPConfig_Bit_Active);   DEBUG_ECHOLNPGM("[MPDBG] ENA REC");   break;
     case MPCommand_DisablePacking:  CBI(state, MPConfig_Bit_Active);   DEBUG_ECHOLNPGM("[MPDBG] DIS REC");   break;
     case MPCommand_TogglePacking:   TBI(state, MPConfig_Bit_Active);   DEBUG_ECHOLNPGM("[MPDBG] TGL REC");   break;
-    case MPCommand_ResetAll:        reset_state();                     DEBUG_ECHOLNPGM("[MPDBG] RESET REC"); break;
+    case MPCommand_ResetAll:        reset_state(serial_num);                     DEBUG_ECHOLNPGM("[MPDBG] RESET REC"); break;
     case MPCommand_EnableNoSpaces:
       SBI(state, MPConfig_Bit_NoSpaces);
       meatPackLookupTable[kSpaceCharIdx] = kSpaceCharReplace;          DEBUG_ECHOLNPGM("[MPDBG] ENA NSP");   break;
@@ -174,12 +174,13 @@ void MeatPack::handle_command(const MeatPack_Command c) {
       meatPackLookupTable[kSpaceCharIdx] = ' ';                        DEBUG_ECHOLNPGM("[MPDBG] DIS NSP");   break;
     default:                                                           DEBUG_ECHOLNPGM("[MPDBG] UNK CMD REC");
   }
-  report_state();
+  report_state(serial_num);
 }
 
-void MeatPack::report_state() {
+void MeatPack::report_state(const uint8_t serial_num) {
   // NOTE: if any configuration vars are added below, the outgoing sync text for host plugin
   // should not contain the "PV' substring, as this is used to indicate protocol version
+  PORT_REDIRECT(serial_num);
   SERIAL_ECHOPGM("[MP] ");
   SERIAL_ECHOPGM(MeatPack_ProtocolVersion " ");
   serialprint_onoff(TEST(state, MPConfig_Bit_Active));
@@ -190,7 +191,7 @@ void MeatPack::report_state() {
  * Interpret a single character received from serial
  * according to the current meatpack state.
  */
-void MeatPack::handle_rx_char(const uint8_t c) {
+void MeatPack::handle_rx_char(const uint8_t c, const uint8_t serial_num) {
   if (c == kCommandByte) {                // A command (0xFF) byte?
     if (cmd_count) {                      // In fact, two in a row?
       cmd_is_next = true;                 // Then a MeatPack command follows
@@ -202,7 +203,7 @@ void MeatPack::handle_rx_char(const uint8_t c) {
   }
 
   if (cmd_is_next) {                      // Were two command bytes received?
-    handle_command((MeatPack_Command)c);  // Then the byte is a MeatPack command
+    handle_command((MeatPack_Command)c,serial_num);  // Then the byte is a MeatPack command
     cmd_is_next = false;
     return;
   }
diff --git a/Marlin/src/feature/meatpack.h b/Marlin/src/feature/meatpack.h
index b89f87844f4e..00ae735b4ec5 100644
--- a/Marlin/src/feature/meatpack.h
+++ b/Marlin/src/feature/meatpack.h
@@ -102,7 +102,7 @@ class MeatPack {
 
   // Pass in a character rx'd by SD card or serial. Automatically parses command/ctrl sequences,
   // and will control state internally.
-  static void handle_rx_char(const uint8_t c);
+  static void handle_rx_char(const uint8_t c, const uint8_t i);
 
   /**
    * After passing in rx'd char using above method, call this to get characters out.
@@ -112,11 +112,11 @@ class MeatPack {
    */
   static uint8_t get_result_char(char* const __restrict out);
 
-  static void reset_state();
-  static void report_state();
+  static void reset_state(const uint8_t serial_num);
+  static void report_state(const uint8_t serial_num);
   static uint8_t unpacked_char(register const uint8_t in);
   static uint8_t unpack_chars(const uint8_t pk, uint8_t* __restrict const chars_out);
-  static void handle_command(const MeatPack_Command c);
+  static void handle_command(const MeatPack_Command c, const uint8_t serial_num);
   static void handle_output_char(const uint8_t c);
   static void handle_rx_char_inner(const uint8_t c);
 };
diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index 51fec7d41c93..cc124698b846 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -479,7 +479,7 @@ void GCodeQueue::get_serial_commands() {
       if (c < 0) continue;
 
       #if ENABLED(MEATPACK)
-        meatpack.handle_rx_char(uint8_t(c));
+        meatpack.handle_rx_char(uint8_t(c),i);
         char c_res[2] = { 0, 0 };
         const uint8_t char_count = meatpack.get_result_char(c_res);
       #else

From 49eaf451260fe516791458ac08367d2affdaba99 Mon Sep 17 00:00:00 2001
From: ellensp <ellensp@hotmsil.com>
Date: Thu, 28 Jan 2021 16:05:49 +1300
Subject: [PATCH 02/10] fixes spaces

---
 Marlin/src/feature/meatpack.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Marlin/src/feature/meatpack.cpp b/Marlin/src/feature/meatpack.cpp
index 7bc579128dc6..30e2d9765098 100644
--- a/Marlin/src/feature/meatpack.cpp
+++ b/Marlin/src/feature/meatpack.cpp
@@ -165,7 +165,7 @@ void MeatPack::handle_command(const MeatPack_Command c, const uint8_t serial_num
     case MPCommand_EnablePacking:   SBI(state, MPConfig_Bit_Active);   DEBUG_ECHOLNPGM("[MPDBG] ENA REC");   break;
     case MPCommand_DisablePacking:  CBI(state, MPConfig_Bit_Active);   DEBUG_ECHOLNPGM("[MPDBG] DIS REC");   break;
     case MPCommand_TogglePacking:   TBI(state, MPConfig_Bit_Active);   DEBUG_ECHOLNPGM("[MPDBG] TGL REC");   break;
-    case MPCommand_ResetAll:        reset_state(serial_num);                     DEBUG_ECHOLNPGM("[MPDBG] RESET REC"); break;
+    case MPCommand_ResetAll:        reset_state(serial_num);           DEBUG_ECHOLNPGM("[MPDBG] RESET REC"); break;
     case MPCommand_EnableNoSpaces:
       SBI(state, MPConfig_Bit_NoSpaces);
       meatPackLookupTable[kSpaceCharIdx] = kSpaceCharReplace;          DEBUG_ECHOLNPGM("[MPDBG] ENA NSP");   break;
@@ -203,7 +203,7 @@ void MeatPack::handle_rx_char(const uint8_t c, const uint8_t serial_num) {
   }
 
   if (cmd_is_next) {                      // Were two command bytes received?
-    handle_command((MeatPack_Command)c,serial_num);  // Then the byte is a MeatPack command
+    handle_command((MeatPack_Command)c, serial_num);  // Then the byte is a MeatPack command
     cmd_is_next = false;
     return;
   }

From c95ae7450af2053239c50b354be5fb26abdd3974 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Thu, 28 Jan 2021 00:24:32 -0600
Subject: [PATCH 03/10] Add serial_index_t

---
 Marlin/src/core/serial.cpp      |  2 +-
 Marlin/src/core/serial.h        |  4 +++-
 Marlin/src/feature/meatpack.cpp | 18 +++++++++---------
 Marlin/src/feature/meatpack.h   |  6 +++---
 Marlin/src/gcode/host/M118.cpp  |  2 +-
 Marlin/src/gcode/queue.cpp      | 28 ++++++++++++++--------------
 Marlin/src/gcode/queue.h        |  4 ++--
 Marlin/src/sd/cardreader.cpp    |  2 +-
 Marlin/src/sd/cardreader.h      |  2 +-
 9 files changed, 35 insertions(+), 33 deletions(-)

diff --git a/Marlin/src/core/serial.cpp b/Marlin/src/core/serial.cpp
index 7e53f3851786..5871c61f9966 100644
--- a/Marlin/src/core/serial.cpp
+++ b/Marlin/src/core/serial.cpp
@@ -34,7 +34,7 @@ PGMSTR(SP_X_STR, " X");  PGMSTR(SP_Y_STR, " Y");  PGMSTR(SP_Z_STR, " Z");  PGMST
 PGMSTR(SP_X_LBL, " X:"); PGMSTR(SP_Y_LBL, " Y:"); PGMSTR(SP_Z_LBL, " Z:"); PGMSTR(SP_E_LBL, " E:");
 
 #if HAS_MULTI_SERIAL
-  int8_t serial_port_index = 0;
+  serial_index_t serial_port_index = 0;
 #endif
 
 void serialprintPGM(PGM_P str) {
diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h
index 1dd3cd9cd06a..ae1ef4169f20 100644
--- a/Marlin/src/core/serial.h
+++ b/Marlin/src/core/serial.h
@@ -61,9 +61,11 @@ extern uint8_t marlin_debug_flags;
 //
 // Serial redirection
 //
+typedef int8_t serial_index_t;
 #define SERIAL_BOTH 0x7F
+
 #if HAS_MULTI_SERIAL
-  extern int8_t serial_port_index;
+  extern serial_index_t serial_port_index;
   #define _PORT_REDIRECT(n,p)   REMEMBER(n,serial_port_index,p)
   #define _PORT_RESTORE(n)      RESTORE(n)
 
diff --git a/Marlin/src/feature/meatpack.cpp b/Marlin/src/feature/meatpack.cpp
index 30e2d9765098..427c0f5e6027 100644
--- a/Marlin/src/feature/meatpack.cpp
+++ b/Marlin/src/feature/meatpack.cpp
@@ -68,13 +68,13 @@ uint8_t meatPackLookupTable[16] = {
 
 TERN_(MP_DEBUG, uint8_t chars_decoded = 0); // Log the first 64 bytes after each reset
 
-void MeatPack::reset_state(const uint8_t serial_num) {
+void MeatPack::reset_state(const serial_index_t serial_ind) {
   state = 0;
   cmd_is_next = false;
   second_char = 0;
   cmd_count = full_char_count = char_out_count = 0;
   TERN_(MP_DEBUG, chars_decoded = 0);
-  report_state(serial_num);
+  report_state(serial_ind);
 }
 
 /**
@@ -159,13 +159,13 @@ void MeatPack::handle_output_char(const uint8_t c) {
  * Process a MeatPack command byte to update the state.
  * Report the new state to serial.
  */
-void MeatPack::handle_command(const MeatPack_Command c, const uint8_t serial_num) {
+void MeatPack::handle_command(const MeatPack_Command c, const serial_index_t serial_ind) {
   switch (c) {
     case MPCommand_QueryConfig:     break;
     case MPCommand_EnablePacking:   SBI(state, MPConfig_Bit_Active);   DEBUG_ECHOLNPGM("[MPDBG] ENA REC");   break;
     case MPCommand_DisablePacking:  CBI(state, MPConfig_Bit_Active);   DEBUG_ECHOLNPGM("[MPDBG] DIS REC");   break;
     case MPCommand_TogglePacking:   TBI(state, MPConfig_Bit_Active);   DEBUG_ECHOLNPGM("[MPDBG] TGL REC");   break;
-    case MPCommand_ResetAll:        reset_state(serial_num);           DEBUG_ECHOLNPGM("[MPDBG] RESET REC"); break;
+    case MPCommand_ResetAll:        reset_state(serial_ind);           DEBUG_ECHOLNPGM("[MPDBG] RESET REC"); break;
     case MPCommand_EnableNoSpaces:
       SBI(state, MPConfig_Bit_NoSpaces);
       meatPackLookupTable[kSpaceCharIdx] = kSpaceCharReplace;          DEBUG_ECHOLNPGM("[MPDBG] ENA NSP");   break;
@@ -174,13 +174,13 @@ void MeatPack::handle_command(const MeatPack_Command c, const uint8_t serial_num
       meatPackLookupTable[kSpaceCharIdx] = ' ';                        DEBUG_ECHOLNPGM("[MPDBG] DIS NSP");   break;
     default:                                                           DEBUG_ECHOLNPGM("[MPDBG] UNK CMD REC");
   }
-  report_state(serial_num);
+  report_state(serial_ind);
 }
 
-void MeatPack::report_state(const uint8_t serial_num) {
+void MeatPack::report_state(const serial_index_t serial_ind) {
   // NOTE: if any configuration vars are added below, the outgoing sync text for host plugin
   // should not contain the "PV' substring, as this is used to indicate protocol version
-  PORT_REDIRECT(serial_num);
+  PORT_REDIRECT(serial_ind);
   SERIAL_ECHOPGM("[MP] ");
   SERIAL_ECHOPGM(MeatPack_ProtocolVersion " ");
   serialprint_onoff(TEST(state, MPConfig_Bit_Active));
@@ -191,7 +191,7 @@ void MeatPack::report_state(const uint8_t serial_num) {
  * Interpret a single character received from serial
  * according to the current meatpack state.
  */
-void MeatPack::handle_rx_char(const uint8_t c, const uint8_t serial_num) {
+void MeatPack::handle_rx_char(const uint8_t c, const serial_index_t serial_ind) {
   if (c == kCommandByte) {                // A command (0xFF) byte?
     if (cmd_count) {                      // In fact, two in a row?
       cmd_is_next = true;                 // Then a MeatPack command follows
@@ -203,7 +203,7 @@ void MeatPack::handle_rx_char(const uint8_t c, const uint8_t serial_num) {
   }
 
   if (cmd_is_next) {                      // Were two command bytes received?
-    handle_command((MeatPack_Command)c, serial_num);  // Then the byte is a MeatPack command
+    handle_command((MeatPack_Command)c, serial_ind);  // Then the byte is a MeatPack command
     cmd_is_next = false;
     return;
   }
diff --git a/Marlin/src/feature/meatpack.h b/Marlin/src/feature/meatpack.h
index 00ae735b4ec5..0c1c432f158a 100644
--- a/Marlin/src/feature/meatpack.h
+++ b/Marlin/src/feature/meatpack.h
@@ -112,11 +112,11 @@ class MeatPack {
    */
   static uint8_t get_result_char(char* const __restrict out);
 
-  static void reset_state(const uint8_t serial_num);
-  static void report_state(const uint8_t serial_num);
+  static void reset_state(const serial_index_t serial_ind);
+  static void report_state(const serial_index_t serial_ind);
   static uint8_t unpacked_char(register const uint8_t in);
   static uint8_t unpack_chars(const uint8_t pk, uint8_t* __restrict const chars_out);
-  static void handle_command(const MeatPack_Command c, const uint8_t serial_num);
+  static void handle_command(const MeatPack_Command c, const serial_index_t serial_ind);
   static void handle_output_char(const uint8_t c);
   static void handle_rx_char_inner(const uint8_t c);
 };
diff --git a/Marlin/src/gcode/host/M118.cpp b/Marlin/src/gcode/host/M118.cpp
index 27207b717210..7a77861e2bdb 100644
--- a/Marlin/src/gcode/host/M118.cpp
+++ b/Marlin/src/gcode/host/M118.cpp
@@ -53,7 +53,7 @@ void GcodeSuite::M118() {
   }
 
   #if HAS_MULTI_SERIAL
-    const int8_t old_serial = serial_port_index;
+    const serial_index_t old_serial = serial_port_index;
     if (WITHIN(port, 0, NUM_SERIAL))
       serial_port_index = (
         port == 0 ? SERIAL_BOTH
diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index cc124698b846..29105d098767 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -153,14 +153,14 @@ void GCodeQueue::_commit_command(bool say_ok
  */
 bool GCodeQueue::_enqueue(const char* cmd, bool say_ok/*=false*/
   #if HAS_MULTI_SERIAL
-    , int16_t pn/*=-1*/
+    , serial_index_t serial_ind/*=-1*/
   #endif
 ) {
   if (*cmd == ';' || length >= BUFSIZE) return false;
   strcpy(command_buffer[index_w], cmd);
   _commit_command(say_ok
     #if HAS_MULTI_SERIAL
-      , pn
+      , serial_ind
     #endif
   );
   return true;
@@ -289,9 +289,9 @@ void GCodeQueue::enqueue_now_P(PGM_P const pgcode) {
  */
 void GCodeQueue::ok_to_send() {
   #if HAS_MULTI_SERIAL
-    const int16_t pn = command_port();
-    if (pn < 0) return;
-    PORT_REDIRECT(pn);                    // Reply to the serial port that sent the command
+    const serial_index_t serial_ind = command_port();
+    if (serial_ind < 0) return;
+    PORT_REDIRECT(serial_ind);                    // Reply to the serial port that sent the command
   #endif
   if (!send_ok[index_r]) return;
   SERIAL_ECHOPGM(STR_OK);
@@ -314,14 +314,14 @@ void GCodeQueue::ok_to_send() {
  * indicate that a command needs to be re-sent.
  */
 void GCodeQueue::flush_and_request_resend() {
-  const int16_t pn = command_port();
+  const serial_index_t serial_ind = command_port();
   #if HAS_MULTI_SERIAL
-    if (pn < 0) return;
-    PORT_REDIRECT(pn);                    // Reply to the serial port that sent the command
+    if (serial_ind < 0) return;
+    PORT_REDIRECT(serial_ind);                    // Reply to the serial port that sent the command
   #endif
   SERIAL_FLUSH();
   SERIAL_ECHOPGM(STR_RESEND);
-  SERIAL_ECHOLN(last_N[pn] + 1);
+  SERIAL_ECHOLN(last_N[serial_ind] + 1);
   ok_to_send();
 }
 
@@ -348,14 +348,14 @@ inline int read_serial(const uint8_t index) {
   }
 }
 
-void GCodeQueue::gcode_line_error(PGM_P const err, const int8_t pn) {
-  PORT_REDIRECT(pn);                      // Reply to the serial port that sent the command
+void GCodeQueue::gcode_line_error(PGM_P const err, const serial_index_t serial_ind) {
+  PORT_REDIRECT(serial_ind);                      // Reply to the serial port that sent the command
   SERIAL_ERROR_START();
   serialprintPGM(err);
-  SERIAL_ECHOLN(last_N[pn]);
-  while (read_serial(pn) != -1);          // Clear out the RX buffer
+  SERIAL_ECHOLN(last_N[serial_ind]);
+  while (read_serial(serial_ind) != -1);          // Clear out the RX buffer
   flush_and_request_resend();
-  serial_count[pn] = 0;
+  serial_count[serial_ind] = 0;
 }
 
 FORCE_INLINE bool is_M29(const char * const cmd) {  // matches "M29" & "M29 ", but not "M290", etc
diff --git a/Marlin/src/gcode/queue.h b/Marlin/src/gcode/queue.h
index 57d4beecb84d..6c22ca207d65 100644
--- a/Marlin/src/gcode/queue.h
+++ b/Marlin/src/gcode/queue.h
@@ -165,7 +165,7 @@ class GCodeQueue {
 
   static bool _enqueue(const char* cmd, bool say_ok=false
     #if HAS_MULTI_SERIAL
-      , int16_t p=-1
+      , serial_index_t serial_ind=-1
     #endif
   );
 
@@ -181,7 +181,7 @@ class GCodeQueue {
    */
   static bool enqueue_one(const char* cmd);
 
-  static void gcode_line_error(PGM_P const err, const int8_t pn);
+  static void gcode_line_error(PGM_P const err, const serial_index_t serial_ind);
 
 };
 
diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp
index 307f31e43115..2e9101ff84cd 100644
--- a/Marlin/src/sd/cardreader.cpp
+++ b/Marlin/src/sd/cardreader.cpp
@@ -1229,7 +1229,7 @@ void CardReader::fileHasFinished() {
   uint8_t CardReader::auto_report_sd_interval = 0;
   millis_t CardReader::next_sd_report_ms;
   #if HAS_MULTI_SERIAL
-    int8_t CardReader::auto_report_port;
+    serial_index_t CardReader::auto_report_port;
   #endif
 
   void CardReader::auto_report_sd_status() {
diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h
index 7a312b1b572d..272e213800aa 100644
--- a/Marlin/src/sd/cardreader.h
+++ b/Marlin/src/sd/cardreader.h
@@ -267,7 +267,7 @@ class CardReader {
     static uint8_t auto_report_sd_interval;
     static millis_t next_sd_report_ms;
     #if HAS_MULTI_SERIAL
-      static int8_t auto_report_port;
+      static serial_index_t auto_report_port;
     #endif
   #endif
 

From eea496725c212192f1c8a5aef448287b143fdfe6 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Thu, 28 Jan 2021 00:26:28 -0600
Subject: [PATCH 04/10] Use 'p' for port index

---
 Marlin/src/gcode/queue.cpp | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index 29105d098767..0701d468ad47 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -473,13 +473,13 @@ void GCodeQueue::get_serial_commands() {
    * Loop while serial characters are incoming and the queue is not full
    */
   while (length < BUFSIZE && serial_data_available()) {
-    LOOP_L_N(i, NUM_SERIAL) {
+    LOOP_L_N(p, NUM_SERIAL) {
 
-      const int c = read_serial(i);
+      const int c = read_serial(p);
       if (c < 0) continue;
 
       #if ENABLED(MEATPACK)
-        meatpack.handle_rx_char(uint8_t(c),i);
+        meatpack.handle_rx_char(uint8_t(c), p);
         char c_res[2] = { 0, 0 };
         const uint8_t char_count = meatpack.get_result_char(c_res);
       #else
@@ -492,10 +492,10 @@ void GCodeQueue::get_serial_commands() {
         if (ISEOL(serial_char)) {
 
           // Reset our state, continue if the line was empty
-          if (process_line_done(serial_input_state[i], serial_line_buffer[i], serial_count[i]))
+          if (process_line_done(serial_input_state[p], serial_line_buffer[p], serial_count[p]))
             continue;
 
-          char* command = serial_line_buffer[i];
+          char* command = serial_line_buffer[p];
 
           while (*command == ' ') command++;                   // Skip leading spaces
           char *npos = (*command == 'N') ? command : nullptr;  // Require the N parameter to start the line
@@ -511,25 +511,25 @@ void GCodeQueue::get_serial_commands() {
 
             const long gcode_N = strtol(npos + 1, nullptr, 10);
 
-            if (gcode_N != last_N[i] + 1 && !M110)
-              return gcode_line_error(PSTR(STR_ERR_LINE_NO), i);
+            if (gcode_N != last_N[p] + 1 && !M110)
+              return gcode_line_error(PSTR(STR_ERR_LINE_NO), p);
 
             char *apos = strrchr(command, '*');
             if (apos) {
               uint8_t checksum = 0, count = uint8_t(apos - command);
               while (count) checksum ^= command[--count];
               if (strtol(apos + 1, nullptr, 10) != checksum)
-                return gcode_line_error(PSTR(STR_ERR_CHECKSUM_MISMATCH), i);
+                return gcode_line_error(PSTR(STR_ERR_CHECKSUM_MISMATCH), p);
             }
             else
-              return gcode_line_error(PSTR(STR_ERR_NO_CHECKSUM), i);
+              return gcode_line_error(PSTR(STR_ERR_NO_CHECKSUM), p);
 
-            last_N[i] = gcode_N;
+            last_N[p] = gcode_N;
           }
           #if ENABLED(SDSUPPORT)
             // Pronterface "M29" and "M29 " has no line number
             else if (card.flag.saving && !is_M29(command))
-              return gcode_line_error(PSTR(STR_ERR_NO_CHECKSUM), i);
+              return gcode_line_error(PSTR(STR_ERR_NO_CHECKSUM), p);
           #endif
 
           //
@@ -547,7 +547,7 @@ void GCodeQueue::get_serial_commands() {
                 #if ENABLED(BEZIER_CURVE_SUPPORT)
                   case 5:
                 #endif
-                  PORT_REDIRECT(i);                      // Reply to the serial port that sent the command
+                  PORT_REDIRECT(p);                      // Reply to the serial port that sent the command
                   SERIAL_ECHOLNPGM(STR_ERR_STOPPED);
                   LCD_MESSAGEPGM(MSG_STOPPED);
                   break;
@@ -569,9 +569,9 @@ void GCodeQueue::get_serial_commands() {
           #endif
 
           // Add the command to the queue
-          _enqueue(serial_line_buffer[i], true
+          _enqueue(serial_line_buffer[p], true
             #if HAS_MULTI_SERIAL
-              , i
+              , p
             #endif
           );
         }

From b54cd116ba9c084a348f4b77c9db8176046609aa Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Thu, 28 Jan 2021 00:37:34 -0600
Subject: [PATCH 05/10] redirect before command

---
 Marlin/src/feature/meatpack.cpp | 15 +++++++--------
 Marlin/src/feature/meatpack.h   |  8 ++++----
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/Marlin/src/feature/meatpack.cpp b/Marlin/src/feature/meatpack.cpp
index 427c0f5e6027..88968108f27c 100644
--- a/Marlin/src/feature/meatpack.cpp
+++ b/Marlin/src/feature/meatpack.cpp
@@ -68,13 +68,12 @@ uint8_t meatPackLookupTable[16] = {
 
 TERN_(MP_DEBUG, uint8_t chars_decoded = 0); // Log the first 64 bytes after each reset
 
-void MeatPack::reset_state(const serial_index_t serial_ind) {
+void MeatPack::reset_state() {
   state = 0;
   cmd_is_next = false;
   second_char = 0;
   cmd_count = full_char_count = char_out_count = 0;
   TERN_(MP_DEBUG, chars_decoded = 0);
-  report_state(serial_ind);
 }
 
 /**
@@ -159,13 +158,13 @@ void MeatPack::handle_output_char(const uint8_t c) {
  * Process a MeatPack command byte to update the state.
  * Report the new state to serial.
  */
-void MeatPack::handle_command(const MeatPack_Command c, const serial_index_t serial_ind) {
+void MeatPack::handle_command(const MeatPack_Command c) {
   switch (c) {
     case MPCommand_QueryConfig:     break;
     case MPCommand_EnablePacking:   SBI(state, MPConfig_Bit_Active);   DEBUG_ECHOLNPGM("[MPDBG] ENA REC");   break;
     case MPCommand_DisablePacking:  CBI(state, MPConfig_Bit_Active);   DEBUG_ECHOLNPGM("[MPDBG] DIS REC");   break;
     case MPCommand_TogglePacking:   TBI(state, MPConfig_Bit_Active);   DEBUG_ECHOLNPGM("[MPDBG] TGL REC");   break;
-    case MPCommand_ResetAll:        reset_state(serial_ind);           DEBUG_ECHOLNPGM("[MPDBG] RESET REC"); break;
+    case MPCommand_ResetAll:        reset_state();                     DEBUG_ECHOLNPGM("[MPDBG] RESET REC"); break;
     case MPCommand_EnableNoSpaces:
       SBI(state, MPConfig_Bit_NoSpaces);
       meatPackLookupTable[kSpaceCharIdx] = kSpaceCharReplace;          DEBUG_ECHOLNPGM("[MPDBG] ENA NSP");   break;
@@ -174,13 +173,12 @@ void MeatPack::handle_command(const MeatPack_Command c, const serial_index_t ser
       meatPackLookupTable[kSpaceCharIdx] = ' ';                        DEBUG_ECHOLNPGM("[MPDBG] DIS NSP");   break;
     default:                                                           DEBUG_ECHOLNPGM("[MPDBG] UNK CMD REC");
   }
-  report_state(serial_ind);
+  report_state();
 }
 
-void MeatPack::report_state(const serial_index_t serial_ind) {
+void MeatPack::report_state() {
   // NOTE: if any configuration vars are added below, the outgoing sync text for host plugin
   // should not contain the "PV' substring, as this is used to indicate protocol version
-  PORT_REDIRECT(serial_ind);
   SERIAL_ECHOPGM("[MP] ");
   SERIAL_ECHOPGM(MeatPack_ProtocolVersion " ");
   serialprint_onoff(TEST(state, MPConfig_Bit_Active));
@@ -203,7 +201,8 @@ void MeatPack::handle_rx_char(const uint8_t c, const serial_index_t serial_ind)
   }
 
   if (cmd_is_next) {                      // Were two command bytes received?
-    handle_command((MeatPack_Command)c, serial_ind);  // Then the byte is a MeatPack command
+    PORT_REDIRECT(serial_ind);
+    handle_command((MeatPack_Command)c);  // Then the byte is a MeatPack command
     cmd_is_next = false;
     return;
   }
diff --git a/Marlin/src/feature/meatpack.h b/Marlin/src/feature/meatpack.h
index 0c1c432f158a..c248ed536bcf 100644
--- a/Marlin/src/feature/meatpack.h
+++ b/Marlin/src/feature/meatpack.h
@@ -102,7 +102,7 @@ class MeatPack {
 
   // Pass in a character rx'd by SD card or serial. Automatically parses command/ctrl sequences,
   // and will control state internally.
-  static void handle_rx_char(const uint8_t c, const uint8_t i);
+  static void handle_rx_char(const uint8_t c, const serial_index_t serial_ind);
 
   /**
    * After passing in rx'd char using above method, call this to get characters out.
@@ -112,11 +112,11 @@ class MeatPack {
    */
   static uint8_t get_result_char(char* const __restrict out);
 
-  static void reset_state(const serial_index_t serial_ind);
-  static void report_state(const serial_index_t serial_ind);
+  static void reset_state();
+  static void report_state();
   static uint8_t unpacked_char(register const uint8_t in);
   static uint8_t unpack_chars(const uint8_t pk, uint8_t* __restrict const chars_out);
-  static void handle_command(const MeatPack_Command c, const serial_index_t serial_ind);
+  static void handle_command(const MeatPack_Command c);
   static void handle_output_char(const uint8_t c);
   static void handle_rx_char_inner(const uint8_t c);
 };

From 060f6ffe7cefc59f1fbf9a61a99dd55adb760d28 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Thu, 28 Jan 2021 00:48:34 -0600
Subject: [PATCH 06/10] More serial_index_t

---
 Marlin/src/gcode/queue.cpp | 8 ++++----
 Marlin/src/gcode/queue.h   | 9 +++------
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index 0701d468ad47..463f84f4d1fc 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -89,7 +89,7 @@ char GCodeQueue::command_buffer[BUFSIZE][MAX_CMD_SIZE];
  * The port that the command was received on
  */
 #if HAS_MULTI_SERIAL
-  int16_t GCodeQueue::port[BUFSIZE];
+  serial_index_t GCodeQueue::port[BUFSIZE];
 #endif
 
 /**
@@ -136,11 +136,11 @@ void GCodeQueue::clear() {
  */
 void GCodeQueue::_commit_command(bool say_ok
   #if HAS_MULTI_SERIAL
-    , int16_t p/*=-1*/
+    , serial_index_t serial_ind
   #endif
 ) {
   send_ok[index_w] = say_ok;
-  TERN_(HAS_MULTI_SERIAL, port[index_w] = p);
+  TERN_(HAS_MULTI_SERIAL, port[index_w] = serial_ind);
   TERN_(POWER_LOSS_RECOVERY, recovery.commit_sdpos(index_w));
   if (++index_w >= BUFSIZE) index_w = 0;
   length++;
@@ -153,7 +153,7 @@ void GCodeQueue::_commit_command(bool say_ok
  */
 bool GCodeQueue::_enqueue(const char* cmd, bool say_ok/*=false*/
   #if HAS_MULTI_SERIAL
-    , serial_index_t serial_ind/*=-1*/
+    , serial_index_t serial_ind
   #endif
 ) {
   if (*cmd == ';' || length >= BUFSIZE) return false;
diff --git a/Marlin/src/gcode/queue.h b/Marlin/src/gcode/queue.h
index 6c22ca207d65..d677146a7dbe 100644
--- a/Marlin/src/gcode/queue.h
+++ b/Marlin/src/gcode/queue.h
@@ -56,12 +56,9 @@ class GCodeQueue {
    * The port that the command was received on
    */
   #if HAS_MULTI_SERIAL
-    static int16_t port[BUFSIZE];
+    static serial_index_t port[BUFSIZE];
   #endif
-
-  static int16_t command_port() {
-    return TERN0(HAS_MULTI_SERIAL, port[index_r]);
-  }
+  static inline serial_index_t command_port() { return TERN0(HAS_MULTI_SERIAL, port[index_r]); }
 
   GCodeQueue();
 
@@ -159,7 +156,7 @@ class GCodeQueue {
 
   static void _commit_command(bool say_ok
     #if HAS_MULTI_SERIAL
-      , int16_t p=-1
+      , serial_index_t serial_ind=-1
     #endif
   );
 

From 83c2afa92e497780aa548e9b8be2d8de9793c338 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Thu, 28 Jan 2021 00:49:09 -0600
Subject: [PATCH 07/10] defaults

---
 Marlin/src/gcode/queue.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index 463f84f4d1fc..5dcb9d5a9500 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -136,7 +136,7 @@ void GCodeQueue::clear() {
  */
 void GCodeQueue::_commit_command(bool say_ok
   #if HAS_MULTI_SERIAL
-    , serial_index_t serial_ind
+    , serial_index_t serial_ind/*=-1*/
   #endif
 ) {
   send_ok[index_w] = say_ok;
@@ -153,7 +153,7 @@ void GCodeQueue::_commit_command(bool say_ok
  */
 bool GCodeQueue::_enqueue(const char* cmd, bool say_ok/*=false*/
   #if HAS_MULTI_SERIAL
-    , serial_index_t serial_ind
+    , serial_index_t serial_ind/*=-1*/
   #endif
 ) {
   if (*cmd == ';' || length >= BUFSIZE) return false;

From 2af2de0ee4710ece6289e472bf9c75973909d535 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Thu, 28 Jan 2021 00:57:36 -0600
Subject: [PATCH 08/10] Add a note

---
 Marlin/src/gcode/queue.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index 5dcb9d5a9500..4f5d3780adf6 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -290,7 +290,7 @@ void GCodeQueue::enqueue_now_P(PGM_P const pgcode) {
 void GCodeQueue::ok_to_send() {
   #if HAS_MULTI_SERIAL
     const serial_index_t serial_ind = command_port();
-    if (serial_ind < 0) return;
+    if (serial_ind < 0) return;                   // Never mind. Command came from SD or Flash Drive
     PORT_REDIRECT(serial_ind);                    // Reply to the serial port that sent the command
   #endif
   if (!send_ok[index_r]) return;
@@ -316,7 +316,7 @@ void GCodeQueue::ok_to_send() {
 void GCodeQueue::flush_and_request_resend() {
   const serial_index_t serial_ind = command_port();
   #if HAS_MULTI_SERIAL
-    if (serial_ind < 0) return;
+    if (serial_ind < 0) return;                   // Never mind. Command came from SD or Flash Drive
     PORT_REDIRECT(serial_ind);                    // Reply to the serial port that sent the command
   #endif
   SERIAL_FLUSH();

From b77bba5467682bfed7e6e968ccdfd2998c5b8ed1 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Thu, 28 Jan 2021 00:58:21 -0600
Subject: [PATCH 09/10] p

---
 Marlin/src/gcode/queue.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index 4f5d3780adf6..1059997edb98 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -576,7 +576,7 @@ void GCodeQueue::get_serial_commands() {
           );
         }
         else
-          process_stream_char(serial_char, serial_input_state[i], serial_line_buffer[i], serial_count[i]);
+          process_stream_char(serial_char, serial_input_state[p], serial_line_buffer[p], serial_count[p]);
 
       } // char_count loop
 

From d7d1ad93ec8dc161030713cbf0b75a0015cf93e7 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Thu, 28 Jan 2021 01:00:27 -0600
Subject: [PATCH 10/10] fix trigraph warning

---
 Marlin/src/feature/spindle_laser.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/src/feature/spindle_laser.h b/Marlin/src/feature/spindle_laser.h
index 57fc136c8ca3..d50bc7eb42d2 100644
--- a/Marlin/src/feature/spindle_laser.h
+++ b/Marlin/src/feature/spindle_laser.h
@@ -157,7 +157,7 @@ class SpindleLaser {
         #elif CUTTER_UNIT_IS(RPM)
           2
         #else
-          #error "CUTTER_UNIT_IS(???)"
+          #error "CUTTER_UNIT_IS(unknown)"
         #endif
       ));
     }