From ba1f8e5474da55496a730780f543d0bbc72f2e17 Mon Sep 17 00:00:00 2001 From: Kurt Kiefer Date: Thu, 14 Jun 2018 13:27:07 +0000 Subject: [PATCH] Merged in kekiefer/nuttx/stm32f7-serial-fix-tiocssinglewire-upstream (pull request #658) stm32f7: serial: Fix ioctl TIOCSSINGLEWIRE The TRM notes that UE must be disabled in order to write HDSEL in USART_CR3. This was not being done, so calls to TIOCSSINGLEWIRE were silently failing. This change checks the state of UE in USART_CR1, clears the UE bit before writing HDSEL, then re-enables it if neccesary. Approved-by: GregoryN --- arch/arm/src/stm32f7/stm32_serial.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/arm/src/stm32f7/stm32_serial.c b/arch/arm/src/stm32f7/stm32_serial.c index ba6edead301..c200e813b56 100644 --- a/arch/arm/src/stm32f7/stm32_serial.c +++ b/arch/arm/src/stm32f7/stm32_serial.c @@ -1926,6 +1926,22 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) #ifdef CONFIG_STM32F7_USART_SINGLEWIRE case TIOCSSINGLEWIRE: { + uint32_t cr1; + uint32_t cr1_ue; + irqstate_t flags; + + flags = enter_critical_section(); + + /* Get the original state of UE */ + + cr1 = up_serialin(priv, STM32_USART_CR1_OFFSET); + cr1_ue = cr1 & USART_CR1_UE; + cr1 &= ~USART_CR1_UE; + + /* Disable UE, HDSEL can only be written when UE=0 */ + + up_serialout(priv, STM32_USART_CR1_OFFSET, cr1); + /* Change the TX port to be open-drain/push-pull and enable/disable * half-duplex mode. */ @@ -1944,6 +1960,11 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) } up_serialout(priv, STM32_USART_CR3_OFFSET, cr); + + /* Re-enable UE if appropriate */ + + up_serialout(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue); + leave_critical_section(flags); } break; #endif