core: Fix uart.c for ATmega32U4

This commit is contained in:
tmk 2019-03-22 22:15:26 +09:00
parent 494faeb488
commit c41e48a0ab

View file

@ -1,4 +1,3 @@
// TODO: Teensy support(ATMega32u4/AT90USB128)
// Fixed for Arduino Duemilanove ATmega168p by Jun Wako // Fixed for Arduino Duemilanove ATmega168p by Jun Wako
/* UART Example for Teensy USB Development Board /* UART Example for Teensy USB Development Board
* http://www.pjrc.com/teensy/ * http://www.pjrc.com/teensy/
@ -32,6 +31,39 @@
#include "uart.h" #include "uart.h"
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
# define UDRn UDR0
# define UBRRn UBRR0
# define UCSRnA UCSR0A
# define UCSRnB UCSR0B
# define UCSRnC UCSR0C
# define U2Xn U2X0
# define RXENn RXEN0
# define TXENn TXEN0
# define RXCIEn RXCIE0
# define UCSZn1 UCSZ01
# define UCSZn0 UCSZ00
# define UDRIEn UDRIE0
# define UDRE_vect USART_UDRE_vect
# define RX_vect USART_RX_vect
#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
# define UDRn UDR1
# define UBRRn UBRR1
# define UCSRnA UCSR1A
# define UCSRnB UCSR1B
# define UCSRnC UCSR1C
# define U2Xn U2X1
# define RXENn RXEN1
# define TXENn TXEN1
# define RXCIEn RXCIE1
# define UCSZn1 UCSZ11
# define UCSZn0 UCSZ10
# define UDRIEn UDRIE1
# define UDRE_vect USART1_UDRE_vect
# define RX_vect USART1_RX_vect
#endif
// These buffers may be any size from 2 to 256 bytes. // These buffers may be any size from 2 to 256 bytes.
#define RX_BUFFER_SIZE 64 #define RX_BUFFER_SIZE 64
#define TX_BUFFER_SIZE 40 #define TX_BUFFER_SIZE 40
@ -47,10 +79,10 @@ static volatile uint8_t rx_buffer_tail;
void uart_init(uint32_t baud) void uart_init(uint32_t baud)
{ {
cli(); cli();
UBRR0 = (F_CPU / 4 / baud - 1) / 2; UBRRn = (F_CPU / 4 / baud - 1) / 2;
UCSR0A = (1<<U2X0); UCSRnA = (1<<U2Xn);
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0); UCSRnB = (1<<RXENn) | (1<<TXENn) | (1<<RXCIEn);
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00); UCSRnC = (1<<UCSZn1) | (1<<UCSZn0);
tx_buffer_head = tx_buffer_tail = 0; tx_buffer_head = tx_buffer_tail = 0;
rx_buffer_head = rx_buffer_tail = 0; rx_buffer_head = rx_buffer_tail = 0;
sei(); sei();
@ -67,7 +99,7 @@ void uart_putchar(uint8_t c)
//cli(); //cli();
tx_buffer[i] = c; tx_buffer[i] = c;
tx_buffer_head = i; tx_buffer_head = i;
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (1<<UDRIE0); UCSRnB = (1<<RXENn) | (1<<TXENn) | (1<<RXCIEn) | (1<<UDRIEn);
//sei(); //sei();
} }
@ -98,27 +130,27 @@ uint8_t uart_available(void)
} }
// Transmit Interrupt // Transmit Interrupt
ISR(USART_UDRE_vect) ISR(UDRE_vect)
{ {
uint8_t i; uint8_t i;
if (tx_buffer_head == tx_buffer_tail) { if (tx_buffer_head == tx_buffer_tail) {
// buffer is empty, disable transmit interrupt // buffer is empty, disable transmit interrupt
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0); UCSRnB = (1<<RXENn) | (1<<TXENn) | (1<<RXCIEn);
} else { } else {
i = tx_buffer_tail + 1; i = tx_buffer_tail + 1;
if (i >= TX_BUFFER_SIZE) i = 0; if (i >= TX_BUFFER_SIZE) i = 0;
UDR0 = tx_buffer[i]; UDRn = tx_buffer[i];
tx_buffer_tail = i; tx_buffer_tail = i;
} }
} }
// Receive Interrupt // Receive Interrupt
ISR(USART_RX_vect) ISR(RX_vect)
{ {
uint8_t c, i; uint8_t c, i;
c = UDR0; c = UDRn;
i = rx_buffer_head + 1; i = rx_buffer_head + 1;
if (i >= RX_BUFFER_SIZE) i = 0; if (i >= RX_BUFFER_SIZE) i = 0;
if (i != rx_buffer_tail) { if (i != rx_buffer_tail) {