Skip to content

Conversation

MaxMax-embedded
Copy link

By creating this pull request you agree to the terms in CONTRIBUTING.md.
https://github.com/Infineon/.github/blob/master/CONTRIBUTING.md
--- DO NOT DELETE ANYTHING ABOVE THIS LINE ---

CONTRIBUTING.md also tells you what to expect in the PR process.

Description

The if condition to store data in the buffer is triggered regardless of the current uart transmit status if tail and head differ:

if(( XMC_USIC_CH_GetTransmitBufferStatus( _XMC_UART_config->channel ) == XMC_USIC_CH_TBUF_STATUS_BUSY )
        || ( _tx_buffer->_iTail != _tx_buffer->_iHead ))

This can lead to an infinte loop in the spinlook if the transmit IRQ is executed in the wrong moment and not new transmission is started. To prevent this a check is added to ensure that a new transmission is started if non is currently in progress by the following code:

  if( XMC_USIC_CH_GetTransmitBufferStatus( _XMC_UART_config->channel ) != XMC_USIC_CH_TBUF_STATUS_BUSY ) 
{
	  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 seems to fix the problem on my setup.

Context
Tested on a XMC4700 Relax Kit using the 3.4.1 Version of the XMC for Arduino Core running 2Mbit Serial1 to a TLE9012 and a 115200 Bit/s Serial to the Host PC

Copy link
Collaborator

@LinjingZhang LinjingZhang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are absolutely correct. The old function does not attempt to re-enable the interrupt and send data, which causes the buffer to remain full and the spinlock persists.
If you can simplify the comments, I will merge your PR. thank you very much!

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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please simplify the comments, for example by keeping only the “//Reenable IRQ and send Data”

@LinjingZhang LinjingZhang changed the base branch from master to bugfix/serial_stuck_in_spinlock October 25, 2024 08:02
@LinjingZhang LinjingZhang merged commit 1527196 into Infineon:bugfix/serial_stuck_in_spinlock Oct 25, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants