/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 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 "can.h"
#include "dma.h"
#include "iwdg.h"
#include "rtc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "can_comm.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 */

//--------------CAN PARAMETERS---------

char moduleTest_flag=0,modulueno=0;


//-------------ACTYPE 2 PARAMETERS-----------
uint16_t cp_val=0;
uint32_t adc1_dat[3];
volatile int adc_init=0;
uint8_t CURRENT_STATE=0;


uint8_t count_D=0,count_C=0,count_A=0,count_B=0;
extern volatile uint8_t Emergency_stop;
extern volatile uint8_t adcsmp;
#define ADC_BUFFER_SIZE 4
volatile uint16_t adcValues[ADC_BUFFER_SIZE];
volatile int averaging[4][10],sensor_value[ADC_BUFFER_SIZE];
volatile float tempvolt[ADC_BUFFER_SIZE];
volatile uint8_t tempsen[ADC_BUFFER_SIZE];
uint8_t adccmpl=0,offset= 30,stop_fanpwm=0;
float vt_factor =2.657;
void Read_temp(void);
volatile uint8_t redsts=0,bluests=0,greensts=0,change=0;
extern uint8_t fanstart;
extern volatile char tempchange;
extern uint16_t Dutycycle;
/* USER CODE END PV */

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


//void AC_TYPE2(void);
//void adc_check();
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* 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_TIM1_Init();
  MX_USART1_UART_Init();
  MX_RTC_Init();
  MX_TIM2_Init();
  MX_ADC1_Init();
  MX_ADC2_Init();
  MX_CAN1_Init();
  MX_CAN2_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
  MX_IWDG_Init();
  MX_TIM5_Init();
  /* USER CODE BEGIN 2 */
  ALL_RELAYOFF;
//  start_fan();
  //UNCOMMENT IF CAN RX IT IS REQUIRED //
  if(HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_BUSOFF ) != HAL_OK)
	{
	 Error_Handler();
	}
  if(HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_BUSOFF ) != HAL_OK)
	{
		 Error_Handler();
	}
	can_filterconfig();
	can2_filterconfig();

	HAL_CAN_Start(&hcan1);
	HAL_CAN_Start(&hcan2);
//  HAL_TIM_Base_Start_IT(&htim3);
	HAL_TIM_Base_MspInit(&htim1);
	HAL_TIM_Base_Start_IT(&htim5);
	HAL_TIM_Base_Start_IT(&htim3);
	bluests =1;
	change=1;
#if target == gun1
	start_fan();
#endif
//	fanstart=3;
	HAL_ADC_Start_DMA(&hadc2, (uint32_t*)adcValues, 4);
	HAL_Delay(5000);
	USER_OUT4_ON;		//AC main supply ON //NEGATIVE
//	USER_OUT6_ON;//postive
//  B_LED_ON;	//IN ac supply indication
//  R_LED_OFF;	//RED OFF
//  G_LED_OFF; // GREEN OFF
//  blueledon;
//  greenledoff;
//  redledoff;
//  can_tx_vbmax();
//  can_tx();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
#if imd == syn
	can_tx_reset();
	HAL_Delay(200);
	can_tx_vbmax();
	HAL_Delay(50);
#endif
//	adc_init = 1;
	//moduleTest_flag=1;

//	R_LED_OFF;
//	G_LED_ON;
//	B_LED_OFF;

//	R_LED_ON;
//	G_LED_ON;
//	B_LED_ON;


  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  HAL_IWDG_Refresh(&hiwdg); //uncomment
	  if(tx_can2flag)
	  {
		can2_tx_frame();
		HAL_Delay(10);
		tx_can2flag=0;
	  }
#if imd == syn
	  if(IMD_rstflag)
	  {
		/*
		  can_tx_reset();
		  HAL_Delay(50);
		  can_tx_vbmax();
		  HAL_Delay(50); */
//		  can2_tx_frame();
//		  HAL_Delay(50);
		  IMD_rstflag=0;
	  }
	  else if(IMD_statusupdateflag)
	  {
		  can_tx_Isolation_State();
		  HAL_Delay(50);
		  can_tx_Error_Flag();
		  HAL_Delay(50);
		  IMD_statusupdateflag=0;
	  }
	  else if(IMD_temperflag)
	  {
		  can_tx_temperature();
		  IMD_temperflag=0;
	  }
#endif
if(change==1)
{
	change=0;
	if(redsts ==1)
	{
		HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_3);
		HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_2);
		HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1);
	}
	else if(greensts ==1)
	{
		HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_3);
		HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_1);
		HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_2);
	}
	else if(bluests==1)
	{
		HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_1);
		HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_2);
		HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_3);
	}
}
//if(fanstart==1)
//{
//	start_fan();
//	fanstart=2;
//}
//else if(fanstart ==3)
//{
////	stop_fan();
//	stop_fanpwm=1;
//	fanstart=0;
//}
#if target == gun1
if(tempchange == 1)
{
	tempchange=0;
	if(chrgsts.charging == 1)
	{
		stop_fanpwm=0;
		Dutycycle=0;
	}
	else if(tempsen[0] >= 45)
	{
		stop_fanpwm=0;
		Dutycycle=0;
	}
	else if(tempsen[0] < 45 && (tempsen[0] > 30))
	{
		Dutycycle=(uint16_t)(100-((tempsen[0]-30) / 0.15));
		stop_fanpwm=0;
	}
	else
	{
		Dutycycle=100;
		stop_fanpwm=1;
	}
}
#endif
	  if(adcsmp ==1)
	  {
		  adcsmp=0;
		  Read_temp();
	  }
//	  AC_TYPE2();
//	  if(moduleTest_flag)
//	  {
//		  maxwellTest(modulueno);
//		  moduleTest_flag=0;
//	  }
//	  AC_TYPE2();
  }

  /* 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_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(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 = 6;
  RCC_OscInitStruct.PLL.PLLN = 96;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  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_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = 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)
	{
		stop_pwm();
//		USER_OUT9_OFF;
		RELAY_GUN1_OFF;
		relaysts_ac02sts = ((relaysts_ac02sts & 0xF0) | 0x0C);
//		can2TX_msg[can2TX_relaysts_ac02sts] = relaysts_ac02sts;
		//HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_SET); //OFF
	}
	else if(CURRENT_STATE==STATE_B)
	{
//		scan_rfid = 1;
		if(Authentication_done )
		{
			if(Emergency_stop == 0 && AC02_stop_flag == 0)
			{
				start_pwm();
				HAL_Delay(100);
			}
		}
		else if(Emergency_stop || AC02_stop_flag == 1  ) //tbd
		{
			stop_pwm();
		}
//		USER_OUT9_OFF;
		RELAY_GUN1_OFF;
		relaysts_ac02sts = ((relaysts_ac02sts & 0xF0) | 0x09);
//		can2TX_msg[can2TX_relaysts_ac02sts] = relaysts_ac02sts;
//		HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_SET); //OFF
//		relay_on = 0;
	}
	else if((CURRENT_STATE==STATE_C)||(CURRENT_STATE==STATE_D)) // && (Type2_OCPP_Authorization_Flag == 1))
	{
		if(Authentication_done)
		{
			if(Emergency_stop == 0 && AC02_stop_flag == 0)
			{
				if(Authentication_done )
				{
					RELAY_GUN1_ON;
//					USER_OUT9_ON;
					start_pwm();
				}
			}
			else
			{
				stop_pwm();
//				USER_OUT9_OFF;
				RELAY_GUN1_OFF;
			}
		}
		relaysts_ac02sts = ((relaysts_ac02sts & 0xF0) | 0x06);
//		can2TX_msg[can2TX_relaysts_ac02sts] = relaysts_ac02sts;
	}
	if(Emergency_stop || AC02_stop_flag == 1  )
	{
		RELAY_GUN1_OFF;
//		USER_OUT9_OFF;
		stop_pwm();
	 }
}
void adc_check()
{
	 if(adc_init==0)return;

	  HAL_ADC_Start_DMA(&hadc1,adc1_dat,1);
      cp_val=adc1_dat[0]; //3081
      //	pp_val=adc1_dat[1];

	  if((cp_val<=STATE_A_LEVEL+100)&&(cp_val>=STATE_A_LEVEL-100))
		{
		  count_D = 0;
		  count_B = 0;
		  count_C = 0;
		  if(++count_A > 25)
		  {
			CURRENT_STATE=STATE_A;
			count_A = 0;
		  }
		}
		else if((cp_val<=STATE_B_LEVEL+100)&&(cp_val>=STATE_B_LEVEL-100))
		{
			count_D = 0;
			count_C = 0;
			count_A = 0;
			if(++count_B > 25)
			{
				CURRENT_STATE=STATE_B;
				count_B = 0;
			}
		}
		else if((cp_val<=STATE_C_LEVEL+100)&&(cp_val>=STATE_C_LEVEL-100))
		{
			count_D = 0;
			count_B = 0;
			count_A = 0;
			if(++count_C > 25)
			  {
				CURRENT_STATE=STATE_C;
				count_C = 0;
			  }
		}
		else if((cp_val<=STATE_D_LEVEL+100)&&(cp_val>=STATE_D_LEVEL-100))
		{
			count_C = 0;
			count_B = 0;
			count_A = 0;
			if(++count_D > 25)
			  {
				CURRENT_STATE=STATE_D;
				count_D = 0;
			  }
		}
}
*/
void Read_temp(void)
{
#if defined(debugmode)
	static char buff[100]={0};
	float sensorVal;
	float tempVolta=0,tempseno=0,tempseno1=0,tempseno2=0,tempseno3=0;
#endif

	static int temp;
	static char avgcnt=0,i,j;
	HAL_ADC_Start_DMA(&hadc2, (uint32_t*) adcValues, 4);

	averaging[0][avgcnt]=adcValues[0];
	averaging[1][avgcnt]=adcValues[1];
	averaging[2][avgcnt]=adcValues[2];
//	averaging[3][avgcnt]=adcValues[3];

	avgcnt++;
	if(avgcnt >9)
	{
		avgcnt=0;
		for(i=0;i<10;i++)
		{
			for(j=0;j<i;j++)
			{
				if(averaging[0][j] > averaging[0][j+1])
				{
					temp =averaging[0][j];
					averaging[0][j] =averaging[0][j+1];
					averaging[0][j+1] =temp;
				}
			}
		}

		sensor_value[0]=((averaging[0][4]+averaging[0][5]+averaging[0][6]+averaging[0][7]) /4);
	 	tempvolt[0]=(float)(sensor_value[0]*(3.3/4096));
	 	tempsen[0]=(uint8_t)(((tempvolt[0]*100)/vt_factor)-offset); // CHANGED BY RONAK
	 	can2TX_msg[can2TX_exhaustfan]= (int)tempsen[0];
#if defined(debugmode)
//	tempVolta=tempvolt[0];
	tempseno=tempsen[0];
#endif
for(i=0;i<10;i++)
		{
			for(j=0;j<i;j++)
			{
				if(averaging[1][j] > averaging[1][j+1])
				{
					temp =averaging[1][j];
					averaging[1][j] =averaging[1][j+1];
					averaging[1][j+1] =temp;
				}
			}
		}

		sensor_value[1]=((averaging[1][4]+averaging[1][5]+averaging[1][6]+averaging[1][7]) /4);
		tempvolt[1]=(float)(sensor_value[1]*(3.3/4096));
		tempsen[1]=(uint8_t)(((tempvolt[1]*100)/vt_factor)-offset);
		can2TX_msg[can2TX_dcpostemp]= (int)tempsen[1];
#if defined(debugmode)
		//tempVolta=tempvolt[1];
		tempseno1=tempsen[1];
#endif
		for(i=0;i<10;i++)
		{
			for(j=0;j<i;j++)
			{
				if(averaging[2][j] > averaging[2][j+1])
				{
					temp =averaging[2][j];
					averaging[2][j] =averaging[2][j+1];
					averaging[2][j+1] =temp;
				}
			}
		}

		sensor_value[2]=((averaging[2][4]+averaging[2][5]+averaging[2][6]+averaging[2][7]) /4);
		tempvolt[2]=(float)(sensor_value[2]*(3.3/4096));
		tempsen[2]=(uint8_t)(((tempvolt[2]*100)/vt_factor)-offset);
		can2TX_msg[can2TX_dcnegtemp]= (int)tempsen[2];
#if defined(debugmode)
		//tempVolta=tempvolt[0];
		tempseno2=tempsen[2];


//int lclcnt= sprintf(buff,"ADC count: %u \r\n Volatge Count: %f \r\n temp: %f \r\n ",sensorVal,tempVolta,tempseno);
int lclcnt= sprintf(buff,"temp1: %f \r\n temp2: %f \r\n temp3: %f \r\n",tempseno,tempseno1,tempseno2);
		HAL_UART_Transmit_IT(&huart1, (uint8_t*)&buff,lclcnt);

#endif


//for(i=0;i<10;i++)
//		{
//			for(j=0;j<i-1;j++)
//			{
//				if(averaging[3][j] > averaging[3][j+1])
//				{
//					temp =averaging[3][j];
//					averaging[3][j] =averaging[3][j+1];
//					averaging[3][j+1] =temp;
//				}
//			}
//		}
//
//		sensor_value[3]=((averaging[3][4]+averaging[3][5]+averaging[3][6]+averaging[3][7]) /4);
//		tempvolt[3]=(float)(sensor_value[3]*(3.3/4096));
//		tempsen[3]=(uint8_t)(((tempvolt[3]*100)/vt_factor)-offset);
//	#if defined(debugmode)
//			//tempVolta=tempvolt[2];
//			tempseno3=tempsen[3];
//	#endif

	}


//	adcValues[0] = adcValues[1] =adcValues[2]=adcValues[3]=0;
//while(adccmpl ==0)

adccmpl =0;

}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
  {

//	 HAL_ADC_Start_DMA(&hadc2, (uint32_t*) adcValues, 4);
//	 sensorVal=adcValues[0];
//
//	 	tempvolt[0]=(float)(sensorVal*(3.3/4096));
//	 	tempsen[0]=(float)((tempvolt[0]*100)/vt_factor)+offset;


//		 adcValues[0] = adcValues[1] =adcValues[2]=adcValues[3]=0;
	adccmpl=1;
  }
/* 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 */
