/****************************************************************************
 *
 * Projekt			:	Glacier Batterieboxdeckel Prüfgerät
 * Dateiname		:	AppMain.c
 * Autor			:	orginal MHoffmann, abgeändert für dieses Projekt Irene Saxer
 * Erstellungsdatum	:	17.04.2019
 * Beschreibung		:	"Mainfile des BatterieboxdeckelPGs"
 *
 *
 * Versionsgeschichte
 * 	Revision 1.0  17.04.2019 SAI erste Version
 *
 ****************************************************************************/

/****************************************************************************/
/* COMPILER Direktiven */

/****************************************************************************/
#include "AppMain.h"
#include <avr/interrupt.h>

/****************************************************************************/
/* KONSTANTEN */
uint8_t gudt_case = 2;
uint8_t gudt_schalterstellung = 0;

/****************************************************************************/
/* Globale Variablen */
TAppMainParameter 	gudt_MainPara;

uint8_t gudt_HALLRdy = 0;

EMPTY_INTERRUPT(INT0_vect);
EMPTY_INTERRUPT(INT1_vect);
EMPTY_INTERRUPT(INT2_vect);
//EMPTY_INTERRUPT(PCINT0_vect);	 // --> Interrupt belegt
EMPTY_INTERRUPT(PCINT1_vect);
//EMPTY_INTERRUPT(PCINT2_vect);  // --> Interrupt belegt
EMPTY_INTERRUPT(PCINT3_vect);
EMPTY_INTERRUPT(WDT_vect);
EMPTY_INTERRUPT(TIMER2_COMPA_vect);
EMPTY_INTERRUPT(TIMER2_COMPB_vect);
EMPTY_INTERRUPT(TIMER2_OVF_vect);
EMPTY_INTERRUPT(TIMER1_CAPT_vect);
EMPTY_INTERRUPT(TIMER1_COMPA_vect);
EMPTY_INTERRUPT(TIMER1_COMPB_vect);
EMPTY_INTERRUPT(TIMER0_COMPA_vect);
EMPTY_INTERRUPT(TIMER0_COMPB_vect);
EMPTY_INTERRUPT(SPI_STC_vect);
EMPTY_INTERRUPT(USART0_UDRE_vect);
EMPTY_INTERRUPT(USART0_TX_vect);
EMPTY_INTERRUPT(USART1_RX_vect);
EMPTY_INTERRUPT(USART1_UDRE_vect);
EMPTY_INTERRUPT(USART1_TX_vect);
EMPTY_INTERRUPT(ANALOG_COMP_vect);
//EMPTY_INTERRUPT(ADC_vect);
EMPTY_INTERRUPT(EE_READY_vect);
EMPTY_INTERRUPT(TWI_vect);
EMPTY_INTERRUPT(SPM_READY_vect);

/****************************************************************************/
/* Funktionen */

static int16_t	AppMain_ShowWelcomeScreen(void);

void AppMain_HardwareInit(void)
/*============================================================================
 *
 *  Funktion:		AppMain_HardwareInit
 *  Ü-Parameter:	-
 *  R-Parameter:	-
 *  Beschreibung:	Initialisierung des gesamten ATmega
 *
 *==========================================================================*/
{
	PRR = 0;			//saemtliche PowerReduceFlags loeschen

	DrvTim_Init();		//Initialisierung der Timer
	DrvGpio_Init();		//Initialisierung aller GPIOs
	DrvUart_Init();		//Initialisierung der seriellen Schnittstellen
	DrvEep_Init();		//ext. EEPROM initialisieren
	DrvRtc_Init();		//ext. RTC initialisieren
}

void AppMain_SoftwareInit()
/*============================================================================
 *
 *  Funktion:		AppMain_SoftwareInit
 *  Ü-Parameter:	-
 *  R-Parameter:	-
 *  Beschreibung:	Initialisierung der Softwaremodule
 *
 *==========================================================================*/
{	
	ObjLcd_Init();					//LCD initialisieren
	AppMonitor_Init();				//Initialisierung des Monitors
	ObjSample_Init();				//Messobjekt initialisieren (muss nach LCD_Init() gerufen werden, da fuer die Kalibrierung das LCD gebraucht wird
	gudt_MainPara.u16_SyncHandlerTimer = DrvTim_StartTimer();	//Timer fuer Synchandler initialisieren
	gudt_MainPara.u8_Flags = 0;		//Logging initialisieren
	AppMain_ShowWelcomeScreen();	//Versionsinfo anzeigen
//	ObjLcd_ShowAction(0);			//Hinweis zur Kalibrierung
	AppMain_DevRdy();
}

int16_t AppMain_DrvHandler()
/*============================================================================
 *
 *  Funktion:		APPMAINdrvhandler
 *  Ü-Parameter:	-
 *  R-Parameter:	Fehlercode
 *  Beschreibung:	Handler aller Treibermodule
 *
 *==========================================================================*/
{
	int16_t int_Ergebnis = ERROR_NOERROR;

	//Behandlung der Treiberaufrufe
	int_Ergebnis |= DrvUart_Transmit(&gudt_MoniIntf);	//UEbertragen der Daten des Monitorsendepuffers
	int_Ergebnis |= DrvGpio_Handler();

	//Auswertung von int_Ergebnis
	if (int_Ergebnis < ERROR_NOERROR)
	{
		DrvUart_Puts(&gudt_MoniIntf, ANSI_VT100_TEXT_ROT);
		DrvUart_Puts(&gudt_MoniIntf, "err [drv] \0");
		DrvUart_Putint(&gudt_MoniIntf, int_Ergebnis);
		DrvUart_Puts(&gudt_MoniIntf, ANSI_VT100_TEXT_SCHWARZ);
		DrvUart_Newline(&gudt_MoniIntf);
	}

	return int_Ergebnis;
}

int16_t AppMain_ObjHandler()
/*============================================================================
 *
 *  Funktion:		APPMAINobjhandler
 *  Ü-Parameter:	-
 *  R-Parameter:	Fehlercode
 *  Beschreibung:	Handler aller Treibermodule
 *
 *==========================================================================*/
{
	int16_t int_Ergebnis = ERROR_NOERROR;

	// Behandlung der Objektaufrufe
	int_Ergebnis |= ObjSample_HallRead();
	//int_Ergebnis |= ObjSample_Handler();
	int_Ergebnis |= ObjLcd_Handler();
	
	// Auswertung von int_Ergebnis
	if (int_Ergebnis < ERROR_NOERROR)
	{
		DrvUart_Puts(&gudt_MoniIntf, ANSI_VT100_TEXT_ROT);
		DrvUart_Puts(&gudt_MoniIntf, "err [obj] \0");
		DrvUart_Putint(&gudt_MoniIntf, int_Ergebnis);
		DrvUart_Puts(&gudt_MoniIntf, ANSI_VT100_TEXT_SCHWARZ);
		DrvUart_Newline(&gudt_MoniIntf);
	}

	return int_Ergebnis;
}

int16_t AppMain_AppHandler()
/*============================================================================
 *
 *  Funktion:		APPMAINapphandler
 *  Ü-Parameter:	-
 *  R-Parameter:	Fehlercode
 *  Beschreibung:	Handler aller Treibermodule
 *
 *==========================================================================*/
{
	int16_t int_Ergebnis = ERROR_NOERROR;

	// Behandlung der Applikationsmodule
	int_Ergebnis |= AppMonitor_Handler();

	// Auswertung von int_Ergebnis
	if (int_Ergebnis < ERROR_NOERROR)
	{
		DrvUart_Puts(&gudt_MoniIntf, ANSI_VT100_TEXT_ROT);
		DrvUart_Puts(&gudt_MoniIntf, "err [app] \0");
		DrvUart_Putint(&gudt_MoniIntf, int_Ergebnis);
		DrvUart_Puts(&gudt_MoniIntf, ANSI_VT100_TEXT_SCHWARZ);
		DrvUart_Newline(&gudt_MoniIntf);
	}

	return int_Ergebnis;
}

//Anzeige Begrüssungstext auf LCD mit Versionsinfo
static int16_t	AppMain_ShowWelcomeScreen()
{
	uint16_t TS;
	
	//Text mit Versionsnummer ausgeben
	ObjLcd_ClearDispBuf();
	ObjLcd_SetBufPos(0,0);
	ObjLcd_Puts("Magnetfeldmessgerät");
	ObjLcd_SetBufPos(1,0);
	ObjLcd_Puts("v");
	ObjLcd_PutBuf('0'+gudt_SoftwareVersion.u16_SoftwareVersionMajor%10);
	ObjLcd_PutBuf('.');
	ObjLcd_PutBuf('0'+gudt_SoftwareVersion.u16_SoftwareVersionMinor%10);	
	ObjLcd_Puts("   Aquis Systems");

	TS = DrvTim_StartTimer();
	
	while(DrvTim_ReadTimer(TS) < 3000)
		ObjLcd_Handler();
	
	ObjLcd_ClearDispBuf();

	return ERROR_NOERROR;
}

int16_t	AppMain_DevRdy()
/*============================================================================
 *
 *  Funktion:		AppMain_DevRdy
 *  Ü-Parameter:	-
 *  R-Parameter:	-
 *  Beschreibung:	Anzeige Messgerät Startbereit für 3 Sekunden nach Init
 *
 *==========================================================================*/
{
	uint16_t TS;
	
	//Text mit Versionsnummer ausgeben
	ObjLcd_ClearDispBuf();
	ObjLcd_SetBufPos(0,2);
	ObjLcd_Puts("Testgerät bereit");

	TS = DrvTim_StartTimer();
	
	while(DrvTim_ReadTimer(TS) < 3000)
		ObjLcd_Handler();
	
	ObjLcd_ClearDispBuf();

	return ERROR_NOERROR;
}


void AppMain_RS232Com(void)
/*============================================================================
 *
 *  Funktion:		AppMain_RS232Com
 *  Ü-Parameter:	-
 *  R-Parameter:	-
 *  Beschreibung:	Prüft ob an der RS232 Schnittstelle etwas angeschlossen ist
 *					und führt die entsprechenden Handler zur PC-Kommunikation aus
 *
 *==========================================================================*/
{
	int16_t i16_measVal = 0;
	
	// Richtigen ADC Kanal auswählen
	DrvAdc_Select(ADC_U_RS232);
	i16_measVal = DrvAdc_Read();
	
	while (i16_measVal == 1023)
	{
		i16_measVal = DrvAdc_Read();
		
		//Treiberbehandlung
		AppMain_DrvHandler();
		
		// Applikationsschicht
		AppMain_AppHandler();
		
	}
}
int main(void)
/*============================================================================
 *
 *  Funktion:		main
 *  Ü-Parameter:	-
 *  R-Parameter:	-
 *  Beschreibung:	Main des Magnetfeldmessgeräts: Initialisierung und Hauptschleife
 *
 *==========================================================================*/
{
	uint16_t	u16_Time = 0;
	uint16_t	u16_measval;
	uint8_t		u8_Tmp = 0;
	int16_t		i16_measValDM = 0;
	int16_t		i16_measValS = 0;
	int16_t		i16_offsetHall = 0;

	//Interrupts global deaktivieren
	cli();

	//disable Watchdog
	WDR();
	WDTCSR &= ~(WDIE);
	MCUSR  &= ~(1<<WDRF);
	WDTCSR |=  (1<<WDCE) | (WDE);
	WDTCSR  =  0x00;

	//INT-Vektoren fuer Programm ohne Bootloader definieren
	
	u8_Tmp = MCUCR;
	u8_Tmp &= 0xfb;
	MCUCR |= (1<<IVCE);
	MCUCR = u8_Tmp;

		//Hardware initialisieren (Treiber)
	AppMain_HardwareInit();

	//INTerrupts freischalten, vor Softwareinit, damit der SW-Timer benutzt werden kann
	sei();

	//Software initialisieren (Objekte, Applikation)
	AppMain_SoftwareInit();

	//Endlosschleife
	u16_Time = DrvTim_StartTimer();

	for(;;)
	{
		
		switch (gudt_case)
		{
			case 0:
				//Treiberbehandlung
				AppMain_DrvHandler();
				
				//Objektbehandlung
				//AppMain_ObjHandler();
				
				//Applikationsschicht
				AppMain_AppHandler();
				
				
				//AppMain_RS232Com();
				gudt_case = 2;
				break;
			// Kalibrierung des ADCs
			case 1:
				ObjSample_calib();
				gudt_case = 2;
				break;
			
			// Messung Offset Hall-Sensor
			case 2:

				AdcExt_Init();
				u16_measval = AdcExt_Read();
			
				i16_offsetHall = ObjSample_GetHallOffset();
				gudt_case = 3;
				break;
			
			// Messung Magnetfeld Dauermagnet
			case 3:
				i16_measValDM = ObjSample_HallRead(DAUERMAGNET, i16_offsetHall);
				if (gudt_ObjSmplIntf.udt_TD.u8_ResultDM == 0);
				{
					gudt_case = 4;
				}
				break;
			
			// Messung Magnetfeld Zylinderspule
			case 4:
				i16_measValS = ObjSample_HallRead(SPULE);
				gudt_case = 2;
				break;
				
		}

	}


	return 0;
}
// Interrupt Service Routine für Kalibration
ISR(PCINT0_vect)
{
	gudt_case = 1;
}
// Interrupt Service Routine für Spulenmessung
ISR(PCINT2_vect)
{
	gudt_case = 4;
}
