#include "bsp_adc.h"

__IO uint32_t u32_GroupFlag = 0;
__IO uint32_t u32_AwdFlag = 0;

__IO uint32_t gu32_ITC_Conunt = 0;    // transfer complete interrupt count
__IO uint32_t gu32_IE_Conunt = 0;     // transfer error interrupt count

ADC_InitTypeDef     ADC_InitStruct;         /* ADC inition parameters */
GPIO_InitTypeDef    adc_gpio_init;          /* ADC GPIO inition parameters */
DMA_InitTypeDef     adc_dma_init;           /* ADC DMA inition parameters */
uint32_t            *AdcResults;            /* ADC global results handle */

/************************************************************************
 * function   : ADC_Polling
 * Description: Polling to get the results of the ADC converter.
 * input      : pData : Destination Buffer address.
 *            : Length : Number of data to be transferred from ADC peripheral to memory.
 *            : Timeout : Polling timeout.
 * return     : ADC_StatusTypeDef
 ************************************************************************/
ADC_StatusTypeDef ADC_Polling(uint32_t* pData, uint32_t Length, uint32_t Timeout)
{
    uint32_t tmp_hal_status;
    __IO uint32_t uiTimeout;    

    if(!pData)  return ADC_ERROR;
    
    uiTimeout = Timeout;
    
    ADC_Cmd(ADC, ENABLE);

    ADC_SoftwareStartConvCmd(ADC, ENABLE);
    
    while(Length)
    {
        tmp_hal_status = ADC_GetStatus(ADC);
        if(tmp_hal_status & ADC_SR_EOC)
        {
            *pData = ADC_GetConversionValue(ADC) | BSP_ADC_EOC_FLAG;
             ADC_ClearFlag(ADC, ADC_SR_EOC);
       
            pData++;
            Length--;
        }
        if(tmp_hal_status & ADC_SR_JEOC)
        {
            *pData = ADC_GetInjectedConversionValue(ADC) | BSP_ADC_JEOC_FLAG;
            ADC_ClearFlag(ADC, ADC_SR_JEOC);
            pData++;
            Length--;
        }
        if(tmp_hal_status & ADC_SR_OVERF)
        {
            ADC_ClearFlag(ADC, ADC_SR_OVERF);
        }        
        if(tmp_hal_status & ADC_SR_EOG)
        {
            ADC_ClearFlag(ADC, ADC_SR_EOG);
            break;
        }
        
        if(uiTimeout)
        {
            uiTimeout--;
            if(uiTimeout == 0)
                return ADC_TIMEOUT;
        }
    }
  
    ADC_Cmd(ADC, DISABLE);
    
    return ADC_OK;
}

/************************************************************************
 * function   : ADC_DMA_Convert
 * Description: Use the DMA to get the results of the ADC converter.
 * input      : pData : Destination Buffer address.
 *            : Length : Number of data to be transferred from ADC peripheral to memory.
 * return     : ADC_StatusTypeDef
 ************************************************************************/
ADC_StatusTypeDef ADC_DMA_Convert(uint32_t* pData, uint32_t Length)
{
    ADC_StatusTypeDef tmp_hal_status;
    
    if(!pData)  return ADC_ERROR;
    
    System_Module_Enable(EN_DMA);
    /* Enable DMA Interrupt */
    NVIC_ClearPendingIRQ(DMA_IRQn);
    NVIC_EnableIRQ(DMA_IRQn);
    
    /* DMA channel2 configuration */
    DMA_DeInit(DMA_Channel2);
    adc_dma_init.Request_ID       = REQ0_ADC;
    adc_dma_init.SrcAddr          = (uint32_t)&ADC->DR;
    adc_dma_init.DstAddr          = (uint32_t)pData;
    adc_dma_init.Data_Flow        = DMA_DATA_FLOW_P2M;
    adc_dma_init.DMA_BufferSize   = Length;
    adc_dma_init.Source_Inc       = DMA_SOURCE_ADDR_INCREASE_DISABLE;
    adc_dma_init.Desination_Inc   = DMA_DST_ADDR_INCREASE_ENABLE;
    adc_dma_init.Source_Width     = DMA_SRC_WIDTH_WORD;
    adc_dma_init.Desination_Width = DMA_DST_WIDTH_WORD;
    adc_dma_init.DMA_Mode         = DMA_CIRCULAR;

    DMA_Init(DMA_Channel2, &adc_dma_init);
    /* Enable DMA Channel2 Transfer Complete interrupt */
    DMA_ITConfig(DMA_Channel2, DMA_CHANNEL_CONFIG_ITC, ENABLE);
    
    /* Clear Pending Interrupt */
    NVIC_ClearPendingIRQ(ADC_IRQn);
    /* Enable ADC Interrupt */
    NVIC_EnableIRQ(ADC_IRQn);

    ADC_Cmd(ADC, ENABLE);
        
    /* Enable ADC DMA mode */
    ADC_DMACmd(ADC, ENABLE);
    
    /* Clear the SR register */
    ADC_ClearFlag(ADC, ADC_SR_AWD | ADC_SR_OVERF | ADC_SR_EOG | ADC_SR_JEOC | ADC_SR_EOC | ADC_SR_ADRDY);      
      
    /* Disable all interruptions before enabling the desired ones */
    ADC_ITConfig(ADC, ADC_IE_EOCIE | ADC_IE_EOGIE | ADC_IE_OVERFIE | ADC_IE_JEOCIE, DISABLE);  
           
    /* Enable DMA channel2 transfer */
    DMA_Cmd(DMA_Channel2, ENABLE);
    
    /* Start ADC group regular conversion */
    ADC_SoftwareStartConvCmd(ADC, ENABLE);

    while(!gu32_ITC_Conunt){}
        
    gu32_ITC_Conunt--;
    
    return ADC_OK;
}

/************************************************************************
 * function   : ADC_GetVrefP
 * Description: ADC Get The VrefP Value. 
 ************************************************************************/ 
uint32_t ADC_GetVrefP(void)
{
    uint32_t TrimValue_3v, AdcValue_VrefP, VrefP,temp;
        
    ADC_DeInit(ADC);
    ADC_InitStruct.ADC_ClockDiv = ADC_CLOCK_DIV8;
    ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStruct.ADC_ExternalTrigConv = ADC_SOFTWARE_START;
    /* The total adc regular channels number */
    ADC_InitStruct.ADC_NbrOfChannel = 1;
        
    System_Module_Enable(EN_ADC);
    ADC_Init(ADC, &ADC_InitStruct);
    
    /* Add adc channels */
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_VBGR, 1, ADC_SMP_CLOCK_320, DISABLE);
    
    ADC_Polling(&AdcValue_VrefP, ADC_InitStruct.ADC_NbrOfChannel, 0);
    
    printfS("The adc convert result : Channel 18 = 0x%08x \r\n", AdcValue_VrefP);
    
    TrimValue_3v = *(volatile uint32_t*)(0x00080240); //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 & 0xFFF));
                
        return VrefP;
    }
    else
        return 0;
}

void ADC_Init_Gpio(void)
{
    //Enable GPIO Clock
    System_Module_Enable(EN_GPIOAB);
    System_Module_Enable(EN_GPIOCD);
    
    /* Config the ADC channel 0,1,2,3,4,5,6,8,9,10,11,12,13 GPIO as analog function */
    adc_gpio_init.Pin = GPIO_PIN_0 | GPIO_PIN_2  | GPIO_PIN_3 | GPIO_PIN_4 | 
                        GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    adc_gpio_init.Mode           = GPIO_MODE_ANALOG;
    adc_gpio_init.Pull           = GPIO_NOPULL;
    GPIO_Init(GPIOA, &adc_gpio_init);             

    adc_gpio_init.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2  | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
    adc_gpio_init.Mode           = GPIO_MODE_ANALOG;
    adc_gpio_init.Pull           = GPIO_NOPULL;
    GPIO_Init(GPIOC, &adc_gpio_init);             
}

/************************************************************************
 * function   : ADC_Init_Polling_Nchannels
 * Description: ADC Initiation. 
 ************************************************************************/ 
void ADC_Init_Polling_Nchannels(void)
{    
    ADC_Init_Gpio();
    
    ADC_DeInit(ADC);
    ADC_InitStruct.ADC_ClockDiv = ADC_CLOCK_DIV8;
    ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStruct.ADC_ExternalTrigConv = ADC_SOFTWARE_START;
    /* The total adc regular channels number */
    ADC_InitStruct.ADC_NbrOfChannel = 16;
        
    System_Module_Enable(EN_ADC);
    ADC_Init(ADC, &ADC_InitStruct);
    
    /* Add adc channels */
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_0,  1,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_15, 2,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_2,  3,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_3,  4,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_4,  5,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_5,  6,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_6,  7,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_7,  8,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_8,  9,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_9,  10, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_10, 11, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_11, 12, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_12, 13, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_13, 14, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_14, 15, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_1,  16, ADC_SMP_CLOCK_320, DISABLE);
}

/************************************************************************
 * function   : ADC_Init_Dma_Diff_Nchannels
 * Description: ADC Initiation. 
 ************************************************************************/ 
void ADC_Init_Dma_Diff_Nchannels(void)
{
    ADC_Init_Gpio();
    
    ADC_DeInit(ADC);
    ADC_InitStruct.ADC_ClockDiv = ADC_CLOCK_DIV3;
    ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStruct.ADC_ExternalTrigConv = ADC_SOFTWARE_START;
    /* The total adc regular channels number */
    ADC_InitStruct.ADC_NbrOfChannel = 8;
        
    System_Module_Enable(EN_ADC);
    ADC_Init(ADC, &ADC_InitStruct);
    
    /* Add adc channels */
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_0,  1,  ADC_SMP_CLOCK_320, ENABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_7,  2,  ADC_SMP_CLOCK_320, ENABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_2,  3,  ADC_SMP_CLOCK_320, ENABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_3,  4,  ADC_SMP_CLOCK_320, ENABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_4,  5,  ADC_SMP_CLOCK_320, ENABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_5,  6,  ADC_SMP_CLOCK_320, ENABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_6,  7,  ADC_SMP_CLOCK_320, ENABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_1,  8,  ADC_SMP_CLOCK_320, ENABLE);
}

/************************************************************************
 * function   : ADC_Init_Dma_Single_Nchannels
 * Description: ADC Initiation. 
 ************************************************************************/ 
void ADC_Init_Dma_Single_Nchannels(void)
{
    ADC_Init_Gpio();
    
    ADC_DeInit(ADC);
    ADC_InitStruct.ADC_ClockDiv = ADC_CLOCK_DIV3;
    ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStruct.ADC_ExternalTrigConv = ADC_SOFTWARE_START;
    /* The total adc regular channels number */
    ADC_InitStruct.ADC_NbrOfChannel = 16;
        
    System_Module_Enable(EN_ADC);    
    ADC_Init(ADC, &ADC_InitStruct);

    /* Add adc channels */
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_0,  1,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_15, 2,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_2,  3,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_3,  4,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_4,  5,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_5,  6,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_6,  7,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_7,  8,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_8,  9,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_9,  10, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_10, 11, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_11, 12, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_12, 13, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_13, 14, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_14, 15, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_1,  16, ADC_SMP_CLOCK_320, DISABLE);
}

/************************************************************************
 * function   : ADC_Init_IT_Injected_WatchDog
 * Description: ADC Initiation. 
 ************************************************************************/ 
void ADC_Init_IT_Injected_WatchDog(void)
{       
    ADC_Init_Gpio();
    
    ADC_DeInit(ADC);
    ADC_InitStruct.ADC_ClockDiv = ADC_CLOCK_DIV8;
    ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStruct.ADC_ExternalTrigConv = ADC_SOFTWARE_START;
    /* The total adc regular channels number */
    ADC_InitStruct.ADC_NbrOfChannel = 15;
        
    System_Module_Enable(EN_ADC);
    /* Clear Pending Interrupt */
    NVIC_ClearPendingIRQ(ADC_IRQn);
    /* Enable ADC Interrupt */
    NVIC_EnableIRQ(ADC_IRQn);
    
    ADC_Init(ADC, &ADC_InitStruct);

    /* Add adc channels */
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_0,  1,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_15, 2,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_2,  3,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_3,  4,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_4,  5,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_5,  6,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_6,  7,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_7,  8,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_8,  9,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_9,  10, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_10, 11, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_11, 12, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_12, 13, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_13, 14, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_14, 15, ADC_SMP_CLOCK_320, DISABLE);
    
    /* Enable adc injected function */
    ADC_InjectedConvCmd(ADC, ENABLE);
    /* Add adc injected channel */
    ADC_InjectedChannelConfig(ADC, ADC_CHANNEL_1, ADC_SMP_CLOCK_320, DISABLE);
    /* Set adc injected channel trig mode */
    ADC_ExternalTrigInjectedConvConfig(ADC, ADC_SOFTWARE_START);
    
    /* Config adc analog watchdog channel */ 
    ADC_AnalogWatchdogCmd(ADC, ADC_ANALOGWATCHDOG_JCH_SINGLE);
    ADC_AnalogWatchdogThresholdsConfig(ADC, 4000, 10); //HighThreshold: between 0~4095; LowThreshold : between 0~4095
    ADC_AnalogWatchdogInjectedChannelConfig(ADC, ADC_CHANNEL_1);
    
    /* Clear the SR register */
    ADC_ClearFlag(ADC, ADC_SR_AWD | ADC_SR_OVERF | ADC_SR_EOG | ADC_SR_JEOC | ADC_SR_EOC | ADC_SR_ADRDY);      
      
    /* Disable all interruptions before enabling the desired ones */
    ADC_ITConfig(ADC, ADC_IE_EOCIE | ADC_IE_EOGIE | ADC_IE_OVERFIE | ADC_IE_JEOCIE, DISABLE);  

    /* Enable AWD EOC EOG and JEOC interrupt */
    ADC_ITConfig(ADC, ADC_SR_AWD | ADC_IE_EOCIE | ADC_IE_EOGIE | ADC_SR_JEOC, ENABLE);
}

/************************************************************************
 * function   : ADC_Init_IT_Injected_TimTrig
 * Description: ADC Initiation. 
 ************************************************************************/ 
void ADC_Init_IT_Injected_TimTrig(void)
{
    ADC_Init_Gpio();
    
    ADC_DeInit(ADC);
    ADC_InitStruct.ADC_ClockDiv = ADC_CLOCK_DIV8;
    ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStruct.ADC_ExternalTrigConv = ADC_SOFTWARE_START;
    /* The total adc regular channels number */
    ADC_InitStruct.ADC_NbrOfChannel = 15;
        
    System_Module_Enable(EN_ADC);
    /* Clear Pending Interrupt */
    NVIC_ClearPendingIRQ(ADC_IRQn);
    /* Enable ADC Interrupt */
    NVIC_EnableIRQ(ADC_IRQn);
    
    ADC_Init(ADC, &ADC_InitStruct);

    /* Add adc channels */
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_0,  1,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_15, 2,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_2,  3,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_3,  4,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_4,  5,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_5,  6,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_6,  7,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_7,  8,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_8,  9,  ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_9,  10, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_10, 11, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_11, 12, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_12, 13, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_13, 14, ADC_SMP_CLOCK_320, DISABLE);
    ADC_RegularChannelConfig(ADC, ADC_CHANNEL_14, 15, ADC_SMP_CLOCK_320, DISABLE);
    
    /* Enable adc injected function */
    ADC_InjectedConvCmd(ADC, ENABLE);
    /* Add adc injected channel */
    ADC_InjectedChannelConfig(ADC, ADC_CHANNEL_1, ADC_SMP_CLOCK_320, DISABLE);
    /* Set adc injected channel trig mode */
    ADC_ExternalTrigInjectedConvConfig(ADC, ADC_EXTERNAL_TIG6); //TIM6_TRGO
   
    /* Clear the SR register */
    ADC_ClearFlag(ADC, ADC_SR_AWD | ADC_SR_OVERF | ADC_SR_EOG | ADC_SR_JEOC | ADC_SR_EOC | ADC_SR_ADRDY);      
      
    /* Disable all interruptions before enabling the desired ones */
    ADC_ITConfig(ADC, ADC_IE_EOCIE | ADC_IE_EOGIE | ADC_IE_OVERFIE | ADC_IE_JEOCIE, DISABLE);  

    /* Enable EOC EOG and JEOC interrupt */
    ADC_ITConfig(ADC, ADC_IE_EOCIE | ADC_IE_EOGIE | ADC_SR_JEOC, ENABLE);
}

/************************************************************************
 * function   : ADC_IRQProcess
 * Description: This function handles ADC interrupt process.
 ************************************************************************/
void ADC_IRQProcess(void)
{
    __IO uint32_t TempData;
    __IO uint32_t Status;
    
    /* Check the parameters */
  
    Status = ADC_GetStatus(ADC);
    /************ Check End of Conversion flag for injected ************/
    if(ADC_GetITSource(ADC, ADC_IE_JEOCIE) == SET)
    {
        if((Status & ADC_SR_JEOC) == ADC_SR_JEOC)
        {
            if(ADC_InitStruct.ADC_ContinuousConvMode == DISABLE)
            {
                /* Disable ADC end of conversion interrupt on group injected */
                ADC_ITConfig(ADC, ADC_IE_JEOCIE, DISABLE);
            }

            /* Conversion complete callback */ 
            TempData = ADC_GetInjectedConversionValue(ADC);
            AdcResults[(TempData>> 16) & 0x1f] = TempData | BSP_ADC_JEOC_FLAG;
      
            /* Clear injected group conversion flag */
            ADC_ClearFlag(ADC, ADC_SR_JEOC);
        }
    }

    /************ Check Conversion flag for regular group ************/
    if(ADC_GetITSource(ADC, ADC_IE_EOCIE) == SET)
    {
        if((Status & ADC_SR_EOC) == ADC_SR_EOC)
        {      
            /* Conversion complete callback */
            TempData = ADC_GetConversionValue(ADC);
            AdcResults[(TempData>> 16) & 0x1f] = TempData | BSP_ADC_EOC_FLAG;
      
            /* Clear conversion flag */
            ADC_ClearFlag(ADC, ADC_SR_EOC);
        }
    }

    /************ Check Analog watchdog flags ************/
    if(ADC_GetITSource(ADC, ADC_IE_AWDIE) == SET)
    {
        if((Status & ADC_SR_AWD) == ADC_SR_AWD)
        {
            /* Level out of window callback */ 
            u32_AwdFlag = 1;

            /* Clear the ADC analog watchdog flag */
            ADC_ClearFlag(ADC, ADC_SR_AWD);
        }
    }  
    
    /************ Check End of Conversion flag for regular group ************/
    if(ADC_GetITSource(ADC, ADC_IE_EOGIE) == SET)
    {
        if((Status & ADC_SR_EOG) == ADC_SR_EOG)
        {      
            if(ADC_InitStruct.ADC_ContinuousConvMode == DISABLE)
            {
                /* Disable ADC end of conversion interrupt on group regular */
                ADC_ITConfig(ADC, ADC_IE_EOGIE, DISABLE);
            }
      
            /* Conversion complete callback */
            u32_GroupFlag = 1;

            /* Clear regular group conversion flag */
            ADC_ClearFlag(ADC, ADC_SR_EOG);
        }
    }
}
