/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    adc.c
  * @brief   This file provides code for the configuration
  *          of the ADC instances.
  ******************************************************************************
  * @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 "adc.h"

/* USER CODE BEGIN 0 */
float CalculateTemperature(uint16_t adc_value, float vref);
/* USER CODE END 0 */

ADC_HandleTypeDef hadc1;

/* ADC1 init function */
void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = ENABLE;
  hadc1.Init.NbrOfDiscConversion = 1;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 3;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_10;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_11;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_12;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */

  /* USER CODE END ADC1_MspInit 0 */
    /* ADC1 clock enable */
    __HAL_RCC_ADC1_CLK_ENABLE();

    __HAL_RCC_GPIOC_CLK_ENABLE();
    /**ADC1 GPIO Configuration
    PC0     ------> ADC1_IN10
    PC1     ------> ADC1_IN11
    PC2     ------> ADC1_IN12
    */
    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /* USER CODE BEGIN ADC1_MspInit 1 */

  /* USER CODE END ADC1_MspInit 1 */
  }
}

void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{

  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspDeInit 0 */

  /* USER CODE END ADC1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_ADC1_CLK_DISABLE();

    /**ADC1 GPIO Configuration
    PC0     ------> ADC1_IN10
    PC1     ------> ADC1_IN11
    PC2     ------> ADC1_IN12
    */
    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2);

  /* USER CODE BEGIN ADC1_MspDeInit 1 */

  /* USER CODE END ADC1_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */

uint8_t adc1_byte1 = 0;   
uint8_t adc2_byte1 = 0;                      // 定义一个字节变量用于存储转换结果
uint8_t adc3_byte1 = 0;   
uint8_t adc1_byte2 = 0;   
uint8_t adc2_byte2 = 0;                      // 定义一个字节变量用于存储转换结果
uint8_t adc3_byte2 = 0;
uint16_t Value_old_addr2;
uint16_t Value_old_addr3;
uint16_t adc1_filtered = 0;
uint16_t adc2_filtered = 0;
uint16_t adc3_filtered = 0;
uint16_t adc1_raw_buffer[FILTER_LENGTH] = {0};
uint16_t adc2_raw_buffer[FILTER_LENGTH] = {0};
uint16_t adc3_raw_buffer[FILTER_LENGTH] = {0};
uint8_t adc1_raw_buffer_index = 0;
uint8_t adc2_raw_buffer_index = 0;
uint8_t adc3_raw_buffer_index = 0;
uint16_t adc2_rawValue = 0;
uint16_t adc3_rawValue = 0;

void AdcCalibration_init(void)
{
    Value_old_addr2 = read_flash_16(ADDR_FLASH_PAGE_124);
    Value_old_addr3 = read_flash_16(ADDR_FLASH_PAGE_134);
    
    Adc2_CalibrationValue = Value_old_addr2 != 0xFFFF ? Value_old_addr2 : Adc2_CalibrationValue;
    Adc3_CalibrationValue = Value_old_addr3 != 0xFFFF ? Value_old_addr3 : Adc3_CalibrationValue;
    Adc2_CalibrationValue &= 0x7FFF;
    Adc3_CalibrationValue &= 0x7FFF;
}  

void ApplyFilter(uint16_t raw_data, uint16_t* filtered_data, uint16_t* raw_data_buffer, uint8_t* buffer_index)
{
    raw_data_buffer[*buffer_index] = raw_data;
    uint32_t sum = 0;
    for (uint8_t i = 0; i < FILTER_LENGTH; i++) {
        sum += raw_data_buffer[i];
    }
    *filtered_data = (uint16_t)(sum / FILTER_LENGTH);
    *buffer_index = (*buffer_index + 1) % FILTER_LENGTH;	//指向最旧的
}

void GetADCResults(ADC_HandleTypeDef* hadc)
{
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, 100);
    uint16_t adc1_raw = HAL_ADC_GetValue(&hadc1);
    float temperature = CalculateTemperature(adc1_raw, 3.3) * 10 - 40;
    ApplyFilter((uint16_t)temperature, &adc1_filtered, adc1_raw_buffer, &adc1_raw_buffer_index);
    
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, 100);
    uint16_t adc2_raw = HAL_ADC_GetValue(&hadc1);
    adc2_rawValue = adc2_raw;
    if (adc2_raw != 0) {
        adc2_raw += (Value_old_addr2 & 0x8000) ? Adc2_CalibrationValue : -Adc2_CalibrationValue;
    }
    ApplyFilter(adc2_raw, &adc2_filtered, adc2_raw_buffer, &adc2_raw_buffer_index);
    
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, 100);
    uint16_t adc3_raw = HAL_ADC_GetValue(&hadc1);
    adc3_rawValue = adc3_raw;
    if (adc3_raw != 0) {
        adc3_raw += (Value_old_addr3 & 0x8000) ? Adc3_CalibrationValue : -Adc3_CalibrationValue;
    }
    ApplyFilter(adc3_raw, &adc3_filtered, adc3_raw_buffer, &adc3_raw_buffer_index);
    
    adc1_byte1 = (uint8_t)(adc1_filtered >> 8);
    adc1_byte2 = (uint8_t)(adc1_filtered);
    adc2_byte1 = (uint8_t)(adc2_filtered >> 8);
    adc2_byte2 = (uint8_t)(adc2_filtered);
    adc3_byte1 = (uint8_t)(adc3_filtered >> 8);
    adc3_byte2 = (uint8_t)(adc3_filtered);
}


#define R_NOMINAL 10000.0f   // 注册时NTC热敏电阻的阻值
#define T_NOMINAL 298.15f    // 注册时NTC热敏电阻的温度值，转化为开尔文温标
#define B_FACTOR 3950.0f     // NTC热敏电阻的B参数
float CalculateTemperature(uint16_t adc_value, float vref)
{
    float voltage = adc_value * vref / 4095.0f;   // 根据ADC值计算输入电压
    float resistance = R_NOMINAL * (voltage / (vref - voltage));   // 根据电压计算NTC热敏电阻阻值
    float steinhart = log(resistance / R_NOMINAL) / B_FACTOR + 1.0f / T_NOMINAL;   // 根据瑞利恒式计算温度
    return 1.0f / steinhart - 273.15f;   // 转换为摄氏温度并返回
}
/* USER CODE END 1 */
