Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed edge case that might lead to Serial beeing stuck in spinlook wait #307

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

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”

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