Browse Source

Support a third serial port (#21784)

ellensp 4 years ago
parent
commit
02405add76
No account linked to committer's email address

+ 7
- 0
Marlin/Configuration.h View File

112
 //#define SERIAL_PORT_2 -1
112
 //#define SERIAL_PORT_2 -1
113
 
113
 
114
 /**
114
 /**
115
+ * Select a third serial port on the board to use for communication with the host.
116
+ * Currently only supported for AVR, DUE, LPC1768/9 and STM32/STM32F1
117
+ * :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
118
+ */
119
+//#define SERIAL_PORT_3 1
120
+
121
+/**
115
  * This setting determines the communication speed of the printer.
122
  * This setting determines the communication speed of the printer.
116
  *
123
  *
117
  * 250000 works in most cases, but you might try a lower speed if
124
  * 250000 works in most cases, but you might try a lower speed if

+ 7
- 0
Marlin/src/HAL/AVR/HAL.h View File

103
     #endif
103
     #endif
104
     #define MYSERIAL2 customizedSerial2
104
     #define MYSERIAL2 customizedSerial2
105
   #endif
105
   #endif
106
+
107
+  #ifdef SERIAL_PORT_3
108
+    #if !WITHIN(SERIAL_PORT_3, -1, 3)
109
+      #error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial."
110
+    #endif
111
+    #define MYSERIAL3 customizedSerial3
112
+  #endif
106
 #endif
113
 #endif
107
 
114
 
108
 #ifdef MMU2_SERIAL_PORT
115
 #ifdef MMU2_SERIAL_PORT

+ 16
- 0
Marlin/src/HAL/AVR/MarlinSerial.cpp View File

585
 
585
 
586
 #endif // SERIAL_PORT_2
586
 #endif // SERIAL_PORT_2
587
 
587
 
588
+#ifdef SERIAL_PORT_3
589
+
590
+  // Hookup ISR handlers
591
+  ISR(SERIAL_REGNAME(USART, SERIAL_PORT_3, _RX_vect)) {
592
+    MarlinSerial<MarlinSerialCfg<SERIAL_PORT_3>>::store_rxd_char();
593
+  }
594
+
595
+  ISR(SERIAL_REGNAME(USART, SERIAL_PORT_3, _UDRE_vect)) {
596
+    MarlinSerial<MarlinSerialCfg<SERIAL_PORT_3>>::_tx_udr_empty_irq();
597
+  }
598
+
599
+  template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT_3> >;
600
+  MSerialT3 customizedSerial3(MSerialT3::HasEmergencyParser);
601
+
602
+#endif // SERIAL_PORT_3
603
+
588
 #ifdef MMU2_SERIAL_PORT
604
 #ifdef MMU2_SERIAL_PORT
589
 
605
 
590
   ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _RX_vect)) {
606
   ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _RX_vect)) {

+ 5
- 0
Marlin/src/HAL/AVR/MarlinSerial.h View File

246
     extern MSerialT2 customizedSerial2;
246
     extern MSerialT2 customizedSerial2;
247
   #endif
247
   #endif
248
 
248
 
249
+  #ifdef SERIAL_PORT_3
250
+    typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_3> > > MSerialT3;
251
+    extern MSerialT3 customizedSerial3;
252
+  #endif
253
+
249
 #endif // !USBCON
254
 #endif // !USBCON
250
 
255
 
251
 #ifdef MMU2_SERIAL_PORT
256
 #ifdef MMU2_SERIAL_PORT

+ 10
- 0
Marlin/src/HAL/DUE/HAL.h View File

68
   #endif
68
   #endif
69
 #endif
69
 #endif
70
 
70
 
71
+#ifdef SERIAL_PORT_3
72
+  #if SERIAL_PORT_3 == -1 || ENABLED(EMERGENCY_PARSER)
73
+    #define MYSERIAL3 customizedSerial3
74
+  #elif WITHIN(SERIAL_PORT_3, 0, 3)
75
+    #define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
76
+  #else
77
+    #error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial."
78
+  #endif
79
+#endif
80
+
71
 #ifdef MMU2_SERIAL_PORT
81
 #ifdef MMU2_SERIAL_PORT
72
   #if WITHIN(MMU2_SERIAL_PORT, 0, 3)
82
   #if WITHIN(MMU2_SERIAL_PORT, 0, 3)
73
     #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
83
     #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)

+ 5
- 0
Marlin/src/HAL/DUE/MarlinSerial.cpp View File

486
   MSerialT2 customizedSerial2(MarlinSerialCfg<SERIAL_PORT_2>::EMERGENCYPARSER);
486
   MSerialT2 customizedSerial2(MarlinSerialCfg<SERIAL_PORT_2>::EMERGENCYPARSER);
487
 #endif
487
 #endif
488
 
488
 
489
+#if defined(SERIAL_PORT_3) && SERIAL_PORT_3 >= 0
490
+  template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT_3> >;
491
+  MSerialT3 customizedSerial3(MarlinSerialCfg<SERIAL_PORT_3>::EMERGENCYPARSER);
492
+#endif
493
+
489
 #endif // ARDUINO_ARCH_SAM
494
 #endif // ARDUINO_ARCH_SAM

+ 5
- 0
Marlin/src/HAL/DUE/MarlinSerial.h View File

149
   typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
149
   typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
150
   extern MSerialT2 customizedSerial2;
150
   extern MSerialT2 customizedSerial2;
151
 #endif
151
 #endif
152
+
153
+#if defined(SERIAL_PORT_3) && SERIAL_PORT_3 >= 0
154
+  typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_3> > > MSerialT3;
155
+  extern MSerialT3 customizedSerial3;
156
+#endif

+ 3
- 0
Marlin/src/HAL/DUE/MarlinSerialUSB.cpp View File

134
 #if SERIAL_PORT_2 == -1
134
 #if SERIAL_PORT_2 == -1
135
   MSerialT2 customizedSerial2(TERN0(EMERGENCY_PARSER, true));
135
   MSerialT2 customizedSerial2(TERN0(EMERGENCY_PARSER, true));
136
 #endif
136
 #endif
137
+#if SERIAL_PORT_3 == -1
138
+  MSerialT3 customizedSerial3(TERN0(EMERGENCY_PARSER, true));
139
+#endif
137
 
140
 
138
 #endif // HAS_USB_SERIAL
141
 #endif // HAS_USB_SERIAL
139
 #endif // ARDUINO_ARCH_SAM
142
 #endif // ARDUINO_ARCH_SAM

+ 4
- 0
Marlin/src/HAL/DUE/MarlinSerialUSB.h View File

59
   extern MSerialT2 customizedSerial2;
59
   extern MSerialT2 customizedSerial2;
60
 #endif
60
 #endif
61
 
61
 
62
+#if SERIAL_PORT_3 == -1
63
+  typedef Serial1Class<MarlinSerialUSB> MSerialT3;
64
+  extern MSerialT3 customizedSerial3;
65
+#endif

+ 10
- 0
Marlin/src/HAL/LPC1768/HAL.h View File

84
   #endif
84
   #endif
85
 #endif
85
 #endif
86
 
86
 
87
+#ifdef SERIAL_PORT_3
88
+  #if SERIAL_PORT_3 == -1
89
+    #define MYSERIAL3 USBSerial
90
+  #elif WITHIN(SERIAL_PORT_3, 0, 3)
91
+    #define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
92
+  #else
93
+    #error "SERIAL_PORT_3 must be from 0 to 3. You can also use -1 if the board supports Native USB."
94
+  #endif
95
+#endif
96
+
87
 #ifdef MMU2_SERIAL_PORT
97
 #ifdef MMU2_SERIAL_PORT
88
   #if MMU2_SERIAL_PORT == -1
98
   #if MMU2_SERIAL_PORT == -1
89
     #define MMU2_SERIAL USBSerial
99
     #define MMU2_SERIAL USBSerial

+ 10
- 0
Marlin/src/HAL/STM32/HAL.h View File

68
   #endif
68
   #endif
69
 #endif
69
 #endif
70
 
70
 
71
+#ifdef SERIAL_PORT_3
72
+  #if SERIAL_PORT_3 == -1
73
+    #define MYSERIAL3 MSerial0
74
+  #elif WITHIN(SERIAL_PORT_3, 1, 6)
75
+    #define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
76
+  #else
77
+    #error "SERIAL_PORT_3 must be from 1 to 6. You can also use -1 if the board supports Native USB."
78
+  #endif
79
+#endif
80
+
71
 #ifdef MMU2_SERIAL_PORT
81
 #ifdef MMU2_SERIAL_PORT
72
   #if MMU2_SERIAL_PORT == -1
82
   #if MMU2_SERIAL_PORT == -1
73
     #define MMU2_SERIAL MSerial0
83
     #define MMU2_SERIAL MSerial0

+ 11
- 0
Marlin/src/HAL/STM32F1/HAL.h View File

98
   #endif
98
   #endif
99
 #endif
99
 #endif
100
 
100
 
101
+#ifdef SERIAL_PORT_3
102
+  #if SERIAL_PORT_3 == -1
103
+    #define MYSERIAL3 UsbSerial
104
+  #elif WITHIN(SERIAL_PORT_3, 1, NUM_UARTS)
105
+    #define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
106
+  #else
107
+    #define MYSERIAL3 MSERIAL(1) // dummy port
108
+    static_assert(false, "SERIAL_PORT_3 must be from 1 to " STRINGIFY(NUM_UARTS) ". You can also use -1 if the board supports Native USB.")
109
+  #endif
110
+#endif
111
+
101
 #ifdef MMU2_SERIAL_PORT
112
 #ifdef MMU2_SERIAL_PORT
102
   #if MMU2_SERIAL_PORT == -1
113
   #if MMU2_SERIAL_PORT == -1
103
     #define MMU2_SERIAL UsbSerial
114
     #define MMU2_SERIAL UsbSerial

+ 5
- 0
Marlin/src/MarlinCore.cpp View File

1075
     MYSERIAL2.begin(BAUDRATE);
1075
     MYSERIAL2.begin(BAUDRATE);
1076
     serial_connect_timeout = millis() + 1000UL;
1076
     serial_connect_timeout = millis() + 1000UL;
1077
     while (!MYSERIAL2.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
1077
     while (!MYSERIAL2.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
1078
+    #ifdef SERIAL_PORT_3
1079
+      MYSERIAL3.begin(BAUDRATE);
1080
+      serial_connect_timeout = millis() + 1000UL;
1081
+      while (!MYSERIAL3.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
1082
+    #endif
1078
   #endif
1083
   #endif
1079
   SERIAL_ECHOLNPGM("start");
1084
   SERIAL_ECHOLNPGM("start");
1080
 
1085
 

+ 11
- 1
Marlin/src/core/serial.cpp View File

44
 #if ENABLED(MEATPACK_ON_SERIAL_PORT_2)
44
 #if ENABLED(MEATPACK_ON_SERIAL_PORT_2)
45
   SerialLeafT2 mpSerial2(false, _SERIAL_LEAF_2);
45
   SerialLeafT2 mpSerial2(false, _SERIAL_LEAF_2);
46
 #endif
46
 #endif
47
+#if ENABLED(MEATPACK_ON_SERIAL_PORT_3)
48
+  SerialLeafT3 mpSerial3(false, _SERIAL_LEAF_3);
49
+#endif
47
 
50
 
48
 // Step 2: For multiserial, handle the second serial port as well
51
 // Step 2: For multiserial, handle the second serial port as well
49
 #if HAS_MULTI_SERIAL
52
 #if HAS_MULTI_SERIAL
52
     SerialLeafT2 msSerial2(ethernet.have_telnet_client, MYSERIAL2, false);
55
     SerialLeafT2 msSerial2(ethernet.have_telnet_client, MYSERIAL2, false);
53
   #endif
56
   #endif
54
 
57
 
55
-  SerialOutputT multiSerial(SERIAL_LEAF_1, SERIAL_LEAF_2);
58
+  #define __S_LEAF(N) ,SERIAL_LEAF_##N
59
+  #define _S_LEAF(N) __S_LEAF(N)
60
+
61
+  SerialOutputT multiSerial( SERIAL_LEAF_1 REPEAT_S(2, INCREMENT(NUM_SERIAL), _S_LEAF) );
62
+
63
+  #undef __S_LEAF
64
+  #undef _S_LEAF
65
+
56
 #endif
66
 #endif
57
 
67
 
58
 void serialprintPGM(PGM_P str) {
68
 void serialprintPGM(PGM_P str) {

+ 20
- 1
Marlin/src/core/serial.h View File

95
     #define _SERIAL_LEAF_2 MYSERIAL2 // Don't create a useless instance here, directly use the existing instance
95
     #define _SERIAL_LEAF_2 MYSERIAL2 // Don't create a useless instance here, directly use the existing instance
96
   #endif
96
   #endif
97
 
97
 
98
+  // Nothing complicated here
99
+  #define _SERIAL_LEAF_3 MYSERIAL3
100
+
98
   // Hook Meatpack if it's enabled on the second leaf
101
   // Hook Meatpack if it's enabled on the second leaf
99
   #if ENABLED(MEATPACK_ON_SERIAL_PORT_2)
102
   #if ENABLED(MEATPACK_ON_SERIAL_PORT_2)
100
     typedef MeatpackSerial<decltype(_SERIAL_LEAF_2)> SerialLeafT2;
103
     typedef MeatpackSerial<decltype(_SERIAL_LEAF_2)> SerialLeafT2;
104
     #define SERIAL_LEAF_2 _SERIAL_LEAF_2
107
     #define SERIAL_LEAF_2 _SERIAL_LEAF_2
105
   #endif
108
   #endif
106
 
109
 
107
-  typedef MultiSerial<decltype(SERIAL_LEAF_1), decltype(SERIAL_LEAF_2), 0> SerialOutputT;
110
+  // Hook Meatpack if it's enabled on the third leaf
111
+  #if ENABLED(MEATPACK_ON_SERIAL_PORT_3)
112
+    typedef MeatpackSerial<decltype(_SERIAL_LEAF_3)> SerialLeafT3;
113
+    extern SerialLeafT3 mpSerial3;
114
+    #define SERIAL_LEAF_3 mpSerial3
115
+  #else
116
+    #define SERIAL_LEAF_3 _SERIAL_LEAF_3
117
+  #endif
118
+
119
+  #define __S_MULTI(N) decltype(SERIAL_LEAF_##N),
120
+  #define _S_MULTI(N) __S_MULTI(N)
121
+
122
+  typedef MultiSerial< REPEAT_S(1, INCREMENT(NUM_SERIAL), _S_MULTI) 0> SerialOutputT;
123
+
124
+  #undef __S_MULTI
125
+  #undef _S_MULTI
126
+
108
   extern SerialOutputT        multiSerial;
127
   extern SerialOutputT        multiSerial;
109
   #define SERIAL_IMPL         multiSerial
128
   #define SERIAL_IMPL         multiSerial
110
 #else
129
 #else

+ 67
- 42
Marlin/src/core/serial_hook.h View File

195
   RuntimeSerial(const bool e, Args... args) : BaseClassT(e), SerialT(args...), writeHook(0), eofHook(0), userPointer(0) {}
195
   RuntimeSerial(const bool e, Args... args) : BaseClassT(e), SerialT(args...), writeHook(0), eofHook(0), userPointer(0) {}
196
 };
196
 };
197
 
197
 
198
-// A class that duplicates its output conditionally to 2 serial interfaces
199
-template <class Serial0T, class Serial1T, const uint8_t offset = 0, const uint8_t step = 1>
200
-struct MultiSerial : public SerialBase< MultiSerial<Serial0T, Serial1T, offset, step> > {
201
-  typedef SerialBase< MultiSerial<Serial0T, Serial1T, offset, step> > BaseClassT;
198
+#define _S_CLASS(N) class Serial##N##T,
199
+#define _S_NAME(N) Serial##N##T,
200
+
201
+template < REPEAT(NUM_SERIAL, _S_CLASS) const uint8_t offset=0, const uint8_t step=1 >
202
+struct MultiSerial : public SerialBase< MultiSerial< REPEAT(NUM_SERIAL, _S_NAME) offset, step > > {
203
+  typedef SerialBase< MultiSerial< REPEAT(NUM_SERIAL, _S_NAME) offset, step > > BaseClassT;
204
+
205
+  #undef _S_CLASS
206
+  #undef _S_NAME
202
 
207
 
203
   SerialMask portMask;
208
   SerialMask portMask;
204
-  Serial0T & serial0;
205
-  Serial1T & serial1;
206
 
209
 
207
-  static constexpr uint8_t Usage         =  ((1 << step) - 1); // A bit mask containing as many bits as step
208
-  static constexpr uint8_t FirstOutput   = (Usage << offset);
209
-  static constexpr uint8_t SecondOutput  = (Usage << (offset + step));
210
-  static constexpr uint8_t Both          = FirstOutput | SecondOutput;
210
+  #define _S_DECLARE(N) Serial##N##T & serial##N;
211
+  REPEAT(NUM_SERIAL, _S_DECLARE);
212
+  #undef _S_DECLARE
213
+
214
+  static constexpr uint8_t Usage = _BV(step) - 1; // A bit mask containing 'step' bits
215
+
216
+  #define _OUT_PORT(N) (Usage << (offset + (step * N))),
217
+  static constexpr uint8_t output[] = { REPEAT(NUM_SERIAL, _OUT_PORT) };
218
+  #undef _OUT_PORT
219
+
220
+  #define _OUT_MASK(N) | output[N]
221
+  static constexpr uint8_t ALL = 0 REPEAT(NUM_SERIAL, _OUT_MASK);
222
+  #undef _OUT_MASK
211
 
223
 
212
   NO_INLINE void write(uint8_t c) {
224
   NO_INLINE void write(uint8_t c) {
213
-    if (portMask.enabled(FirstOutput))   serial0.write(c);
214
-    if (portMask.enabled(SecondOutput))  serial1.write(c);
225
+    #define _S_WRITE(N) if (portMask.enabled(output[N])) serial##N.write(c);
226
+    REPEAT(NUM_SERIAL, _S_WRITE);
227
+    #undef _S_WRITE
215
   }
228
   }
216
   NO_INLINE void msgDone() {
229
   NO_INLINE void msgDone() {
217
-    if (portMask.enabled(FirstOutput))   serial0.msgDone();
218
-    if (portMask.enabled(SecondOutput))  serial1.msgDone();
230
+    #define _S_DONE(N) if (portMask.enabled(output[N])) serial##N.msgDone();
231
+    REPEAT(NUM_SERIAL, _S_DONE);
232
+    #undef _S_DONE
219
   }
233
   }
220
   int available(serial_index_t index) {
234
   int available(serial_index_t index) {
221
-    if (index.within(0 + offset, step + offset - 1))
222
-      return serial0.available(index);
223
-    else if (index.within(step + offset, 2 * step + offset - 1))
224
-      return serial1.available(index);
235
+    uint8_t pos = offset;
236
+    #define _S_AVAILABLE(N) if (index.within(pos, pos + step - 1)) return serial##N.available(index); else pos += step;
237
+    REPEAT(NUM_SERIAL, _S_AVAILABLE);
238
+    #undef _S_AVAILABLE
225
     return false;
239
     return false;
226
   }
240
   }
227
   int read(serial_index_t index) {
241
   int read(serial_index_t index) {
228
-    if (index.within(0 + offset, step + offset - 1))
229
-      return serial0.read(index);
230
-    else if (index.within(step + offset, 2 * step + offset - 1))
231
-      return serial1.read(index);
242
+    uint8_t pos = offset;
243
+    #define _S_READ(N) if (index.within(pos, pos + step - 1)) return serial##N.read(index); else pos += step;
244
+    REPEAT(NUM_SERIAL, _S_READ);
245
+    #undef _S_READ
232
     return -1;
246
     return -1;
233
   }
247
   }
234
   void begin(const long br) {
248
   void begin(const long br) {
235
-    if (portMask.enabled(FirstOutput))   serial0.begin(br);
236
-    if (portMask.enabled(SecondOutput))  serial1.begin(br);
249
+    #define _S_BEGIN(N) if (portMask.enabled(output[N])) serial##N.begin(br);
250
+    REPEAT(NUM_SERIAL, _S_BEGIN);
251
+    #undef _S_BEGIN
237
   }
252
   }
238
   void end() {
253
   void end() {
239
-    if (portMask.enabled(FirstOutput))   serial0.end();
240
-    if (portMask.enabled(SecondOutput))  serial1.end();
254
+    #define _S_END(N) if (portMask.enabled(output[N])) serial##N.end();
255
+    REPEAT(NUM_SERIAL, _S_END);
256
+    #undef _S_END
241
   }
257
   }
242
   bool connected() {
258
   bool connected() {
243
     bool ret = true;
259
     bool ret = true;
244
-    if (portMask.enabled(FirstOutput))   ret = CALL_IF_EXISTS(bool, &serial0, connected);
245
-    if (portMask.enabled(SecondOutput))  ret = ret && CALL_IF_EXISTS(bool, &serial1, connected);
260
+    #define _S_CONNECTED(N) if (portMask.enabled(output[N]) && !CALL_IF_EXISTS(bool, &serial##N, connected)) ret = false;
261
+    REPEAT(NUM_SERIAL, _S_CONNECTED);
262
+    #undef _S_CONNECTED
246
     return ret;
263
     return ret;
247
   }
264
   }
248
 
265
 
250
   using BaseClassT::read;
267
   using BaseClassT::read;
251
 
268
 
252
   // Redirect flush
269
   // Redirect flush
253
-  NO_INLINE void flush()      {
254
-    if (portMask.enabled(FirstOutput))   serial0.flush();
255
-    if (portMask.enabled(SecondOutput))  serial1.flush();
270
+  NO_INLINE void flush() {
271
+    #define _S_FLUSH(N) if (portMask.enabled(output[N])) serial##N.flush();
272
+    REPEAT(NUM_SERIAL, _S_FLUSH);
273
+    #undef _S_FLUSH
256
   }
274
   }
257
-  NO_INLINE void flushTX()    {
258
-    if (portMask.enabled(FirstOutput))   CALL_IF_EXISTS(void, &serial0, flushTX);
259
-    if (portMask.enabled(SecondOutput))  CALL_IF_EXISTS(void, &serial1, flushTX);
275
+  NO_INLINE void flushTX() {
276
+    #define _S_FLUSHTX(N) if (portMask.enabled(output[N])) CALL_IF_EXISTS(void, &serial0, flushTX);
277
+    REPEAT(NUM_SERIAL, _S_FLUSHTX);
278
+    #undef _S_FLUSHTX
260
   }
279
   }
261
 
280
 
262
   // Forward feature queries
281
   // Forward feature queries
263
-  SerialFeature features(serial_index_t index) const  {
264
-    if (index.within(0 + offset, step + offset - 1))
265
-      return serial0.features(index);
266
-    else if (index.within(step + offset, 2 * step + offset - 1))
267
-      return serial1.features(index);
282
+  SerialFeature features(serial_index_t index) const {
283
+    uint8_t pos = offset;
284
+    #define _S_FEATURES(N) if (index.within(pos, pos + step - 1)) return serial##N.features(index); else pos += step;
285
+    REPEAT(NUM_SERIAL, _S_FEATURES);
286
+    #undef _S_FEATURES
268
     return SerialFeature::None;
287
     return SerialFeature::None;
269
   }
288
   }
270
 
289
 
271
-  MultiSerial(Serial0T & serial0, Serial1T & serial1, const SerialMask mask = Both, const bool e = false) :
272
-    BaseClassT(e),
273
-    portMask(mask), serial0(serial0), serial1(serial1) {}
290
+  #define _S_REFS(N) Serial##N##T & serial##N,
291
+  #define _S_INIT(N) ,serial##N (serial##N)
292
+
293
+  MultiSerial(REPEAT(NUM_SERIAL, _S_REFS) const SerialMask mask = ALL, const bool e = false)
294
+    : BaseClassT(e), portMask(mask) REPEAT(NUM_SERIAL, _S_INIT) {}
295
+
274
 };
296
 };
275
 
297
 
276
 // Build the actual serial object depending on current configuration
298
 // Build the actual serial object depending on current configuration
278
 #define ForwardSerial1Class TERN(SERIAL_RUNTIME_HOOK, RuntimeSerial, ForwardSerial)
300
 #define ForwardSerial1Class TERN(SERIAL_RUNTIME_HOOK, RuntimeSerial, ForwardSerial)
279
 #ifdef HAS_MULTI_SERIAL
301
 #ifdef HAS_MULTI_SERIAL
280
   #define Serial2Class ConditionalSerial
302
   #define Serial2Class ConditionalSerial
303
+  #if NUM_SERIAL >= 3
304
+    #define Serial3Class ConditionalSerial
305
+  #endif
281
 #endif
306
 #endif

+ 6
- 2
Marlin/src/inc/Conditionals_LCD.h View File

955
 // Serial Port Info
955
 // Serial Port Info
956
 //
956
 //
957
 #ifdef SERIAL_PORT_2
957
 #ifdef SERIAL_PORT_2
958
-  #define NUM_SERIAL 2
959
   #define HAS_MULTI_SERIAL 1
958
   #define HAS_MULTI_SERIAL 1
959
+  #ifdef SERIAL_PORT_3
960
+    #define NUM_SERIAL 3
961
+  #else
962
+    #define NUM_SERIAL 2
963
+  #endif
960
 #elif defined(SERIAL_PORT)
964
 #elif defined(SERIAL_PORT)
961
   #define NUM_SERIAL 1
965
   #define NUM_SERIAL 1
962
 #else
966
 #else
963
   #define NUM_SERIAL 0
967
   #define NUM_SERIAL 0
964
   #undef BAUD_RATE_GCODE
968
   #undef BAUD_RATE_GCODE
965
 #endif
969
 #endif
966
-#if SERIAL_PORT == -1 || SERIAL_PORT_2 == -1
970
+#if SERIAL_PORT == -1 || SERIAL_PORT_2 == -1 || SERIAL_PORT_3 == -1
967
   #define HAS_USB_SERIAL 1
971
   #define HAS_USB_SERIAL 1
968
 #endif
972
 #endif
969
 #if SERIAL_PORT_2 == -2
973
 #if SERIAL_PORT_2 == -2

+ 1
- 0
Marlin/src/inc/Conditionals_post.h View File

1859
 // Flag the indexed hardware serial ports in use
1859
 // Flag the indexed hardware serial ports in use
1860
 #define CONF_SERIAL_IS(N) (  (defined(SERIAL_PORT)      && SERIAL_PORT == N) \
1860
 #define CONF_SERIAL_IS(N) (  (defined(SERIAL_PORT)      && SERIAL_PORT == N) \
1861
                           || (defined(SERIAL_PORT_2)    && SERIAL_PORT_2 == N) \
1861
                           || (defined(SERIAL_PORT_2)    && SERIAL_PORT_2 == N) \
1862
+                          || (defined(SERIAL_PORT_3)    && SERIAL_PORT_3 == N) \
1862
                           || (defined(MMU2_SERIAL_PORT) && MMU2_SERIAL_PORT == N) \
1863
                           || (defined(MMU2_SERIAL_PORT) && MMU2_SERIAL_PORT == N) \
1863
                           || (defined(LCD_SERIAL_PORT)  && LCD_SERIAL_PORT == N) )
1864
                           || (defined(LCD_SERIAL_PORT)  && LCD_SERIAL_PORT == N) )
1864
 
1865
 

+ 8
- 0
Marlin/src/inc/SanityCheck.h View File

607
   #error "SERIAL_PORT must be defined."
607
   #error "SERIAL_PORT must be defined."
608
 #elif defined(SERIAL_PORT_2) && SERIAL_PORT_2 == SERIAL_PORT
608
 #elif defined(SERIAL_PORT_2) && SERIAL_PORT_2 == SERIAL_PORT
609
   #error "SERIAL_PORT_2 cannot be the same as SERIAL_PORT."
609
   #error "SERIAL_PORT_2 cannot be the same as SERIAL_PORT."
610
+#elif defined(SERIAL_PORT_3)
611
+  #ifndef SERIAL_PORT_2
612
+    #error "Use SERIAL_PORT_2 before using SERIAL_PORT_3"
613
+  #elif SERIAL_PORT_3 == SERIAL_PORT
614
+    #error "SERIAL_PORT_3 cannot be the same as SERIAL_PORT."
615
+  #elif SERIAL_PORT_3 == SERIAL_PORT_2
616
+    #error "SERIAL_PORT_3 cannot be the same as SERIAL_PORT_2."
617
+  #endif
610
 #endif
618
 #endif
611
 #if !(defined(__AVR__) && defined(USBCON))
619
 #if !(defined(__AVR__) && defined(USBCON))
612
   #if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024
620
   #if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024

+ 1
- 1
buildroot/tests/LPC1768 View File

14
 #exec_test $1 $2 "Default Configuration" "$3"
14
 #exec_test $1 $2 "Default Configuration" "$3"
15
 
15
 
16
 restore_configs
16
 restore_configs
17
-opt_set MOTHERBOARD BOARD_RAMPS_14_RE_ARM_EFB NEOPIXEL_PIN P1_16
17
+opt_set MOTHERBOARD BOARD_RAMPS_14_RE_ARM_EFB NEOPIXEL_PIN P1_16 SERIAL_PORT_3 3
18
 opt_enable VIKI2 SDSUPPORT SDCARD_READONLY SERIAL_PORT_2 NEOPIXEL_LED
18
 opt_enable VIKI2 SDSUPPORT SDCARD_READONLY SERIAL_PORT_2 NEOPIXEL_LED
19
 exec_test $1 $2 "ReARM EFB VIKI2, SDSUPPORT, 2 Serial ports (USB CDC + UART0), NeoPixel" "$3"
19
 exec_test $1 $2 "ReARM EFB VIKI2, SDSUPPORT, 2 Serial ports (USB CDC + UART0), NeoPixel" "$3"
20
 
20
 

Loading…
Cancel
Save