/*\}*/
#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
#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
* - 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
/* 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
#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
#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
#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
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
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)
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)
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)
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)
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);
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);