diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index 049c24a74d5..7b8ee993581 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -450,10 +450,12 @@ int HardwareSerial::peek(void) int HardwareSerial::read(void) { - if(available()) { - return uartRead(_uart); + uint8_t c = 0; + if (uartReadBytes(_uart, &c, 1, 0) == 1) { + return c; + } else { + return -1; } - return -1; } // read characters into buffer @@ -462,16 +464,13 @@ int HardwareSerial::read(void) // the buffer is NOT null terminated. size_t HardwareSerial::read(uint8_t *buffer, size_t size) { - size_t avail = available(); - if (size < avail) { - avail = size; - } - size_t count = 0; - while(count < avail) { - *buffer++ = uartRead(_uart); - count++; - } - return count; + return uartReadBytes(_uart, buffer, size, 0); +} + +// Overrides Stream::readBytes() to be faster using IDF +size_t HardwareSerial::readBytes(uint8_t *buffer, size_t length) +{ + return uartReadBytes(_uart, buffer, length, (uint32_t)getTimeout()); } void HardwareSerial::flush(void) diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index 0c673c1483f..d5f9c7c1a7b 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -118,6 +118,12 @@ class HardwareSerial: public Stream { return read((uint8_t*) buffer, size); } + // Overrides Stream::readBytes() to be faster using IDF + size_t readBytes(uint8_t *buffer, size_t length); + size_t readBytes(char *buffer, size_t length) + { + return readBytes((uint8_t *) buffer, length); + } void flush(void); void flush( bool txOnly); size_t write(uint8_t); diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index e4b24a112f5..cad9ce7d9c2 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -326,7 +326,36 @@ uint32_t uartAvailableForWrite(uart_t* uart) return available; } +size_t uartReadBytes(uart_t* uart, uint8_t *buffer, size_t size, uint32_t timeout_ms) +{ + if(uart == NULL || size == 0 || buffer == NULL) { + return 0; + } + + size_t bytes_read = 0; + UART_MUTEX_LOCK(); + + if (uart->has_peek) { + uart->has_peek = false; + *buffer++ = uart->peek_byte; + size--; + bytes_read = 1; + } + + if (size > 0) { + int len = uart_read_bytes(uart->num, buffer, size, pdMS_TO_TICKS(timeout_ms)); + if (len < 0) len = 0; // error reading UART + bytes_read += len; + } + + + UART_MUTEX_UNLOCK(); + return bytes_read; +} + +// DEPRICATED but the original code will be kepts here as future reference when a final solution +// to the UART driver is defined in the use case of reading byte by byte from UART. uint8_t uartRead(uart_t* uart) { if(uart == NULL) { @@ -342,7 +371,7 @@ uint8_t uartRead(uart_t* uart) } else { int len = uart_read_bytes(uart->num, &c, 1, 20 / portTICK_RATE_MS); - if (len == 0) { + if (len <= 0) { // includes negative return from IDF in case of error c = 0; } } @@ -350,6 +379,7 @@ uint8_t uartRead(uart_t* uart) return c; } + uint8_t uartPeek(uart_t* uart) { if(uart == NULL) { @@ -363,7 +393,7 @@ uint8_t uartPeek(uart_t* uart) c = uart->peek_byte; } else { int len = uart_read_bytes(uart->num, &c, 1, 20 / portTICK_RATE_MS); - if (len == 0) { + if (len <= 0) { // includes negative return from IDF in case of error c = 0; } else { uart->has_peek = true; diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h index ffb0a3f027a..8e6e7ec4a1b 100644 --- a/cores/esp32/esp32-hal-uart.h +++ b/cores/esp32/esp32-hal-uart.h @@ -69,6 +69,7 @@ void uartGetEventQueue(uart_t* uart, QueueHandle_t *q); uint32_t uartAvailable(uart_t* uart); uint32_t uartAvailableForWrite(uart_t* uart); +size_t uartReadBytes(uart_t* uart, uint8_t *buffer, size_t size, uint32_t timeout_ms); uint8_t uartRead(uart_t* uart); uint8_t uartPeek(uart_t* uart);