From: Michel Pollet <buserror@gmail.com>
Date: Wed, 14 Sep 2011 08:17:03 +0000 (+0100)
Subject: uart: Do not assume all interupt vectors are available, etc
X-Git-Tag: v1.0a9~4
X-Git-Url: https://git.htl-mechatronik.at/public/?a=commitdiff_plain;h=1cc10d37c5d82e88dfe56adafd6d84924f3465c6;p=sx%2Fsimavr.git

uart: Do not assume all interupt vectors are available, etc

LIN uart doesn't have them (?)

- fixed uart code to only trigger rxt if more pending
  characters are in the input buffer
- fixed uart-echo test code to not get stuck in
  endless loop upon receiving '\r'

Signed-off-by: Markus Lampert  <mlampert@telus.net>
Signed-off-by: Michel Pollet <buserror@gmail.com>
---

diff --git a/simavr/sim/avr_uart.c b/simavr/sim/avr_uart.c
index 9447ce3..5e36863 100644
--- a/simavr/sim/avr_uart.c
+++ b/simavr/sim/avr_uart.c
@@ -106,9 +106,9 @@ static uint8_t avr_uart_read(struct avr_t * avr, avr_io_addr_t addr, void * para
 	// made to trigger potential watchpoints
 	v = avr_core_watch_read(avr, addr);
 
-	// should always trigger that timer
-//	if (!uart_fifo_isempty(&p->input))
-	avr_cycle_timer_register_usec(avr, p->usec_per_byte, avr_uart_rxc_raise, p);
+	// trigger timer if more characters are pending
+	if (!uart_fifo_isempty(&p->input))
+		avr_cycle_timer_register_usec(avr, p->usec_per_byte, avr_uart_rxc_raise, p);
 
 	return v;
 }
@@ -143,7 +143,8 @@ static void avr_uart_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, vo
 	if (addr == p->r_udr) {
 		avr_core_watch_write(avr, addr, v);
 
-		avr_regbit_clear(avr, p->udrc.raised);
+		if ( p->udrc.vector)
+			avr_regbit_clear(avr, p->udrc.raised);
 		avr_cycle_timer_register_usec(avr,
 				p->usec_per_byte, avr_uart_txc_raise, p); // should be uart speed dependent
 
@@ -162,7 +163,7 @@ static void avr_uart_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, vo
 		if (avr_regbit_get(avr, p->txen))
 			avr_raise_irq(p->io.irq + UART_IRQ_OUTPUT, v);
 	}
-	if (addr == p->udrc.enable.reg) {
+	if (p->udrc.vector && addr == p->udrc.enable.reg) {
 		/*
 		 * If enabling the UDRC interrupt, raise it immediately if FIFO is empty
 		 */
@@ -177,7 +178,7 @@ static void avr_uart_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, vo
 				avr_raise_interrupt(avr, &p->udrc);
 		}
 	}
-	if (addr == p->udrc.raised.reg) {
+	if (p->udrc.vector && addr == p->udrc.raised.reg) {
 		// get the bits before the write
 		//uint8_t udre = avr_regbit_get(avr, p->udrc.raised);
 		uint8_t txc = avr_regbit_get(avr, p->txc.raised);
@@ -214,7 +215,8 @@ void avr_uart_reset(struct avr_io_t *io)
 {
 	avr_uart_t * p = (avr_uart_t *)io;
 	avr_t * avr = p->io.avr;
-	avr_regbit_set(avr, p->udrc.raised);
+	if (p->udrc.vector)
+		avr_regbit_set(avr, p->udrc.raised);
 	avr_irq_register_notify(p->io.irq + UART_IRQ_INPUT, avr_uart_irq_input, p);
 	avr_cycle_timer_cancel(avr, avr_uart_rxc_raise, p);
 	avr_cycle_timer_cancel(avr, avr_uart_txc_raise, p);
@@ -279,12 +281,15 @@ void avr_uart_init(avr_t * avr, avr_uart_t * p)
 	p->io.irq[UART_IRQ_OUT_XON].flags |= IRQ_FLAG_FILTERED;
 
 	avr_register_io_write(avr, p->r_udr, avr_uart_write, p);
-	avr_register_io_write(avr, p->udrc.enable.reg, avr_uart_write, p);
 	avr_register_io_read(avr, p->r_udr, avr_uart_read, p);
 	// monitor code that reads the rxc flag, and delay it a bit
 	avr_register_io_read(avr, p->rxc.raised.reg, avr_uart_rxc_read, p);
 
-	avr_register_io_write(avr, p->r_ucsra, avr_uart_write, p);
-	avr_register_io_write(avr, p->r_ubrrl, avr_uart_baud_write, p);
+	if (p->udrc.vector)
+		avr_register_io_write(avr, p->udrc.enable.reg, avr_uart_write, p);
+	if (p->r_ucsra)
+		avr_register_io_write(avr, p->r_ucsra, avr_uart_write, p);
+	if (p->r_ubrrl)
+		avr_register_io_write(avr, p->r_ubrrl, avr_uart_baud_write, p);
 }
 
diff --git a/tests/atmega88_uart_echo.c b/tests/atmega88_uart_echo.c
index 17be737..e65fd56 100644
--- a/tests/atmega88_uart_echo.c
+++ b/tests/atmega88_uart_echo.c
@@ -37,8 +37,10 @@ const struct avr_mmcu_vcd_trace_t _mytrace[]  _MMCU_ = {
 };
 
 static int uart_putchar(char c, FILE *stream) {
-	if (c == '\r')
+#if 0 // don't want character translation for this test
+	if (c == '\n')
 		uart_putchar('\r', stream);
+#endif
 	loop_until_bit_is_set(UCSR0A, UDRE0);
 	UDR0 = c;
 	return 0;