|
@@ -23,6 +23,12 @@
|
23
|
23
|
#define MarlinSerial_h
|
24
|
24
|
#include "Marlin.h"
|
25
|
25
|
|
|
26
|
+#ifndef CRITICAL_SECTION_START
|
|
27
|
+ #define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli();
|
|
28
|
+ #define CRITICAL_SECTION_END SREG = _sreg;
|
|
29
|
+#endif
|
|
30
|
+
|
|
31
|
+
|
26
|
32
|
#ifndef SERIAL_PORT
|
27
|
33
|
#define SERIAL_PORT 0
|
28
|
34
|
#endif
|
|
@@ -69,9 +75,13 @@
|
69
|
75
|
// using a ring buffer (I think), in which rx_buffer_head is the index of the
|
70
|
76
|
// location to which to write the next incoming character and rx_buffer_tail
|
71
|
77
|
// is the index of the location from which to read.
|
72
|
|
-// 256 is the max limit due to uint8_t head and tail. Thats needed to make them atomic.
|
73
|
|
-#define RX_BUFFER_SIZE 128
|
74
|
|
-
|
|
78
|
+// 256 is the max limit due to uint8_t head and tail. Use only powers of 2. (...,16,32,64,128,256)
|
|
79
|
+#ifndef RX_BUFFER_SIZE
|
|
80
|
+ #define RX_BUFFER_SIZE 128
|
|
81
|
+#endif
|
|
82
|
+#if !((RX_BUFFER_SIZE == 256) ||(RX_BUFFER_SIZE == 128) ||(RX_BUFFER_SIZE == 64) ||(RX_BUFFER_SIZE == 32) ||(RX_BUFFER_SIZE == 16) ||(RX_BUFFER_SIZE == 8) ||(RX_BUFFER_SIZE == 4) ||(RX_BUFFER_SIZE == 2))
|
|
83
|
+ #error RX_BUFFER_SIZE has to be a power of 2 and >= 2
|
|
84
|
+#endif
|
75
|
85
|
|
76
|
86
|
struct ring_buffer {
|
77
|
87
|
unsigned char buffer[RX_BUFFER_SIZE];
|
|
@@ -94,7 +104,11 @@ class MarlinSerial { //: public Stream
|
94
|
104
|
void flush(void);
|
95
|
105
|
|
96
|
106
|
FORCE_INLINE uint8_t available(void) {
|
97
|
|
- return (uint8_t)(RX_BUFFER_SIZE + rx_buffer.head - rx_buffer.tail) % RX_BUFFER_SIZE;
|
|
107
|
+ CRITICAL_SECTION_START;
|
|
108
|
+ uint8_t h = rx_buffer.head;
|
|
109
|
+ uint8_t t = rx_buffer.tail;
|
|
110
|
+ CRITICAL_SECTION_END;
|
|
111
|
+ return (uint8_t)(RX_BUFFER_SIZE + h - t) & (RX_BUFFER_SIZE - 1);
|
98
|
112
|
}
|
99
|
113
|
|
100
|
114
|
FORCE_INLINE void write(uint8_t c) {
|
|
@@ -106,16 +120,19 @@ class MarlinSerial { //: public Stream
|
106
|
120
|
FORCE_INLINE void checkRx(void) {
|
107
|
121
|
if (TEST(M_UCSRxA, M_RXCx)) {
|
108
|
122
|
unsigned char c = M_UDRx;
|
109
|
|
- uint8_t i = (uint8_t)(rx_buffer.head + 1) % RX_BUFFER_SIZE;
|
110
|
|
-
|
111
|
|
- // if we should be storing the received character into the location
|
112
|
|
- // just before the tail (meaning that the head would advance to the
|
113
|
|
- // current location of the tail), we're about to overflow the buffer
|
114
|
|
- // and so we don't write the character or advance the head.
|
115
|
|
- if (i != rx_buffer.tail) {
|
116
|
|
- rx_buffer.buffer[rx_buffer.head] = c;
|
117
|
|
- rx_buffer.head = i;
|
118
|
|
- }
|
|
123
|
+ CRITICAL_SECTION_START;
|
|
124
|
+ uint8_t h = rx_buffer.head;
|
|
125
|
+ uint8_t i = (uint8_t)(h + 1) & (RX_BUFFER_SIZE - 1);
|
|
126
|
+
|
|
127
|
+ // if we should be storing the received character into the location
|
|
128
|
+ // just before the tail (meaning that the head would advance to the
|
|
129
|
+ // current location of the tail), we're about to overflow the buffer
|
|
130
|
+ // and so we don't write the character or advance the head.
|
|
131
|
+ if (i != rx_buffer.tail) {
|
|
132
|
+ rx_buffer.buffer[h] = c;
|
|
133
|
+ rx_buffer.head = i;
|
|
134
|
+ }
|
|
135
|
+ CRITICAL_SECTION_END;
|
119
|
136
|
}
|
120
|
137
|
}
|
121
|
138
|
|