diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index a06a6275eb..ff9ca2d2a5 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -441,7 +441,7 @@ void HardwareSerial::begin(unsigned long baud, byte config) void HardwareSerial::end() { // wait for transmission of outgoing data - flush(); + flush(TX_TIMEOUT); uart_deinit(&_serial); @@ -487,20 +487,25 @@ int HardwareSerial::availableForWrite(void) return tail - head - 1; } -void HardwareSerial::flush() +void HardwareSerial::flush(uint32_t timeout) { // If we have never written a byte, no need to flush. This special // case is needed since there is no way to force the TXC (transmit // complete) bit to 1 during initialization - if (!_written) { - return; - } - - while ((_serial.tx_head != _serial.tx_tail)) { - // nop, the interrupt handler will free up space for us + if (_written) { + uint32_t tickstart = HAL_GetTick(); + while ((_serial.tx_head != _serial.tx_tail)) { + // the interrupt handler will free up space for us + // Only manage timeout if any + if ((timeout != 0) && ((HAL_GetTick() - tickstart) >= timeout)) { + // clear any transmit data + _serial.tx_head = _serial.tx_tail; + break; + } + } + // If we get here, nothing is queued anymore (DRIE is disabled) and + // the hardware finished transmission (TXC is set). } - // If we get here, nothing is queued anymore (DRIE is disabled) and - // the hardware finished transmission (TXC is set). } size_t HardwareSerial::write(const uint8_t *buffer, size_t size) diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index 54ebfe2af3..b0089bab19 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -125,7 +125,7 @@ class HardwareSerial : public Stream { virtual int peek(void); virtual int read(void); int availableForWrite(void); - virtual void flush(void); + virtual void flush(uint32_t timeout = 0); virtual size_t write(uint8_t); inline size_t write(unsigned long n) { diff --git a/cores/arduino/stm32/uart.h b/cores/arduino/stm32/uart.h index 9d2da47549..2a8537f45c 100644 --- a/cores/arduino/stm32/uart.h +++ b/cores/arduino/stm32/uart.h @@ -86,7 +86,9 @@ struct serial_s { }; /* Exported constants --------------------------------------------------------*/ +#ifndef TX_TIMEOUT #define TX_TIMEOUT 1000 +#endif #if !defined(RCC_USART1CLKSOURCE_HSI) /* Some series like C0 have 2 derivated clock from HSI: HSIKER (for peripherals)