-
Notifications
You must be signed in to change notification settings - Fork 74
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
F4_HAL/uart: Fix data loss when using DMA Rx with hardware flow control. #12
Conversation
FYI, this is a variation of part of the fixes from bluekitchen/btstack@bef4d37. Disabling IRQs is probably also needed, but I'm not sure the way it is done in the linked commit won't cause problems for existing users of MicroPython (i.e. interrupts may already be disabled). |
This looks OK to me. I assume you have tested it and it fixed the issue with lost chars on DMA RX?
All F4 MCUs have a bit-band region (every bit is assigned a 32-bit word alias), and this can be used to make atomic changes to bits in peripheral registers. I think this would be a good way to solve that issue of Eg: #define PERIPH_BB_REG_ADDR(reg, bit_pos) (__IO uint32_t *)(PERIPH_BB_BASE + ((uintptr_t)&(reg) - PERIPH_BASE) * 32 + (bit_pos) * 4)
#define SET_BIT_PERIPH_BB(reg, bit_pos) (*(PERIPH_BB_REG_ADDR((reg), (bit_pos)) = 1)
{
...
SET_BIT_PERIPH_BB(huart->Instance->CR1, USART_CR1_PEIE_Pos);
...
} Note: the above macros are untested! |
Also, can you please retarget this to the new working branch |
Data loss can occur when using DMA Rx + hardware flow control. Consider the following situation where a device is receiving UART data that consists of one byte that gives the size of the data followed by "size" bytes: - MCU requests to read one byte from UART by calling HAL_UART_Receive_IT() - The remote may or may not have already sent the byte, but it doesn't matter, this works correctly. - After the UART_Receive_IT() callback, the MCU requests to read "size" bytes by calling HAL_UART_Receive_DMA(). - If the remote has not sent the next byte yet, then all is well, but it could have sent the next byte already, which is waiting in the DR register. The RTS line will be high which prevents the remote from sending any more data, so no overrun will occur. But since __HAL_UART_CLEAR_OREFLAG() reads the DR register, this byte will be lost and the DMA read will read one extra byte from the incoming stream causing the algorithm to get out of sync. This adds a check to see if flow control is enabled and only calls __HAL_UART_CLEAR_OREFLAG() if flow control is disabled. This should prevent breaking users who aren't using flow control and may already depend on this behavior.
This changes writes to the CR1 and CR3 registers to use bit-band access to atomically modify the registers. This is needed since the interrupt handlers also modify these same registers and an interrupt could occur in the time between when the registers is read and when the modify value is written back. This change is not made in the init functions since interrupts will not be enabled yet and it is more efficient to set more than one bit at a time.
9cc7d02
to
74cc9b3
Compare
Hi @dpgeorge. I have rebased and added the suggested bit-band macros. This has been tested and confirmed to fix the DMA issue. |
This pulls in fixes to the MicroPython stm32lib needed for BTStack. This patch can be dropped once micropython/stm32lib#12 is merged.
This pulls in fixes to the MicroPython stm32lib needed for BTStack. This patch can be dropped once micropython/stm32lib#12 is merged.
This pulls in fixes to the MicroPython stm32lib needed for BTStack. This patch can be dropped once micropython/stm32lib#12 is merged.
This pulls in fixes to the MicroPython stm32lib needed for BTStack. This patch can be dropped once micropython/stm32lib#12 is merged.
This pulls in fixes to the MicroPython stm32lib needed for BTStack. This patch can be dropped once micropython/stm32lib#12 is merged.
74cc9b3
into
micropython:work-F0-1.9.0+F4-1.16.0+F7-1.7.0+G4-1.3.0+H7-1.6.0+L0-1.11.2+L4-1.8.1+WB-1.10.0
Sorry this got lost, now merged. |
This pulls in fixes to the MicroPython stm32lib needed for BTStack. This patch can be dropped once micropython/stm32lib#12 is merged.
Data loss can occur when using DMA Rx + hardware flow control.
Consider the following situation where a device is receiving UART data that consists of one byte that gives the size of the data followed by "size" bytes:
This adds a check to see if flow control is enabled and only calls __HAL_UART_CLEAR_OREFLAG() if flow control is disabled. This should prevent breaking users who aren't using flow control and may already depend on this behavior.