Commit b77d26e251cf8647a835b193c04b86ca8e4e3aa1
authorhovercraft-github <hovercraft@yandex.ru>
Wed, 15 Feb 2017 09:28:51 +0000 (17:28 +0800)
committerhovercraft-github <hovercraft@yandex.ru>
Wed, 15 Feb 2017 09:28:51 +0000 (17:28 +0800)
Fixes #104, #193 and others.

15 files changed:
simavr/cores/sim_90usb162.c
simavr/cores/sim_mega128.c
simavr/cores/sim_mega1280.c
simavr/cores/sim_mega1281.c
simavr/cores/sim_mega128rfa1.c
simavr/cores/sim_mega128rfr2.c
simavr/cores/sim_mega169.c
simavr/cores/sim_mega2560.c
simavr/cores/sim_megax.h
simavr/cores/sim_megax4.h
simavr/cores/sim_megax8.h
simavr/cores/sim_tiny2313.c
simavr/sim/avr_lin.c
simavr/sim/avr_uart.c
simavr/sim/avr_uart.h

index bfc05d4f4de1ff559faf4e5cd01edd0bd66cbf60..bd3f1363f3fa613b79c65defc59e4c849526842d 100644 (file)
@@ -91,37 +91,8 @@ const struct mcu_t {
        },
        AVR_IOPORT_DECLARE(d, 'D', D),
 
-       .uart1 = {
-               .disabled = AVR_IO_REGBIT(PRR1,PRUSART1),
-               .name = '1',
-               .r_udr = UDR1,
-
-               .txen = AVR_IO_REGBIT(UCSR1B, TXEN1),
-               .rxen = AVR_IO_REGBIT(UCSR1B, RXEN1),
-               .ucsz = AVR_IO_REGBITS(UCSR1C, UCSZ10, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR1B, UCSZ12),         // 1 bits
+       AVR_UARTX_DECLARE(1, PRR1, PRUSART1),
 
-               .r_ucsra = UCSR1A,
-               .r_ucsrb = UCSR1B,
-               .r_ucsrc = UCSR1C,
-               .r_ubrrl = UBRR1L,
-               .r_ubrrh = UBRR1H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, RXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, RXC1),
-                       .vector = USART1_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, TXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, TXC1),
-                       .vector = USART1_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, UDRIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, UDRE1),
-                       .vector = USART1_UDRE_vect,
-               },
-       },
        .timer0 = {
                .name = '0',
                .disabled = AVR_IO_REGBIT(PRR0,PRTIM0),
index 0570c64b68ee92533754c0bff6a03bf4a8871c5e..4236b67288608390ae69136cc908d7153cbe2f6b 100644 (file)
@@ -85,68 +85,10 @@ const struct mcu_t {
        AVR_IOPORT_DECLARE(f, 'F', F),
        AVR_IOPORT_DECLARE(g, 'G', G),
 
-       .uart0 = {
-          // no PRUSART .disabled = AVR_IO_REGBIT(PRR,PRUSART0),
-               .name = '0',
-               .r_udr = UDR0,
-
-               .txen = AVR_IO_REGBIT(UCSR0B, TXEN0),
-               .rxen = AVR_IO_REGBIT(UCSR0B, RXEN0),
-               .ucsz = AVR_IO_REGBITS(UCSR0C, UCSZ00, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR0B, UCSZ02),         // 1 bits
-
-               .r_ucsra = UCSR0A,
-               .r_ucsrb = UCSR0B,
-               .r_ucsrc = UCSR0C,
-               .r_ubrrl = UBRR0L,
-               .r_ubrrh = UBRR0H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, RXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, RXC0),
-                       .vector = USART0_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, TXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, TXC0),
-                       .vector = USART0_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, UDRIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, UDRE0),
-                       .vector = USART0_UDRE_vect,
-               },
-       },
-       .uart1 = {
-          // no PRUSART .disabled = AVR_IO_REGBIT(PRR,PRUSART1),
-               .name = '1',
-               .r_udr = UDR1,
-
-               .txen = AVR_IO_REGBIT(UCSR1B, TXEN1),
-               .rxen = AVR_IO_REGBIT(UCSR1B, RXEN1),
-               .ucsz = AVR_IO_REGBITS(UCSR1C, UCSZ10, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR1B, UCSZ12),         // 1 bits
-
-               .r_ucsra = UCSR1A,
-               .r_ucsrb = UCSR1B,
-               .r_ucsrc = UCSR1C,
-               .r_ubrrl = UBRR1L,
-               .r_ubrrh = UBRR1H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, RXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, RXC1),
-                       .vector = USART1_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, TXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, TXC1),
-                       .vector = USART1_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, UDRIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, UDRE1),
-                       .vector = USART1_UDRE_vect,
-               },
-       },
+       // no PRUSART
+       AVR_UARTX_DECLARE(0, 0, 0),
+       AVR_UARTX_DECLARE(1, 0, 0),
+
        .adc = {
                .r_admux = ADMUX,
                .mux = { AVR_IO_REGBIT(ADMUX, MUX0), AVR_IO_REGBIT(ADMUX, MUX1),
index b3353c5ee8a352b63a12bc9305361565548a9854..84a26a80fb95752484c63a5534e08c7459c2edf1 100644 (file)
@@ -100,132 +100,12 @@ const struct mcu_t {
        AVR_IOPORT_DECLARE(j, 'J', J),
        AVR_IOPORT_DECLARE(k, 'K', K),
        AVR_IOPORT_DECLARE(l, 'L', L),
-       .uart0 = {
-               .disabled = AVR_IO_REGBIT(PRR0,PRUSART0),
-               .name = '0',
-               .r_udr = UDR0,
-
-               .txen = AVR_IO_REGBIT(UCSR0B, TXEN0),
-               .rxen = AVR_IO_REGBIT(UCSR0B, RXEN0),
-               .ucsz = AVR_IO_REGBITS(UCSR0C, UCSZ00, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR0B, UCSZ02),         // 1 bits
-
-               .r_ucsra = UCSR0A,
-               .r_ucsrb = UCSR0B,
-               .r_ucsrc = UCSR0C,
-               .r_ubrrl = UBRR0L,
-               .r_ubrrh = UBRR0H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, RXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, RXC0),
-                       .vector = USART0_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, TXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, TXC0),
-                       .vector = USART0_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, UDRIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, UDRE0),
-                       .vector = USART0_UDRE_vect,
-               },
-       },
-       .uart1 = {
-               .disabled = AVR_IO_REGBIT(PRR1,PRUSART1),
-               .name = '1',
-               .r_udr = UDR1,
-
-               .txen = AVR_IO_REGBIT(UCSR1B, TXEN1),
-               .rxen = AVR_IO_REGBIT(UCSR1B, RXEN1),
-               .ucsz = AVR_IO_REGBITS(UCSR1C, UCSZ10, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR1B, UCSZ12),         // 1 bits
-
-               .r_ucsra = UCSR1A,
-               .r_ucsrb = UCSR1B,
-               .r_ucsrc = UCSR1C,
-               .r_ubrrl = UBRR1L,
-               .r_ubrrh = UBRR1H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, RXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, RXC1),
-                       .vector = USART1_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, TXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, TXC1),
-                       .vector = USART1_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, UDRIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, UDRE1),
-                       .vector = USART1_UDRE_vect,
-               },
-       },
 
-       .uart2 = {
-               .disabled = AVR_IO_REGBIT(PRR1,PRUSART2),
-               .name = '2',
-               .r_udr = UDR2,
-
-               .txen = AVR_IO_REGBIT(UCSR2B, TXEN2),
-               .rxen = AVR_IO_REGBIT(UCSR2B, RXEN2),
-               .ucsz = AVR_IO_REGBITS(UCSR2C, UCSZ20, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR2B, UCSZ22),         // 1 bits
-
-               .r_ucsra = UCSR2A,
-               .r_ucsrb = UCSR2B,
-               .r_ucsrc = UCSR2C,
-               .r_ubrrl = UBRR2L,
-               .r_ubrrh = UBRR2H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR2B, RXCIE2),
-                       .raised = AVR_IO_REGBIT(UCSR2A, RXC2),
-                       .vector = USART2_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR2B, TXCIE2),
-                       .raised = AVR_IO_REGBIT(UCSR2A, TXC2),
-                       .vector = USART2_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR2B, UDRIE2),
-                       .raised = AVR_IO_REGBIT(UCSR2A, UDRE2),
-                       .vector = USART2_UDRE_vect,
-               },
-       },
+       AVR_UARTX_DECLARE(0, PRR0, PRUSART0),
+       AVR_UARTX_DECLARE(1, PRR1, PRUSART1),
+       AVR_UARTX_DECLARE(2, PRR1, PRUSART2),
+       AVR_UARTX_DECLARE(3, PRR1, PRUSART3),
 
-       .uart3 = {
-               .disabled = AVR_IO_REGBIT(PRR1,PRUSART3),
-               .name = '3',
-               .r_udr = UDR3,
-
-               .txen = AVR_IO_REGBIT(UCSR3B, TXEN3),
-               .rxen = AVR_IO_REGBIT(UCSR3B, RXEN3),
-               .ucsz = AVR_IO_REGBITS(UCSR3C, UCSZ30, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR3B, UCSZ32),         // 1 bits
-
-               .r_ucsra = UCSR3A,
-               .r_ucsrb = UCSR3B,
-               .r_ucsrc = UCSR3C,
-               .r_ubrrl = UBRR3L,
-               .r_ubrrh = UBRR3H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR3B, RXCIE3),
-                       .raised = AVR_IO_REGBIT(UCSR3A, RXC3),
-                       .vector = USART3_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR3B, TXCIE3),
-                       .raised = AVR_IO_REGBIT(UCSR3A, TXC3),
-                       .vector = USART3_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR3B, UDRIE3),
-                       .raised = AVR_IO_REGBIT(UCSR3A, UDRE3),
-                       .vector = USART3_UDRE_vect,
-               },
-       },
        .adc = {
                .r_admux = ADMUX,
                .mux = { AVR_IO_REGBIT(ADMUX, MUX0), AVR_IO_REGBIT(ADMUX, MUX1),
index 986e989c700421f632a5b5086bda682bc9a46c77..7c534d1ad0e879dda871ae65bb37b901bcee8125 100644 (file)
@@ -92,68 +92,10 @@ const struct mcu_t {
        AVR_IOPORT_DECLARE(e, 'E', E),
        AVR_IOPORT_DECLARE(f, 'F', F),
        AVR_IOPORT_DECLARE(g, 'G', G),
-       .uart0 = {
-               .disabled = AVR_IO_REGBIT(PRR0,PRUSART0),
-               .name = '0',
-               .r_udr = UDR0,
-
-               .txen = AVR_IO_REGBIT(UCSR0B, TXEN0),
-               .rxen = AVR_IO_REGBIT(UCSR0B, RXEN0),
-               .ucsz = AVR_IO_REGBITS(UCSR0C, UCSZ00, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR0B, UCSZ02),         // 1 bits
-
-               .r_ucsra = UCSR0A,
-               .r_ucsrb = UCSR0B,
-               .r_ucsrc = UCSR0C,
-               .r_ubrrl = UBRR0L,
-               .r_ubrrh = UBRR0H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, RXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, RXC0),
-                       .vector = USART0_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, TXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, TXC0),
-                       .vector = USART0_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, UDRIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, UDRE0),
-                       .vector = USART0_UDRE_vect,
-               },
-       },
-       .uart1 = {
-               .disabled = AVR_IO_REGBIT(PRR1,PRUSART1),
-               .name = '1',
-               .r_udr = UDR1,
-
-               .txen = AVR_IO_REGBIT(UCSR1B, TXEN1),
-               .rxen = AVR_IO_REGBIT(UCSR1B, RXEN1),
-               .ucsz = AVR_IO_REGBITS(UCSR1C, UCSZ10, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR1B, UCSZ12),         // 1 bits
-
-               .r_ucsra = UCSR1A,
-               .r_ucsrb = UCSR1B,
-               .r_ucsrc = UCSR1C,
-               .r_ubrrl = UBRR1L,
-               .r_ubrrh = UBRR1H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, RXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, RXC1),
-                       .vector = USART1_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, TXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, TXC1),
-                       .vector = USART1_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, UDRIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, UDRE1),
-                       .vector = USART1_UDRE_vect,
-               },
-       },
+
+       AVR_UARTX_DECLARE(0, PRR0, PRUSART0),
+       AVR_UARTX_DECLARE(1, PRR1, PRUSART1),
+
        .adc = {
                .r_admux = ADMUX,
                .mux = { AVR_IO_REGBIT(ADMUX, MUX0), AVR_IO_REGBIT(ADMUX, MUX1),
index 8e62fbfac8e281a50b98a2329c12c165532e74f2..6f433eeb95a3ce51a816cc1b4646dc21ca73444d 100644 (file)
@@ -101,68 +101,9 @@ const struct mcu_t {
        AVR_IOPORT_DECLARE(f, 'F', F),
        AVR_IOPORT_DECLARE(g, 'G', G),
 
-       .uart0 = {
-               .disabled = AVR_IO_REGBIT(PRR0,PRUSART0),
-               .name = '0',
-               .r_udr = UDR0,
-
-               .txen = AVR_IO_REGBIT(UCSR0B, TXEN0),
-               .rxen = AVR_IO_REGBIT(UCSR0B, RXEN0),
-               .ucsz = AVR_IO_REGBITS(UCSR0C, UCSZ00, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR0B, UCSZ02),         // 1 bits
-
-               .r_ucsra = UCSR0A,
-               .r_ucsrb = UCSR0B,
-               .r_ucsrc = UCSR0C,
-               .r_ubrrl = UBRR0L,
-               .r_ubrrh = UBRR0H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, RXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, RXC0),
-                       .vector = USART0_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, TXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, TXC0),
-                       .vector = USART0_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, UDRIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, UDRE0),
-                       .vector = USART0_UDRE_vect,
-               },
-       },
-       .uart1 = {
-               .disabled = AVR_IO_REGBIT(PRR1,PRUSART1),
-               .name = '1',
-               .r_udr = UDR1,
-
-               .txen = AVR_IO_REGBIT(UCSR1B, TXEN1),
-               .rxen = AVR_IO_REGBIT(UCSR1B, RXEN1),
-               .ucsz = AVR_IO_REGBITS(UCSR1C, UCSZ10, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR1B, UCSZ12),         // 1 bits
-
-               .r_ucsra = UCSR1A,
-               .r_ucsrb = UCSR1B,
-               .r_ucsrc = UCSR1C,
-               .r_ubrrl = UBRR1L,
-               .r_ubrrh = UBRR1H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, RXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, RXC1),
-                       .vector = USART1_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, TXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, TXC1),
-                       .vector = USART1_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, UDRIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, UDRE1),
-                       .vector = USART1_UDRE_vect,
-               },
-       },
+       AVR_UARTX_DECLARE(0, PRR0, PRUSART0),
+       AVR_UARTX_DECLARE(1, PRR1, PRUSART1),
+
        .adc = {
                .r_admux = ADMUX,
                .mux = { AVR_IO_REGBIT(ADMUX, MUX0), AVR_IO_REGBIT(ADMUX, MUX1),
index 62271df5abf2a95ad673665511dfe82ba0ed7ba5..c69907d78816d41da129a4b8223239db3c71fc75 100644 (file)
@@ -127,68 +127,9 @@ const struct mcu_t {
        AVR_IOPORT_DECLARE(f, 'F', F),
        AVR_IOPORT_DECLARE(g, 'G', G),
 
-       .uart0 = {
-               .disabled = AVR_IO_REGBIT(PRR0,PRUSART0),
-               .name = '0',
-               .r_udr = UDR0,
-
-               .txen = AVR_IO_REGBIT(UCSR0B, TXEN0),
-               .rxen = AVR_IO_REGBIT(UCSR0B, RXEN0),
-               .ucsz = AVR_IO_REGBITS(UCSR0C, UCSZ00, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR0B, UCSZ02),         // 1 bits
-
-               .r_ucsra = UCSR0A,
-               .r_ucsrb = UCSR0B,
-               .r_ucsrc = UCSR0C,
-               .r_ubrrl = UBRR0L,
-               .r_ubrrh = UBRR0H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, RXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, RXC0),
-                       .vector = USART0_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, TXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, TXC0),
-                       .vector = USART0_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, UDRIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, UDRE0),
-                       .vector = USART0_UDRE_vect,
-               },
-       },
-       .uart1 = {
-               .disabled = AVR_IO_REGBIT(PRR1,PRUSART1),
-               .name = '1',
-               .r_udr = UDR1,
-
-               .txen = AVR_IO_REGBIT(UCSR1B, TXEN1),
-               .rxen = AVR_IO_REGBIT(UCSR1B, RXEN1),
-               .ucsz = AVR_IO_REGBITS(UCSR1C, UCSZ10, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR1B, UCSZ12),         // 1 bits
-
-               .r_ucsra = UCSR1A,
-               .r_ucsrb = UCSR1B,
-               .r_ucsrc = UCSR1C,
-               .r_ubrrl = UBRR1L,
-               .r_ubrrh = UBRR1H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, RXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, RXC1),
-                       .vector = USART1_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, TXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, TXC1),
-                       .vector = USART1_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, UDRIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, UDRE1),
-                       .vector = USART1_UDRE_vect,
-               },
-       },
+       AVR_UARTX_DECLARE(0, PRR0, PRUSART0),
+       AVR_UARTX_DECLARE(1, PRR1, PRUSART1),
+
        .adc = {
                .r_admux = ADMUX,
                .mux = { AVR_IO_REGBIT(ADMUX, MUX0), AVR_IO_REGBIT(ADMUX, MUX1),
index 4af93a6a3b65041d2c569698f305309216a25558..c72e96ea2a751bf88c2c68b0b811347836430975 100644 (file)
@@ -77,36 +77,8 @@ const struct mcu_t {
        AVR_IOPORT_DECLARE(f, 'F', F),
        AVR_IOPORT_DECLARE(g, 'G', G),
 
-       .uart0 = {
-               .name = '0',
-               .r_udr = UDR0,
-
-               .txen = AVR_IO_REGBIT(UCSR0B, TXEN0),
-               .rxen = AVR_IO_REGBIT(UCSR0B, RXEN0),
-               .ucsz = AVR_IO_REGBITS(UCSR0C, UCSZ00, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR0B, UCSZ02),         // 1 bits
-
-               .r_ucsra = UCSR0A,
-               .r_ucsrb = UCSR0B,
-               .r_ucsrc = UCSR0C,
-               .r_ubrrl = UBRR0L,
-               .r_ubrrh = UBRR0H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, RXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, RXC0),
-                       .vector = USART0_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, TXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, TXC0),
-                       .vector = USART0_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, UDRIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, UDRE0),
-                       .vector = USART0_UDRE_vect,
-               },
-       },
+       AVR_UARTX_DECLARE(0, PRR, PRUSART0),
+
        .adc = {
                .r_admux = ADMUX,
                .mux = { AVR_IO_REGBIT(ADMUX, MUX0), AVR_IO_REGBIT(ADMUX, MUX1),
index c1383a2385aeb49161cc81df2fc1df89f84bdf8c..8e09e71323979200917ffe1e5b9806582aa0536d 100644 (file)
@@ -102,132 +102,12 @@ const struct mcu_t {
        AVR_IOPORT_DECLARE(j, 'J', J),
        AVR_IOPORT_DECLARE(k, 'K', K),
        AVR_IOPORT_DECLARE(l, 'L', L),
-       .uart0 = {
-               .disabled = AVR_IO_REGBIT(PRR0,PRUSART0),
-               .name = '0',
-               .r_udr = UDR0,
-
-               .txen = AVR_IO_REGBIT(UCSR0B, TXEN0),
-               .rxen = AVR_IO_REGBIT(UCSR0B, RXEN0),
-               .ucsz = AVR_IO_REGBITS(UCSR0C, UCSZ00, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR0B, UCSZ02),         // 1 bits
-
-               .r_ucsra = UCSR0A,
-               .r_ucsrb = UCSR0B,
-               .r_ucsrc = UCSR0C,
-               .r_ubrrl = UBRR0L,
-               .r_ubrrh = UBRR0H,
-               .rxc = {
-                        .enable = AVR_IO_REGBIT(UCSR0B, RXCIE0),
-                        .raised = AVR_IO_REGBIT(UCSR0A, RXC0),
-                        .vector = USART0_RX_vect,
-               },
-               .txc = {
-                        .enable = AVR_IO_REGBIT(UCSR0B, TXCIE0),
-                        .raised = AVR_IO_REGBIT(UCSR0A, TXC0),
-                        .vector = USART0_TX_vect,
-               },
-               .udrc = {
-                        .enable = AVR_IO_REGBIT(UCSR0B, UDRIE0),
-                        .raised = AVR_IO_REGBIT(UCSR0A, UDRE0),
-                        .vector = USART0_UDRE_vect,
-               },
-       },
-       .uart1 = {
-               .disabled = AVR_IO_REGBIT(PRR1,PRUSART1),
-               .name = '1',
-               .r_udr = UDR1,
-
-               .txen = AVR_IO_REGBIT(UCSR1B, TXEN1),
-               .rxen = AVR_IO_REGBIT(UCSR1B, RXEN1),
-               .ucsz = AVR_IO_REGBITS(UCSR1C, UCSZ10, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR1B, UCSZ12),         // 1 bits
-
-               .r_ucsra = UCSR1A,
-               .r_ucsrb = UCSR1B,
-               .r_ucsrc = UCSR1C,
-               .r_ubrrl = UBRR1L,
-               .r_ubrrh = UBRR1H,
-               .rxc = {
-                        .enable = AVR_IO_REGBIT(UCSR1B, RXCIE1),
-                        .raised = AVR_IO_REGBIT(UCSR1A, RXC1),
-                        .vector = USART1_RX_vect,
-               },
-               .txc = {
-                        .enable = AVR_IO_REGBIT(UCSR1B, TXCIE1),
-                        .raised = AVR_IO_REGBIT(UCSR1A, TXC1),
-                        .vector = USART1_TX_vect,
-               },
-               .udrc = {
-                        .enable = AVR_IO_REGBIT(UCSR1B, UDRIE1),
-                        .raised = AVR_IO_REGBIT(UCSR1A, UDRE1),
-                        .vector = USART1_UDRE_vect,
-               },
-       },
 
-       .uart2 = {
-               .disabled = AVR_IO_REGBIT(PRR1,PRUSART2),
-               .name = '2',
-               .r_udr = UDR2,
-
-               .txen = AVR_IO_REGBIT(UCSR2B, TXEN2),
-               .rxen = AVR_IO_REGBIT(UCSR2B, RXEN2),
-               .ucsz = AVR_IO_REGBITS(UCSR2C, UCSZ20, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR2B, UCSZ22),         // 1 bits
-
-               .r_ucsra = UCSR2A,
-               .r_ucsrb = UCSR2B,
-               .r_ucsrc = UCSR2C,
-               .r_ubrrl = UBRR2L,
-               .r_ubrrh = UBRR2H,
-               .rxc = {
-                        .enable = AVR_IO_REGBIT(UCSR2B, RXCIE2),
-                        .raised = AVR_IO_REGBIT(UCSR2A, RXC2),
-                        .vector = USART2_RX_vect,
-               },
-               .txc = {
-                        .enable = AVR_IO_REGBIT(UCSR2B, TXCIE2),
-                        .raised = AVR_IO_REGBIT(UCSR2A, TXC2),
-                        .vector = USART2_TX_vect,
-               },
-               .udrc = {
-                        .enable = AVR_IO_REGBIT(UCSR2B, UDRIE2),
-                        .raised = AVR_IO_REGBIT(UCSR2A, UDRE2),
-                        .vector = USART2_UDRE_vect,
-               },
-       },
+       AVR_UARTX_DECLARE(0, PRR0, PRUSART0),
+       AVR_UARTX_DECLARE(1, PRR1, PRUSART1),
+       AVR_UARTX_DECLARE(2, PRR1, PRUSART2),
+       AVR_UARTX_DECLARE(3, PRR1, PRUSART3),
 
-       .uart3 = {
-               .disabled = AVR_IO_REGBIT(PRR1,PRUSART3),
-               .name = '3',
-               .r_udr = UDR3,
-
-               .txen = AVR_IO_REGBIT(UCSR3B, TXEN3),
-               .rxen = AVR_IO_REGBIT(UCSR3B, RXEN3),
-               .ucsz = AVR_IO_REGBITS(UCSR3C, UCSZ30, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR3B, UCSZ32),         // 1 bits
-
-               .r_ucsra = UCSR3A,
-               .r_ucsrb = UCSR3B,
-               .r_ucsrc = UCSR3C,
-               .r_ubrrl = UBRR3L,
-               .r_ubrrh = UBRR3H,
-               .rxc = {
-                        .enable = AVR_IO_REGBIT(UCSR3B, RXCIE3),
-                        .raised = AVR_IO_REGBIT(UCSR3A, RXC3),
-                        .vector = USART3_RX_vect,
-               },
-               .txc = {
-                        .enable = AVR_IO_REGBIT(UCSR3B, TXCIE3),
-                        .raised = AVR_IO_REGBIT(UCSR3A, TXC3),
-                        .vector = USART3_TX_vect,
-               },
-               .udrc = {
-                        .enable = AVR_IO_REGBIT(UCSR3B, UDRIE3),
-                        .raised = AVR_IO_REGBIT(UCSR3A, UDRE3),
-                        .vector = USART3_UDRE_vect,
-               },
-       },
        .adc = {
                .r_admux = ADMUX,
                .mux = { AVR_IO_REGBIT(ADMUX, MUX0), AVR_IO_REGBIT(ADMUX, MUX1),
index a6c14f8a20475fa562ad3735aab99a918693e65b..81c26f5bc31d87b77aa4bef4a768e8bf98888b0f 100644 (file)
@@ -98,37 +98,10 @@ const struct mcu_t SIM_CORENAME = {
        AVR_IOPORT_DECLARE(b, 'B', B),
        AVR_IOPORT_DECLARE(c, 'C', C),
        AVR_IOPORT_DECLARE(d, 'D', D),
-       .uart = {
-          // no PRUSART .disabled = AVR_IO_REGBIT(PRR,PRUSART0),
-               .name = '0',
-               .r_udr = UDR,
-
-               .txen = AVR_IO_REGBIT(UCSRB, TXEN),
-               .rxen = AVR_IO_REGBIT(UCSRB, RXEN),
-               .ucsz = AVR_IO_REGBITS(UCSRC, UCSZ0, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSRB, UCSZ2),   // 1 bits
-
-               .r_ucsra = UCSRA,
-               .r_ucsrb = UCSRB,
-               .r_ucsrc = UCSRC,
-               .r_ubrrl = UBRRL,
-               .r_ubrrh = UBRRH,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSRB, RXCIE),
-                       .raised = AVR_IO_REGBIT(UCSRA, RXC),
-                       .vector = USART_RXC_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSRB, TXCIE),
-                       .raised = AVR_IO_REGBIT(UCSRA, TXC),
-                       .vector = USART_TXC_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSRB, UDRIE),
-                       .raised = AVR_IO_REGBIT(UCSRA, UDRE),
-                       .vector = USART_UDRE_vect,
-               },
-       },
+
+       //no PRUSART, upe=PE, no reg/bit name index, 'C' in RX/TX vector names
+       AVR_UART_DECLARE(0, 0, PE, , C),
+
        .adc = {
                .r_admux = ADMUX,
                .mux = { AVR_IO_REGBIT(ADMUX, MUX0), AVR_IO_REGBIT(ADMUX, MUX1),
index 9a22b8531e0b13f82ecf8b0c38a0aad168072aa3..26886927da114d479ddb557a340d7281fb7d2207 100644 (file)
@@ -128,70 +128,9 @@ const struct mcu_t SIM_CORENAME = {
                .r_pcint = PCMSK3,
        },
 
-       .uart0 = {
-               .disabled = AVR_IO_REGBIT(PRR0,PRUSART0),
-               .name = '0',
-               .r_udr = UDR0,
-
-               .u2x = AVR_IO_REGBIT(UCSR0A, U2X0),
-               .txen = AVR_IO_REGBIT(UCSR0B, TXEN0),
-               .rxen = AVR_IO_REGBIT(UCSR0B, RXEN0),
-               .ucsz = AVR_IO_REGBITS(UCSR0C, UCSZ00, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR0B, UCSZ02),         // 1 bits
-
-               .r_ucsra = UCSR0A,
-               .r_ucsrb = UCSR0B,
-               .r_ucsrc = UCSR0C,
-               .r_ubrrl = UBRR0L,
-               .r_ubrrh = UBRR0H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, RXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, RXC0),
-                       .vector = USART0_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, TXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, TXC0),
-                       .vector = USART0_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, UDRIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, UDRE0),
-                       .vector = USART0_UDRE_vect,
-               },
-       },
-       .uart1 = {
-               .disabled = AVR_IO_REGBIT(PRR0,PRUSART1),
-               .name = '1',
-               .r_udr = UDR1,
-
-               .u2x = AVR_IO_REGBIT(UCSR1A, U2X1),
-               .txen = AVR_IO_REGBIT(UCSR1B, TXEN1),
-               .rxen = AVR_IO_REGBIT(UCSR1B, RXEN1),
-               .ucsz = AVR_IO_REGBITS(UCSR1C, UCSZ10, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR1B, UCSZ12),         // 1 bits
-
-               .r_ucsra = UCSR1A,
-               .r_ucsrb = UCSR1B,
-               .r_ucsrc = UCSR1C,
-               .r_ubrrl = UBRR1L,
-               .r_ubrrh = UBRR1H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, RXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, RXC1),
-                       .vector = USART1_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, TXCIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, TXC1),
-                       .vector = USART1_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR1B, UDRIE1),
-                       .raised = AVR_IO_REGBIT(UCSR1A, UDRE1),
-                       .vector = USART1_UDRE_vect,
-               },
-       },
+       AVR_UARTX_DECLARE(0, PRR0, PRUSART0),
+       AVR_UARTX_DECLARE(1, PRR0, PRUSART1),
+
        .adc = {
        //      .disabled = AVR_IO_REGBIT(PRR0,PRADC),
                .r_admux = ADMUX,
index 06723ea8abbda52fc06283640fa33d71400bbb4d..f9661ab15ed44e1877939f9d0207e10c6c7ce7d3 100644 (file)
@@ -117,38 +117,9 @@ const struct mcu_t SIM_CORENAME = {
                .r_pcint = PCMSK2,
        },
 
-       .uart = {
-               .disabled = AVR_IO_REGBIT(PRR,PRUSART0),
-               .name = '0',
-               .r_udr = UDR0,
-
-               .txen = AVR_IO_REGBIT(UCSR0B, TXEN0),
-               .rxen = AVR_IO_REGBIT(UCSR0B, RXEN0),
-               .usbs = AVR_IO_REGBIT(UCSR0C, USBS0),
-               .ucsz = AVR_IO_REGBITS(UCSR0C, UCSZ00, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSR0B, UCSZ02),         // 1 bits
-
-               .r_ucsra = UCSR0A,
-               .r_ucsrb = UCSR0B,
-               .r_ucsrc = UCSR0C,
-               .r_ubrrl = UBRR0L,
-               .r_ubrrh = UBRR0H,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, RXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, RXC0),
-                       .vector = USART_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, TXCIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, TXC0),
-                       .vector = USART_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSR0B, UDRIE0),
-                       .raised = AVR_IO_REGBIT(UCSR0A, UDRE0),
-                       .vector = USART_UDRE_vect,
-               },
-       },
+       //PRR/PRUSART0, upe=UPE, reg/bit name index=0, no 'C' in RX/TX vector names
+       AVR_UART_DECLARE(PRR, PRUSART0, UPE, 0, ),
+
        .adc = {
                .r_admux = ADMUX,
                .mux = { AVR_IO_REGBIT(ADMUX, MUX0), AVR_IO_REGBIT(ADMUX, MUX1),
index 43d254375bab033399a054d9635b02ed87d718a5..6cb836609c374022fe165d6d43eb774d488bd4b3 100644 (file)
@@ -70,38 +70,10 @@ static const struct mcu_t {
                .r_pcint = PCMSK,
        },
        AVR_IOPORT_DECLARE(d, 'D', D), // port D has no PCInts..
-       .uart = {
-               // no PRR register on the 2313
-               //.disabled = AVR_IO_REGBIT(PRR,PRUSART0),
-               .name = '0',
-               .r_udr = UDR,
-
-               .txen = AVR_IO_REGBIT(UCSRB, TXEN),
-               .rxen = AVR_IO_REGBIT(UCSRB, RXEN),
-               .ucsz = AVR_IO_REGBITS(UCSRC, UCSZ0, 0x3), // 2 bits
-               .ucsz2 = AVR_IO_REGBIT(UCSRB, UCSZ2),   // 1 bits
-
-               .r_ucsra = UCSRA,
-               .r_ucsrb = UCSRB,
-               .r_ucsrc = UCSRC,
-               .r_ubrrl = UBRRL,
-               .r_ubrrh = UBRRH,
-               .rxc = {
-                       .enable = AVR_IO_REGBIT(UCSRB, RXCIE),
-                       .raised = AVR_IO_REGBIT(UCSRA, RXC),
-                       .vector = USART_RX_vect,
-               },
-               .txc = {
-                       .enable = AVR_IO_REGBIT(UCSRB, TXCIE),
-                       .raised = AVR_IO_REGBIT(UCSRA, TXC),
-                       .vector = USART_TX_vect,
-               },
-               .udrc = {
-                       .enable = AVR_IO_REGBIT(UCSRB, UDRIE),
-                       .raised = AVR_IO_REGBIT(UCSRA, UDRE),
-                       .vector = USART_UDRE_vect,
-               },
-       },
+
+       //no PRUSART, upe=UPE, no reg/bit name index, no 'C' in RX/TX vector names
+       AVR_UART_DECLARE(0, 0, UPE, , ),
+
        .timer0 = {
                .name = '0',
                .wgm = { AVR_IO_REGBIT(TCCR0A, WGM00), AVR_IO_REGBIT(TCCR0A, WGM01), AVR_IO_REGBIT(TCCR0B, WGM02) },
index 1d397d5a0025bcfef844598988289a0173caf87c..001b34cbb9ea24c0490f3c4f4529125757e8cb9c 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <stdio.h>
 #include "avr_lin.h"
+#include "sim_time.h"
 
 
 static void
@@ -59,14 +60,18 @@ avr_lin_baud_write(
        uint32_t lbrr = (avr->data[p->r_linbrrh] << 8) | avr->data[p->r_linbrrl];
        AVR_LOG(avr, LOG_TRACE, "LIN: UART LBT/LBRR to %04x/%04x\n", lbt, lbrr);
        // there is no division by zero case here, lbt is >= 8
-       uint32_t baud = avr->frequency / (lbt * (lbrr + 1));
+       //uint32_t baud = avr->frequency / (lbt * (lbrr + 1));
        uint32_t word_size = 1 /*start*/+ 8 /*data bits*/+ 1 /*parity*/+ 1 /*stop*/;
+       int cycles_per_bit = lbt * (lbrr + 1);
+       double baud = ((double)avr->frequency) / cycles_per_bit; // can be less than 1
+       p->uart.cycles_per_byte = cycles_per_bit * word_size;
 
-       AVR_LOG(avr, LOG_TRACE, "LIN: UART configured to %04x/%04x = %d bps, 8 data 1 stop\n", lbt,
+       AVR_LOG(avr, LOG_TRACE, "LIN: UART configured to %04x/%04x = %.4f bps, 8 data 1 stop\n", lbt,
                lbrr, baud);
 
-       p->uart.usec_per_byte = 1000000 / (baud / word_size);
-       AVR_LOG(avr, LOG_TRACE, "LIN: Roughly %d usec per bytes\n", (int) p->uart.usec_per_byte);
+       //p->uart.cycles_per_byte = 1000000 / (baud / word_size);
+       AVR_LOG(avr, LOG_TRACE, "LIN: Roughly %d usec per byte\n",
+                       avr_cycles_to_usec(avr, p->uart.cycles_per_byte));
 }
 
 static void
index 2a69c16e2a3b0bcdb9a89dea7b424f4ec85f35f3..bb4bc1556605cfa6ba9f563ef88efd7a451ce8c2 100644 (file)
@@ -37,6 +37,8 @@
 #include <stdlib.h>
 #include "avr_uart.h"
 #include "sim_hex.h"
+#include "sim_time.h"
+#include "sim_gdb.h"
 
 //#define TRACE(_w) _w
 #ifndef TRACE
 
 DEFINE_FIFO(uint8_t, uart_fifo);
 
+static inline void avr_uart_clear_interrupt(
+               avr_t * avr,
+               avr_int_vector_t * vector)
+{
+       if (!vector->vector)
+               return;
+       // clear the interrupt flag even it's 'sticky'
+       if (avr_regbit_get(avr, vector->raised))
+               avr_clear_interrupt_if(avr, vector, 0);
+       if (avr_regbit_get(avr, vector->raised))
+               avr_regbit_clear(avr, vector->raised);
+}
+
+static inline void avr_uart_regbit_clear(avr_t * avr, avr_regbit_t rb)
+{
+       uint16_t a = rb.reg;
+       if (!a)
+               return;
+       avr_regbit_clear(avr, rb);
+}
+
 static avr_cycle_count_t avr_uart_txc_raise(struct avr_t * avr, avr_cycle_count_t when, void * param)
 {
        avr_uart_t * p = (avr_uart_t *)param;
-       if (avr_regbit_get(avr, p->txen)) {
-               // if the interrupts are not used, still raise the UDRE and TXC flag
-               avr_raise_interrupt(avr, &p->udrc);
-               avr_raise_interrupt(avr, &p->txc);
+       if (p->tx_cnt) {
+               // Even if the interrupt is disabled, still raise the TXC flag
+               if (p->tx_cnt == 1)
+                       avr_raise_interrupt(avr, &p->txc);
+               p->tx_cnt--;
        }
-       return 0;
+       if (p->udrc.vector) {// UDRE is disabled in the LIN mode
+               if (p->tx_cnt) {
+                       if (avr_regbit_get(avr, p->udrc.raised)) {
+                               avr_uart_clear_interrupt(avr, &p->udrc);
+                       }
+               } else {
+                       if (avr_regbit_get(avr, p->txen)) {
+                               // Even if the interrupt is disabled, still raise the UDRE flag
+                               avr_raise_interrupt(avr, &p->udrc);
+                               if (!avr_regbit_get(avr, p->udrc.enable)) {
+                                       return 0; //polling mode: stop TX pump
+                               } else // udrc (alias udre) should be rased repeatedly while output buffer is empty
+                                       return when + p->cycles_per_byte;
+                       } else
+                               return 0; // transfer disabled: stop TX pump
+               }
+       }
+       if (p->tx_cnt)
+               return when + p->cycles_per_byte;
+       return 0; // stop TX pump
 }
 
 static avr_cycle_count_t avr_uart_rxc_raise(struct avr_t * avr, avr_cycle_count_t when, void * param)
 {
        avr_uart_t * p = (avr_uart_t *)param;
-       if (avr_regbit_get(avr, p->rxen))
-               avr_raise_interrupt(avr, &p->rxc);
+       if (avr_regbit_get(avr, p->rxen)) {
+               // rxc should be rased continiosly untill input buffer is empty
+               if (!uart_fifo_isempty(&p->input)) {
+                       if (!avr_regbit_get(avr, p->rxc.raised)) {
+                               p->rxc_raise_time = when;
+                               p->rx_cnt = 0;
+                       }
+                       avr_raise_interrupt(avr, &p->rxc);
+                       return when + p->cycles_per_byte;
+               }
+       }
        return 0;
 }
 
@@ -80,7 +132,7 @@ static uint8_t avr_uart_rxc_read(struct avr_t * avr, avr_io_addr_t addr, void *
        uint8_t ri = !avr_regbit_get(avr, p->rxen) || !avr_regbit_get(avr, p->rxc.raised);
        uint8_t ti = !avr_regbit_get(avr, p->txen) || !avr_regbit_get(avr, p->txc.raised);
 
-       if (p->flags & AVR_UART_FLAG_POOL_SLEEP) {
+       if (p->flags & AVR_UART_FLAG_POLL_SLEEP) {
 
                if (ri && ti)
                        usleep(1);
@@ -97,27 +149,46 @@ static uint8_t avr_uart_rxc_read(struct avr_t * avr, avr_io_addr_t addr, void *
 static uint8_t avr_uart_read(struct avr_t * avr, avr_io_addr_t addr, void * param)
 {
        avr_uart_t * p = (avr_uart_t *)param;
+       uint8_t v = 0;
 
-       // clear the rxc interrupt in case the code is using polling
-       uint8_t rxc = avr_regbit_get(avr, p->rxc.raised);
-       avr_clear_interrupt_if(avr, &p->rxc, rxc);
-
-       if (!avr_regbit_get(avr, p->rxen)) {
+       if (!avr_regbit_get(avr, p->rxen) ||
+                       !avr_regbit_get(avr, p->rxc.raised) // rxc flag not raised - nothing to read!
+                       ) {
+               AVR_LOG(avr, LOG_TRACE, "UART%c: attempt to read empty rx buffer\n", p->name);
                avr->data[addr] = 0;
                // made to trigger potential watchpoints
                avr_core_watch_read(avr, addr);
-               return 0;
+               //return 0;
+               goto avr_uart_read_check;
+       }
+       if (!uart_fifo_isempty(&p->input)) { // probably redundant check
+               v = uart_fifo_read(&p->input);
+               p->rx_cnt++;
+               if ((p->rx_cnt > 1) && // UART actually has 2-character rx buffer
+                               ((avr->cycle-p->rxc_raise_time)/p->rx_cnt < p->cycles_per_byte)) {
+                       // prevent the firmware from reading input characters with non-realistic high speed
+                       avr_uart_clear_interrupt(avr, &p->rxc);
+                       p->rx_cnt = 0;
+               }
+       } else {
+               AVR_LOG(avr, LOG_TRACE, "UART%c: BUG: rxc raised with empty rx buffer\n", p->name);
        }
-       uint8_t v = uart_fifo_read(&p->input);
 
 //     TRACE(printf("UART read %02x %s\n", v, uart_fifo_isempty(&p->input) ? "EMPTY!" : "");)
        avr->data[addr] = v;
        // made to trigger potential watchpoints
        v = avr_core_watch_read(avr, addr);
 
-       // 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);
+avr_uart_read_check:
+       if (uart_fifo_isempty(&p->input)) {
+               avr_cycle_timer_cancel(avr, avr_uart_rxc_raise, p);
+               avr_uart_clear_interrupt(avr, &p->rxc);
+               avr_raise_irq(p->io.irq + UART_IRQ_OUT_XOFF, 0);
+               avr_raise_irq(p->io.irq + UART_IRQ_OUT_XON, 1);
+       }
+       if (!uart_fifo_isfull(&p->input)) {
+               avr_uart_regbit_clear(avr, p->dor);
+       }
 
        return v;
 }
@@ -127,34 +198,38 @@ static void avr_uart_baud_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t
        avr_uart_t * p = (avr_uart_t *)param;
        avr_core_watch_write(avr, addr, v);
        uint32_t val = avr->data[p->r_ubrrl] | (avr->data[p->r_ubrrh] << 8);
-       uint32_t baud = avr->frequency / (val+1);
-       if (avr_regbit_get(avr, p->u2x))
-               baud /= 8;
-       else
-               baud /= 16;
 
        const int databits[] = { 5,6,7,8,  /* 'reserved', assume 8 */8,8,8, 9 };
        int db = databits[avr_regbit_get(avr, p->ucsz) | (avr_regbit_get(avr, p->ucsz2) << 2)];
        int sb = 1 + avr_regbit_get(avr, p->usbs);
        int word_size = 1 /* start */ + db /* data bits */ + 1 /* parity */ + sb /* stops */;
+       int cycles_per_bit = (val+1)*8;
+       if (!avr_regbit_get(avr, p->u2x))
+               cycles_per_bit *= 2;
+       double baud = ((double)avr->frequency) / cycles_per_bit; // can be less than 1
+       p->cycles_per_byte = cycles_per_bit * word_size;
 
-       AVR_LOG(avr, LOG_TRACE, "UART: %c configured to %04x = %d bps (x%d), %d data %d stop\n",
+       AVR_LOG(avr, LOG_TRACE, "UART: %c configured to %04x = %.4f bps (x%d), %d data %d stop\n",
                        p->name, val, baud, avr_regbit_get(avr, p->u2x)?2:1, db, sb);
-       // TODO: Use the divider value and calculate the straight number of cycles
-       p->usec_per_byte = 1000000 / (baud / word_size);
-       AVR_LOG(avr, LOG_TRACE, "UART: Roughly %d usec per bytes\n", (int)p->usec_per_byte);
+       AVR_LOG(avr, LOG_TRACE, "UART: Roughly %d usec per byte\n",
+                       avr_cycles_to_usec(avr, p->cycles_per_byte));
 }
 
 static void avr_uart_udr_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
 {
        avr_uart_t * p = (avr_uart_t *)param;
 
-       avr_core_watch_write(avr, addr, v);
+       // The byte to be sent should NOT be writen there,
+       // the value writen could never be read back.
+       //avr_core_watch_write(avr, addr, v);
+       if (avr->gdb) {
+               avr_gdb_handle_watchpoints(avr, addr, AVR_GDB_WATCH_WRITE);
+       }
 
-       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
+       //avr_cycle_timer_cancel(avr, avr_uart_txc_raise, p); // synchronize tx pump
+       if (p->udrc.vector && avr_regbit_get(avr, p->udrc.raised)) {
+               avr_uart_clear_interrupt(avr, &p->udrc);
+       }
 
        if (p->flags & AVR_UART_FLAG_STDIO) {
                const int maxsize = 256;
@@ -169,8 +244,14 @@ static void avr_uart_udr_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v
        }
        TRACE(printf("UDR%c(%02x) = %02x\n", p->name, addr, v);)
        // tell other modules we are "outputting" a byte
-       if (avr_regbit_get(avr, p->txen))
+       if (avr_regbit_get(avr, p->txen)) {
                avr_raise_irq(p->io.irq + UART_IRQ_OUTPUT, v);
+               p->tx_cnt++;
+               if (p->tx_cnt > 2) // AVR actually has 1-character UART tx buffer, plus shift register
+                       AVR_LOG(avr, LOG_TRACE, "UART%c: tx buffer overflow %d\n", p->name, (int)p->tx_cnt);
+               if (avr_cycle_timer_status(avr, avr_uart_txc_raise, p) == 0)
+                       avr_cycle_timer_register(avr, p->cycles_per_byte, avr_uart_txc_raise, p); // start the tx pump
+       }
 }
 
 
@@ -178,34 +259,96 @@ static void avr_uart_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, vo
 {
        avr_uart_t * p = (avr_uart_t *)param;
 
-       if (p->udrc.vector && addr == p->udrc.enable.reg) {
-               /*
-                * If enabling the UDRC interrupt, raise it immediately if FIFO is empty
-                */
-               uint8_t udrce = avr_regbit_get(avr, p->udrc.enable);
-               avr_core_watch_write(avr, addr, v);
-               uint8_t nudrce = avr_regbit_get(avr, p->udrc.enable);
-               if (!udrce && nudrce) {
-                       // if the FIDO is not empty (clear timer is flying) we don't
-                       // need to raise the interrupt, it will happen when the timer
-                       // is fired.
-                       if (avr_cycle_timer_status(avr, avr_uart_txc_raise, p) == 0)
-                               avr_raise_interrupt(avr, &p->udrc);
+       uint8_t masked_v = v;
+       uint8_t clear_txc = 0;
+       uint8_t clear_rxc = 0;
+
+       // exclude these locations from direct write:
+       if (p->udrc.raised.reg == addr) {
+               masked_v &= ~(p->udrc.raised.mask << p->udrc.raised.bit);
+               masked_v |= avr_regbit_get_raw(avr, p->udrc.raised);
+       }
+       if (p->txc.raised.reg == addr) {
+               uint8_t mask = p->txc.raised.mask << p->txc.raised.bit;
+               masked_v &= ~(mask);
+               masked_v |= avr_regbit_get_raw(avr, p->txc.raised);
+               // it can be cleared by writing a one to its bit location
+               if (v & mask)
+                       clear_txc = 1;
+       }
+       if (p->rxc.raised.reg == addr) {
+               uint8_t mask = p->rxc.raised.mask << p->rxc.raised.bit;
+               masked_v &= ~(mask);
+               masked_v |= avr_regbit_get_raw(avr, p->rxc.raised);
+               if (!p->udrc.vector) {
+                       // In the LIN mode it can be cleared by writing a one to its bit location
+                       if (v & mask)
+                               clear_rxc = 1;
+               }
+       }
+       // mainly to prevent application to confuse itself
+       // by writing something there and reading it back:
+       if (p->fe.reg == addr) {
+               masked_v &= ~(p->fe.mask << p->fe.bit);
+               masked_v |= avr_regbit_get_raw(avr, p->fe);
+       }
+       if (p->dor.reg == addr) {
+               masked_v &= ~(p->dor.mask << p->dor.bit);
+               //masked_v |= avr_regbit_get_raw(avr, p->dor);
+       }
+       if (p->upe.reg == addr) {
+               masked_v &= ~(p->upe.mask << p->upe.bit);
+               masked_v |= avr_regbit_get_raw(avr, p->upe);
+       }
+       if (p->rxb8.reg == addr) {
+               masked_v &= ~(p->rxb8.mask << p->rxb8.bit);
+               masked_v |= avr_regbit_get_raw(avr, p->rxb8);
+       }
+
+       uint8_t txen = avr_regbit_get(avr, p->txen);
+       uint8_t rxen = avr_regbit_get(avr, p->rxen);
+       uint8_t udrce = avr_regbit_get(avr, p->udrc.enable);
+       // Now write whatever bits could be writen directly.
+       // It is necessary anyway, to trigger potential watchpoints.
+       avr_core_watch_write(avr, addr, masked_v);
+       uint8_t new_txen = avr_regbit_get(avr, p->txen);
+       uint8_t new_rxen = avr_regbit_get(avr, p->rxen);
+       uint8_t new_udrce = avr_regbit_get(avr, p->udrc.enable);
+       if (p->udrc.vector && (!udrce && new_udrce) && new_txen) {
+               // If enabling the UDRC (alias is UDRE) interrupt, raise it immediately if FIFO is empty.
+               // If the FIFO is not empty (clear timer is flying) we don't
+               // need to raise the interrupt, it will happen when the timer
+               // is fired.
+               if (avr_cycle_timer_status(avr, avr_uart_txc_raise, p) == 0)
+                       avr_raise_interrupt(avr, &p->udrc);
+       }
+       if (clear_txc)
+               avr_uart_clear_interrupt(avr, &p->txc);
+       if (clear_rxc)
+               avr_uart_clear_interrupt(avr, &p->rxc);
+
+       ///TODO: handle the RxD & TxD pins function override
+
+       if (new_rxen != rxen) {
+               if (new_rxen) {
+                       if (uart_fifo_isempty(&p->input)) {
+                               // if reception is enabled and the fifo is empty, tell whomever there is room
+                               avr_raise_irq(p->io.irq + UART_IRQ_OUT_XOFF, 0);
+                               avr_raise_irq(p->io.irq + UART_IRQ_OUT_XON, 1);
+                       }
+               } else {
+                       avr_raise_irq(p->io.irq + UART_IRQ_OUT_XOFF, 1);
+                       avr_cycle_timer_cancel(avr, avr_uart_rxc_raise, p);
+                       // flush the Receive Buffer
+                       uart_fifo_reset(&p->input);
+                       // clear the rxc interrupt flag
+                       avr_uart_clear_interrupt(avr, &p->rxc);
                }
        }
-       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);
-
-                // setting u2x (double uart transmission speed) may also involve
-                // overwriting read only flags, therefore set u2x explicitly.
-                if(addr == p->u2x.reg) {
-                       avr_regbit_setto_raw(avr, p->u2x, v);
-                }
-
-               //avr_clear_interrupt_if(avr, &p->udrc, udre);
-               avr_clear_interrupt_if(avr, &p->txc, txc);
+       if (new_txen != txen) {
+               if (p->udrc.vector && !new_txen) {
+                       avr_uart_clear_interrupt(avr, &p->udrc);
+               }
        }
 }
 
@@ -218,9 +361,27 @@ static void avr_uart_irq_input(struct avr_irq_t * irq, uint32_t value, void * pa
        if (!avr_regbit_get(avr, p->rxen))
                return;
 
-       if (uart_fifo_isempty(&p->input))
-               avr_cycle_timer_register_usec(avr, p->usec_per_byte, avr_uart_rxc_raise, p); // should be uart speed dependent
-       uart_fifo_write(&p->input, value); // add to fifo
+       // reserved/not implemented:
+       //avr_uart_regbit_clear(avr, p->fe);
+       //avr_uart_regbit_clear(avr, p->upe);
+       //avr_uart_regbit_clear(avr, p->rxb8);
+
+       if (uart_fifo_isempty(&p->input) &&
+                       (avr_cycle_timer_status(avr, avr_uart_rxc_raise, p) == 0)
+                       ) {
+               avr_cycle_timer_register(avr, p->cycles_per_byte, avr_uart_rxc_raise, p); // start the rx pump
+               p->rx_cnt = 0;
+               avr_uart_regbit_clear(avr, p->dor);
+       } else if (uart_fifo_isfull(&p->input)) {
+               avr_regbit_setto(avr, p->dor, 1);
+       }
+       if (!avr_regbit_get(avr, p->dor)) { // otherwise newly received character must be rejected
+               uart_fifo_write(&p->input, value); // add to fifo
+       } else {
+               AVR_LOG(avr, LOG_ERROR, "UART%c: %s: RX buffer overrun, lost char=%c=0x%02X\n", p->name, __func__,
+                               (char)value, (uint8_t)value
+                               );
+       }
 
        TRACE(printf("UART IRQ in %02x (%d/%d) %s\n", value, p->input.read, p->input.write, uart_fifo_isfull(&p->input) ? "FULL!!" : "");)
 
@@ -233,19 +394,24 @@ void avr_uart_reset(struct avr_io_t *io)
 {
        avr_uart_t * p = (avr_uart_t *)io;
        avr_t * avr = p->io.avr;
-       if (p->udrc.vector)
+       if (p->udrc.vector) {
                avr_regbit_set(avr, p->udrc.raised);
+               avr_uart_regbit_clear(avr, p->dor);
+       }
+       avr_uart_clear_interrupt(avr, &p->txc);
+       avr_uart_clear_interrupt(avr, &p->rxc);
        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);
        uart_fifo_reset(&p->input);
+       p->tx_cnt =  0;
 
-        avr_regbit_set(avr, p->ucsz);
-        avr_regbit_clear(avr, p->ucsz2);
+       avr_regbit_set(avr, p->ucsz);
+       avr_uart_regbit_clear(avr, p->ucsz2);
 
        // DEBUG allow printf without fiddling with enabling the uart
        avr_regbit_set(avr, p->txen);
-       p->usec_per_byte = 100;
+       p->cycles_per_byte = avr_usec_to_cycles(avr, 100);
 }
 
 static int avr_uart_ioctl(struct avr_io_t * port, uint32_t ctl, void * io_param)
@@ -288,7 +454,7 @@ void avr_uart_init(avr_t * avr, avr_uart_t * p)
 
 //     printf("%s UART%c UDR=%02x\n", __FUNCTION__, p->name, p->r_udr);
 
-       p->flags = AVR_UART_FLAG_POOL_SLEEP|AVR_UART_FLAG_STDIO;
+       p->flags = AVR_UART_FLAG_POLL_SLEEP|AVR_UART_FLAG_STDIO;
 
        avr_register_io(avr, &p->io);
        avr_register_vector(avr, &p->rxc);
@@ -311,5 +477,6 @@ void avr_uart_init(avr_t * avr, avr_uart_t * p)
                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);
+       avr_register_io_write(avr, p->rxen.reg, avr_uart_write, p);
 }
 
index 8db33a074c48a4a1b1d1fdbc83696013849b97b7..dd3a53626780d6962eb6fa4db8c057e81b7c1523 100644 (file)
@@ -76,11 +76,12 @@ enum {
 #define AVR_IOCTL_UART_GETIRQ(_name) AVR_IOCTL_DEF('u','a','r',(_name))
 
 enum {
-       // the uart code monitors for firmware that pool on
+       // the uart code monitors for firmware that poll on
        // reception registers, and can do an atomic usleep()
        // if it's detected, this helps regulating CPU
        AVR_UART_FLAG_POOL_SLEEP = (1 << 0),
-       AVR_UART_FLAG_STDIO = (1 << 1),                 // print lines on the console
+       AVR_UART_FLAG_POLL_SLEEP = (1 << 0),            // to replace pool_sleep
+       AVR_UART_FLAG_STDIO = (1 << 1),                         // print lines on the console
 };
 
 typedef struct avr_uart_t {
@@ -100,6 +101,12 @@ typedef struct avr_uart_t {
        avr_regbit_t    ucsz;           // data bits
        avr_regbit_t    ucsz2;          // data bits, continued
 
+       // read-only bits (just to mask it out)
+       avr_regbit_t    fe;                     // frame error bit
+       avr_regbit_t    dor;            // data overrun bit
+       avr_regbit_t    upe;            // parity error bit
+       avr_regbit_t    rxb8;           // receive data bit 8
+
        avr_io_addr_t r_ubrrl,r_ubrrh;
 
        avr_int_vector_t rxc;
@@ -107,9 +114,12 @@ typedef struct avr_uart_t {
        avr_int_vector_t udrc;  
 
        uart_fifo_t     input;
+       uint8_t         tx_cnt;                 // number of unsent characters in the output buffer
+       uint32_t        rx_cnt;                 // number of characters read by app since rxc_raise_time
 
        uint32_t                flags;
-       avr_cycle_count_t usec_per_byte;
+       avr_cycle_count_t cycles_per_byte;
+       avr_cycle_count_t rxc_raise_time; // the cpu cycle when rxc flag was raised last time
 
        uint8_t *               stdio_out;
        int                             stdio_len;      // current size in the stdio output
@@ -121,6 +131,90 @@ typedef struct avr_uart_t {
 
 void avr_uart_init(avr_t * avr, avr_uart_t * port);
 
+#define AVR_UARTX_DECLARE(_name, _prr, _prusart) \
+       .uart ## _name = { \
+               .name = '0' + _name, \
+               .disabled = AVR_IO_REGBIT(_prr, _prusart), \
+       \
+               .r_udr = UDR ## _name, \
+       \
+               .fe = AVR_IO_REGBIT(UCSR ## _name ## A, FE ## _name), \
+               .dor = AVR_IO_REGBIT(UCSR ## _name ## A, DOR ## _name), \
+               .upe = AVR_IO_REGBIT(UCSR ## _name ## A, UPE ## _name), \
+               .u2x = AVR_IO_REGBIT(UCSR ## _name ## A, U2X ## _name), \
+               .txen = AVR_IO_REGBIT(UCSR ## _name ## B, TXEN ## _name), \
+               .rxen = AVR_IO_REGBIT(UCSR ## _name ## B, RXEN ## _name), \
+               .rxb8 = AVR_IO_REGBIT(UCSR ## _name ## B, RXB8 ## _name), \
+               .usbs = AVR_IO_REGBIT(UCSR ## _name ## C, USBS ## _name), \
+               .ucsz = AVR_IO_REGBITS(UCSR ## _name ## C, UCSZ ## _name ## 0, 0x3), \
+               .ucsz2 = AVR_IO_REGBIT(UCSR ## _name ## B, UCSZ ## _name ## 2), \
+       \
+               .r_ucsra = UCSR ## _name ## A, \
+               .r_ucsrb = UCSR ## _name ## B, \
+               .r_ucsrc = UCSR ## _name ## C, \
+               .r_ubrrl = UBRR ## _name ## L, \
+               .r_ubrrh = UBRR ## _name ## H, \
+               .rxc = { \
+                       .enable = AVR_IO_REGBIT(UCSR ## _name ## B, RXCIE ## _name), \
+                       .raised = AVR_IO_REGBIT(UCSR ## _name ## A, RXC ## _name), \
+                       .vector = USART ## _name ## _RX_vect, \
+                       .raise_sticky = 1, \
+               }, \
+               .txc = { \
+                       .enable = AVR_IO_REGBIT(UCSR ## _name ## B, TXCIE ## _name), \
+                       .raised = AVR_IO_REGBIT(UCSR ## _name ## A, TXC ## _name), \
+                       .vector = USART ## _name ## _TX_vect, \
+               }, \
+               .udrc = { \
+                       .enable = AVR_IO_REGBIT(UCSR ## _name ## B, UDRIE ## _name), \
+                       .raised = AVR_IO_REGBIT(UCSR ## _name ## A, UDRE ## _name), \
+                       .vector = USART ## _name ## _UDRE_vect, \
+                       .raise_sticky = 1, \
+               }, \
+       }
+
+// This macro is for older single-interface devices where variable names are bit divergent
+#define AVR_UART_DECLARE(_prr, _prusart, _upe_name, _rname_ix, _intr_c) \
+       .uart = { \
+               .name = '0', \
+               .disabled = AVR_IO_REGBIT(_prr, _prusart), \
+               .r_udr = UDR ## _rname_ix, \
+       \
+               .fe = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, FE ## _rname_ix), \
+               .dor = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, DOR ## _rname_ix), \
+               .upe = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, _upe_name ## _rname_ix), \
+               .u2x = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, U2X ## _rname_ix), \
+               .txen = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, TXEN ## _rname_ix), \
+               .rxen = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, RXEN ## _rname_ix), \
+               .rxb8 = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, RXB8 ## _rname_ix), \
+               .usbs = AVR_IO_REGBIT(UCSR ## _rname_ix ## C, USBS ## _rname_ix), \
+               .ucsz = AVR_IO_REGBITS(UCSR ## _rname_ix ## C, UCSZ ## _rname_ix ## 0, 0x3), \
+               .ucsz2 = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, UCSZ ## _rname_ix ## 2), \
+       \
+               .r_ucsra = UCSR ## _rname_ix ## A, \
+               .r_ucsrb = UCSR ## _rname_ix ## B, \
+               .r_ucsrc = UCSR ## _rname_ix ## C, \
+               .r_ubrrl = UBRR ## _rname_ix ## L, \
+               .r_ubrrh = UBRR ## _rname_ix ## H, \
+               .rxc = { \
+                       .enable = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, RXCIE ## _rname_ix), \
+                       .raised = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, RXC ## _rname_ix), \
+                       .vector = USART_RX ## _intr_c ## _vect, \
+                       .raise_sticky = 1, \
+               }, \
+               .txc = { \
+                       .enable = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, TXCIE ## _rname_ix), \
+                       .raised = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, TXC ## _rname_ix), \
+                       .vector = USART_TX ## _intr_c ## _vect, \
+               }, \
+               .udrc = { \
+                       .enable = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, UDRIE ## _rname_ix), \
+                       .raised = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, UDRE ## _rname_ix), \
+                       .vector = USART_UDRE_vect, \
+                       .raise_sticky = 1, \
+               }, \
+       }
+
 #ifdef __cplusplus
 };
 #endif