From 1cc10d37c5d82e88dfe56adafd6d84924f3465c6 Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Wed, 14 Sep 2011 09:17:03 +0100 Subject: [PATCH] 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 Signed-off-by: Michel Pollet --- simavr/sim/avr_uart.c | 25 +++++++++++++++---------- tests/atmega88_uart_echo.c | 4 +++- 2 files changed, 18 insertions(+), 11 deletions(-) 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; -- 2.39.5