avr: Clean up serial port register aliases
Define unique register aliases for all of the hardware serial port definitions. This makes it easier to deal with the AVR chips that use different register names. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
22c49a7c3f
commit
cf475a9a39
|
@ -110,6 +110,10 @@ config SERIAL_BAUD_U2X
|
|||
depends on AVR_SERIAL && !SIMULAVR
|
||||
bool
|
||||
default y
|
||||
config SERIAL_PORT
|
||||
int
|
||||
default 1 if MACH_at90usb1286 || MACH_at90usb646
|
||||
default 0
|
||||
|
||||
config SIMULAVR
|
||||
depends on MACH_atmega168 || MACH_atmega328 || MACH_atmega644p || MACH_atmega1284p
|
||||
|
|
|
@ -4,66 +4,69 @@
|
|||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include <avr/interrupt.h> // USART0_RX_vect
|
||||
#include <avr/interrupt.h> // USART_RX_vect
|
||||
#include "autoconf.h" // CONFIG_SERIAL_BAUD
|
||||
#include "board/serial_irq.h" // serial_rx_byte
|
||||
#include "sched.h" // DECL_INIT
|
||||
|
||||
// Define serial port registers on AT90USB1286
|
||||
#if !defined(UCSR0A) && defined(UCSR1A)
|
||||
#define UCSR0A UCSR1A
|
||||
#define UCSR0B UCSR1B
|
||||
#define UCSR0C UCSR1C
|
||||
#define UBRR0 UBRR1
|
||||
#define UDR0 UDR1
|
||||
#define UCSZ01 UCSZ11
|
||||
#define UCSZ00 UCSZ10
|
||||
#define U2X0 U2X1
|
||||
#define RXEN0 RXEN1
|
||||
#define TXEN0 TXEN1
|
||||
#define RXCIE0 RXCIE1
|
||||
#define UDRIE0 UDRIE1
|
||||
#define USART0_RX_vect USART1_RX_vect
|
||||
#define USART0_UDRE_vect USART1_UDRE_vect
|
||||
#endif
|
||||
// Helper macros for defining serial port aliases
|
||||
#define AVR_SERIAL_REG1(prefix, id, suffix) prefix ## id ## suffix
|
||||
#define AVR_SERIAL_REG(prefix, id, suffix) AVR_SERIAL_REG1(prefix, id, suffix)
|
||||
|
||||
// Serial port register aliases
|
||||
#define UCSRxA AVR_SERIAL_REG(UCSR, CONFIG_SERIAL_PORT, A)
|
||||
#define UCSRxB AVR_SERIAL_REG(UCSR, CONFIG_SERIAL_PORT, B)
|
||||
#define UCSRxC AVR_SERIAL_REG(UCSR, CONFIG_SERIAL_PORT, C)
|
||||
#define UBRRx AVR_SERIAL_REG(UBRR, CONFIG_SERIAL_PORT,)
|
||||
#define UDRx AVR_SERIAL_REG(UDR, CONFIG_SERIAL_PORT,)
|
||||
#define UCSZx1 AVR_SERIAL_REG(UCSZ, CONFIG_SERIAL_PORT, 1)
|
||||
#define UCSZx0 AVR_SERIAL_REG(UCSZ, CONFIG_SERIAL_PORT, 0)
|
||||
#define U2Xx AVR_SERIAL_REG(U2X, CONFIG_SERIAL_PORT,)
|
||||
#define RXENx AVR_SERIAL_REG(RXEN, CONFIG_SERIAL_PORT,)
|
||||
#define TXENx AVR_SERIAL_REG(TXEN, CONFIG_SERIAL_PORT,)
|
||||
#define RXCIEx AVR_SERIAL_REG(RXCIE, CONFIG_SERIAL_PORT,)
|
||||
#define UDRIEx AVR_SERIAL_REG(UDRIE, CONFIG_SERIAL_PORT,)
|
||||
|
||||
// Define serial port registers on atmega168 / atmega328
|
||||
#if defined(USART_RX_vect)
|
||||
#define USART0_RX_vect USART_RX_vect
|
||||
#define USART0_UDRE_vect USART_UDRE_vect
|
||||
// The atmega168 / atmega328 doesn't have an ID in the irq names
|
||||
#define USARTx_RX_vect USART_RX_vect
|
||||
#define USARTx_UDRE_vect USART_UDRE_vect
|
||||
#else
|
||||
#define USARTx_RX_vect AVR_SERIAL_REG(USART, CONFIG_SERIAL_PORT, _RX_vect)
|
||||
#define USARTx_UDRE_vect AVR_SERIAL_REG(USART, CONFIG_SERIAL_PORT, _UDRE_vect)
|
||||
#endif
|
||||
|
||||
void
|
||||
serial_init(void)
|
||||
{
|
||||
UCSR0A = CONFIG_SERIAL_BAUD_U2X ? (1<<U2X0) : 0;
|
||||
UCSRxA = CONFIG_SERIAL_BAUD_U2X ? (1<<U2Xx) : 0;
|
||||
uint32_t cm = CONFIG_SERIAL_BAUD_U2X ? 8 : 16;
|
||||
UBRR0 = DIV_ROUND_CLOSEST(CONFIG_CLOCK_FREQ, cm * CONFIG_SERIAL_BAUD) - 1UL;
|
||||
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
|
||||
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (1<<UDRIE0);
|
||||
UBRRx = DIV_ROUND_CLOSEST(CONFIG_CLOCK_FREQ, cm * CONFIG_SERIAL_BAUD) - 1UL;
|
||||
UCSRxC = (1<<UCSZx1) | (1<<UCSZx0);
|
||||
UCSRxB = (1<<RXENx) | (1<<TXENx) | (1<<RXCIEx) | (1<<UDRIEx);
|
||||
}
|
||||
DECL_INIT(serial_init);
|
||||
|
||||
// Rx interrupt - data available to be read.
|
||||
ISR(USART0_RX_vect)
|
||||
ISR(USARTx_RX_vect)
|
||||
{
|
||||
serial_rx_byte(UDR0);
|
||||
serial_rx_byte(UDRx);
|
||||
}
|
||||
|
||||
// Tx interrupt - data can be written to serial.
|
||||
ISR(USART0_UDRE_vect)
|
||||
ISR(USARTx_UDRE_vect)
|
||||
{
|
||||
uint8_t data;
|
||||
int ret = serial_get_tx_byte(&data);
|
||||
if (ret)
|
||||
UCSR0B &= ~(1<<UDRIE0);
|
||||
UCSRxB &= ~(1<<UDRIEx);
|
||||
else
|
||||
UDR0 = data;
|
||||
UDRx = data;
|
||||
}
|
||||
|
||||
// Enable tx interrupts
|
||||
void
|
||||
serial_enable_tx_irq(void)
|
||||
{
|
||||
UCSR0B |= 1<<UDRIE0;
|
||||
UCSRxB |= 1<<UDRIEx;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue