/*------------------------------------------------*/ /* UART functions */ #include #include #include "uart.h" #define SYSCLK 9216000 #define BAUD 115200 typedef struct _fifo { uint8_t idx_w; uint8_t idx_r; uint8_t count; uint8_t buff[64]; } FIFO; static volatile FIFO txfifo, rxfifo; /* Initialize UART */ void uart_init() { rxfifo.idx_r = 0; rxfifo.idx_w = 0; rxfifo.count = 0; txfifo.idx_r = 0; txfifo.idx_w = 0; txfifo.count = 0; UBRR0L = SYSCLK/BAUD/16-1; UCSR0B = _BV(RXEN0)|_BV(RXCIE0)|_BV(TXEN0); } /* Get a received character */ uint8_t uart_test () { return rxfifo.count; } uint8_t uart_get () { uint8_t d, i; i = rxfifo.idx_r; while(rxfifo.count == 0); d = rxfifo.buff[i++]; cli(); rxfifo.count--; sei(); if(i >= sizeof(rxfifo.buff)) i = 0; rxfifo.idx_r = i; return d; } /* Put a character to transmit */ void uart_put (uint8_t d) { uint8_t i; i = txfifo.idx_w; while(txfifo.count >= sizeof(txfifo.buff)); txfifo.buff[i++] = d; cli(); txfifo.count++; UCSR0B = _BV(RXEN0)|_BV(RXCIE0)|_BV(TXEN0)|_BV(UDRIE0); sei(); if(i >= sizeof(txfifo.buff)) i = 0; txfifo.idx_w = i; } /* UART RXC interrupt */ SIGNAL(SIG_UART0_RECV) { uint8_t d, n, i; d = UDR0; n = rxfifo.count; if(n < sizeof(rxfifo.buff)) { rxfifo.count = ++n; i = rxfifo.idx_w; rxfifo.buff[i++] = d; if(i >= sizeof(rxfifo.buff)) i = 0; rxfifo.idx_w = i; } } /* UART UDRE interrupt */ SIGNAL(SIG_UART0_DATA) { uint8_t n, i; n = txfifo.count; if(n) { txfifo.count = --n; i = txfifo.idx_r; UDR0 = txfifo.buff[i++]; if(i >= sizeof(txfifo.buff)) i = 0; txfifo.idx_r = i; } if(n == 0) UCSR0B = _BV(RXEN0)|_BV(RXCIE0)|_BV(TXEN0); }