/*
 * LED_Projekt.c
 *
 * Created: 21.04.2016 16:43:37
 * Author : Christian Karle
 */ 

#define SS PB4
#define MOSI PB5
#define MISO PB6
#define SCK PB7
#define F_CPU 8000000 // global defines

#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h> // global includes 

volatile uint8_t byte_counter = 0;

volatile uint8_t Data [ 48 ];

volatile uint8_t Data_12 [ 36 ];

void Update_Data ( void ) // Data update function
{
	Data_12 [ 0 ] = ( Data [ 0 ] );
	Data_12 [ 1 ] = ( ( Data [ 1 ] << 4 ) | ( Data [ 2 ] >> 4 ) );
	Data_12 [ 2 ] = ( ( Data [ 3 ] ) | ( Data [ 2 ] << 4 ) ); // Manipulation of Data
}

ISR ( TIMER0_OVF_vect ) // Timer 0 overflow interrupt function
{   
	cli ( );

	for ( volatile uint8_t Position1 = 0; Position1 <= 35 ; Position1 ++ )
	{
		SPDR = Data_12 [ Position1 ]; // Set SPI Data

		while ( ! ( SPSR & ( 1 << SPIF ) ) ) { } // wait for SPI buffer is cleared
	}

	PORTB |= ( 1 << PB0 );

	_delay_loop_1 ( 5 ); // wait

	PORTB &= ~ ( 1 << PB0 ); // Update data

	sei ( );
}

void Init_SPI ( void ) // Initialize SPI function
{
	SPCR |= ( 1 << SPR1 ) | ( 1 << SPR0 );
	SPSR |= ( 1 << SPI2X ); // SPI frequency CPU/64

	SPCR &= ~ ( 1 << CPOL ); // Leading edge rising, trailing edge falling
	SPCR &= ~ ( 1 << DORD ); // Transmit MSB first

	SPCR &= ~ ( 1 << CPHA ); // Leading edge sample, trailing edge setup

	SPCR |= ( ( 1 << SPIE ) | ( 1 << SPE ) | ( 1 << MSTR ) ); // Master mode, SPI enable, SPI interrupt enable
}

void DDR_Set ( void ) // DDR_Set function
{
	DDRB |= ( 1 << PB0 ); // Set PB0 output
	PORTB &= ~ ( 1 << PB0 ); // Set PB0

	DDRB |= ( 1 << SS ); // Set SS output
	DDRB |= ( 1 << MISO ) | ( 1 << MOSI ) | ( 1 << SCK ); // Set MISO, MOSI, SCK output

	DDRD &= ~ ( 1 << PB0 );
	DDRD |= ( 1 << PB1 );
}

void Init_Timer0 ( void ) // Initialize Timer0 function
{
	TCCR0 |= ( ( 1 << CS02 ) | ( 1 << CS00 ) ); // Timer0 CPU/1024
										  
	TIMSK |= ( 1 << TOIE0 ); // Enable Timer0 overflow interrupt
}

void Init_USART ( void ) // Initialize USART function
{
	UBRRL  = 51; // 9600 Baud/s
	UBRRH  = 0; // Register default value

	UCSRC  = ( ( 1 << URSEL ) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 ) );
	UCSRB  = ( ( 1 << RXCIE ) | ( 1 << RXEN ) ); // Enable USART, enable USART interrupt
}

ISR ( USART_RXC_vect ) // USART Rx interrupt function
{
	if ( byte_counter == 0 )
	{
		Data_12 [ 0 ] = UDR;
		Data_12 [ 1 ] = 255;
		byte_counter ++;
	}
	
}

int main ( void )
{
	DDR_Set ( ); // Setup DDR

	Init_SPI ( ); // Initialize SPI

	Init_Timer0 ( ); // Initialize Timer0

	Init_USART ( );

	sei ( ); // enable global interrupt

	while ( 1 )
	{

	}
}

