-
Notifications
You must be signed in to change notification settings - Fork 1k
Hardware serial ports issue with full-duplex usage #467
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
Comments
This serial problem happens in my 3dprinter frameware too . |
I'm using the Marlin 3d-printer firmware on the selfmade 3D-printer board (STM32F429IG). |
I have ref #421 |
Hi @ShenRen If you find RX interrupt disabled you probably have the same issue I had. Lines added are marked with "+" and those removed are marked with "-". Just find the two functions |
Please, @ppescher could you submit a PR? |
No. I still have this problem! |
Solved thanks #502 |
The way serial ports are implemented in the Arduino core can lead to a serial port permanently stop receiving under particular conditions.
If the serial port is transmitting some data, the last transmit callback does not re-enable the TX interrupt if the ring buffer is empty. This is done at the end of the HardwareSerial::write() function, outside the IRQ context.
If a receive interrupt fires at this time, inside the Transmit_IT() function, when the receive callback is finally called it will fail to re-enable the RX interrupt, because Receive_IT() finds the handle locked.
You can see my solution in this commit: fortebit@21cbddd
Another issue that happened while I was trying to debug this nightmare was that the USART kept receiving bytes after hitting a breakpoint and eventually signaled an overrun error. I'm not entirely sure how the error callback should be handled, but the current implementation inside the uart driver does not seem correct: the error flags are not cleared correctly for an STM32L4 (reading the data register is not enough) and probably you should re-enable the RX interrupt because the normal receive callback does not get called.
You can see my solution in this other commit: fortebit@6653e31
I'm not sure if the flags are cleared correctly for all STM32 families, as was only debugging on an STM32L4.
My variant is based on an old STM32 core version, I think it was 1.2.0, but I verified the affected code has not changed significantly in the latest official release 1.5.0.
The first bug depends on how the handle locking mechanism is implemented in the HAL, I don't know if this has changed lately but my guess is it has not. If the lock is already acquired, an asynchrounous function (called from an IRQ for example) simply fails.
And when the Receive_IT() function fails there was no special handling and no way to know something went bad. It took me many hours of debugging to catch this and finally spot the __HAL_LOCK(handle) macro was leaving the function with an error code.
In my solution I just disabled the UART IRQ when the HAL Receive_IT/Transmit_IT are called, implementing a true critical section, but only affecting a single IRQ and not global interrupts.
The text was updated successfully, but these errors were encountered: