@@ -96,7 +96,9 @@ void SerialUART::begin(unsigned long baud, uint16_t config) {
96
96
gpio_set_function (_tx, GPIO_FUNC_UART);
97
97
gpio_set_function (_rx, GPIO_FUNC_UART);
98
98
_running = true ;
99
- _peek = -1 ;
99
+ while (!_swFIFO.empty ()) {
100
+ (void )_swFIFO.pop (); // Just throw out anything in our old FIFO
101
+ }
100
102
}
101
103
102
104
void SerialUART::end () {
@@ -107,52 +109,66 @@ void SerialUART::end() {
107
109
_running = false ;
108
110
}
109
111
112
+ // Transfers any data in the HW FIFO into our SW one, up to 32 bytes
113
+ void SerialUART::_pumpFIFO () {
114
+ while ((_swFIFO.size () < 32 ) && (uart_is_readable (_uart))) {
115
+ _swFIFO.push (uart_getc (_uart));
116
+ }
117
+ }
118
+
110
119
int SerialUART::peek () {
111
120
CoreMutex m (&_mutex);
112
121
if (!_running || !m) {
113
122
return -1 ;
114
123
}
115
- if (_peek >= 0 ) {
116
- return _peek;
124
+ _pumpFIFO ();
125
+ // If there's something in the FIFO now, just peek at it
126
+ if (_swFIFO.size ()) {
127
+ return _swFIFO.front ();
117
128
}
129
+ // The SW FIFO is empty, read the HW one until the timeout
118
130
if (uart_is_readable_within_us (_uart, _timeout * 1000 )) {
119
- _peek = uart_getc (_uart);
120
- } else {
121
- _peek = - 1 ; // Timeout
131
+ // We got one char, put it in the FIFO (which will now have exactly 1 byte) and return it
132
+ _swFIFO. push ( uart_getc (_uart));
133
+ return _swFIFO. front ();
122
134
}
123
- return _peek;
135
+ return - 1 ; // Nothing available before timeout
124
136
}
125
137
126
138
int SerialUART::read () {
127
139
CoreMutex m (&_mutex);
128
140
if (!_running || !m) {
129
141
return -1 ;
130
142
}
131
- if (_peek >= 0 ) {
132
- int ret = _peek;
133
- _peek = -1 ;
143
+ _pumpFIFO ();
144
+ if (_swFIFO.size ()) {
145
+ auto ret = _swFIFO.front ();
146
+ _swFIFO.pop ();
134
147
return ret;
135
148
}
149
+ // The SW FIFO is empty, read the HW one until the timeout
136
150
if (uart_is_readable_within_us (_uart, _timeout * 1000 )) {
151
+ // We got one char, return it (FIFO will still be empty
137
152
return uart_getc (_uart);
138
- } else {
139
- return -1 ; // Timeout
140
153
}
154
+ return -1 ; // Timeout
141
155
}
142
156
143
157
int SerialUART::available () {
144
158
CoreMutex m (&_mutex);
145
159
if (!_running || !m) {
146
160
return 0 ;
147
161
}
148
- return (uart_is_readable (_uart)) ? 1 : 0 ;
162
+ _pumpFIFO ();
163
+ return _swFIFO.size ();
149
164
}
150
165
151
166
int SerialUART::availableForWrite () {
152
167
CoreMutex m (&_mutex);
153
168
if (!_running || !m) {
154
169
return 0 ;
155
170
}
171
+ _pumpFIFO ();
156
172
return (uart_is_writable (_uart)) ? 1 : 0 ;
157
173
}
158
174
@@ -161,6 +177,7 @@ void SerialUART::flush() {
161
177
if (!_running || !m) {
162
178
return ;
163
179
}
180
+ _pumpFIFO ();
164
181
uart_tx_wait_blocking (_uart);
165
182
}
166
183
@@ -169,6 +186,7 @@ size_t SerialUART::write(uint8_t c) {
169
186
if (!_running || !m) {
170
187
return 0 ;
171
188
}
189
+ _pumpFIFO ();
172
190
uart_putc_raw (_uart, c);
173
191
return 1 ;
174
192
}
@@ -178,6 +196,7 @@ size_t SerialUART::write(const uint8_t *p, size_t len) {
178
196
if (!_running || !m) {
179
197
return 0 ;
180
198
}
199
+ _pumpFIFO ();
181
200
size_t cnt = len;
182
201
while (cnt) {
183
202
uart_putc_raw (_uart, *p);
0 commit comments