
#include <stdint.h>
#include "flash_save.h"
#include "stm32f10x_flash.h"
#include "eeprom.h"

#include "net.h"
#include "server.h"
#include "my_USART.h"

// Exportovane promenne
extern const uint16_t EEPROM_VirtAdd[3];

extern uint16_t FANtemp[4];
extern uint16_t SHUTDOWNtemp;
extern uint16_t FANval[4];
extern uint8_t AutomatickyRezim;
extern uint8_t my_MAC[MAC_ADR_SIZE];
extern uint8_t my_IP[IP_ADR_SIZE];
extern uint8_t my_MASK[IP_ADR_SIZE];
extern uint8_t my_GATE[IP_ADR_SIZE];
extern uint16_t my_HTTP_Port;
extern uint16_t my_UDP_Port;
extern uint16_t PWM_max[5];
extern uint8_t ServerEnable;

//#define DEBUG
// Globalni promenne

/* ------------------------------------------
 Funkce ulozi 16-bit hodnotu na zvolene misto
 v pameti FLASH. Adresa je index od zacatku 
 vyhrazene pameti pro ulozeni nastaveni
 ----------------------------------------- */
uint8_t FlashSave_Save16(uint16_t adresa, uint16_t hodnota)
{	
	uint8_t Status;
	FLASH_Unlock();								// Odemceni FLASH pameti pro zapis
	Status = EE_WriteVariable(EEPROM_VirtAdd[AddrNastaveni]+adresa,hodnota);
	FLASH_Lock();								// Zamce FLASH pamet pro zapis - nebude fungovat zapis do virtualni EEPROM
	if(Status==0)
	{		
		return(1);
	}		
	else
	{
		return(0);
	}
}

/* ------------------------------------------
 Funkce ulozi 8-bit hodnotu na zvolene misto
 v pameti FLASH do hornich 16-bitu. Adresa je index od zacatku 
 vyhrazene pameti pro ulozeni nastaveni
 ----------------------------------------- */
uint8_t FlashSave_Save8_high(uint16_t adresa, uint8_t hodnota)
{	
	uint16_t puvodni_hodnota;
	uint8_t Status;

	FLASH_Unlock();								// Odemceni FLASH pameti pro zapis
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrNastaveni]+adresa, &puvodni_hodnota)!=0)
	{
		puvodni_hodnota=0x0000;							// Promenna ve FLASH neexistuje
	}
	puvodni_hodnota=(puvodni_hodnota & 0x00FF) | (((uint16_t)hodnota)<<8);
	Status = EE_WriteVariable(EEPROM_VirtAdd[AddrNastaveni]+adresa,puvodni_hodnota);
	FLASH_Lock();								// Zamce FLASH pamet pro zapis - nebude fungovat zapis do virtualni EEPROM
	if(Status==0)
	{		
		return(1);
	}		
	else
	{	
		return(0);
	}
}

/* ------------------------------------------
 Funkce ulozi 8-bit hodnotu na zvolene misto
 v pameti FLASH do dolnich 16-bitu. Adresa je index od zacatku 
 vyhrazene pameti pro ulozeni nastaveni
 ----------------------------------------- */
uint8_t FlashSave_Save8_low(uint16_t adresa, uint8_t hodnota)
{	
	uint16_t puvodni_hodnota;
	uint8_t Status;

	FLASH_Unlock();								// Odemceni FLASH pameti pro zapis
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrNastaveni]+adresa, &puvodni_hodnota)!=0)
	{
		puvodni_hodnota=0x0000;							// Promenna ve FLASH neexistuje
	}
	puvodni_hodnota=(puvodni_hodnota & 0xFF00) | ((uint16_t)hodnota);
	Status = EE_WriteVariable(EEPROM_VirtAdd[AddrNastaveni]+adresa,puvodni_hodnota);
	FLASH_Lock();								// Zamce FLASH pamet pro zapis - nebude fungovat zapis do virtualni EEPROM
	
	if(Status==0)
	{		
		return(1);
	}		
	else
	{	
		return(0);
	}
}

/* ------------------------------------------
 Funkce nacte 16-bit hodnotu ze zvoleneho mista
 v pameti FLASH. Adresa je index od zacatku 
 vyhrazene pameti pro ulozeni nastaveni
 ----------------------------------------- */
uint8_t FlashSave_Load16(uint16_t adresa, uint16_t *hodnota)
{	
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrNastaveni]+adresa, hodnota)!=0)
	{
		return(0);							// Promenna ve FLASH neexistuje
	}
	else
	{		
		return(1);
	}	
}

/* ------------------------------------------
 Funkce nacte hornich 8-bit hodnoty ze 
 zvoleneho mista v pameti FLASH. Adresa je 
 index od zacatku vyhrazene pameti pro ulozeni 
 nastaveni
 ----------------------------------------- */
uint8_t FlashSave_Load8_high(uint16_t adresa, uint8_t *hodnota)
{	
	uint16_t temp;
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrNastaveni]+adresa, &temp)!=0)
	{
		*hodnota=0x00;
		return(0);							// Promenna ve FLASH neexistuje
	}
	else
	{		
		*hodnota=(temp&0xFF00)>>8;
		return(1);
	}	
}

/* ------------------------------------------
 Funkce nacte dolnich 8-bit hodnoty ze 
 zvoleneho mista v pameti FLASH. Adresa je 
 index od zacatku vyhrazene pameti pro ulozeni 
 nastaveni
 ----------------------------------------- */
uint8_t FlashSave_Load8_low(uint16_t adresa, uint8_t *hodnota)
{	
	uint16_t temp;
	if(EE_ReadVariable(EEPROM_VirtAdd[AddrNastaveni]+adresa, &temp)!=0)
	{
		*hodnota=0x00;
		return(0);							// Promenna ve FLASH neexistuje
	}
	else
	{		
		*hodnota=(temp&0x00FF);
		return(1);
	}	
}

/* ------------------------------------------
 Funkce nacte ulozenou konfiguraci do RAM
 ----------------------------------------- */
void FlashSave_LoadConfig(void)
{
	uint8_t i;
	uint16_t hodnota16;
	uint8_t hodnota8;

	FlashSave_Load16(FLASHSAVE_INIT, &hodnota16);
	
	if(hodnota16==0xDCBA)
	{
		for(i=0;i<4;i++)
		{
			if(FlashSave_Load16(FLASHSAVE_FANTEMP_0+i, &hodnota16)==1)
			{
				FANtemp[i] = hodnota16;
			}
			if(FlashSave_Load16(FLASHSAVE_FANVAL_0+i, &hodnota16)==1)
			{
				FANval[i] = hodnota16;
			}
		}
		if(FlashSave_Load16(FLASHSAVE_SHUTDOWNTEMP, &hodnota16)==1)
		{
			if(hodnota16!=0)
			{
				SHUTDOWNtemp = hodnota16;
			}
		}
		if(FlashSave_Load16(FLASHSAVE_LEDREZIM, &hodnota16)==1)
		{
			AutomatickyRezim = hodnota16;
		}
		if(FlashSave_Load16(FLASHSAVE_HTTPPORT, &hodnota16)==1)
		{
			if(hodnota16!=0)
			{
				my_HTTP_Port = hodnota16;
			}
		}
		if(FlashSave_Load16(FLASHSAVE_UDPPORT, &hodnota16)==1)
		{
			if(hodnota16!=0)
			{
				my_UDP_Port = hodnota16;
			}
		}
		for(i=0;i<2;i++)
		{
			if(FlashSave_Load8_high(FLASHSAVE_IP_0_1+i, &hodnota8)==1)
			{
				my_IP[i*2] = hodnota8;
			}
			if(FlashSave_Load8_low(FLASHSAVE_IP_0_1+i, &hodnota8)==1)
			{
				my_IP[(i*2)+1] = hodnota8;
			}
			
			if(FlashSave_Load8_high(FLASHSAVE_MASKA_0_1+i, &hodnota8)==1)
			{
				my_MASK[i*2] = hodnota8;
			}
			if(FlashSave_Load8_low(FLASHSAVE_MASKA_0_1+i, &hodnota8)==1)
			{
				my_MASK[(i*2)+1] = hodnota8;
			}
	
			if(FlashSave_Load8_high(FLASHSAVE_GATE_0_1+i, &hodnota8)==1)
			{
				my_GATE[i*2] = hodnota8;
			}
			if(FlashSave_Load8_low(FLASHSAVE_GATE_0_1+i, &hodnota8)==1)
			{
				my_GATE[(i*2)+1] = hodnota8;
			}
		}
		for(i=0;i<3;i++)
		{
			if(FlashSave_Load8_high(FLASHSAVE_MAC_0_1+i, &hodnota8)==1)
			{
				my_MAC[i*2] = hodnota8;
			}
			if(FlashSave_Load8_low(FLASHSAVE_MAC_0_1+i, &hodnota8)==1)
			{
				my_MAC[(i*2)+1] = hodnota8;
			}
		}
		for(i=0;i<5;i++)
		{
			if(FlashSave_Load16(FLASHSAVE_PWMMAX_1+i, &hodnota16)==1)
			{
				PWM_max[i] = hodnota16;
			}
		}
		if(FlashSave_Load16(FLASHSAVE_SERVERENABLE, &hodnota16)==1)
		{
			ServerEnable = hodnota16;
		}
	}
	else
	{
		#ifdef DEBUG
			USART1_Send("> FLASH nastaveni prazdne", 1);
		#endif
		for(i=0;i<4;i++)
		{
			FlashSave_Save16(FLASHSAVE_FANTEMP_0+i, FANtemp[i]);
			FlashSave_Save16(FLASHSAVE_FANVAL_0+i, FANval[i]);				
		}
		FlashSave_Save16(FLASHSAVE_SHUTDOWNTEMP, SHUTDOWNtemp);
		FlashSave_Save16(FLASHSAVE_LEDREZIM, AutomatickyRezim);
		FlashSave_Save16(FLASHSAVE_HTTPPORT, my_HTTP_Port);
		FlashSave_Save16(FLASHSAVE_UDPPORT, my_UDP_Port);
		for(i=0;i<2;i++)
		{
			FlashSave_Save8_high(FLASHSAVE_IP_0_1+i, my_IP[i*2]);
			FlashSave_Save8_low(FLASHSAVE_IP_0_1+i, my_IP[(i*2)+1]);
			FlashSave_Save8_high(FLASHSAVE_MASKA_0_1+i, my_MASK[i*2]);
			FlashSave_Save8_low(FLASHSAVE_MASKA_0_1+i, my_MASK[(i*2)+1]);
			FlashSave_Save8_high(FLASHSAVE_GATE_0_1+i, my_GATE[i*2]);
			FlashSave_Save8_low(FLASHSAVE_GATE_0_1+i, my_GATE[(i*2)+1]);				
		}
		for(i=0;i<3;i++)
		{
			FlashSave_Save8_high(FLASHSAVE_MAC_0_1+i, my_MAC[i*2]);
			FlashSave_Save8_low(FLASHSAVE_MAC_0_1+i, my_MAC[(i*2)+1]);				
		}
		for(i=0;i<5;i++)
		{
			FlashSave_Save16(FLASHSAVE_PWMMAX_1+i, PWM_max[i]);				
		}
		FlashSave_Save16(FLASHSAVE_SERVERENABLE, ServerEnable);
					
		FlashSave_Save16(FLASHSAVE_INIT, 0xDCBA);
		return;
	}		
}

/* Konec souboru */
