#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define redport PORTD
#define greenport PORTD
#define blueport PORTB
#define negativeport PORTB
#define OEport PORTB

#define OE PB0
#define red_select PD0
#define green_select PD1
#define blue_select PB1
#define negative_select PB2

unsigned char t=0;

unsigned char red[7];
volatile unsigned char green[7];
unsigned char blue[7];


	void resetSPI(void) // a shift regisztereknek elküldött adat törlése
	{
	PORTD&=~(1<<PD7);
	_delay_us(1);
	PORTD|=(1<<PD7);
	}


	void konfigTIMER(void)	
	{
	TCCR2|=(1<<WGM21);//CTC mód TIMER2
	TIMSK|=(1<<OCIE2);//interrupt bekapcsolása
	OCR2=124; //125-re csordul túl
	TCNT2=0;
	TCCR2|=(1<<CS22);//64-es előosztás, számláló indítása
	}

	void konfigSPI(void)
	{
	SPCR=(1<<MSTR)|(1<<SPE);
	SPSR|=(1<<SPI2X);// 2-es előosztás
	PORTD|=(1<<PD7); // összes shift regiszter engedélyezve
	}

			void red_send(unsigned char red)
			{
			redport&=~(1<<red_select);
			_delay_us(1);
			SPDR=red;
			while(!(SPSR & (1<<SPIF)));
			redport|=(1<<red_select);
			}

			void green_send(unsigned char green)
			{
			greenport&=~(1<<green_select);
			_delay_us(1);
			SPDR=green;
			while(!(SPSR & (1<<SPIF)));
			greenport|=(1<<green_select);
			}

			void blue_send(unsigned char blue)
			{
			blueport&=~(1<<blue_select);
			_delay_us(1);
			SPDR=blue;
			while(!(SPSR & (1<<SPIF)));
			blueport|=(1<<blue_select);
			}

			void negative_send(unsigned char negative)
			{
			negativeport&=~(1<<negative_select);
			_delay_us(1);
			SPDR=negative;
			while(!(SPSR & (1<<SPIF)));
			negativeport|=(1<<negative_select);
			}

//***********************************************************
//***********************************************************

ISR(TIMER2_COMP_vect)
{
OEport|=(1<<OE);
resetSPI();
negative_send(128>>t);//bekapcsoljuk az egyik oszlopot				
red_send(red[t]);// PIROS adat elküldése
green_send(green[t]);
blue_send(blue[t]);
OEport&=~(1<<OE);//kimenetek engedélyezése
t++;
if(t==7) t=0;
}

int main (void)
{
	OEport|=(1<<OE);//letiltjuk a kimeneteket, hogy az előzőleg törölt érték ne jelenjen meg rajtuk
	DDRD=0xFF; //piros és zöld választó kimenet
	DDRB=(1<<blue_select)|(1<<negative_select)|(1<<PB3)|(1<<PB5)|(1<<OE); 
	// MOSI SCK kék és negatív választó kimenet

	konfigSPI();
	konfigTIMER();
	sei();

	while(1)
	{

	for(unsigned char i=0; i<7; i++) //ez a része szépen működik
		{
		green[i]=1; //itt történik az érték átadás
		_delay_ms(200);
		if(i!=6) green[i]=0; //az utolsó oszlop lenullázódik
		}

		while(red[6]<128)
		{
		green[6]=(green[6]<<1);
		_delay_ms(200);
		if(green[6]==128) green[6]=0;
		}

		for(unsigned char j=6; j>0; j--)
		{
		green[(j-1)]=128;
		_delay_ms(200);
		if(j!=1) green[(j-1)]=0;
		}

		while(red[0]>2)
		{
		green[0]=(green[0]>>1);
		_delay_ms(200);
		}


	}

}

