

#include "main.h"
#include "stm32h7xx_hal.h"
#include "string.h"




UART_HandleTypeDef huart2;
TIM_HandleTypeDef htimer2;
uint32_t Input_captures[2] = {0};
uint8_t Count = 1;
uint8_t Is_Capture_Done = FALSE;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
void GPIO_Init(void);
void TIMER2_Init(void);
void LSE_Config(void);
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);


char *data = "Hello world, I made it using STM32 ARM Cortex M7!\r\n";



int main(void)
{

  HAL_Init();
  GPIO_Init();
  MX_USART2_UART_Init();

  MX_GPIO_Init();





	uint8_t Charreceived;
	uint8_t Data_Buffer[100];
	uint32_t count = 0;
	uint8_t Capture_Difference = 0;
	double Timer2_CNT_Freq = 0;
	double Timer2_CNT_Res = 0;
	double User_signal_time_period = 0;
	double User_signal_Freq = 0;
	char User_msg[100];

	data = "Start of program\r\n";
 	if (HAL_UART_Transmit(&huart2,(uint8_t*)data,strlen(data), HAL_MAX_DELAY) != HAL_OK)
 	{
 		// Error occurred
 		Error_Handler();
 	}

 	SystemClock_Config();
 	TIMER2_Init();
 	LSE_Config();



	while(1)
	{
		if(Is_Capture_Done)
		{
			if (Input_captures[1] > Input_captures[0])
				Capture_Difference = Input_captures[1] - Input_captures[0];
			else
				Capture_Difference = (0xFFFFFFFF - Input_captures[0]) + Input_captures[1];

		Timer2_CNT_Freq = ((HAL_RCC_GetPCLK1Freq()) / htimer2.Init.Prescaler);
		Timer2_CNT_Res = 1 / Timer2_CNT_Freq;
		User_signal_time_period = Capture_Difference * Timer2_CNT_Res;
		User_signal_Freq = 1 /User_signal_time_period;
		}
		sprintf(User_msg, "Frequency of the signal applied = %f\r\n", User_signal_Freq);
		HAL_UART_Transmit(&huart2, User_msg, strlen(User_msg), HAL_MAX_DELAY);

		Is_Capture_Done = FALSE;
		//}

		data = "---------LOOP\r\n";
		//HAL_UART_Transmit(&huart2,(uint8_t*)data,strlen(data), HAL_MAX_DELAY);
	}



	data = "End of program\r\n";
	HAL_UART_Transmit(&huart2,(uint8_t*)data,strlen(data), HAL_MAX_DELAY);
}

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

  /** Supply configuration update enable
  */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  //RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
		data = "------------> 1\r\n";
		HAL_UART_Transmit(&huart2,(uint8_t*)data,strlen(data), HAL_MAX_DELAY);
    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_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
		data = "------------> 2\r\n";
		HAL_UART_Transmit(&huart2,(uint8_t*)data,strlen(data), HAL_MAX_DELAY);
    Error_Handler();
  }
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART2;
  PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
		data = "------------> 3\r\n";
		HAL_UART_Transmit(&huart2,(uint8_t*)data,strlen(data), HAL_MAX_DELAY);
    Error_Handler();
  }
}

/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

}


void GPIO_Init(void)
{
	__HAL_RCC_GPIOD_CLK_ENABLE();
	GPIO_InitTypeDef ledgpio;
	ledgpio.Pin = GPIO_PIN_14;
	ledgpio.Mode = GPIO_MODE_OUTPUT_PP;
	ledgpio.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOD, &ledgpio);
}
/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
	data = "Something went wrong\r\n";
	HAL_UART_Transmit(&huart2,(uint8_t*)data,strlen(data), HAL_MAX_DELAY);
	while(1)
	{
		HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
	}
}

void LSE_Config(void)
{
#if 0
	RCC_OscInitTypeDef OSC_Init;

	// Activating LSE
	OSC_Init.OscillatorType = RCC_OSCILLATORTYPE_LSE;
	OSC_Init.LSEState = RCC_LSE_ON;
	if (HAL_RCC_OscConfig(&OSC_Init) != HAL_OK)
	{
		Error_Handler();
	}
#endif

	// Configuring LSE to input pin
	HAL_RCC_MCOConfig(RCC_MCO1,RCC_MCO1SOURCE_LSE,RCC_MCODIV_1);
}


void TIMER2_Init(void)
{
	TIM_IC_InitTypeDef timer2_IC_Config;

	// Initializing Timer
	htimer2.Instance = TIM2;
	htimer2.Init.CounterMode = TIM_COUNTERMODE_UP;
	htimer2.Init.Period = 0xFFFFFFFF;
	htimer2.Init.Prescaler = 0x1;
	if (HAL_TIM_IC_Init(&htimer2) != HAL_OK)
	{
		data = "------------> 4\r\n";
		HAL_UART_Transmit(&huart2,(uint8_t*)data,strlen(data), HAL_MAX_DELAY);
		Error_Handler();
	}

	// Configuring input channel
	timer2_IC_Config.ICFilter = 0;
	timer2_IC_Config.ICPolarity = TIM_ICPOLARITY_RISING;
	timer2_IC_Config.ICSelection = TIM_ICSELECTION_DIRECTTI;
	timer2_IC_Config.ICPrescaler = TIM_ICPSC_DIV1;

	if (HAL_TIM_IC_ConfigChannel(&htimer2, &timer2_IC_Config, TIM_CHANNEL_1) != HAL_OK)
	{
		data = "------------> 5\r\n";
		HAL_UART_Transmit(&huart2,(uint8_t*)data,strlen(data), HAL_MAX_DELAY);
		Error_Handler();
	}
}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	data = "((((((((((((((((((((((((((((((((\r\n";
	//HAL_UART_Transmit(&huart2,(uint8_t*)data,strlen(data), HAL_MAX_DELAY);
	if(!Is_Capture_Done)
	{
		data = "*********************************\r\n";
		//HAL_UART_Transmit(&huart2,(uint8_t*)data,strlen(data), HAL_MAX_DELAY);
		if (Count == 1)
		{
			Input_captures[0] = __HAL_TIM_GET_COMPARE(htim, TIM_CHANNEL_1);
			Count++;
		}
		else if (Count == 2)
		{
			Input_captures[1] = __HAL_TIM_GET_COMPARE(htim, TIM_CHANNEL_1);
			Is_Capture_Done = TRUE;
			Count = 1;
		}
	}
}

#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,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
