@@ -140,30 +140,105 @@ void HardwareSerial::begin(unsigned long baud, byte config)
140140 uart_init (&_serial, (uint32_t )baud, databits, parity, stopbits);
141141}
142142
143+ // MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
144+ void HardwareSerial::fillRxBuffer (void ) // private method: read all characters that can be read
145+ {
146+ // Fill RX buffer during read/available calls
147+ // Newly received characters are added to the buffer
148+ // _rx_buffer_head is the location of the new character
149+ // _rx_buffer_tail is the location of the oldest character that is not read yet
150+ unsigned char c;
151+ /*
152+ while(uart_getc(&_serial, &c) == 0)
153+ {
154+ _rx_buffer[_rx_buffer_head]=c;
155+ _rx_buffer_head = (rx_buffer_index_t)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;
156+ }
157+ */
158+ // To avoid buffer underruns, we try to read during at least a few millis.
159+ // Perhaps there is a better way, but for now it works.
160+ // Maybe we should also do something to handle disruption of interrupts
161+ /*
162+ #define SERIAL_WAIT_FOR_RX 5000L
163+ uint32_t uStart=micros();
164+ while((micros()-uStart)<SERIAL_WAIT_FOR_RX)
165+ */
166+ #define SERIAL_WAIT_FOR_RX 3
167+ uint32_t uStart=millis ();
168+ while ((millis ()-uStart)<SERIAL_WAIT_FOR_RX)
169+ {
170+ if (uart_getc (&_serial, &c) == 0 )
171+ {
172+ /*
173+ _rx_buffer[_rx_buffer_head]=c;
174+ _rx_buffer_head = (rx_buffer_index_t)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;
175+ /**/
176+ rx_buffer_index_t i = (unsigned int )(_rx_buffer_head + 1 ) % SERIAL_RX_BUFFER_SIZE;
177+
178+ // if we should be storing the received character into the location
179+ // just before the tail (meaning that the head would advance to the
180+ // current location of the tail), we're about to overflow the buffer
181+ // and so we don't write the character or advance the head.
182+ if (i != _rx_buffer_tail) {
183+ _rx_buffer[_rx_buffer_head] = c;
184+ _rx_buffer_head = i;
185+ }
186+ /* */
187+ }
188+ }
189+ }
190+
143191void HardwareSerial::end ()
144192{
193+ // MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
194+ // clear any received data
195+ _rx_buffer_head = _rx_buffer_tail;
196+
145197 uart_deinit (&_serial);
146198}
147199
148200int HardwareSerial::available (void )
149201{
150- return -1 ;
202+ // MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
203+ // return -1;
204+ fillRxBuffer ();
205+ return ((unsigned int )(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE;
151206}
152207
153208int HardwareSerial::peek (void )
154209{
155- return -1 ;
210+ // MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
211+ // return -1;
212+ fillRxBuffer (); // MMOLE 240316: Serial.parseInt() uses peek() with timeout to see if more data is available
213+ if (_rx_buffer_head == _rx_buffer_tail) {
214+ return -1 ;
215+ } else {
216+ return _rx_buffer[_rx_buffer_tail];
217+ }
156218}
157219
158220int HardwareSerial::read (void )
159221{
160-
161222 unsigned char c;
223+ // MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
224+ /*
162225 if(uart_getc(&_serial, &c) == 0){
163226 return c;
164227 }else{
165228 return -1;
166229 }
230+ */
231+ // Fill RX buffer during read/available calls
232+ fillRxBuffer ();
233+
234+ // if the head isn't ahead of the tail, we don't have any characters
235+ if (_rx_buffer_head == _rx_buffer_tail) {
236+ return -1 ;
237+ } else {
238+ unsigned char c = _rx_buffer[_rx_buffer_tail];
239+ _rx_buffer_tail = (rx_buffer_index_t )(_rx_buffer_tail + 1 ) % SERIAL_RX_BUFFER_SIZE;
240+ return c;
241+ }
167242}
168243
169244
0 commit comments