#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

// konstanty pro uart ( seriove rozhrani)
#define F_CPU 8000000UL  // clock speed 8 MHz
#define BAUD 9600
#define ubrr F_CPU/16/BAUD-1

// STATUS CODE (TWI - I2C)
#define KOMUNIKACE_START 0x40

char dataB;
char dataC;
char dataD;
	
void getAndSendData();
void USART_Init( unsigned int baud);
void sendData(uint8_t addresse);
void resetChip();

int main(void)
{
	DDRC =  0b00001111;
	PORTC = 0b00000000;
	sei(); // globalni povooleni preruseni 
	
	TWBR = 0x3C; // ''prescaler' of twi nandes v datashetu
	USART_Init(ubrr);

    while(1)
    {
		//ceka na preruseni od uartu
    }
}

void USART_Init( unsigned int baud)
{
	UBRRH = (unsigned char)(baud>>8);
	UBRRL = (unsigned char)baud;
	/* Enable receiver and transmitter and Receive Interrupt */
	UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
	/* Set frame format: 8data, 1stop */
	UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);
}

void getAndSendData(){
	uint8_t i = 0;

	for(i=1; i<128; i++)
	{
		TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // Posle prikaz start (zacatek komunikace)
		while( !(TWCR & (1<<TWINT)) ); // Ceka dokud neni prikaz start v poradku odeslan
		
		TWDR = (i<<1)|1; // adresa slave zarizeni
		TWCR = (1<<TWINT)|(1<<TWEN); // Odesle obsah registru  TWDR (v tomto pripade obsahuje adresu slave zarizeni(7bitu) osmi byt urcuje zda se jedna o cteni ci zapis(1 - read, 0- write)
		while( !(TWCR & (1<<TWINT)) ); // ceka dokud neni SLA_W odeslan

		if ( (TWSR & 0xF8) == KOMUNIKACE_START ){  // pokud neni zarizeni s danou adresou pripojeno tak se preskoci
			
			TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
			while( !(TWCR & (1<<TWINT)) ); // ceka dokud nedojdou data od slejva
			
				// DATA Z PORTU B
			dataB = TWDR;
			TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
			while( !(TWCR & (1<<TWINT)) ); // ceka dokud nedojdou data od slejva
		
				// DATA Z PORTU C
			dataC = TWDR;
			TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
			while( !(TWCR & (1<<TWINT)) ); // ceka dokud nedojdou data od slejva
	
				//DATA Z PORTU D
			dataD = TWDR;	
			sendData(i);
		}
		
		TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);		
	}
}

void sendData(uint8_t addresse){
	/* Wait for empty transmit buffer */
	while ( !( UCSRA & (1<<UDRE)) );
	UDR = addresse;
	
	while ( !( UCSRA & (1<<UDRE)) );
	UDR = dataB;

	while ( !( UCSRA & (1<<UDRE)) );
	UDR = dataC;

	while ( !( UCSRA & (1<<UDRE)) );
	UDR = dataD;
}

void resetChip(){
	PORTC = 0b00001111;
	_delay_ms(4000);
	PORTC = 0x00;
}

ISR(USART_RXC_vect)
{
	uint8_t a = UDR; // musim precist aby se odstranil priznak preruseni
	getAndSendData();
	resetChip();
}