1 #include <avr/interrupt.h>
4 #include "ringbuffer.h"
7 #define BIT(n) (1<<(n))
10 #define SERIAL_BUFSIZE 16
14 static RINGBUFFER(rx, SERIAL_BUFSIZE);
15 static RINGBUFFER(tx, SERIAL_BUFSIZE);
16 static uint8_t rx_overrun;
17 #define INTERRUPTS BIT(RXCIE0)
22 static inline void set_baud(uint16_t baud)
24 baud = (F_CPU/16+baud/2)/baud-1;
29 void serial_init(uint16_t baud)
31 DDRD = (DDRD&~0x03) | 0x02;
36 UCSR0C = BIT(UCSZ00) | BIT(UCSZ01); // 8N1
37 UCSR0B = BIT(RXEN0) | BIT(TXEN0) | INTERRUPTS;
40 void serial_set_baud(uint16_t baud)
43 while(!(UCSR0A&BIT(UDRE0))) ;
45 /* It's impossible to reliably find out when transmission has finished.
46 Wait for one character duration to be safe. */
47 uint16_t delay = (UBRR0H<<8)|UBRR0L;
48 for(uint8_t i=0; i<40; ++i)
56 return ringbuffer_blocking_pop(rx);
58 while(!(UCSR0A&BIT(RXC0))) ;
63 uint8_t serial_read_available()
66 return ringbuffer_fill(rx);
68 return (UCSR0A&BIT(RXC0))!=0;
72 uint8_t serial_read_overrun()
75 uint8_t o = rx_overrun;
79 return (UCSR0A&BIT(DOR0))!=0;
83 void serial_write(uint8_t c)
86 ringbuffer_blocking_push(tx, c);
87 UCSR0B |= BIT(UDRIE0);
89 while(!(UCSR0A&BIT(UDRE0))) ;
94 uint8_t serial_write_space()
97 return ringbuffer_space(tx);
99 return (UCSR0A&BIT(UDRE0))!=0;
106 if(ringbuffer_fill(tx))
107 UDR0 = ringbuffer_pop(tx);
109 UCSR0B &= ~BIT(UDRIE0);
115 if(!ringbuffer_space(rx))
118 ringbuffer_push(rx, c);