Browse Source

XON/XOFF corrections, tweaks, formatting, etc.

Scott Lahteine 7 years ago
parent
commit
4e19ff75b6
6 changed files with 228 additions and 291 deletions
  1. 1
    1
      Marlin/Configuration.h
  2. 17
    14
      Marlin/Configuration_adv.h
  3. 177
    218
      Marlin/MarlinSerial.cpp
  4. 22
    50
      Marlin/MarlinSerial.h
  5. 10
    7
      Marlin/Marlin_main.cpp
  6. 1
    1
      Marlin/macros.h

+ 1
- 1
Marlin/Configuration.h View File

@@ -107,7 +107,7 @@
107 107
  *
108 108
  * 250000 works in most cases, but you might try a lower speed if
109 109
  * you commonly experience drop-outs during host printing.
110
- * You may try up to 1000000 to speed up file transfer to the SD card
110
+ * You may try up to 1000000 to speed up SD file transfer.
111 111
  *
112 112
  * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000]
113 113
  */

+ 17
- 14
Marlin/Configuration_adv.h View File

@@ -740,24 +740,27 @@
740 740
 // :[0, 2, 4, 8, 16, 32, 64, 128, 256]
741 741
 #define TX_BUFFER_SIZE 0
742 742
 
743
-// Reception from Host Buffer Size
744
-// This is the size of the Reception buffer. If XON/XOFF software flow control
745
-// is not enabled, then 32 bytes should be enough. But if you plan to use XON/XOFF
746
-// you need 1024 bytes at least.
743
+// Host Receive Buffer Size
744
+// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough.
745
+// To use flow control, set this buffer size to at least 1024 bytes.
747 746
 // :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]
748
-#define RX_BUFFER_SIZE 1024
747
+//#define RX_BUFFER_SIZE 1024
749 748
 
750
-// This setting determines if the printer will send the XON/XOFF
751
-// control characters to the host to signal RX buffer is becoming full
752
-#define SERIAL_XON_XOFF 1
749
+#if RX_BUFFER_SIZE >= 1024
750
+  // Enable to have the controller send XON/XOFF control characters to
751
+  // the host to signal the RX buffer is becoming full.
752
+  //#define SERIAL_XON_XOFF
753
+#endif
753 754
 
754
-// This setting determines if you want to display and collect
755
-// maximum RX queue usage after transferring a file to the SD
756
-//#define SERIAL_STATS_MAX_RX_QUEUED 1
755
+#if ENABLED(SDSUPPORT)
756
+  // Enable this option to collect and display the maximum
757
+  // RX queue usage after transferring a file to SD.
758
+  //#define SERIAL_STATS_MAX_RX_QUEUED
757 759
 
758
-// This setting determines if you want to display and collect
759
-// the number of dropped bytes after a file transfer to the SD
760
-#define SERIAL_STATS_DROPPED_RX 1
760
+  // Enable this option to collect and display the number
761
+  // of dropped bytes after a file transfer to SD.
762
+  //#define SERIAL_STATS_DROPPED_RX
763
+#endif
761 764
 
762 765
 // Enable an emergency-command parser to intercept certain commands as they
763 766
 // enter the serial receive buffer, so they cannot be blocked.

+ 177
- 218
Marlin/MarlinSerial.cpp View File

@@ -27,15 +27,30 @@
27 27
  * Modified 23 November 2006 by David A. Mellis
28 28
  * Modified 28 September 2010 by Mark Sproul
29 29
  * Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
30
+ * Modified 01 October 2017 by Eduardo José Tagle (added XON/XOFF)
30 31
  */
31 32
 
32
-#include "MarlinSerial.h"
33
-#include "Marlin.h"
34
-
35 33
 // Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.)
36 34
 
35
+#include "MarlinConfig.h"
36
+
37 37
 #if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
38 38
 
39
+  #include "MarlinSerial.h"
40
+  #include "Marlin.h"
41
+
42
+  struct ring_buffer_r {
43
+    unsigned char buffer[RX_BUFFER_SIZE];
44
+    volatile ring_buffer_pos_t head, tail;
45
+  };
46
+
47
+  #if TX_BUFFER_SIZE > 0
48
+    struct ring_buffer_t {
49
+      unsigned char buffer[TX_BUFFER_SIZE];
50
+      volatile uint8_t head, tail;
51
+    };
52
+  #endif
53
+
39 54
   #if UART_PRESENT(SERIAL_PORT)
40 55
     ring_buffer_r rx_buffer = { { 0 }, 0, 0 };
41 56
     #if TX_BUFFER_SIZE > 0
@@ -45,15 +60,21 @@
45 60
   #endif
46 61
 
47 62
   #if ENABLED(SERIAL_XON_XOFF)
48
-	uint8_t xon_xoff_state = XON_XOFF_CHAR_SENT | XON_CHAR;
63
+    uint8_t xon_xoff_state = XON_XOFF_CHAR_SENT | XON_CHAR;
64
+    constexpr uint8_t XON_XOFF_CHAR_SENT = 0x80;  // XON / XOFF Character was sent
65
+    constexpr uint8_t XON_XOFF_CHAR_MASK = 0x1F;  // XON / XOFF character to send
66
+    // XON / XOFF character definitions
67
+    constexpr uint8_t XON_CHAR  = 17;
68
+    constexpr uint8_t XOFF_CHAR = 19;
49 69
   #endif
50
-  
70
+
51 71
   #if ENABLED(SERIAL_STATS_DROPPED_RX)
52
-	uint8_t rx_dropped_bytes = 0;
72
+    uint8_t rx_dropped_bytes = 0;
53 73
   #endif
74
+
54 75
   #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
55
-	ring_buffer_pos_t rx_max_enqueued = 0;
56
-  #endif  
76
+    ring_buffer_pos_t rx_max_enqueued = 0;
77
+  #endif
57 78
 
58 79
   #if ENABLED(EMERGENCY_PARSER)
59 80
 
@@ -149,92 +170,76 @@
149 170
 
150 171
   FORCE_INLINE void store_rxd_char() {
151 172
     const ring_buffer_pos_t h = rx_buffer.head,
152
-							i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1);
173
+                            i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1);
153 174
 
154
-      // if we should be storing the received character into the location
155
-      // just before the tail (meaning that the head would advance to the
156
-      // current location of the tail), we're about to overflow the buffer
157
-      // and so we don't write the character or advance the head.
158
-      if (i != rx_buffer.tail) {
175
+    // If the character is to be stored at the index just before the tail
176
+    // (such that the head would advance to the current tail), the buffer is
177
+    // critical, so don't write the character or advance the head.
178
+    if (i != rx_buffer.tail) {
159 179
       rx_buffer.buffer[h] = M_UDRx;
160
-        rx_buffer.head = i;
180
+      rx_buffer.head = i;
181
+    }
182
+    else {
183
+      (void)M_UDRx;
184
+      #if ENABLED(SERIAL_STATS_DROPPED_RX)
185
+        if (!++rx_dropped_bytes) ++rx_dropped_bytes;
186
+      #endif
187
+    }
188
+
189
+    #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
190
+      // calculate count of bytes stored into the RX buffer
191
+      ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(rx_buffer.head - rx_buffer.tail) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1);
192
+      // Keep track of the maximum count of enqueued bytes
193
+      NOLESS(rx_max_enqueued, rx_count);
194
+    #endif
195
+
196
+    #if ENABLED(SERIAL_XON_XOFF)
197
+
198
+      // for high speed transfers, we can use XON/XOFF protocol to do
199
+      // software handshake and avoid overruns.
200
+      if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XON_CHAR) {
201
+
202
+        // calculate count of bytes stored into the RX buffer
203
+        ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(rx_buffer.head - rx_buffer.tail) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1);
204
+
205
+        // if we are above 12.5% of RX buffer capacity, send XOFF before
206
+        // we run out of RX buffer space .. We need 325 bytes @ 250kbits/s to
207
+        // let the host react and stop sending bytes. This translates to 13mS
208
+        // propagation time.
209
+        if (rx_count >= (RX_BUFFER_SIZE) / 8) {
210
+          // If TX interrupts are disabled and data register is empty,
211
+          // just write the byte to the data register and be done. This
212
+          // shortcut helps significantly improve the effective datarate
213
+          // at high (>500kbit/s) bitrates, where interrupt overhead
214
+          // becomes a slowdown.
215
+          if (!TEST(M_UCSRxB, M_UDRIEx) && TEST(M_UCSRxA, M_UDREx)) {
216
+            // Send an XOFF character
217
+            M_UDRx = XOFF_CHAR;
218
+            // clear the TXC bit -- "can be cleared by writing a one to its bit
219
+            // location". This makes sure flush() won't return until the bytes
220
+            // actually got written
221
+            SBI(M_UCSRxA, M_TXCx);
222
+            // And remember it was sent
223
+            xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT;
224
+          }
225
+          else {
226
+            // TX interrupts disabled, but buffer still not empty ... or
227
+            // TX interrupts enabled. Reenable TX ints and schedule XOFF
228
+            // character to be sent
229
+            #if TX_BUFFER_SIZE > 0
230
+              SBI(M_UCSRxB, M_UDRIEx);
231
+              xon_xoff_state = XOFF_CHAR;
232
+            #else
233
+              // We are not using TX interrupts, we will have to send this manually
234
+              while (!TEST(M_UCSRxA, M_UDREx)) {/* nada */}
235
+              M_UDRx = XOFF_CHAR;
236
+              // And remember we already sent it
237
+              xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT;
238
+            #endif
239
+          }
240
+        }
161 241
       }
162
-	else {
163
-		(void)M_UDRx;
164
-  #if ENABLED(SERIAL_STATS_DROPPED_RX)		
165
-	  if (!++rx_dropped_bytes)
166
-		  ++rx_dropped_bytes;
167
-  #endif	  
168
-	}
169
-  #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
170
-	{
171
-	  // calculate count of bytes stored into the RX buffer
172
-	  ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(rx_buffer.head - rx_buffer.tail) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1);
173
-	  
174
-	  // Keep track of the maximum count of enqueued bytes
175
-	  if (rx_max_enqueued < rx_count)
176
-	    rx_max_enqueued = rx_count;
177
-	}
178
-  #endif  
179
-	  
180
-  #if ENABLED(SERIAL_XON_XOFF)
181
-  
182
-    // for high speed transfers, we can use XON/XOFF protocol to do 
183
-    // software handshake and avoid overruns.
184
-    if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XON_CHAR) {
185
-	
186
-	  // calculate count of bytes stored into the RX buffer
187
-	  ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(rx_buffer.head - rx_buffer.tail) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1);
188
-	
189
-	  // if we are above 12.5% of RX buffer capacity, send XOFF before
190
-	  // 	we run out of RX buffer space .. We need 325 bytes @ 250kbits/s to
191
-	  //  let the host react and stop sending bytes. This translates to 13mS
192
-	  //  propagation time.
193
-	  if (rx_count >= (RX_BUFFER_SIZE/8)) {
194
-		
195
-	    // If TX interrupts are disabled and data register is empty,
196
-	    // just write the byte to the data register and be done. This 
197
-	    // shortcut helps significantly improve the effective datarate
198
-	    // at high (>500kbit/s) bitrates, where interrupt overhead 
199
-	    // becomes a slowdown.
200
-	    if (!TEST(M_UCSRxB, M_UDRIEx) && TEST(M_UCSRxA, M_UDREx)) {
201
-		
202
-		  // Send an XOFF character
203
-		  M_UDRx = XOFF_CHAR;
204
-		
205
-		  // clear the TXC bit -- "can be cleared by writing a one to its bit
206
-		  // location". This makes sure flush() won't return until the bytes
207
-		  // actually got written
208
-		  SBI(M_UCSRxA, M_TXCx);
209
-		  
210
-		  // And remember we already sent it
211
-		  xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT;
212
-		  
213
-	    } else {
214
-
215
-		  // TX interrupts disabled, but buffer still not empty ... or 
216
-		  // TX interrupts enabled. Reenable TX ints and schedule XOFF 
217
-		  // character to be sent
218
-	  #if TX_BUFFER_SIZE > 0		
219
-		
220
-		  SBI(M_UCSRxB, M_UDRIEx);
221
-		  xon_xoff_state = XOFF_CHAR;
222
-		
223
-	  #else
224
-		  // We are not using TX interrupts, we will have to send this manually
225
-		  while (!TEST(M_UCSRxA, M_UDREx))
226
-		    ;
227
-		  M_UDRx = XOFF_CHAR;
228
-		
229
-		  // And remember we already sent it
230
-		  xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT;
231
-
232
-	  #endif
233
-		}
234
-
235
-	  }
236
-	}
237
-  #endif
242
+    #endif // SERIAL_XON_XOFF
238 243
 
239 244
     #if ENABLED(EMERGENCY_PARSER)
240 245
       emergency_parser(c);
@@ -247,52 +252,39 @@
247 252
       // If interrupts are enabled, there must be more data in the output
248 253
       // buffer.
249 254
 
250
-    #if ENABLED(SERIAL_XON_XOFF)
251
-	
252
-	  // If we must do a priority insertion of an XON/XOFF char, 
253
-	  //  do it now
254
-	  uint8_t state = xon_xoff_state;
255
-	  if (!(state & XON_XOFF_CHAR_SENT)) {
256
-		M_UDRx = state & XON_XOFF_CHAR_MASK;
257
-		xon_xoff_state = state | XON_XOFF_CHAR_SENT;
258
-		
259
-	  } else {
260
-	#endif
261
-	  
262
-		// Send the next byte
263
-      const uint8_t t = tx_buffer.tail,
264
-                    c = tx_buffer.buffer[t];
265
-      tx_buffer.tail = (t + 1) & (TX_BUFFER_SIZE - 1);
266
-
267
-      M_UDRx = c;
255
+      #if ENABLED(SERIAL_XON_XOFF)
256
+        // Do a priority insertion of an XON/XOFF char, if needed.
257
+        const uint8_t state = xon_xoff_state;
258
+        if (!(state & XON_XOFF_CHAR_SENT)) {
259
+          M_UDRx = state & XON_XOFF_CHAR_MASK;
260
+          xon_xoff_state = state | XON_XOFF_CHAR_SENT;
261
+        }
262
+        else
263
+      #endif
264
+      { // Send the next byte
265
+        const uint8_t t = tx_buffer.tail, c = tx_buffer.buffer[t];
266
+        tx_buffer.tail = (t + 1) & (TX_BUFFER_SIZE - 1);
267
+        M_UDRx = c;
268
+      }
268 269
 
269
-    #if ENABLED(SERIAL_XON_XOFF)
270
-	  }
271
-	#endif
272
-	
273 270
       // clear the TXC bit -- "can be cleared by writing a one to its bit
274 271
       // location". This makes sure flush() won't return until the bytes
275 272
       // actually got written
276 273
       SBI(M_UCSRxA, M_TXCx);
277 274
 
278
-      if (tx_buffer.head == tx_buffer.tail) {
279
-        // Buffer empty, so disable interrupts
275
+      // Disable interrupts if the buffer is empty
276
+      if (tx_buffer.head == tx_buffer.tail)
280 277
         CBI(M_UCSRxB, M_UDRIEx);
281
-      }
282 278
     }
283 279
 
284 280
     #ifdef M_USARTx_UDRE_vect
285
-      ISR(M_USARTx_UDRE_vect) {
286
-        _tx_udr_empty_irq();
287
-      }
281
+      ISR(M_USARTx_UDRE_vect) { _tx_udr_empty_irq(); }
288 282
     #endif
289 283
 
290 284
   #endif // TX_BUFFER_SIZE
291 285
 
292 286
   #ifdef M_USARTx_RX_vect
293
-    ISR(M_USARTx_RX_vect) {
294
-      store_rxd_char();
295
-    }
287
+    ISR(M_USARTx_RX_vect) { store_rxd_char(); }
296 288
   #endif
297 289
 
298 290
   // Public Methods
@@ -302,9 +294,9 @@
302 294
     bool useU2X = true;
303 295
 
304 296
     #if F_CPU == 16000000UL && SERIAL_PORT == 0
305
-      // hard-coded exception for compatibility with the bootloader shipped
306
-      // with the Duemilanove and previous boards and the firmware on the 8U2
307
-      // on the Uno and Mega 2560.
297
+      // Hard-coded exception for compatibility with the bootloader shipped
298
+      // with the Duemilanove and previous boards, and the firmware on the
299
+      // 8U2 on the Uno and Mega 2560.
308 300
       if (baud == 57600) useU2X = false;
309 301
     #endif
310 302
 
@@ -339,9 +331,9 @@
339 331
 
340 332
   void MarlinSerial::checkRx(void) {
341 333
     if (TEST(M_UCSRxA, M_RXCx)) {
342
-	  CRITICAL_SECTION_START;
334
+      CRITICAL_SECTION_START;
343 335
         store_rxd_char();
344
-	  CRITICAL_SECTION_END;
336
+      CRITICAL_SECTION_END;
345 337
     }
346 338
   }
347 339
 
@@ -361,35 +353,21 @@
361 353
       else {
362 354
         v = rx_buffer.buffer[t];
363 355
         rx_buffer.tail = (ring_buffer_pos_t)(t + 1) & (RX_BUFFER_SIZE - 1);
364
-		
365
-	  #if ENABLED(SERIAL_XON_XOFF)
366
-	  
367
-		// for high speed transfers, we can use XON/XOFF protocol to do 
368
-		// software handshake and avoid overruns.
369
-		if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
370
-			
371
-		  // calculate count of bytes stored into the RX buffer
372
-		  ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(rx_buffer.head - rx_buffer.tail) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1);
373
-			
374
-		  // if we are below 10% of RX buffer capacity, send XON before
375
-		  // 	we run out of RX buffer bytes
376
-		  if (rx_count < (RX_BUFFER_SIZE/10)) {
377
-				
378
-			// Send an XON character
379
-			xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
380
-	
381
-			// End critical section
382
-			CRITICAL_SECTION_END;	
383
-			 
384
-			// Transmit the XON character
385
-			writeNoHandshake(XON_CHAR);
386
-			
387
-			// Done
388
-			return v;
389
-		  }
390
-		}
391
-	  #endif
392
-		
356
+
357
+        #if ENABLED(SERIAL_XON_XOFF)
358
+          if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
359
+            // Get count of bytes in the RX buffer
360
+            ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(rx_buffer.head - rx_buffer.tail) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1);
361
+            // When below 10% of RX buffer capacity, send XON before
362
+            // running out of RX buffer bytes
363
+            if (rx_count < (RX_BUFFER_SIZE) / 10) {
364
+              xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
365
+              CRITICAL_SECTION_END;       // End critical section before returning!
366
+              writeNoHandshake(XON_CHAR);
367
+              return v;
368
+            }
369
+          }
370
+        #endif
393 371
       }
394 372
     CRITICAL_SECTION_END;
395 373
     return v;
@@ -397,68 +375,53 @@
397 375
 
398 376
   ring_buffer_pos_t MarlinSerial::available(void) {
399 377
     CRITICAL_SECTION_START;
400
-      const ring_buffer_pos_t h = rx_buffer.head,
401
-                    t = rx_buffer.tail;
378
+      const ring_buffer_pos_t h = rx_buffer.head, t = rx_buffer.tail;
402 379
     CRITICAL_SECTION_END;
403 380
     return (ring_buffer_pos_t)(RX_BUFFER_SIZE + h - t) & (RX_BUFFER_SIZE - 1);
404 381
   }
405 382
 
406 383
   void MarlinSerial::flush(void) {
407
-    // RX
408
-    // don't reverse this or there may be problems if the RX interrupt
409
-    // occurs after reading the value of rx_buffer_head but before writing
410
-    // the value to rx_buffer_tail; the previous value of rx_buffer_head
411
-    // may be written to rx_buffer_tail, making it appear as if the buffer
412
-    // were full, not empty.
384
+    // Don't change this order of operations. If the RX interrupt occurs between
385
+    // reading rx_buffer_head and updating rx_buffer_tail, the previous rx_buffer_head
386
+    // may be written to rx_buffer_tail, making the buffer appear full rather than empty.
413 387
     CRITICAL_SECTION_START;
414 388
       rx_buffer.head = rx_buffer.tail;
415 389
     CRITICAL_SECTION_END;
416
-	
417
-  #if ENABLED(SERIAL_XON_XOFF)
418
-  
419
-	// for high speed transfers, we can use XON/XOFF protocol to do 
420
-	// software handshake and avoid overruns.
421
-	if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
422
-		
423
-		// Send an XON character
424
-		xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
425
-
426
-		// Transmit the XON character
427
-		writeNoHandshake(XON_CHAR);
428
-	}
429
-  #endif
390
+
391
+    #if ENABLED(SERIAL_XON_XOFF)
392
+      if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
393
+        xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
394
+        writeNoHandshake(XON_CHAR);
395
+      }
396
+    #endif
430 397
   }
431 398
 
432 399
   #if TX_BUFFER_SIZE > 0
433 400
     uint8_t MarlinSerial::availableForWrite(void) {
434 401
       CRITICAL_SECTION_START;
435
-        const uint8_t h = tx_buffer.head,
436
-                      t = tx_buffer.tail;
402
+        const uint8_t h = tx_buffer.head, t = tx_buffer.tail;
437 403
       CRITICAL_SECTION_END;
438 404
       return (uint8_t)(TX_BUFFER_SIZE + h - t) & (TX_BUFFER_SIZE - 1);
439 405
     }
440 406
 
441 407
     void MarlinSerial::write(const uint8_t c) {
442
-	
443
-	#if ENABLED(SERIAL_XON_XOFF)
444
-	  uint8_t state = xon_xoff_state;
445
-  	  if (!(state & XON_XOFF_CHAR_SENT)) {
446
-		// 2 characters to send: The XON/XOFF character and the user
447
-		// specified char. 
448
-		writeNoHandshake(state & XON_XOFF_CHAR_MASK);
449
-		xon_xoff_state = state | XON_XOFF_CHAR_SENT;		
450
-	  }
451
-	#endif
452
-	  writeNoHandshake(c);
408
+      #if ENABLED(SERIAL_XON_XOFF)
409
+        const uint8_t state = xon_xoff_state;
410
+        if (!(state & XON_XOFF_CHAR_SENT)) {
411
+          // Send 2 chars: XON/XOFF, then a user-specified char
412
+          writeNoHandshake(state & XON_XOFF_CHAR_MASK);
413
+          xon_xoff_state = state | XON_XOFF_CHAR_SENT;
414
+        }
415
+      #endif
416
+      writeNoHandshake(c);
453 417
     }
454
-	
455
-	void MarlinSerial::writeNoHandshake(uint8_t c) {
456
-		
418
+
419
+    void MarlinSerial::writeNoHandshake(const uint8_t c) {
457 420
       _written = true;
458 421
       CRITICAL_SECTION_START;
459 422
         bool emty = (tx_buffer.head == tx_buffer.tail);
460 423
       CRITICAL_SECTION_END;
461
-	  
424
+
462 425
       // If the buffer and the data register is empty, just write the byte
463 426
       // to the data register and be done. This shortcut helps
464 427
       // significantly improve the effective datarate at high (>
@@ -497,7 +460,6 @@
497 460
       return;
498 461
     }
499 462
 
500
-	
501 463
     void MarlinSerial::flushTX(void) {
502 464
       // TX
503 465
       // If we have never written a byte, no need to flush. This special
@@ -516,35 +478,32 @@
516 478
       }
517 479
       // If we get here, nothing is queued anymore (DRIE is disabled) and
518 480
       // the hardware finished tranmission (TXC is set).
519
-  }
481
+    }
520 482
 
521
-  #else
522
-    void MarlinSerial::write(uint8_t c) {
523
-		
524
-	#if ENABLED(SERIAL_XON_XOFF)
525
-	  // If we must do a priority insertion of an XON/XOFF char, do it now
526
-	  uint8_t state = xon_xoff_state;
527
-	  if (!(state & XON_XOFF_CHAR_SENT)) {
528
-		  
529
-		writeNoHandshake(state & XON_XOFF_CHAR_MASK);
530
-		xon_xoff_state = state | XON_XOFF_CHAR_SENT;
531
-	  }
532
-	#endif
533
-
534
-	  writeNoHandshake(c);
483
+  #else // TX_BUFFER_SIZE == 0
484
+
485
+    void MarlinSerial::write(const uint8_t c) {
486
+      #if ENABLED(SERIAL_XON_XOFF)
487
+        // Do a priority insertion of an XON/XOFF char, if needed.
488
+        const uint8_t state = xon_xoff_state;
489
+        if (!(state & XON_XOFF_CHAR_SENT)) {
490
+          writeNoHandshake(state & XON_XOFF_CHAR_MASK);
491
+          xon_xoff_state = state | XON_XOFF_CHAR_SENT;
492
+        }
493
+      #endif
494
+      writeNoHandshake(c);
535 495
     }
536
-	
496
+
537 497
     void MarlinSerial::writeNoHandshake(uint8_t c) {
538
-      while (!TEST(M_UCSRxA, M_UDREx))
539
-        ;
498
+      while (!TEST(M_UCSRxA, M_UDREx)) {/* nada */}
540 499
       M_UDRx = c;
541 500
     }
542
-  #endif
543
-
544
-  // end NEW
545 501
 
546
-  /// imports from print.h
502
+  #endif // TX_BUFFER_SIZE == 0
547 503
 
504
+  /**
505
+   * Imports from print.h
506
+   */
548 507
 
549 508
   void MarlinSerial::print(char c, int base) {
550 509
     print((long)c, base);

+ 22
- 50
Marlin/MarlinSerial.h View File

@@ -84,61 +84,32 @@
84 84
   #ifndef RX_BUFFER_SIZE
85 85
     #define RX_BUFFER_SIZE 128
86 86
   #endif
87
-  #if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024
88
-	#error "XON/XOFF requires a 1024 or greater RX_BUFFER_SIZE for allowing reliable transfers without drops"
89
-  #endif
90 87
   #ifndef TX_BUFFER_SIZE
91 88
     #define TX_BUFFER_SIZE 32
92 89
   #endif
93
-  #if !IS_POWEROF2(RX_BUFFER_SIZE) || (RX_BUFFER_SIZE < 2)
94
-    #error "RX_BUFFER_SIZE has to be a power of 2 and >= 2"
95
-  #endif
96
-  #if TX_BUFFER_SIZE != 0 && (TX_BUFFER_SIZE < 2 || TX_BUFFER_SIZE > 256 || !IS_POWEROF2(TX_BUFFER_SIZE))
97
-    #error "TX_BUFFER_SIZE has to be a power of 2 or 0"
98
-  #endif
99
-  #if RX_BUFFER_SIZE > 256
100
-	typedef uint16_t ring_buffer_pos_t;
101
-  #else
102
-	typedef uint8_t ring_buffer_pos_t;
103
-  #endif
104
-
105
-  struct ring_buffer_r {
106
-    unsigned char buffer[RX_BUFFER_SIZE];
107
-    volatile ring_buffer_pos_t head;
108
-    volatile ring_buffer_pos_t tail;
109
-  };
110 90
 
111
-  #if TX_BUFFER_SIZE > 0
112
-    struct ring_buffer_t {
113
-      unsigned char buffer[TX_BUFFER_SIZE];
114
-      volatile uint8_t head;
115
-      volatile uint8_t tail;
116
-    };
91
+  #if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024
92
+    #error "XON/XOFF requires RX_BUFFER_SIZE >= 1024 for reliable transfers without drops."
117 93
   #endif
118
-
119
-  #if UART_PRESENT(SERIAL_PORT)
120
-    extern ring_buffer_r rx_buffer;
121
-    #if TX_BUFFER_SIZE > 0
122
-      extern ring_buffer_t tx_buffer;
123
-    #endif
94
+  #if !IS_POWER_OF_2(RX_BUFFER_SIZE) || RX_BUFFER_SIZE < 2
95
+    #error "RX_BUFFER_SIZE must be a power of 2 greater than 1."
96
+  #endif
97
+  #if TX_BUFFER_SIZE && (TX_BUFFER_SIZE < 2 || TX_BUFFER_SIZE > 256 || !IS_POWER_OF_2(TX_BUFFER_SIZE))
98
+    #error "TX_BUFFER_SIZE must be 0 or a power of 2 greater than 1."
124 99
   #endif
125 100
 
126
-  #if ENABLED(SERIAL_XON_XOFF)
127
-	#define XON_XOFF_CHAR_SENT 	(uint8_t)0x80	/* XON / XOFF Character was sent */
128
-	#define XON_XOFF_CHAR_MASK  (uint8_t)0x1F	/* XON / XOFF character to send */
129
-	
130
-	extern uint8_t xon_xoff_state;
131
-
132
-	// XON / XOFF character definitions
133
-	#define XON_CHAR  (uint8_t)17
134
-	#define XOFF_CHAR (uint8_t)19
101
+  #if RX_BUFFER_SIZE > 256
102
+    typedef uint16_t ring_buffer_pos_t;
103
+  #else
104
+    typedef uint8_t ring_buffer_pos_t;
135 105
   #endif
136 106
   
137 107
   #if ENABLED(SERIAL_STATS_DROPPED_RX)
138
-	extern uint8_t rx_dropped_bytes;
108
+    extern uint8_t rx_dropped_bytes;
139 109
   #endif
110
+
140 111
   #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
141
-	extern ring_buffer_pos_t rx_max_enqueued;
112
+    extern ring_buffer_pos_t rx_max_enqueued;
142 113
   #endif  
143 114
   
144 115
   class MarlinSerial { //: public Stream
@@ -157,14 +128,15 @@
157 128
         static uint8_t availableForWrite(void);
158 129
         static void flushTX(void);
159 130
       #endif
160
-	  static void writeNoHandshake(uint8_t c);
131
+      static void writeNoHandshake(const uint8_t c);
161 132
 
162
-  #if ENABLED(SERIAL_STATS_DROPPED_RX)
163
-	  static uint32_t dropped() { return rx_dropped_bytes; }
164
-  #endif
165
-  #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
166
-	  static ring_buffer_pos_t rxMaxEnqueued() { return rx_max_enqueued; }
167
-  #endif  
133
+      #if ENABLED(SERIAL_STATS_DROPPED_RX)
134
+        FORCE_INLINE static uint32_t dropped() { return rx_dropped_bytes; }
135
+      #endif
136
+
137
+      #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
138
+        FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return rx_max_enqueued; }
139
+      #endif  
168 140
 
169 141
     private:
170 142
       static void printNumber(unsigned long, const uint8_t);

+ 10
- 7
Marlin/Marlin_main.cpp View File

@@ -1097,7 +1097,7 @@ inline void get_serial_commands() {
1097 1097
   int c;
1098 1098
   while (commands_in_queue < BUFSIZE && (c = MYSERIAL.read()) >= 0) {
1099 1099
 
1100
-	char serial_char = c;
1100
+    char serial_char = c;
1101 1101
 
1102 1102
     /**
1103 1103
      * If the character ends the line
@@ -13330,12 +13330,15 @@ void loop() {
13330 13330
           // M29 closes the file
13331 13331
           card.closefile();
13332 13332
           SERIAL_PROTOCOLLNPGM(MSG_FILE_SAVED);
13333
-		#if ENABLED(SERIAL_STATS_DROPPED_RX)
13334
-		  SERIAL_ECHOLNPAIR("Dropped bytes: ", MarlinSerial::dropped());
13335
-		#endif
13336
-		#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
13337
-		  SERIAL_ECHOLNPAIR("Max RX Queue Size: ", MarlinSerial::rxMaxEnqueued());
13338
-		#endif  
13333
+
13334
+          #if ENABLED(SERIAL_STATS_DROPPED_RX)
13335
+            SERIAL_ECHOLNPAIR("Dropped bytes: ", customizedSerial.dropped());
13336
+          #endif
13337
+
13338
+          #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
13339
+            SERIAL_ECHOLNPAIR("Max RX Queue Size: ", customizedSerial.rxMaxEnqueued());
13340
+          #endif
13341
+
13339 13342
           ok_to_send();
13340 13343
         }
13341 13344
         else {

+ 1
- 1
Marlin/macros.h View File

@@ -100,7 +100,7 @@
100 100
 #define SET_BIT(n,b,value) (n) ^= ((-value)^(n)) & (_BV(b))
101 101
 
102 102
 // Macro to check that a number if a power if 2
103
-#define IS_POWEROF2(x) ((x) && !((x) & ((x) - 1)))
103
+#define IS_POWER_OF_2(x) ((x) && !((x) & ((x) - 1)))
104 104
 
105 105
 // Macros for maths shortcuts
106 106
 #ifndef M_PI

Loading…
Cancel
Save