#include "sr_adc.h"

//#include "sr_log.h"



#ifndef SR_USE_ADC1
#define SR_USE_ADC1
#endif

static BSP_ADC_INFO_T _adcInfo[] =
{
#ifdef SR_USE_ADC1
	{
		.name = "adc1",
		.srId = SR_ADC1,
		.instance = ADC,
	},
#endif

};

static SR_ADC_DEV_T gs_adcDevice[sizeof(_adcInfo) / sizeof(BSP_ADC_INFO_T)] = {0};



static void AdcRccConfiguration(void)
{
    /* Enable peripheral clocks ------------------------------------------------*/

    /* Enable GPIOC clocks */
    //RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
    /* Enable ADC clocks */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC, ENABLE);

    /* RCC_ADCHCLK_DIV16*/
    ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB, RCC_ADCHCLK_DIV16);
    RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSI, RCC_ADC1MCLK_DIV8);//selsect HSE as RCC ADC1M CLK Source		
}
static void GPIO_Configuration(void)
{
    GPIO_InitType GPIO_InitStructure;

	RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);

    GPIO_InitStruct(&GPIO_InitStructure);
    /* Configure  as analog input -------------------------*/
    GPIO_InitStructure.Pin       = GPIO_PIN_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Analog;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
}

static void ADC_Initial(void)
{
    uint32_t u32MaxDelay = 0;
    ADC_InitType ADC_InitStructure;
    /* ADC configuration ------------------------------------------------------*/
    ADC_InitStructure.MultiChEn      = DISABLE;
    ADC_InitStructure.ContinueConvEn = DISABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIGCONV_NONE;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = 1;
    ADC_Init(ADC, &ADC_InitStructure);
    /* Enable ADC */
    ADC_Enable(ADC, ENABLE);
    /* Check ADC Ready */
    while(ADC_GetFlagStatusNew(ADC,ADC_FLAG_RDY) == RESET)
    {
        u32MaxDelay++;
        if(u32MaxDelay % 50 == 0) //lida add code
        {
            //Bsp_Iwdg_Feed();//喂狗<<
        }
        if(u32MaxDelay > 100000)
        {
            u32MaxDelay  = 0;
            break;      //等待超时退出等待发送标志
        }
    }
    u32MaxDelay  = 0;
    /* Start ADC1 calibration */
    ADC_StartCalibration(ADC);
    /* Check the end of ADC1 calibration */
    while (ADC_GetCalibrationStatus(ADC))
    {
        u32MaxDelay++;
        if(u32MaxDelay % 50 == 0) //
        {
            //Bsp_Iwdg_Feed();//喂狗<<
        }
        if(u32MaxDelay > 100000)
        {
            u32MaxDelay  = 0;
            break;      //等待超时退出等待发送标志
        }        
    }
}
SR_DEVICE_T *BspAdcOpen(SR_ADC_ID_E adcId)
{
	uint8_t i,devicenNum = sizeof(_adcInfo) / sizeof(BSP_ADC_INFO_T);
	int ret = -1;
	 
	SR_ADC_DEV_T *adcDev = SR_NULL;

	// 从数组中查找adcId指定的设备
	for (i = 0; i < devicenNum; i++)
	{
		if (adcId == _adcInfo[i].srId)
		{
			adcDev = &gs_adcDevice[i];

			adcDev->parent.deviceData = &_adcInfo[i]; // 绑定设备数据

			break;
		}
	}

	if (!adcDev) return SR_NULL; // 没有该设备，返回

	//国民ADC初始化
	/*时钟初始化*/
	AdcRccConfiguration();	

	GPIO_Configuration();
	ADC_Initial();

	return  &adcDev->parent;
	//return (ret == 0) ? &adcDev->parent : SR_NULL;
}

int BspAdcClose(SR_DEVICE_T *dev)
{
	int ret = -1;

	if (!dev || !dev->deviceData) return SR_NOEXIST;
	BSP_ADC_INFO_T *adcInfo = (BSP_ADC_INFO_T *)dev->deviceData;

    ADC_DeInit(adcInfo->instance);
	ADC_Enable(adcInfo->instance, DISABLE);
	RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC, DISABLE); //关闭ADC时钟
	
    //GPIO关闭：暂不处理
 
	ret =0;

	return (ret == 0) ? SR_OK : SR_FAIL;
}


static uint16_t Get_Adc(ADC_Module *ADCx,uint8_t ADC_Channel)     //检测电池电压
{
    uint16_t u16Data;
    uint32_t u32MaxDelay = 0;

	//通道设置
    ADC_EnableTempSensorVrefint(ENABLE);
    ADC_ConfigRegularChannel(ADCx, ADC_Channel, 1, ADC_SAMP_TIME_55CYCLES5);

	//启动转换
    /* Start ADC Software Conversion */
    ADC_EnableSoftwareStartConv(ADCx,ENABLE);
    while(ADC_GetFlagStatus(ADCx,ADC_FLAG_ENDC)==0){
        u32MaxDelay++;
        if(u32MaxDelay % 50 == 0) //lida add code
        {
           // Bsp_Iwdg_Feed();//喂狗<<
        }
        if(u32MaxDelay > 100000)
        {
            break;      //等待超时退出等待发送标志
        }
    }
    ADC_ClearFlag(ADCx,ADC_FLAG_ENDC);
    ADC_ClearFlag(ADCx,ADC_FLAG_STR);

	//获取转换后的数据
    u16Data=ADC_GetDat(ADCx);

    return u16Data;
}
int BspAdcRead(SR_DEVICE_T *dev, uint8_t chn, int *valRaw,int *valCvt)
{
	int ret = -1;
	uint8_t i=0;
	uint16_t raw;
	uint32_t cvt,rawSum=0,cvtSum=0;
	uint32_t ADC_Vrefint;

	if (!dev || !dev->deviceData || chn!=0) return SR_INVALID;
	

	BSP_ADC_INFO_T *adcInfo = (BSP_ADC_INFO_T *)dev->deviceData;


	for(i=0;i<2;i++)                  //采集多次取平均值
    {
        ADC_Vrefint=Get_Adc(adcInfo->instance,ADC_CH_VREFINT);  //数字量程？
        /*获取电量ADC采样值*/
        raw=Get_Adc(adcInfo->instance,chn);      //原始数字量
        cvt=((BSP_ANALOG_VOLT_RANGE*raw)/ADC_Vrefint);      //数模转换。12位分辨率，靠右对齐>>12 3000/4096
        cvtSum=cvtSum+cvt;
		rawSum+=raw;
    } 

	//求平均
	*valCvt = cvtSum/2;
	*valRaw = rawSum/2;

	return  SR_OK;
}

#if 0
int BspAdcReadCvt(SR_DEVICE_T *dev, uint8_t chn, int *volt)
{
	int valRaw=0;
	return BspAdcRead(dev,chn, &valRaw,volt);
}

int BspAdcReadRaw(SR_DEVICE_T *dev, uint8_t chn, int *raw)
{
	int valCvt=0;
	return BspAdcRead(dev,chn, raw,&valCvt);
}
#endif


int BspAdcChnEnable(SR_DEVICE_T *dev, uint32_t chn,uint8_t isEnable)
{
	
	//合宙ADC没有chn概念
	return SR_OPT_DENIED;
}