@@ -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;
@@ -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)
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 <wpaul@windriver.com> Cc: Paolo Bonzini <pbonzini@redhat.com> --- hw/char/stm32f2xx_usart.c | 7 ++++++- include/hw/char/stm32f2xx_usart.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-)