From 07eeba40a955e2ec6b68009cabddb64608b2c31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20=27MaxMax=27=20M=C3=B6nikes?= Date: Mon, 7 Oct 2024 23:35:53 +0200 Subject: [PATCH] Fixed edge case that might lead to Serial beeing stuck in spinlook wait --- cores/HardwareSerial.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/cores/HardwareSerial.cpp b/cores/HardwareSerial.cpp index 64a8e649..63c0a518 100644 --- a/cores/HardwareSerial.cpp +++ b/cores/HardwareSerial.cpp @@ -185,6 +185,17 @@ if(( XMC_USIC_CH_GetTransmitBufferStatus( _XMC_UART_config->channel ) == XMC_USI int nextWrite = _tx_buffer->_iHead + 1; if( nextWrite >= SERIAL_BUFFER_SIZE ) nextWrite = 0; + + //This should always be false but in case transmission is completed before head is advanced at the end of this function we might get stuck in an infinte loop at the spinlook stage + if( XMC_USIC_CH_GetTransmitBufferStatus( _XMC_UART_config->channel ) != XMC_USIC_CH_TBUF_STATUS_BUSY ) { + //Reenable IRQ and send Data + XMC_UART_CH_EnableEvent( _XMC_UART_config->channel, XMC_UART_CH_EVENT_TRANSMIT_BUFFER ); + XMC_UART_CH_Transmit( _XMC_UART_config->channel, _tx_buffer->_aucBuffer[ _tx_buffer->_iTail ] ); + _tx_buffer->_iTail++; + if(_tx_buffer->_iTail >= SERIAL_BUFFER_SIZE) + _tx_buffer->_iTail = _tx_buffer->_iTail - SERIAL_BUFFER_SIZE; //This should be interchangeable with iTail = 0 but I like this style more as it provides a correct value if iTail is larger than Serial Buffer Size (which should never be the case) + } + while( _tx_buffer->_iTail == nextWrite ) ; // Spin locks if we're about to overwrite the buffer. This continues once the data is sent @@ -232,12 +243,14 @@ if( ( status & XMC_UART_CH_STATUS_FLAG_TRANSMIT_BUFFER_INDICATION ) != 0U ) if( _tx_buffer->_iTail >= SERIAL_BUFFER_SIZE ) _tx_buffer->_iTail = 0; } - else + else { // Mask off transmit interrupt so we don't get it any more - XMC_UART_CH_DisableEvent( _XMC_UART_config->channel, XMC_UART_CH_EVENT_TRANSMIT_BUFFER ); + XMC_UART_CH_DisableEvent( _XMC_UART_config->channel, XMC_UART_CH_EVENT_TRANSMIT_BUFFER ); + } } } //**************************************************************************** // END OF FILE //**************************************************************************** +