#include <avr/io.h>
#define f_cpu 8000000
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "mydefs.h"
#include "serial.h"
#include "lcd.h"
#include "crc.h"


char buffer[2];
unsigned char ebus_buffer[20];    /* buffer for the received message */
volatile unsigned int ebus_pos=0;        /* index counter for the receive buffer */
volatile unsigned int c;        /* received character from the uart */
volatile unsigned int ebus_control;
volatile unsigned int zustand;
volatile unsigned char Folge_Bytes; 
unsigned char DATA_TABLE[5][15] = {
{SLAVE_ADRESSE,0x07,0x04,0x01,0x00}, // Identanfrage von einem Master
{MASTER_ADRESSE,0xFE,0x07,0x04,0x0A,0xC5,0x53,0x6F,0x6C,0x41,0x6E,0x10,0x10,0x10,0x10}, // Sendet am Start die eigene Identnummer
{0x00,0x0A,0xC5,0x53,0x6F,0x6C,0x41,0x6E,0x10,0x10,0x10,0x10}, //  Sendet auf Anforderung die eigene Identnummer
{MASTER_ADRESSE,WRSOL_SLAVE,0x09,0x00,0x03,0x88,0xF4,0x02}, // aus der WRSol die Temp für Speicher unten auslesen
{MASTER_ADRESSE,WRSOL_SLAVE,0x07,0x04,0x01,0x00} // Fordert die WRSOL auf sich zu Identifizieren
}; 


/* unsigned char analyse_ident(void)
{
unsigned char l=0;
unsigned char pos=ebus_pos-2 ; // -2 weil Qelladresse und CRC Byte der Funktion crc_analyse geprüft wird
if (crc_analyse()==ENABLE) l++;
for (unsigned char i=1; i <= pos; i++){
if (ebus_buffer[i]==DATA_TABLE[0][i-1]) l++;} 
if (l==6) return 1;
else return 0;
} */


unsigned char analyse_data(unsigned char DATA, unsigned char DATA_SIZE) //wertet das Telegramm aus und prüft die CRC
{
unsigned char l=0;
if (crc_analyse()==ENABLE) l++;
for (unsigned char i=1; i < DATA_SIZE; i++){
if (ebus_buffer[i]==DATA_TABLE[DATA][i-1]) l++;} 
if (l==DATA_SIZE+1) return 1;
else return 0;
}

void daten_senden(unsigned char DATA, unsigned char DATA_SIZE) // Sendet die Daten aus der DATA_TABLE, berechnet die CRC und sendet diese
{
UCSRB &= ~(1<<RXEN); // Muss ich hier machen um nicht die gesendeten Daten wieder zu empfangen
for (unsigned char i=0; i < DATA_SIZE ; i++){
ser_putc(DATA_TABLE[DATA][i]);}
UCSRB |= (1<<RXEN); // Empfang wieder aktivieren
ser_putc(crc_calculation_to_send(DATA, DATA_SIZE));
ebus_pos=0;
}

void data_push(void) // Schiebt den ebus_buffer und die Telegrammlänge in die richtige Reihenfolge 
{
unsigned int i;
for (i=0; i<(sizeof(ebus_buffer))-2; i++)
{
ebus_buffer[i]=ebus_buffer[i+2];
}
ebus_pos=ebus_pos-3;
}


void init(void)
{
DDRC = 0xFF;
// PORTC |= RX_ENABLE;
lcd_init();
lcd_clear();
lcd_home();
lcd_write_str("eBus Auswertung");
ser_init();
sei(); 
ebus_pos=0;
zustand=SYSTEM_START;
ebus_control |= START;
}


int main(void)
{

init();

  for(;;)
  {
switch(zustand)
{

case REC_DATA: // Hier werden die normalen Telegramme aufgezeichnet
		 c = ser_getc();        
//          if (c==0) PORTC |= (1<<2);
		{
        if ((!(c==SYN))||(c==0x00)) { ebus_buffer[ebus_pos] = c; if (!(ebus_pos>39)) ebus_pos++; ebus_control &= ~READY_TO_SEND;}  
        else if (c==SYN) {ebus_pos=0; PORTC ^= (1<<0); ebus_control |= READY_TO_SEND;}
  }
		if (ebus_pos>=1) {PORTC |= (1<<1);} 
        else PORTC &= ~(1<<1) ;
		
        if (ebus_pos==5) Folge_Bytes = ebus_buffer[4];
	
 		if (ebus_pos==Folge_Bytes+6) zustand=ANALYSE_DATA;

	// 	if (ebus_control==READY_TO_SEND) zustand=SEND_DATA;
        break;

case ANALYSE_DATA: // Hier werden die normalen Telegramme ausgewertet
        if (analyse_data(ident_string, 5)) { daten_senden(identifikation_anforderung, 12);}
        zustand=REC_DATA;
// lcd_goto(1,5);
// lcd_write_str(itoa(Folge_Bytes,buffer,10));
// lcd_goto(2,1);
// lcd_write_str(itoa(ebus_buffer[6],buffer,10));
		 break;
case SEND_DATA: break;

case SYSTEM_START: // Systemstart, Senden der Ident 
do { c=ser_getc();}while(c!=SYN);
daten_senden(identifikation, 15);
do { c=ser_getc();}while(c!=SYN);
do { c=ser_getc();}while(c!=SYN);
daten_senden(4,6);
// ebus_pos=0;
// lcd_goto(2,1);
// lcd_write_str(itoa(crc_calculation_to_send(3,8),buffer,10));
//  lcd_goto(2,5);
// lcd_write_str(itoa(ebus_pos,buffer,10));
zustand=READ_DATA;
break;

case READ_DATA: // Hier ist das PROBLEM, HIER WERDEN DIE VON ATMEGA GESENDETE BYTE NOCH MAL EMPFANGEN, UND DER BUFFER FÜLLT SICH FALSCH
c = ser_getc();        
		{
		if ((!(c==SYN))) { ebus_buffer[ebus_pos] = c; if (!(ebus_pos>39)) ebus_pos++;}  
        else if ((c==SYN)) { } // data_push(); zustand=ANALYSE_READ_DATA;/* ebus_control |= ERROR_TO_READ_DATA;*/}

        }
     if (ebus_pos==5) Folge_Bytes = ebus_buffer[3];
  if (ebus_pos==(Folge_Bytes+6)) {data_push(); zustand=ANALYSE_READ_DATA;} //data_push() schiebt den ebus_buffer ich richtige POSITION  
// else zustand=REC_DATA;
break;


case ANALYSE_READ_DATA: // Hier kommt die Auswertung der Angeforderten Daten
lcd_goto(2,1);
 lcd_write_str(itoa(Folge_Bytes,buffer,10)); lcd_goto(2,6); lcd_write_str(itoa(ebus_pos,buffer,10));
switch (ebus_control)
{
case START: //Hier wird später überprüft ob die WRSol im eBUS arbeitet 
// if ((ebus_buffer[1]==0x00)&&(ebus_buffer[2]==0x0A)&&(ebus_buffer[3]==0x10)) lcd_write_str("Erfolgreich");
break;
} 
zustand=REC_DATA;
break;

}

} 
}

