Subversion Repositories svnkaklik

Compare Revisions

Ignore whitespace Rev 506 → Rev 507

/programy/C/avr/SDcard/uart.c
0,0 → 1,128
/*------------------------------------------------*/
/* UART functions */
 
 
#include <avr/io.h>
#include <avr/interrupt.h>
#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);
}