/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "iwdg.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ext_fun.h"
#include "ext_var.h"

#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
union
{
	unsigned short int word;
	uint32_t dword;
	float dfloat;
	unsigned char byte[4];
}split_int;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void UART_Printf(const char* fmt, ...)
{
    char buff[256];
    va_list args;
    va_start(args, fmt);
    vsnprintf(buff, sizeof(buff), fmt, args);
    HAL_UART_Transmit(&huart1, (uint8_t*)buff, strlen(buff),500);
    va_end(args);
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_TIM3_Init();
  MX_USART1_UART_Init();
  MX_IWDG_Init();
  MX_TIM6_Init();
  MX_TIM7_Init();
  /* USER CODE BEGIN 2 */

	Read_Params();
	HAL_Delay(10);
	if(configparameters.magic_value != 0xAA66)
	{
		Read_Params();
	}
	HAL_Delay(10);

	if(configparameters.magic_value != 0xAA66)
	{
		Read_Params();
	}
	HAL_Delay(10);

	if(configparameters.magic_value != 0xAA66)
	{
		configparameters =default_params;
		Write_Params();
		HAL_Delay(10);
		Read_Params();

	}



	HAL_TIM_Base_MspInit(&htim3);
	HAL_TIM_Base_Start_IT(&htim3);
//	HAL_UART_Receive_DMA(&huart1,id,14);
	HAL_UART_Receive_DMA(&huart1,&rxchar,1);
	HAL_ADC_Start_DMA(&hadc1,(uint32_t*)adc1_dat,2);

	stop_pwm();
	adc_init_2=1;
	adc_init=1;
	powerONflag=1;
	powerONflag1=1;
//	ui8fivesectimeout=1;
#if defined(uarten)
	TxbuffIndex=sprintf(Txbuff,"device ON\r\n");
	HAL_UART_Transmit(&huart1, (uint8_t*)Txbuff,TxbuffIndex,0Xffff);
#endif
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		HAL_IWDG_Refresh(&hiwdg);
//	  LED1B_ON;
	  if(ui8fivesectimeout == 1)
	  {
			AC_TYPE2();
			AC_TYPE2_1();
	  }
	  else if(configmode == 1)
	  {
		  configuraitonmode();
	  }

  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 8;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
void AC_TYPE2(void )
{
	if(CURRENT_STATE==STATE_A)
	{
		GUN1RELAY_OFF;
		powerONflag=1;
		if(GUN1.chargingStart==1)
		{
			stop_pwm();
		}
		pwm_start_stop = 0;
		GUN1.chargingStop=0;
		GUN1.chargingStart=0;
		GUN1.Authentication_done=0;

	}
	else if(CURRENT_STATE==STATE_B)
	{
		if((Emergency_stop == 0 && GFD_stop == 0 && powerONflag == 1 && GUN1.chargingStop == 0 && user1_stop ==0)  &&( (GUN1.Authentication_done ==1 ) || configparameters.RFIDBypassEn == 1))
		{
			if(pwm_start_stop != 1)
			{
			start_pwm();
			GUN1.chargingStart=1;
			}

		}
		else
		{
			stop_pwm();
			GUN1.chargingStop = 1;
		}
		GUN1RELAY_OFF;
	}
	else if(CURRENT_STATE==STATE_C)
	{
		powerONflag=0;
		GUN1.Authentication_done=0;
		if(Emergency_stop==0 && GFD_stop == 0 && GUN1.chargingStop == 0 && GUN1.chargingStart == 1 && user1_stop == 0)
		{
			GUN1RELAY_ON;
		}
	}
	if(Emergency_stop==1 || GUN1.chargingStop == 1 || GFD_stop == 1 || user1_stop == 1)
	{
		GUN1RELAY_OFF;
		powerONflag=0;
		GUN1.chargingStart=0;
	}
}
void AC_TYPE2_1()
{

	if(CURRENT_STATE_1==STATE_A)
		{
			GUN2RELAY_OFF;
			powerONflag1=1;
			if(GUN2.chargingStart==1)
			{
				stop_pwm_1();
			}
			GUN2.chargingStop=0;
			GUN2.chargingStart=0;
			GUN2.Authentication_done=0;
		}
		else if(CURRENT_STATE_1==STATE_B)
		{
			if((Emergency_stop == 0 && GFD_stop == 0 && powerONflag1 == 1 && GUN2.chargingStop == 0 && user2_stop ==0 )  &&( (GUN2.Authentication_done ==1 ) || configparameters.RFIDBypassEn == 1))
				{
					if(pwm_start_stop_1 != 1)
					{
					start_pwm_1();
					GUN2.chargingStart=1;
					}

				}
			else
			{
				stop_pwm_1();
				GUN2.chargingStop = 1;
			}
			GUN2RELAY_OFF;
		}
		else if(CURRENT_STATE_1==STATE_C)
		{
			powerONflag1=0;
			if(Emergency_stop==0 && GFD_stop == 0 && GUN2.chargingStop == 0 && GUN2.chargingStart == 1 && user2_stop ==0)
			{
				GUN2RELAY_ON;
			}
		}
		if(Emergency_stop==1 || GUN2.chargingStop == 1 || GFD_stop == 1 || user2_stop ==1)
		{
			GUN2RELAY_OFF;
			powerONflag1=0;
			GUN2.chargingStart=0;
		}

}


void adc_check()
{


	  if(adc_init==0)return;

		HAL_ADC_Start_DMA(&hadc1,(uint32_t*)adc1_dat,2);
		cp_val=adc1_dat[0];
		 cp_val_2=adc1_dat[1];

		//cp_val=adc1_dat[1];
	/*if(cp_val < 1100)
	 {
		adc_error++;
		if(adc_error>10)
		{
			 NVIC_SystemReset();
			//__HAL_TIM_ENABLE(&htim1);
		}
	 }
	 else
	 {
		 adc_error=0;
	 }*/

	if(cp_val < 1000)
	{
		countdisturbance++;
		if(countdisturbance > 20)
		{
			countdisturbance=0;
		}
	}

	else if((cp_val<=configparameters.STATE_A_LEVEL+100)&&(cp_val>=configparameters.STATE_A_LEVEL-100))
		{
		  count_B = 0;
		  count_C = 0;
		  if(++count_A > 10)
		  {
			CURRENT_STATE=STATE_A;
			count_A = 0;
		  }
		}
	else if((cp_val<=configparameters.STATE_B_LEVEL+100)&&(cp_val>=configparameters.STATE_B_LEVEL-100))
		{

			count_C = 0;
			count_A = 0;
			if(++count_B > 10)
			{
				CURRENT_STATE=STATE_B;
				count_B = 0;
			}
		}
		else if((cp_val<=configparameters.STATE_C_LEVEL+100)&&(cp_val>=configparameters.STATE_C_LEVEL-100))
		{

			count_B = 0;
			count_A = 0;
			if(++count_C > 10)
			  {
					CURRENT_STATE=STATE_C;
					count_C = 0;
			  }
		}

	 /////////

	if(cp_val_2 < 1000)
	{

	}
	else if((cp_val_2<=configparameters.STATE_A_LEVEL+100)&&(cp_val_2>=configparameters.STATE_A_LEVEL-100))
	 		{
	 		  count_D_2 = 0;
	 		  count_B_2 = 0;
	 		  count_C_2 = 0;
	 		  if(++count_A_2 > 10)
	 		  {
	 			  CURRENT_STATE_1=STATE_A;
	 			  count_A_2 = 0;
	 		  }
	 		}
	 		else if((cp_val_2<=configparameters.STATE_B_LEVEL+80)&&(cp_val_2>=configparameters.STATE_B_LEVEL-80))
	 		{
	 			count_D_2 = 0;
	 			count_C_2 = 0;
	 			count_A_2 = 0;
	 			if(++count_B_2 > 10)
	 			{
	 				CURRENT_STATE_1=STATE_B;
	 				count_B_2 = 0;
	 			}
	 		}
	 		else if((cp_val_2<=configparameters.STATE_C_LEVEL+80)&&(cp_val_2>=configparameters.STATE_C_LEVEL-80))
	 		{
	 			count_D_2 = 0;
	 			count_B_2 = 0;
	 			count_A_2 = 0;
	 			if(++count_C_2 > 10)
	 			  {
	 				CURRENT_STATE_1=STATE_C;
	 				count_C_2 = 0;
	 			  }
	 		}
	 		else if((cp_val_2<=configparameters.STATE_D_LEVEL+80)&&(cp_val_2>=configparameters.STATE_D_LEVEL-80))
	 		{
	 			count_C_2 = 0;
	 			count_B_2 = 0;
	 			count_A_2 = 0;
	 			if(++count_D_2 > 10)
	 			  {
	 				CURRENT_STATE_1=STATE_D;
	 				count_D_2 = 0;
	 			  }
	 		}

	 	//adc1_dat[0] = adc1_dat[1] = 0;
}

void adc_check_2(void)
{
	 if(adc_init_2==0)return;

	  HAL_ADC_Start_DMA(&hadc1,adc1_dat,1);
	  cp_val_2=adc1_dat[1];

	  if((cp_val_2<=configparameters.STATE_A_LEVEL+100)&&(cp_val_2>=configparameters.STATE_A_LEVEL-100))
		{
		  count_D_2 = 0;
		  count_B_2 = 0;
		  count_C_2 = 0;
		  if(++count_A_2 > 10)
		  {
			  CURRENT_STATE_1=STATE_A;
			  count_A_2 = 0;
		  }
		}
		else if((cp_val_2<=configparameters.STATE_B_LEVEL+80)&&(cp_val_2>=configparameters.STATE_B_LEVEL-80))
		{
			count_D_2 = 0;
			count_C_2 = 0;
			count_A_2 = 0;
			if(++count_B_2 > 10)
			{
				CURRENT_STATE_1=STATE_B;
				count_B_2 = 0;
			}
		}
		else if((cp_val_2<=configparameters.STATE_C_LEVEL+80)&&(cp_val_2>=configparameters.STATE_C_LEVEL-80))
		{
			count_D_2 = 0;
			count_B_2 = 0;
			count_A_2 = 0;
			if(++count_C_2 > 10)
			  {
				CURRENT_STATE_1=STATE_C;
				count_C_2 = 0;
			  }
		}
		else if((cp_val_2<=configparameters.STATE_D_LEVEL+80)&&(cp_val_2>=configparameters.STATE_D_LEVEL-80))
		{
			count_C_2 = 0;
			count_B_2 = 0;
			count_A_2 = 0;
			if(++count_D_2 > 10)
			  {
				CURRENT_STATE_1=STATE_D;
				count_D_2 = 0;
			  }
		}
}


void configuraitonmode(void)
{
	volatile uint16_t temp_cp_val=0,temp_stage=0,temp_val_1=0;
	memset((unsigned char*)Txbuff,'\0',sizeof(Txbuff));
	if(cmdrxd==1)
	{	TxbuffIndex=0;

		if(rxbuff[1]== configmodeEn)
		{
			TxbuffIndex=sprintf(Txbuff,"config mode enabled\r\n");
		}
		else if(rxbuff[1]==GFDconf)
		{
			if(rxbuff[2]=='1')	//enable GFD
			{
				configparameters.GFDBypassEn =1;
				TxbuffIndex=sprintf(Txbuff,"GFD detection enabled\r\n");
			}
			else if(rxbuff[2]=='2')	//disable GFD
			{
				configparameters.GFDBypassEn =0;
				TxbuffIndex=sprintf(Txbuff,"GFD detection disabled\r\n");
			}
			else
			{
				 TxbuffIndex=sprintf(Txbuff,"Invalid command\r\n");
			}
		}
		else if(rxbuff[1]==AddRFIDgun1)	//add RFID gun1
		{
			configparameters.gun1TagId[0]=rxbuff[2];
			configparameters.gun1TagId[1]=rxbuff[3];
			configparameters.gun1TagId[2]=rxbuff[4];
			configparameters.gun1TagId[3]=rxbuff[5];
			configparameters.gun1TagId[4]=rxbuff[6];
			configparameters.gun1TagId[5]=rxbuff[7];
			configparameters.gun1TagId[6]=rxbuff[8];
			configparameters.gun1TagId[7]=rxbuff[9];
			configparameters.gun1TagId[8]=rxbuff[10];
			configparameters.gun1TagId[9]=rxbuff[11];
			configparameters.gun1TagId[10]=rxbuff[12];
			configparameters.gun1TagId[11]=rxbuff[13];
			configparameters.gun1TagId[12]='\0';
			 TxbuffIndex=sprintf(Txbuff,"Added RFID GUN1: %s \r\n",configparameters.gun1TagId);

		}
		else if(rxbuff[1]==AddRFIDgun2)	//add RFID gun2
		{
			configparameters.gun2TagId[0]=rxbuff[2];
			configparameters.gun2TagId[1]=rxbuff[3];
			configparameters.gun2TagId[2]=rxbuff[4];
			configparameters.gun2TagId[3]=rxbuff[5];
			configparameters.gun2TagId[4]=rxbuff[6];
			configparameters.gun2TagId[5]=rxbuff[7];
			configparameters.gun2TagId[6]=rxbuff[8];
			configparameters.gun2TagId[7]=rxbuff[9];
			configparameters.gun2TagId[8]=rxbuff[10];
			configparameters.gun2TagId[9]=rxbuff[11];
			configparameters.gun2TagId[10]=rxbuff[12];
			configparameters.gun2TagId[11]=rxbuff[13];
			configparameters.gun2TagId[12]='\0';
			 TxbuffIndex=sprintf(Txbuff,"Added RFID GUN2: %s \r\n",configparameters.gun2TagId);
		}
		else if(rxbuff[1]==removeReadRFIDgun1)
		{
			if(rxbuff[2]=='1')	//remove RFID gun1
			{
				 memset(configparameters.gun1TagId,'\0',sizeof(configparameters.gun1TagId));
				 TxbuffIndex=sprintf(Txbuff,"Removed RFID GUN1: %s \r\n",configparameters.gun1TagId);
			}
			else if(rxbuff[2]=='2') //read RFID gun1
			{
				 Read_Params();
				 TxbuffIndex=sprintf(Txbuff,"RFID GUN1: %s \r\n",configparameters.gun1TagId);

			}
			else
			{
				 TxbuffIndex=sprintf(Txbuff,"Invalid command\r\n");
			}
		}
		else if(rxbuff[1]==removeReadRFIDgun2)
		{
			if(rxbuff[2]=='1')	// Remove RFID gun2
			{
				 memset(configparameters.gun2TagId,'\0',sizeof(configparameters.gun2TagId));
				 TxbuffIndex=sprintf(Txbuff,"Removed RFID GUN2: %s \r\n",configparameters.gun2TagId);
			}
			else if(rxbuff[2]=='2')	//	read RFID gun2
			{
				 Read_Params();
				 TxbuffIndex=sprintf(Txbuff,"RFID GUN2: %s \r\n",configparameters.gun2TagId);
			}
			else
			{
				 TxbuffIndex=sprintf(Txbuff,"Invalid command\r\n");
			}
		}
		else if(rxbuff[1]==bypassRFIDen)
		{
			if(rxbuff[2]=='1')	//byPass RFID enabled
			{
				configparameters.RFIDBypassEn=1;
				 TxbuffIndex=sprintf(Txbuff,"RFID detection disabled\r\n");
			}
			else if(rxbuff[2]=='2')	//byPass RFID disabled
			{
				configparameters.RFIDBypassEn=0;
				 TxbuffIndex=sprintf(Txbuff,"RFID detection enabled\r\n");
			}
			else
			{
				 TxbuffIndex=sprintf(Txbuff,"Invalid command\r\n");
			}
		}
		else if(rxbuff[1]==readCPcnt)
		{
			if(rxbuff[2]=='1')	//Read CP count
			{
				temp_cp_val=cp_val;
				temp_val_1=cp_val_2;
				TxbuffIndex=sprintf(Txbuff,"gun1 Cp count: %d , gun2 cp count: %d ",temp_cp_val, temp_val_1);
			}
			else if(rxbuff[2]=='2')	//Read Stages count
			{
				TxbuffIndex=sprintf(Txbuff,"Stages A: %d,B : %d ,C : %d ,D : %d \r\n",configparameters.STATE_A_LEVEL,configparameters.STATE_B_LEVEL,configparameters.STATE_C_LEVEL,configparameters.STATE_D_LEVEL);

			}
			else
			{
				TxbuffIndex=sprintf(Txbuff,"Invalid command\r\n");
			}
		}
		else if(rxbuff[1]==setcnt)
		{
			if(rxbuff[2]=='1')	//set count for stage A
			{
				configparameters.STATE_A_LEVEL=atoi(&rxbuff[3]);
				TxbuffIndex=sprintf(Txbuff,"Stage A count updated\r\n");
			}
			else if(rxbuff[2]=='2')	//set count for stage B
			{
				configparameters.STATE_B_LEVEL=atoi(&rxbuff[3]);
				TxbuffIndex=sprintf(Txbuff,"Stage B count updated\r\n");
			}
			else if(rxbuff[2]=='3')	//set count for stage C
			{
				configparameters.STATE_C_LEVEL=atoi(&rxbuff[3]);
				TxbuffIndex=sprintf(Txbuff,"Stage C count updated\r\n");
			}
			else if(rxbuff[2]=='4')	//set count for stage D
			{
				configparameters.STATE_D_LEVEL=atoi(&rxbuff[3]);
				TxbuffIndex=sprintf(Txbuff,"Stage D count updated\r\n");
			}
			else
			{
				TxbuffIndex=sprintf(Txbuff,"Invalid command\r\n");
			}
		}
		else
		{
			 TxbuffIndex=sprintf(Txbuff,"Invalid command\r\n");
		}

		   HAL_UART_Transmit(&huart1, (uint8_t*)Txbuff,TxbuffIndex,0Xffff);

		   Write_Params();
		cmdrxd=0;
	}
}

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
