+ 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
+ return ringbuffer_blocking_pop(rx);
+#else
+ while(!(UCSR0A&BIT(RXC0))) ;
+ return UDR0;
+#endif
+}
+
+uint8_t serial_read_available()
+{
+#ifdef SERIAL_ASYNC
+ return ringbuffer_fill(rx);
+#else
+ return (UCSR0A&BIT(RXC0))!=0;
+#endif
+}
+
+uint8_t serial_read_overrun()
+{
+#ifdef SERIAL_ASYNC
+ uint8_t o = rx_overrun;
+ rx_overrun = 0;
+ return o;
+#else
+ return (UCSR0A&BIT(DOR0))!=0;
+#endif