#include "control.h"
ProjectSettings_TypeDef PROJSET;
uint32_t PageError = 0x00;
	uint8_t UpdateSettings = 0;

void WriteSettingsToMem(void)
{
	FillStructWithDefines();
	//HAL_FLASH_Unlock();
	//
	//CheckSettingsInFLASH();
	//
	//if(CheckIsSettingsValid(&PROJSET)) 	// if new settings are invalid
	//	PROJSET = *PROJSET_MEM;						// take the old settings from mem
	//else											 					// if new settings are valid
	//	SetFlagUpdateSettingsInMem();			// save the new settings in mem (set flag to do this)
	//	
	//HAL_FLASH_Lock();
		
}

void SetFlagUpdateSettingsInMem(void)
{				
	//UpdateSettings = 0;
	//// MODBUS settings
	//if(PROJSET_MEM->MB_DEVICE_ID != PROJSET.MB_DEVICE_ID)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->MB_SPEED != PROJSET.MB_SPEED)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->MB_GPIOX != PROJSET.MB_GPIOX)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->MB_GPIO_PIN_RX != PROJSET.MB_GPIO_PIN_RX)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->MB_GPIO_PIN_RX != PROJSET.MB_GPIO_PIN_RX)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->MB_MAX_TIMEOUT != PROJSET.MB_MAX_TIMEOUT)	
	//	UpdateSettings = 1;
	//
	//// PWM settings
	//if(PROJSET_MEM->TIM_PWM_TICKBASE != PROJSET.TIM_PWM_TICKBASE)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM_AHB_FREQ != PROJSET.TIM_PWM_AHB_FREQ)
	//	UpdateSettings = 1;
	//
	//if(PROJSET_MEM->TIM_PWM1_TIM_CHANNEL1 != PROJSET.TIM_PWM1_TIM_CHANNEL1)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM1_TIM_CHANNEL2 != PROJSET.TIM_PWM1_TIM_CHANNEL2)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM1_GPIOx != PROJSET.TIM_PWM1_GPIOx)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM1_GPIO_PIN_X1 != PROJSET.TIM_PWM1_GPIO_PIN_X1)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM1_GPIO_PIN_X2 != PROJSET.TIM_PWM1_GPIO_PIN_X2)
	//	UpdateSettings = 1;
	//
	//if(PROJSET_MEM->TIM_PWM2_INSTANCE != PROJSET.TIM_PWM2_INSTANCE)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM2_TIM_CHANNEL1 != PROJSET.TIM_PWM2_TIM_CHANNEL1)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM2_TIM_CHANNEL2 != PROJSET.TIM_PWM2_TIM_CHANNEL2)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM2_GPIOx != PROJSET.TIM_PWM2_GPIOx)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM2_GPIO_PIN_X1 != PROJSET.TIM_PWM2_GPIO_PIN_X1)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM2_GPIO_PIN_X2 != PROJSET.TIM_PWM2_GPIO_PIN_X2)
	//	UpdateSettings = 1;
	//
	//if(PROJSET_MEM->TIM_PWM3_INSTANCE != PROJSET.TIM_PWM3_INSTANCE)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM3_TIM_CHANNEL1 != PROJSET.TIM_PWM3_TIM_CHANNEL1)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM3_TIM_CHANNEL2 != PROJSET.TIM_PWM3_TIM_CHANNEL2)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM3_GPIOx != PROJSET.TIM_PWM3_GPIOx)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM3_GPIO_PIN_X1 != PROJSET.TIM_PWM3_GPIO_PIN_X1)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_PWM3_GPIO_PIN_X2 != PROJSET.TIM_PWM3_GPIO_PIN_X2)
	//	UpdateSettings = 1;
	//	
	//// CTRL settings		
	//if(PROJSET_MEM->TIM_CTRL_TICKBASE != PROJSET.TIM_CTRL_TICKBASE)
	//	UpdateSettings = 1;
	//if(PROJSET_MEM->TIM_CTRL_AHB_FREQ != PROJSET.TIM_CTRL_AHB_FREQ)
	//	UpdateSettings = 1;
}


void UpdateSettingsInMem(void)
{	
	//if(UpdateSettings)
	//{
	//	FLASH_EraseInitTypeDef EraseInitStruct;
	//	PageError = 0x00;
	//	
	//	EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;// erase pages
	//	EraseInitStruct.Banks = FLASH_BANK_1;
	//	EraseInitStruct.Sector = FLASH_SECTOR_4;   //first sector for erase
	//	EraseInitStruct.NbSectors = 1;// num of sector that need to be erased
	//		
	//	HAL_FLASH_Unlock();
	//	HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);	
	//		
	//	
	//	/* Wait for last operation to be completed */
	//	if(FLASH_WaitForLastOperation((uint32_t)50000U) == HAL_OK)
	//	{
	//		/* If the previous operation is completed, proceed to program the new data */
	//		CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
	//		FLASH->CR |= FLASH_PSIZE_WORD;
	//		FLASH->CR |= FLASH_CR_PG;
	//		*PROJSET_MEM = PROJSET;						// save the new settings in mem
	//	}
	//	HAL_FLASH_Lock();
	//	UpdateSettings = 0;
	//}
}

void FillSettingsWithDefines(void)
{
	// rewrite all setting corresponding to defines
		
	//FLASH_EraseInitTypeDef EraseInitStruct;
	//PageError = 0x00;
	//	
	//EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;// erase pages
	//EraseInitStruct.Banks = FLASH_BANK_1;
	//EraseInitStruct.Sector = FLASH_SECTOR_4;   //first sector for erase
	//EraseInitStruct.NbSectors = 1;// num of sector that need to be erased
	//	
	//HAL_FLASH_Unlock();
	//HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);		
	//// MODBUS settings
	//FLASH_WRITE_SETTING(PROJSET_MEM->MB_DEVICE_ID, 					MODBUS_DEVICE_ID);
	//FLASH_WRITE_SETTING(PROJSET_MEM->MB_SPEED, 							MODBUS_SPEED);
	//FLASH_WRITE_SETTING(PROJSET_MEM->MB_GPIOX, 							(uint32_t)MODBUS_GPIOX);
	//FLASH_WRITE_SETTING(PROJSET_MEM->MB_GPIO_PIN_RX, 				MODBUS_GPIO_PIN_RX);
	//FLASH_WRITE_SETTING(PROJSET_MEM->MB_GPIO_PIN_TX, 				MODBUS_GPIO_PIN_TX);
	//FLASH_WRITE_SETTING(PROJSET_MEM->MB_MAX_TIMEOUT, 				MODBUS_MAX_TIMEOUT);	
	//FLASH_WRITE_SETTING(PROJSET_MEM->MB_TIM_AHB_FREQ, 			MODBUS_TIM_AHB_FREQ);	
	//	
	//// PWM settings
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM_TICKBASE, 			TIMER_PWM_TICKBASE);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM_AHB_FREQ, 			TIMER_PWM_AHB_FREQ);
	//	
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM1_TIM_CHANNEL1, TIMER_PWM1_TIM_CHANNEL1);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM1_TIM_CHANNEL2, TIMER_PWM1_TIM_CHANNEL2);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM1_GPIOx, 				(uint32_t)TIMER_PWM1_GPIOx);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM1_GPIO_PIN_X1, 	TIMER_PWM1_GPIO_PIN_X1);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM1_GPIO_PIN_X2, 	TIMER_PWM1_GPIO_PIN_X2);
	//	
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM2_INSTANCE, 		(uint32_t)TIMER_PWM2_INSTANCE);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM2_TIM_CHANNEL1, TIMER_PWM2_TIM_CHANNEL1);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM2_TIM_CHANNEL2, TIMER_PWM2_TIM_CHANNEL2);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM2_GPIOx, 				(uint32_t)TIMER_PWM2_GPIOx);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM2_GPIO_PIN_X1, 	TIMER_PWM2_GPIO_PIN_X1);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM2_GPIO_PIN_X2, 	TIMER_PWM2_GPIO_PIN_X2);
	//	
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM3_INSTANCE, 		(uint32_t)TIMER_PWM3_INSTANCE);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM3_TIM_CHANNEL1, TIMER_PWM3_TIM_CHANNEL1);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM3_TIM_CHANNEL2, TIMER_PWM3_TIM_CHANNEL2);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM3_GPIOx, 				(uint32_t)TIMER_PWM3_GPIOx);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM3_GPIO_PIN_X1, 	TIMER_PWM3_GPIO_PIN_X1);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM3_GPIO_PIN_X2, 	TIMER_PWM3_GPIO_PIN_X2);
	//
	//// CTRL settings		
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_CTRL_TICKBASE, 			TIMER_CTRL_TICKBASE);
	//FLASH_WRITE_SETTING(PROJSET_MEM->TIM_CTRL_AHB_FREQ, 			TIMER_CTRL_AHB_FREQ);
	//HAL_FLASH_Lock();
		
}

void FillStructWithDefines(void)
{
	// rewrite all setting corresponding to defines

	
	// MODBUS settings
	STRUCT_WRITE_SETTING(PROJSET.MB_DEVICE_ID, 					MODBUS_DEVICE_ID);
	STRUCT_WRITE_SETTING(PROJSET.MB_SPEED, 							MODBUS_SPEED);
	STRUCT_WRITE_SETTING(PROJSET.MB_GPIOX, 							MODBUS_GPIOX);
	STRUCT_WRITE_SETTING(PROJSET.MB_GPIO_PIN_RX, 				MODBUS_GPIO_PIN_RX);
	STRUCT_WRITE_SETTING(PROJSET.MB_GPIO_PIN_TX, 				MODBUS_GPIO_PIN_TX);
	STRUCT_WRITE_SETTING(PROJSET.MB_MAX_TIMEOUT, 				MODBUS_MAX_TIMEOUT);	
	STRUCT_WRITE_SETTING(PROJSET.MB_TIM_AHB_FREQ, 			MODBUS_TIM_AHB_FREQ);	
		
	// PWM settings
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM_TICKBASE, 			TIMER_PWM_TICKBASE);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM_AHB_FREQ, 			TIMER_PWM_AHB_FREQ);
		
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM1_TIM_CHANNEL1, TIMER_PWM1_TIM_CHANNEL1);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM1_TIM_CHANNEL2, TIMER_PWM1_TIM_CHANNEL2);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM1_GPIOx, 				TIMER_PWM1_GPIOx);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM1_GPIO_PIN_X1, 	TIMER_PWM1_GPIO_PIN_X1);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM1_GPIO_PIN_X2, 	TIMER_PWM1_GPIO_PIN_X2);
		
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM2_INSTANCE, 		TIMER_PWM2_INSTANCE);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM2_TIM_CHANNEL1, TIMER_PWM2_TIM_CHANNEL1);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM2_TIM_CHANNEL2, TIMER_PWM2_TIM_CHANNEL2);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM2_GPIOx, 				TIMER_PWM2_GPIOx);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM2_GPIO_PIN_X1, 	TIMER_PWM2_GPIO_PIN_X1);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM2_GPIO_PIN_X2, 	TIMER_PWM2_GPIO_PIN_X2);
		
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM3_INSTANCE, 		TIMER_PWM3_INSTANCE);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM3_TIM_CHANNEL1, TIMER_PWM3_TIM_CHANNEL1);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM3_TIM_CHANNEL2, TIMER_PWM3_TIM_CHANNEL2);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM3_GPIOx, 				TIMER_PWM3_GPIOx);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM3_GPIO_PIN_X1, 	TIMER_PWM3_GPIO_PIN_X1);
	STRUCT_WRITE_SETTING(PROJSET.TIM_PWM3_GPIO_PIN_X2, 	TIMER_PWM3_GPIO_PIN_X2);
	
	// CTRL settings		
	STRUCT_WRITE_SETTING(PROJSET.TIM_CTRL_TICKBASE, 			TIMER_CTRL_TICKBASE);
	STRUCT_WRITE_SETTING(PROJSET.TIM_CTRL_AHB_FREQ, 			TIMER_CTRL_AHB_FREQ);

}
void CheckSettingsInFLASH(void)
{
	//if(CheckIsSettingsValid(PROJSET_MEM))
	//	FillSettingsWithDefines();
	//
	//PROJSET = *PROJSET_MEM;
}
int CheckIsSettingsValid(ProjectSettings_TypeDef *set_struct)
{
	// if some of setting are missing
	// chech MODBUS
	if((!IS_UART_BAUDRATE(set_struct->MB_SPEED) || (set_struct->MB_SPEED ) == 0)	||
	(!IS_GPIO_ALL_INSTANCE((GPIO_TypeDef *)set_struct->MB_GPIOX))									||
	(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->MB_GPIO_PIN_TX))										||
	(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->MB_GPIO_PIN_RX))	||
	((set_struct->MB_TIM_AHB_FREQ) == 0))
	{
		return 1;
	}
	// chech control tim
	if((set_struct->TIM_CTRL_AHB_FREQ) == 0)
	{
		return 1;
	}
	// chech PWM tims
	if((set_struct->TIM_PWM_AHB_FREQ) == 0															||
	(!IS_GPIO_ALL_INSTANCE((GPIO_TypeDef *)set_struct->TIM_PWM1_GPIOx))	||
	(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->TIM_PWM1_GPIO_PIN_X1))		||
	(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->TIM_PWM1_GPIO_PIN_X2))		||
	(!IS_TIM_CHANNELS(set_struct->TIM_PWM1_TIM_CHANNEL1))		||
	(!IS_TIM_CHANNELS(set_struct->TIM_PWM1_TIM_CHANNEL2))		||
	(!IS_TIM_INSTANCE((TIM_TypeDef *)set_struct->TIM_PWM2_INSTANCE))		||
	(!IS_GPIO_ALL_INSTANCE((GPIO_TypeDef *)set_struct->TIM_PWM2_GPIOx)) ||
	(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->TIM_PWM2_GPIO_PIN_X1))		||
	(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->TIM_PWM2_GPIO_PIN_X2))		||
	(!IS_TIM_CHANNELS(set_struct->TIM_PWM2_TIM_CHANNEL1))		||
	(!IS_TIM_CHANNELS(set_struct->TIM_PWM2_TIM_CHANNEL2))	||
	(!IS_TIM_INSTANCE((TIM_TypeDef *)set_struct->TIM_PWM3_INSTANCE))		||
	(!IS_GPIO_ALL_INSTANCE((GPIO_TypeDef *)set_struct->TIM_PWM3_GPIOx))	||
	(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->TIM_PWM3_GPIO_PIN_X1))		||
	(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->TIM_PWM3_GPIO_PIN_X2))		||
	(!IS_TIM_CHANNELS(set_struct->TIM_PWM3_TIM_CHANNEL1))		||
	(!IS_TIM_CHANNELS(set_struct->TIM_PWM3_TIM_CHANNEL2)))
	{
		return 1;
	}
	
	return 0;
}