Skip to content

Serial discard line break #274

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

Closed
wants to merge 3 commits into from

Conversation

descampsa
Copy link
Contributor

Enable the Receiver Line Status interrupt source in order to discard the 0x00 byte that is generated in case of line break.

I need this because i use the uart to implement a half duplex communication by connecting rx and tx together and enabling/disabling rx/tx. When i disable rx, a line break is generated, and a false data byte of 0x00 is read.

Maybe data shoud also be discarded in case of parity error and framing error?

This code is based on #266

Test case :
serial3_error.ino.txt

Current version of write will never use the interrupt mode
transmission, because it fails to check if holding register is
empty. This commit fix that, and several (maybe not all) bugs
related to interrupt mode serial transmission.
When possible, fill the tx FIFO in interrupt handler, in order to reduce
number of interrupts called and overhead.
In case of line break, a 0x00 byte is added to the receive fifo.
This commit change the irq handler to discard this data.
Other LSR interrupt sources (overrun, parity or framing error) are ignored.
@descampsa
Copy link
Contributor Author

I also have a question about the hardware implementation of the uart.

From my experiments, it seems that when i disconnect the uart rx pin (using SET_PIN_MODE(17, GPIO_MUX_MODE)), it is consistently pulled down to gnd level (hence the line break). I assume that a pull down resistor, or a direct connection to gnd is connected to the rx pin?
Can you confirm that it is the case, and that there is no chance to receive false data in this case, due to em noise or whatever?

@@ -168,7 +168,7 @@ int UARTClass::read( void )

void UARTClass::flush( void )
{
while (_tx_buffer->_iHead != _tx_buffer->_iTail); //wait for transmit data to be sent
while (_tx_buffer->_iHead != *(volatile int*)&(_tx_buffer->_iTail)); //wait for transmit data to be sent
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a particular reason for casting the pointer to a volatile pointer first prior to using it? Is the code being optimized out by the compiler if the volatile casting is omitted?

Copy link
Contributor Author

@descampsa descampsa Oct 18, 2016

Choose a reason for hiding this comment

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

The reason is that iTail can be updated in the irq handler.
Without the volatile, the compiler may optimize the code by reading it only once from memory, and keeping its value in register. That would lead to an infinite loop.

I don't remember if i actually ran into this problem or not, and i did not check the resulting assembly, but that looks like a typical case where volatile is needed.

Note that this more related to pull request #266 than to #274

@kitsunami kitsunami assigned descampsa and SidLeung and unassigned SidLeung and descampsa Oct 24, 2016
@descampsa
Copy link
Contributor Author

I will rebase this against #266 (when merged), and complete it with the parity and framing error cases, so put it on hold for now.

@kitsunami kitsunami modified the milestones: Elnath, Deneb Feb 24, 2017
@kitsunami kitsunami removed this from the Elnath milestone Mar 13, 2017
@novashah
Copy link

Released and merged with 266.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants