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
|
depends on AVR_SERIAL && !SIMULAVR
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
config SERIAL_PORT
|
||||||
|
int
|
||||||
|
default 1 if MACH_at90usb1286 || MACH_at90usb646
|
||||||
|
default 0
|
||||||
|
|
||||||
config SIMULAVR
|
config SIMULAVR
|
||||||
depends on MACH_atmega168 || MACH_atmega328 || MACH_atmega644p || MACH_atmega1284p
|
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.
|
// 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 "autoconf.h" // CONFIG_SERIAL_BAUD
|
||||||
#include "board/serial_irq.h" // serial_rx_byte
|
#include "board/serial_irq.h" // serial_rx_byte
|
||||||
#include "sched.h" // DECL_INIT
|
#include "sched.h" // DECL_INIT
|
||||||
|
|
||||||
// Define serial port registers on AT90USB1286
|
// Helper macros for defining serial port aliases
|
||||||
#if !defined(UCSR0A) && defined(UCSR1A)
|
#define AVR_SERIAL_REG1(prefix, id, suffix) prefix ## id ## suffix
|
||||||
#define UCSR0A UCSR1A
|
#define AVR_SERIAL_REG(prefix, id, suffix) AVR_SERIAL_REG1(prefix, id, suffix)
|
||||||
#define UCSR0B UCSR1B
|
|
||||||
#define UCSR0C UCSR1C
|
// Serial port register aliases
|
||||||
#define UBRR0 UBRR1
|
#define UCSRxA AVR_SERIAL_REG(UCSR, CONFIG_SERIAL_PORT, A)
|
||||||
#define UDR0 UDR1
|
#define UCSRxB AVR_SERIAL_REG(UCSR, CONFIG_SERIAL_PORT, B)
|
||||||
#define UCSZ01 UCSZ11
|
#define UCSRxC AVR_SERIAL_REG(UCSR, CONFIG_SERIAL_PORT, C)
|
||||||
#define UCSZ00 UCSZ10
|
#define UBRRx AVR_SERIAL_REG(UBRR, CONFIG_SERIAL_PORT,)
|
||||||
#define U2X0 U2X1
|
#define UDRx AVR_SERIAL_REG(UDR, CONFIG_SERIAL_PORT,)
|
||||||
#define RXEN0 RXEN1
|
#define UCSZx1 AVR_SERIAL_REG(UCSZ, CONFIG_SERIAL_PORT, 1)
|
||||||
#define TXEN0 TXEN1
|
#define UCSZx0 AVR_SERIAL_REG(UCSZ, CONFIG_SERIAL_PORT, 0)
|
||||||
#define RXCIE0 RXCIE1
|
#define U2Xx AVR_SERIAL_REG(U2X, CONFIG_SERIAL_PORT,)
|
||||||
#define UDRIE0 UDRIE1
|
#define RXENx AVR_SERIAL_REG(RXEN, CONFIG_SERIAL_PORT,)
|
||||||
#define USART0_RX_vect USART1_RX_vect
|
#define TXENx AVR_SERIAL_REG(TXEN, CONFIG_SERIAL_PORT,)
|
||||||
#define USART0_UDRE_vect USART1_UDRE_vect
|
#define RXCIEx AVR_SERIAL_REG(RXCIE, CONFIG_SERIAL_PORT,)
|
||||||
#endif
|
#define UDRIEx AVR_SERIAL_REG(UDRIE, CONFIG_SERIAL_PORT,)
|
||||||
|
|
||||||
// Define serial port registers on atmega168 / atmega328
|
|
||||||
#if defined(USART_RX_vect)
|
#if defined(USART_RX_vect)
|
||||||
#define USART0_RX_vect USART_RX_vect
|
// The atmega168 / atmega328 doesn't have an ID in the irq names
|
||||||
#define USART0_UDRE_vect USART_UDRE_vect
|
#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
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
serial_init(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;
|
uint32_t cm = CONFIG_SERIAL_BAUD_U2X ? 8 : 16;
|
||||||
UBRR0 = DIV_ROUND_CLOSEST(CONFIG_CLOCK_FREQ, cm * CONFIG_SERIAL_BAUD) - 1UL;
|
UBRRx = DIV_ROUND_CLOSEST(CONFIG_CLOCK_FREQ, cm * CONFIG_SERIAL_BAUD) - 1UL;
|
||||||
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
|
UCSRxC = (1<<UCSZx1) | (1<<UCSZx0);
|
||||||
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (1<<UDRIE0);
|
UCSRxB = (1<<RXENx) | (1<<TXENx) | (1<<RXCIEx) | (1<<UDRIEx);
|
||||||
}
|
}
|
||||||
DECL_INIT(serial_init);
|
DECL_INIT(serial_init);
|
||||||
|
|
||||||
// Rx interrupt - data available to be read.
|
// 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.
|
// Tx interrupt - data can be written to serial.
|
||||||
ISR(USART0_UDRE_vect)
|
ISR(USARTx_UDRE_vect)
|
||||||
{
|
{
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
int ret = serial_get_tx_byte(&data);
|
int ret = serial_get_tx_byte(&data);
|
||||||
if (ret)
|
if (ret)
|
||||||
UCSR0B &= ~(1<<UDRIE0);
|
UCSRxB &= ~(1<<UDRIEx);
|
||||||
else
|
else
|
||||||
UDR0 = data;
|
UDRx = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable tx interrupts
|
// Enable tx interrupts
|
||||||
void
|
void
|
||||||
serial_enable_tx_irq(void)
|
serial_enable_tx_irq(void)
|
||||||
{
|
{
|
||||||
UCSR0B |= 1<<UDRIE0;
|
UCSRxB |= 1<<UDRIEx;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue