/*
* uart_demo_01.c
* Initialisierung der UART, 9600, 8N1; unter Verwendung von Marcos
* Funktionen zum Senden und Empfangen eines Bytes im Polling
* Ein empfangenes Zeichen wieder senden und am PortB ausgeben * Pinbelegung der UART-Schnittstelle: Tx = PD1, Rx = PD0
* Controller: ATmega88 @ 8MHz
*/
#include <avr/io.h>

#define FOSC 8000000				// Set clock Speed in Hz
#define BAUD 9600					// Set baud rate
#define UBRR_Value FOSC/16/BAUD-1	// Set baud rate value in baud rate register

void USART_Init( uint16_t ubrr)
{
	UBRR0H = (uint8_t)(ubrr >> 8);		// Set baud rate in high- and low-register
	UBRR0L = (uint8_t)ubrr;				// Set low-register always after high-register
	UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);	// Set frame format: 8data, 1stop bit
	UCSR0B = (1<<RXEN0)|(1<<TXEN0);		// Enable receiver and transmitter
}

void USART_Transmit(uint8_t data)
{
	while ( !( UCSR0A & (1<<UDRE0)) );	// Wait for empty transmit buffer
	UDR0 = data;						// Put data into buffer, sends the data
}

uint8_t USART_Receive(void)
{
	while ( !(UCSR0A & (1<<RXC0)) );	// Wait for data to be received
	return UDR0;						// Get and return received data from buffer
}

/**** Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte) ****/
void USART_Flush(void)
{
	uint8_t dummy;
	while (UCSR0A & (1<<RXC0))
	dummy = UDR0;
}

int main( void )
{
	uint8_t data;
	USART_Init(UBRR_Value);		// Init UART
	USART_Flush();				// Flush Receive-Buffer
	DDRB = 0xFF;				// alle PINs an PortB als Ausgänge
	
	while(1)
	{
		USART_Transmit(data = USART_Receive());		// receive on byte, send it
		PORTB = data;								// and write to Port B
	}
}