/************************************************************************************************/
/**
* @file               adc_bsp.c
* @author             MCU Ecosystem Development Team
* @brief              ADC BSP驱动函数。
*
*
**************************************************************************************************
* @attention
* Copyright (c) CEC Huada Electronic Design Co.,Ltd. All rights reserved.
*
**************************************************************************************************
*/

/*-------------------------------------------includes-------------------------------------------*/
#include "adc_bsp.h"

/*--------------------------------------------define--------------------------------------------*/
/* ADC采样次数，根据实际需求可调整此值 */
#define ADC_SAMPLE_NUM                      (10U)

/* 校准系数的最值 */
#define CALFACT_MAX                         (31)
#define CALFACT_MIN                         (-31)

/* ADC出厂校准值 */
#define ADC_COMPENSATION_VALUE              (*(int32_t *)(0x1FFF03CC))  

/*-------------------------------------------variables------------------------------------------*/
__IO uint8_t g_adc_complete = 0U;
__IO uint32_t g_sample_channel_4 = 0U;
__IO uint32_t g_sample_channel_VBGR = 0U;

/*-------------------------------------------functions------------------------------------------*/
/**
* @brief  提升ADC校准系数的精度
* @retval 无
*/
void bsp_adc_software_calibrate(void)
{
    int32_t get_calfact = 0;

    /* ADC出厂校准值的相反数作为校准系数 */
    get_calfact = 0 - ADC_COMPENSATION_VALUE;
    
    /* 判断校准系数是否超限 */
    if(get_calfact > CALFACT_MAX)
    {
        get_calfact = CALFACT_MAX;
    }
    else if(get_calfact < CALFACT_MIN)
    {
        get_calfact = CALFACT_MIN;
    }
    std_adc_calibration_factor_config(get_calfact);
}

/**
* @brief  转换ADC通道采样值
* @retval uint32_t 转换结果
*/
uint32_t bsp_adc_get_channel_voltage(void)
{
    uint32_t get_sample_channel_4 = 0;
    uint32_t get_sample_channel_vbgr = 0;
    uint32_t get_channel_4_voltage = 0;
    uint32_t get_cal_voltage = 0;
    
    /* ADC多次采样取平均，提升采样精度 */
    for(uint8_t i = 0; i < ADC_SAMPLE_NUM; i++)
    {
        /* 启动转换 */
        std_adc_start_conversion();
        
        /* 等待ADC通道转换完成 */
        while(g_adc_complete == 0x00U);
         
        g_adc_complete = 0U;
        
        /* 通道4采样值 */
        get_sample_channel_4 += g_sample_channel_4;
        
        /* 内部通道VBGR采样值 */
        get_sample_channel_vbgr += g_sample_channel_VBGR;
    }
    
    /* 计算通道4平均值 */
    get_sample_channel_4 = get_sample_channel_4 / ADC_SAMPLE_NUM; 
    
    /* 计算内部通道VBGR平均值 */
    get_sample_channel_vbgr = get_sample_channel_vbgr / ADC_SAMPLE_NUM; 
    
    /* 校准参考电压 */
    get_cal_voltage = std_adc_calc_vref_voltage(get_sample_channel_vbgr);
    
    /* 计算通道4采样电压 */
    get_channel_4_voltage = get_sample_channel_4 * get_cal_voltage / ADC_CONVER_SCALE;

    return get_channel_4_voltage;
}
