#include <avr/interrupt.h>
#include <avr/io.h>
+#include "delay.h"
#include "ringbuffer.h"
#include "serial.h"
#define INTERRUPTS 0
#endif
+static inline void set_baud(uint16_t baud)
+{
+ baud = (F_CPU/16+baud/2)/baud-1;
+ UBRR0H = baud>>8;
+ UBRR0L = baud;
+}
+
void serial_init(uint16_t baud)
{
DDRD = (DDRD&~0x03) | 0x02;
PORTD &= ~0x03;
- baud = (F_CPU/16+baud/2)/baud-1;
- UBRR0H = baud>>8;
- UBRR0L = baud;
+ set_baud(baud);
UCSR0A = 0;
UCSR0C = BIT(UCSZ00) | BIT(UCSZ01); // 8N1
UCSR0B = BIT(RXEN0) | BIT(TXEN0) | INTERRUPTS;
}
+void serial_set_baud(uint16_t baud)
+{
+#ifdef SERIAL_ASYNC
+ while(!(UCSR0A&BIT(UDRE0))) ;
+#endif
+ /* It's impossible to reliably find out when transmission has finished.
+ Wait for one character duration to be safe. */
+ uint16_t delay = (UBRR0H<<8)|UBRR0L;
+ for(uint8_t i=0; i<40; ++i)
+ delay_loop16(delay);
+ set_baud(baud);
+}
+
uint8_t serial_read()
{
#ifdef SERIAL_ASYNC
#include <stdint.h>
void serial_init(uint16_t);
+void serial_set_baud(uint16_t);
uint8_t serial_read();
uint8_t serial_read_available();
uint8_t serial_read_overrun();