X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Favr%2Fdrv%2Fser_avr.c;h=ce44fd1983c08d7027f4b5b04233bb2ae95fd3f1;hb=2e1423c0e63c12bb4eb996480ec2a51f8899aa88;hp=11a6c65c024c7d628f5041056d556d238eeab21e;hpb=6be047844350e6988c1a82a68ff8572fb2b60b57;p=bertos.git diff --git a/bertos/cpu/avr/drv/ser_avr.c b/bertos/cpu/avr/drv/ser_avr.c index 11a6c65c..ce44fd19 100644 --- a/bertos/cpu/avr/drv/ser_avr.c +++ b/bertos/cpu/avr/drv/ser_avr.c @@ -74,7 +74,7 @@ /*\}*/ #endif -#if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA1280 +#if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560 #define BIT_RXCIE0 RXCIE0 #define BIT_RXEN0 RXEN0 #define BIT_TXEN0 TXEN0 @@ -84,7 +84,7 @@ #define BIT_RXEN1 RXEN1 #define BIT_TXEN1 TXEN1 #define BIT_UDRIE1 UDRIE1 - #if CPU_AVR_ATMEGA1280 + #if CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560 #define BIT_RXCIE2 RXCIE2 #define BIT_RXEN2 RXEN2 #define BIT_TXEN2 TXEN2 @@ -146,6 +146,7 @@ * - Enable only the RX complete interrupt */ #define SER_UART0_BUS_TXINIT do { \ + UCSR0A = 0; /* The Arduino Uno bootloader turns on U2X0 */ \ UCSR0B = BV(BIT_RXCIE0) | BV(BIT_RXEN0) | BV(BIT_TXEN0); \ } while (0) #endif @@ -332,7 +333,7 @@ /* SPI port and pin configuration */ #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103 || CPU_AVR_ATMEGA1281 \ - || CPU_AVR_ATMEGA1280 + || CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560 #define SPI_PORT PORTB #define SPI_DDR DDRB #define SPI_SS_BIT PB0 @@ -355,12 +356,19 @@ #define SPI_SCK_BIT PB5 #define SPI_MOSI_BIT PB3 #define SPI_MISO_BIT PB4 +#elif CPU_AVR_ATMEGA32 + #define SPI_PORT PORTB + #define SPI_DDR DDRB + #define SPI_SS_BIT PB4 + #define SPI_SCK_BIT PB7 + #define SPI_MOSI_BIT PB5 + #define SPI_MISO_BIT PB6 #else #error Unknown architecture #endif /* USART register definitions */ -#if CPU_AVR_ATMEGA1280 +#if CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560 #define AVR_HAS_UART1 1 #define AVR_HAS_UART2 1 #define AVR_HAS_UART3 1 @@ -375,7 +383,7 @@ #define USART0_UDRE_vect USART_UDRE_vect #define USART0_RX_vect USART_RX_vect #define USART0_TX_vect USART_TX_vect -#elif CPU_AVR_ATMEGA8 +#elif CPU_AVR_ATMEGA8 || CPU_AVR_ATMEGA32 #define AVR_HAS_UART1 0 #define AVR_HAS_UART2 0 #define AVR_HAS_UART3 0 @@ -385,9 +393,11 @@ #define UDR0 UDR #define UBRR0L UBRRL #define UBRR0H UBRRH + #define UPM01 UPM1 + #define UPM00 UPM0 #define USART0_UDRE_vect USART_UDRE_vect - #define USART0_RX_vect USART_RX_vect - #define USART0_TX_vect USART_TX_vect + #define USART0_RX_vect USART_RXC_vect + #define USART0_TX_vect USART_TXC_vect #elif CPU_AVR_ATMEGA103 #define AVR_HAS_UART1 0 #define AVR_HAS_UART2 0 @@ -448,7 +458,20 @@ struct AvrSerial volatile bool sending; }; +static uint16_t uart_period(unsigned long bps) +{ + uint16_t period = DIV_ROUND(CPU_FREQ / 16UL, bps) - 1; + + #ifdef _DEBUG + long skew = bps - (long)(period + 1) * (CPU_FREQ / 16); + /* 8N1 is reliable within 3% skew */ + if ((unsigned long)ABS(skew) > bps / (100 / 3)) + kprintf("Baudrate off by %ldbps\n", skew); + #endif + //DB(kprintf("uart_period(bps=%lu): period=%u\n", bps, period);) + return period; +} /* * Callbacks @@ -485,15 +508,12 @@ static void uart0_enabletxirq(struct SerialHardware *_hw) static void uart0_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) { - /* Compute baud-rate period */ - uint16_t period = DIV_ROUND(CPU_FREQ / 16UL, rate) - 1; + uint16_t period = uart_period(rate); #if !CPU_AVR_ATMEGA103 - UBRR0H = (period) >> 8; + UBRR0H = period >> 8; #endif - UBRR0L = (period); - - //DB(kprintf("uart0_setbaudrate(rate=%lu): period=%d\n", rate, period);) + UBRR0L = period; } static void uart0_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity) @@ -538,13 +558,9 @@ static void uart1_enabletxirq(struct SerialHardware *_hw) static void uart1_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) { - /* Compute baud-rate period */ - uint16_t period = DIV_ROUND(CPU_FREQ / 16UL, rate) - 1; - - UBRR1H = (period) >> 8; - UBRR1L = (period); - - //DB(kprintf("uart1_setbaudrate(rate=%ld): period=%d\n", rate, period);) + uint16_t period = uart_period(rate); + UBRR1H = period >> 8; + UBRR1L = period; } static void uart1_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity) @@ -589,13 +605,9 @@ static void uart2_enabletxirq(struct SerialHardware *_hw) static void uart2_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) { - /* Compute baud-rate period */ - uint16_t period = DIV_ROUND(CPU_FREQ / 16UL, rate) - 1; - - UBRR2H = (period) >> 8; - UBRR2L = (period); - - //DB(kprintf("uart2_setbaudrate(rate=%ld): period=%d\n", rate, period);) + uint16_t period = uart_period(rate); + UBRR2H = period >> 8; + UBRR2L = period; } static void uart2_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity) @@ -640,13 +652,9 @@ static void uart3_enabletxirq(struct SerialHardware *_hw) static void uart3_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate) { - /* Compute baud-rate period */ - uint16_t period = DIV_ROUND(CPU_FREQ / 16UL, rate) - 1; - - UBRR3H = (period) >> 8; - UBRR3L = (period); - - //DB(kprintf("uart3_setbaudrate(rate=%ld): period=%d\n", rate, period);) + uint16_t period = uart_period(rate); + UBRR3H = period >> 8; + UBRR3L = period; } static void uart3_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity) @@ -1080,22 +1088,6 @@ DECLARE_ISR(USART2_UDRE_vect) UARTDescs[SER_UART2].sending = false; #endif } - -/** - * ATMEGA64, 128 and 103 do not have more than 2 USARTs - -#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103 - else if (!IS_CTS_ON) - { - // Disable rx interrupt and tx, enable CTS interrupt - // UNTESTED - UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); - EIFR |= EIMSKF_CTS; - EIMSK |= EIMSKF_CTS; - } -#endif - - */ else { char c = fifo_pop(txfifo); @@ -1148,22 +1140,6 @@ DECLARE_ISR(USART3_UDRE_vect) UARTDescs[SER_UART3].sending = false; #endif } - -/** - * ATMEGA64, 128 and 103 do not have more than 2 USARTs - -#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA103 - else if (!IS_CTS_ON) - { - // Disable rx interrupt and tx, enable CTS interrupt - // UNTESTED - UCSR1B = BV(BIT_RXCIE1) | BV(BIT_RXEN1) | BV(BIT_TXEN1); - EIFR |= EIMSKF_CTS; - EIMSK |= EIMSKF_CTS; - } -#endif - - */ else { char c = fifo_pop(txfifo);