
/******************************************************************************
*@file  : app.c
*@brief : application
******************************************************************************/

#include "app.h" 

#define ADC_NUM    (14)
uint32_t gadcBuffer[ADC_NUM];                 

#define ADCX    (ADC1)


/******************************************************************************
* @brief : ADC GPIO config.
* @param : None
* @return: None
******************************************************************************/
void ADC_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    
    __RCC_GPIOA_CLK_ENABLE();
    __RCC_GPIOB_CLK_ENABLE();
    __RCC_GPIOC_CLK_ENABLE();
    
    /* Configure ADC Channel_0 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_0;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStruct); 

    /* Configure ADC Channel_1 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_1;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStruct); 

//    /* Configure ADC Channel_2 pin as analog input */
//    GPIO_InitStruct.Pin       = GPIO_PIN_2;
//    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull      = GPIO_NOPULL;
//    GPIO_Init(GPIOA, &GPIO_InitStruct); 

//    /* Configure ADC Channel_3 pin as analog input */
//    GPIO_InitStruct.Pin       = GPIO_PIN_3;
//    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull      = GPIO_NOPULL;
//    GPIO_Init(GPIOA, &GPIO_InitStruct);     

    /* Configure ADC Channel_4 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_4;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStruct);  

    /* Configure ADC Channel_5 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_5;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStruct);  

    /* Configure ADC Channel_6 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_6;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStruct);  

    /* Configure ADC Channel_7 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_7;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStruct);   

    /* Configure ADC Channel_8 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_0;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStruct); 

    /* Configure ADC Channel_9 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_1;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* Configure ADC Channel_10 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_0;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* Configure ADC Channel_11 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_1;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* Configure ADC Channel_12 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_2;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* Configure ADC Channel_13 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_3;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* Configure ADC Channel_14 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_4;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* Configure ADC Channel_15 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_5;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStruct);    
}

/******************************************************************************
* @brief : ADC Common register config.
* @param : None
* @return: None
******************************************************************************/
void ADC_Common_Register_Config(void)
{
    ADC_CommonInitTypeDef ADC_CommonInitStructure;

    ADC_CommonInitStructure.ADC_Mode = ADC_MODE_INDEPENDENT;//双ADC模式选择
    ADC_CommonInitStructure.ADC_Prescaler = ADC_CLOCK_DIV4;//ADC_CLK分频选择
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAACCESSMODE_DISABLED;//双ADC下DMA功能选择
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;//2个采样阶段之间的延迟
    ADC_CommonInit(&ADC_CommonInitStructure);
}

/******************************************************************************
* @brief : ADC config.
* @param : None
* @return: None
******************************************************************************/
void ADC_Config(void)
{
    ADC_InitTypeDef ADC_InitStructure;
    
    ADC_InitStructure.ADC_Resolution = ADC_RESOLUTION_12B;//分辨率
    ADC_InitStructure.ADC_ContinuousConvMode = ADC_CONT_DISABLE;//连续转换模式
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//外部触发边沿选择
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_EXTERNAL_TIG0;//触发模式
    ADC_InitStructure.ADC_DataAlign = ADC_DATAALIGN_RIGHT;//数据对齐
    ADC_InitStructure.ADC_NbrOfConversion = ADC_NUM;//规则通道序列长度
    ADC_Init(ADCX, &ADC_InitStructure);
    
    //规则通道设置
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_0, ADC_SEQUENCE_SQ1, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_1, ADC_SEQUENCE_SQ2, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_4, ADC_SEQUENCE_SQ3, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_5, ADC_SEQUENCE_SQ4, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_6, ADC_SEQUENCE_SQ5, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_7, ADC_SEQUENCE_SQ6, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_8, ADC_SEQUENCE_SQ7, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_9, ADC_SEQUENCE_SQ8, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_10, ADC_SEQUENCE_SQ9, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_11, ADC_SEQUENCE_SQ10, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_12, ADC_SEQUENCE_SQ11, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_13, ADC_SEQUENCE_SQ12, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_14, ADC_SEQUENCE_SQ13, ADC_SMP_CLOCK_320);
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_15, ADC_SEQUENCE_SQ14, ADC_SMP_CLOCK_320);
//    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_2, ADC_SEQUENCE_SQ15, ADC_SMP_CLOCK_320);
//    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_3, ADC_SEQUENCE_SQ16, ADC_SMP_CLOCK_320);
}

/******************************************************************************
* @brief : ADC Polling.
* @param : None
* @return: None
******************************************************************************/
void ADC_Polling(uint32_t* pData, uint32_t Length, uint32_t Timeout)
{
    uint32_t tmp_status;
    uint32_t uiTimeout;  
    
    //开启ADC
    ADC_Cmd(ADCX, ENABLE);    

    //开始转换规则通道
    ADC_SoftwareStartConv(ADCX);

    uiTimeout = Timeout;

    while(Length)
    {
        tmp_status = ADCX->SR;
        if(tmp_status & ADC_IT_FLAG_EOC)//规则通道转换结束
        {
            *pData = ADC_GetConversionValue(ADCX);//获取规则转换的结果   
            ADC_ClearFlag(ADCX, ADC_IT_FLAG_EOC);
            pData++;
            Length--;
        }
        if(tmp_status & ADC_IT_FLAG_OVERF)//规则通道数据溢出
        {
            ADC_ClearFlag(ADCX, ADC_IT_FLAG_OVERF);
        }        
        if(tmp_status & ADC_IT_FLAG_EOG)//规则通道组转换结束
        {
            ADC_ClearFlag(ADCX, ADC_IT_FLAG_EOG);
            break;
        }

        if(uiTimeout)
        {
            uiTimeout--;
            if(uiTimeout == 0)
            {
                return;
            }
        }
    }

    ADC_Cmd(ADCX, DISABLE); 
    ADC_ClearFlag(ADCX, ADC_IT_FLAG_ALL);
}


/******************************************************************************
* @brief : ADC Get The VrefP Value.
* @param : none
* @return: VrefP Value
******************************************************************************/ 
uint32_t ADC_GetVrefP(void)
{
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    
    uint32_t TrimValue_3v, AdcValue_VrefP[1], VrefP,temp;
    
    //PMU CLK Enable
    __RCC_PMU_CLK_ENABLE();
    //VBG1P2
    *(__IO uint32_t*)(PMU_BASE_ADDR + 0xC0) = 0x05;
    
    Delay_Simple(2000);

    ADC_CommonInitStructure.ADC_Mode = ADC_MODE_INDEPENDENT;//双ADC模式选择
    ADC_CommonInitStructure.ADC_Prescaler = ADC_CLOCK_DIV4;//ADC_CLK分频选择
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAACCESSMODE_DISABLED;//双ADC下DMA功能选择
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;//2个采样阶段之间的延迟
    ADC_CommonInit(&ADC_CommonInitStructure);
     
    ADC_InitStructure.ADC_Resolution = ADC_RESOLUTION_12B;//分辨率
    ADC_InitStructure.ADC_ContinuousConvMode = ADC_CONT_DISABLE;//连续转换模式
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//外部触发边沿选择
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_EXTERNAL_TIG0;//触发模式
    ADC_InitStructure.ADC_DataAlign = ADC_DATAALIGN_RIGHT;//数据对齐
    ADC_InitStructure.ADC_NbrOfConversion = ADC_NUM;//规则通道序列长度
    ADC_Init(ADCX, &ADC_InitStructure);
    
    ADC_OverSamplingConfig(ADCX, ADC_OVERSAMPLING_RATIO_256, ADC_RIGHTBITSHIFT_8);//过采样率,过采样移位系数
    ADC_OverSamplingCmd(ADCX, ENABLE);//过采样使能

    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_17, ADC_SEQUENCE_SQ1, ADC_SMP_CLOCK_320);
    
    ADC_Polling(AdcValue_VrefP, 1, 0);
    
    printfS("The adc convert result :  0x%08x[%d], VBGR = %dmV\r\n", AdcValue_VrefP[0], AdcValue_VrefP[0] & 0xFFF, ((AdcValue_VrefP[0] & 0xFFF) * 3300 / 4095));
    
    //VBG1P2
    *(__IO uint32_t*)(PMU_BASE_ADDR + 0xC0) &= ~0x05;
    
    TrimValue_3v = *(volatile uint32_t*)(EFLASH_NVR_ADC_1V2_VAL_ADDR); //Read the 1.2v trim value in 3.0v vrefp.

    printfS("The adc 1.2v trim value is : 0x%08x \r\n", TrimValue_3v);

    if(((~TrimValue_3v & 0xFFFF0000) >> 16) == (TrimValue_3v & 0x0000FFFF))
    {
        temp = TrimValue_3v & 0xFFF;
        
        VrefP = (uint32_t)(temp * 3000 / (AdcValue_VrefP[0] & 0xFFF));
        
        printfS("Vrefp : %d mV \r\n", VrefP);
        return VrefP;
    }
    return 0;
}

/******************************************************************************
* @brief : ADC function test.
* @param : None
* @return: None
******************************************************************************/
void APP_ADC_Test(void)
{
    uint32_t i;
    
    printfS("ADC polling test \r\n");
    
    ADC_GetVrefP();
    
    ADC_GPIO_Config();
    
    ADC_Common_Register_Config();
    
    ADC_Config();
    
    
    while(1)
    {
        for (i = 0; i < ADC_NUM; i++)
        {
            gadcBuffer[i] = 0;
        }

        ADC_Polling(gadcBuffer, ADC_NUM, 0);

        for (i = 0; i < ADC_NUM; i++)
        {
            printfS("Channel_%d = %d\r\n", gadcBuffer[i]>>16 & 0xFF,gadcBuffer[i]&0xFFF);
        } 
        DelayMs(1000);     
    }
    
    
    
}






