qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] Fix TXE/TXEIE support in the STM32 USART model


From: Bill Paul
Subject: [Qemu-devel] [PATCH] Fix TXE/TXEIE support in the STM32 USART model
Date: Mon, 5 Sep 2016 13:40:25 -0700

This commit attempts to fix the behavior of the TX FIFO Empty bit in
the STM32 USART driver. The two changes are:

1) After wrtiting to the data register, don't clear the TXE
bit in the status register. The way this model works, the FIFO is
effectively always empty. This is because we dump each character to
qemu_chr_fe_write_all() right away and unlike real hardware we don't
have to wait for the appropriate bits to be written to the I/O pins.

2) Implement support for the TXEIE (TXE interrupt enable) bit in CR1. When
OS driver code unmasks this bit and TXE is set, this should trigger an
interrupt to let the OS know the channel is now empty and it can send again.

ChibiOS depends on the correct behavior of the TXE and the TXEIE interrupt.
It checks to see if the TXE bit is set before trying to write any
characters. however at the outset TXE is clear, so it blocks forever
(or until you press a key at the serial console, which causes an RX
interrupt that unjams in).

Also once a character has been written, it waits for a TXEIE interrupt
before sending the next character in a string. With these two fixes, it can
now write to the serial port sucessfully.

Signed-off-by: Bill Paul <address@hidden>
Cc: Paolo Bonzini <address@hidden>
---
 hw/char/stm32f2xx_usart.c         | 7 ++++++-
 include/hw/char/stm32f2xx_usart.h | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
index 15657ab..5671a7d 100644
--- a/hw/char/stm32f2xx_usart.c
+++ b/hw/char/stm32f2xx_usart.c
@@ -156,7 +156,6 @@ static void stm32f2xx_usart_write(void *opaque, hwaddr addr,
                 qemu_chr_fe_write_all(s->chr, &ch, 1);
             }
             s->usart_sr |= USART_SR_TC;
-            s->usart_sr &= ~USART_SR_TXE;
         }
         return;
     case USART_BRR:
@@ -168,6 +167,12 @@ static void stm32f2xx_usart_write(void *opaque, hwaddr 
addr,
                 s->usart_sr & USART_SR_RXNE) {
                 qemu_set_irq(s->irq, 1);
             }
+
+            if (s->usart_cr1 & USART_CR1_TXEIE &&
+                s->usart_sr & USART_SR_TXE) {
+                qemu_set_irq(s->irq, 1);
+            }
+
         return;
     case USART_CR2:
         s->usart_cr2 = value;
diff --git a/include/hw/char/stm32f2xx_usart.h 
b/include/hw/char/stm32f2xx_usart.h
index b97f192..2820209 100644
--- a/include/hw/char/stm32f2xx_usart.h
+++ b/include/hw/char/stm32f2xx_usart.h
@@ -44,6 +44,7 @@
 #define USART_SR_RXNE (1 << 5)
 
 #define USART_CR1_UE  (1 << 13)
+#define USART_CR1_TXEIE (1 << 7)
 #define USART_CR1_RXNEIE  (1 << 5)
 #define USART_CR1_TE  (1 << 3)
 #define USART_CR1_RE  (1 << 2)
-- 
2.9.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]