
/******************************************************************************
*@file  : fxx_adc.c
*@brief : ADC SPL module driver.
******************************************************************************/
#include  "fxx_adc.h"



/******************************************************************************
* @brief:  Deinitializes ADC registers to their default reset values.
* @param:  None.
* @return: None
******************************************************************************/
void ADC_DeInit(void)
{
    /* Release all ADCs from reset state */
    SCU->IPRST |= (1 << 14);
    System_Delay(50);
    ADC->CR2 &= ~ADC_CR2_AFERSTN;
}


/******************************************************************************
* @brief:  Initializes the ADCx periphera.
* @param:  None.
* @return: None
******************************************************************************/
void ADC_Init(void)
{
    /* Enable ADC CLK */
    SCU->IPCKENR1 |= (1 << 14);
    /* Release Reset ADC AFE */
    ADC->CR2 |= ADC_CR2_AFERSTN;
}


/******************************************************************************
* @brief:  Configure ADC clock division.
* @param:  Division: division factor
* @return: None
******************************************************************************/
void ADC_ClockConfig(uint32_t Division)
{
    /* Check the parameters */
    assert_param(IS_ADC_CLOCK_DIV(Division));
    
    ADC->CR2 = (ADC->CR2 & (~ADC_CR2_DIV_Msk)) | Division;
}


/******************************************************************************
* @brief:  Enables or disables the specified ADC peripheral.
* @param:  NewState: new state of the ADCx peripheral. 
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_Cmd(uint32_t NewState)
{
    uint32_t timeout;
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));

    if (NewState != ADC_STATE_DISABLE)
    {
        /* Set the ADC_EN bit to wake up the ADC from power down mode */
        ADC->CR2 |= ADC_CR2_ADCEN;
        /* Wait ADC ready */
        timeout = ADC_READY_TIMEOUT;
        while(!(ADC->SR & ADC_SR_ADRDY))
        {
            if (0 == --timeout)
            {
                return;
            }            
        }      
    }
    else
    {
        /* Disable the selected ADC peripheral */
        ADC->CR2 &= (~ADC_CR2_ADCEN);
    }
}

/******************************************************************************
* @brief:  Enables or disables the ADC fast conversion.
* @param:  NewState: new state of the ADC fast conversion. 
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_FastModeCmd(uint32_t NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));
    if (NewState != ADC_STATE_DISABLE)
    {
        /* Enable the ADC fast conversion */
        ADC->CR2 |= ADC_CR2_FASTMOD;
    }
    else
    {
        /* Disable the ADC fast conversion */
        ADC->CR2 &= (~ADC_CR2_FASTMOD);
    }
}

/******************************************************************************
* @brief:  Enables or disables the ADC continuous conversion mode 
* @param:  NewState: new state of the selected ADC continuous conversion mode
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_ContinuousModeCmd(uint32_t NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));

    if (NewState != ADC_STATE_DISABLE)
    {
        /* Enable the selected ADC continuous conversion mode */
        ADC->CR1 |= ADC_CR1_CONT;
    }
    else
    {
        /* Disable the selected ADC continuous conversion mode */
        ADC->CR1 &= (~ADC_CR1_CONT);
    }
}

/******************************************************************************
* @brief:  Enables or disables the ADC stop control.
* @param:  NewState: new state of the ADC stop control. 
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_StopControlCmd(uint32_t NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));
    if (NewState != ADC_STATE_DISABLE)
    {
        /* Enable the ADC stop control */
        ADC->CR2 |= ADC_CR2_ADCSTP;
    }
    else
    {
        /* Disable the ADC stop control */
        ADC->CR2 &= (~ADC_CR2_ADCSTP);
    }
}

/******************************************************************************
* @brief:  Enables or disables the ADC stop control.
* @param:  Overflowmode: Specifies whether ADC saves the new sampling data 
           or the last sampling data when overflow occurs. 
* @return: None
******************************************************************************/
void ADC_OverflowmodeConfig(uint32_t Overflowmode)
{
    /* Check the parameters */
    assert_param(IS_ADC_OVERFLOW_MODE(Overflowmode));

    ADC->CR2 = (ADC->CR2 &(~ADC_CR2_OVRMOD_Msk)) | Overflowmode;
    
}

/******************************************************************************
* @brief:  Configure single/differential conversion mode.
* @param:  Channel: the channel is set with single terminal or differential. 
* @param:  Mode: single-ended/differential conversion mode.
* @return: None
******************************************************************************/
void ADC_DifferentialConfig(uint8_t Channel, uint8_t Mode)
{
    /* Check the parameters */
    assert_param(IS_ADC_DIFF_SIGN_CHANNEL(Channel));
    assert_param(IS_ADC_DIFF_MODE(Mode));

    ADC->DIFF = (ADC->DIFF & (~(1 << Channel))) | (Mode << Channel);
}

/******************************************************************************
* @brief:  Signed or unsigned number selection.
* @param:  Channel: the channel is set with Signed or unsigned. 
* @param:  Sign: Signed or unsigned.
* @return: None
******************************************************************************/
void ADC_SignConfig(uint8_t Channel, uint8_t Sign)
{
    /* Check the parameters */
    assert_param(IS_ADC_DIFF_SIGN_CHANNEL(Channel));
    assert_param(IS_ADC_SIGN(Sign));
    
    ADC->SIGN = (ADC->SIGN & (~(1 << Channel))) |(Sign << Channel);
}

/******************************************************************************
* @brief:  Configure oversampling
* @param:  Ratio: ADC oversampling ratio.                   
* @param:  Shift: ADC oversampling shift.
* @return: None
******************************************************************************/
void ADC_OverSamplingConfig(uint8_t Ratio, uint8_t Shift)
{
    /* Check the parameters */
    assert_param(IS_ADC_OVERSAMPLING_RATIO(Ratio));
    assert_param(IS_ADC_RIGHTBITSHIFT(Shift));
    
    /* Clear OVSS OVSR bits */
    ADC->CR2 &= (~(ADC_CR2_OVSR_Msk | ADC_CR2_OVSS_Msk));
    
    /* Set the new ratio and Shift */
    ADC->CR2 |= ((Ratio << ADC_CR2_OVSR_Pos) | (Shift << ADC_CR2_OVSS_Pos));
}

/******************************************************************************
* @brief:  Enables or disables the Regular group oversampling
* @param:  NewState: new state of the Regular group oversampling.
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_RegularOverSamplingCmd(uint32_t NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));
    if (NewState != ADC_STATE_DISABLE)
    {
        /* Enable the Regular group oversampling */
        ADC->CR2 |= ADC_CR2_OVSE;
    }
    else
    {
        /* Disable the Regular group oversampling */
        ADC->CR2 &= (~ADC_CR2_OVSE);
    }
}

/******************************************************************************
* @brief:  Configure one trigger for one or more ADC conversions
* @param:  TrigerMode: 1 or more ADC conversions.
* @return: None
******************************************************************************/
void ADC_InjectOverSamplingTrigerConfig(uint32_t TrigerMode)
{
    /* Check the parameters */
    assert_param(IS_ADC_OVERSAMPLING_TRIGER(TrigerMode));
    
    ADC->CR2 = (ADC->CR2 & (~ADC_CR2_JTROVS_Msk)) | TrigerMode;
}

/******************************************************************************
* @brief:  Enables or disables the Inject group oversampling
* @param:  NewState: new state of the Inject group oversampling.
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_InjectOverSamplingCmd(uint32_t NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));
    if (NewState != ADC_STATE_DISABLE)
    {
        /* Enable the Inject group oversampling */
        ADC->CR2 |= ADC_CR2_JOVSE;
    }
    else
    {
        /* Disable the Inject group oversampling */
        ADC->CR2 &= (~ADC_CR2_JOVSE);
    }
}

/******************************************************************************
* @brief:  Enables or disables the analog watchdog on single/all regular or 
*          injected channels
* @param:  Mode: the ADC analog watchdog configuration.
* @return: None	  
******************************************************************************/
void ADC_AnalogWatchdogConfig(uint32_t Mode)
{
    /* Check the parameters */
    assert_param(IS_ADC_ANALOG_WDG(Mode));

    /* Clear AWDEN, JAWDEN and AWDSGL bits */
    ADC->CR1 &= (~(ADC_CR1_AWDSGL_Msk | ADC_CR1_JAWDEN_Msk | ADC_CR1_AWDEN_Msk));

    /* Set the analog watchdog enable mode */
    ADC->CR1 |= Mode;

}


/******************************************************************************
* @brief:  Configure the high threshold and low threshold of single channel analog watchdog.
* @param:  HighTh: the ADC analog watchdog High threshold value.
*          This parameter must be a 12-bit value.
* @param:  LowTh:  the ADC analog watchdog Low threshold value.
*          This parameter must be a 12-bit value.
* @return: None
******************************************************************************/
void ADC_AnalogWatchdogSingleThresholdConfig(uint16_t HighTh, uint16_t LowTh)
{
    /* Check the parameters */
    assert_param(IS_ADC_THRESHOLD(HighTh));
    assert_param(IS_ADC_THRESHOLD(LowTh));

    /* Set the ADCx high threshold */
    ADC->HTR = (ADC->HTR & (~ADC_HTR_HT_Msk)) | HighTh;

    /* Set the ADCx low threshold */
    ADC->LTR = (ADC->LTR & (~ADC_LTR_LT_Msk)) | LowTh;
}

/******************************************************************************
* @brief:  Configure the high threshold and low threshold of differential channel analog watchdog.
* @param:  HighTh: the ADC analog watchdog High threshold value.
*          This parameter must be a 12-bit value.
* @param:  LowTh:  the ADC analog watchdog Low threshold value.
*          This parameter must be a 12-bit value.
* @return: None
******************************************************************************/
void ADC_AnalogWatchdogDifferentialThresholdConfig(uint16_t HighTh, uint16_t LowTh)
{
    /* Check the parameters */
    assert_param(IS_ADC_THRESHOLD(HighTh));
    assert_param(IS_ADC_THRESHOLD(LowTh));
    
    /* Set the ADCx high threshold */
    ADC->HTR = (ADC->HTR & (~ADC_HTR_DHT_Msk)) | (HighTh << ADC_HTR_DHT_Pos);
    
    /* Set the ADCx low threshold */
    ADC->LTR = (ADC->LTR & (~ADC_LTR_DLT_Msk)) | (LowTh << ADC_LTR_DLT_Pos);
}

/******************************************************************************
* @brief:  Configures the analog watchdog Regular channel
* @param:  Channel: the ADC channel to configure for the analog watchdog. 
* @return: None
******************************************************************************/
void ADC_AnalogWatchdogRegularChannelConfig(uint8_t Channel)
{
    /* Check the parameters */
    assert_param(IS_ADC_CHANNEL(Channel));

    /* Set the Analog watchdog channel */
    ADC->CR1 = (ADC->CR1 & (~ADC_CR1_AWDCH_Msk)) | Channel;

}

/******************************************************************************
* @brief:  Configures the analog watchdog Inject channel
* @param:  Channel: the ADC channel to configure for the analog watchdog. 
* @return: None
******************************************************************************/
void ADC_AnalogWatchdogInjectChannelConfig(uint8_t Channel)
{
    /* Check the parameters */
    assert_param(IS_ADC_CHANNEL(Channel));
    
    /* Set the Analog watchdog channel */
    ADC->CR1 = (ADC->CR1 & (~ADC_CR1_AWDJCH_Msk)) | (Channel << ADC_CR1_AWDJCH_Pos);

}

/******************************************************************************
* @brief:  Configures for the selected ADC regular channel its corresponding
*          rank in the sequencer and its sample time.
* @param:  Channel: the ADC channel to configure.                   
* @param:  Rank: The rank in the regular group sequencer.
*          This parameter must be between 1 to 16.
* @param:  SampleTime: The sample time value to be set for the selected channel. 
* @return: None
******************************************************************************/
void ADC_RegularChannelConfig(uint8_t Channel, uint8_t Rank, uint8_t SampleTime)
{
    /* Check the parameters */
    assert_param(IS_ADC_CHANNEL(Channel));
    assert_param(IS_ADC_SEQUENCE(Rank));
    assert_param(IS_ADC_SMPCLOCK(SampleTime));
    
    /*---------------------------- ADCx SMPR3 Configuration -----------------*/
    if (Channel > ADC_CHANNEL_15)/* ADC_Channel include in ADC_Channel_[16..19] */
    {
        /* Clear the old sample time */
        ADC->SMPR3 &= (~(ADC_SMPR3_SMP16_Msk << (4 * (Channel - 16))));

        /* Set the new sample time */
        ADC->SMPR3 |= (SampleTime << (4 * (Channel - 16)));
    }
    /*---------------------------- ADCx SMPR1 Configuration -----------------*/
    else if(Channel < ADC_CHANNEL_8)/* ADC_Channel include in ADC_Channel_[0..7] */
    {
        /* Clear the old sample time */
        ADC->SMPR1 &= (~(ADC_SMPR1_SMP0_Msk << (4 * Channel)));

        /* Set the new sample time */
        ADC->SMPR1 |= (SampleTime << (4 * Channel));
    }
    /*---------------------------- ADCx SMPR2 Configuration -----------------*/
    else /* ADC_Channel include in ADC_Channel_[8..15] */
    {
        /* Clear the old sample time */
        ADC->SMPR2 &= (~(ADC_SMPR2_SMP8_Msk << (4 * (Channel - 8))));
        
        /* Set the new sample time */
        ADC->SMPR2 |= (SampleTime << (4 * (Channel - 8)));
    }
    /*---------------------------- ADCx SQR1 Configuration -----------------*/
    if (Rank < 6)/* For Rank 1 to 5 */
    {
        /* Clear the old SQx bits for the selected rank */
        ADC->SQR1 &= (~(ADC_SQR1_SQ1_Msk << (5 * (Rank - 1))));

        /* Set the SQx bits for the selected rank */
        ADC->SQR1 |= (Channel << (5 * Rank));
    }
    /*---------------------------- ADCx SQR3 Configuration -----------------*/
    else if(Rank > 11)/* For Rank 12 to 16 */
    {
        /* Clear the old SQx bits for the selected rank */
        ADC->SQR3 &= (~(ADC_SQR3_SQ12_Msk << (5 * (Rank - 12))));

        /* Set the SQx bits for the selected rank */
        ADC->SQR3 |= (Channel << (5 * (Rank - 12)));

    }
    /*---------------------------- ADCx SQR1 Configuration -----------------*/
    else/* For Rank 6 to 11 */
    {
        /* Clear the old SQx bits for the selected rank */
        ADC->SQR2 &= (~(ADC_SQR2_SQ6_Msk << (5 * (Rank - 6))));

        /* Set the SQx bits for the selected rank */
        ADC->SQR2 |= (Channel << (5 * (Rank - 6)));
    }
}

/******************************************************************************
* @brief:  Configure the length of the regular channel sequence.
* @param:  Length: the length of the regular channel sequence.                   
* @return: None
******************************************************************************/
void ADC_RegularChannelSequenceLengthConfig(uint8_t Length)
{
    /* Check the parameters */
    assert_param(IS_ADC_REGULAR_LENGTH(Length));
    
    ADC->SQR1 = (ADC->SQR1 & (~ADC_SQR1_L_Msk)) | (Length -1);

}

/******************************************************************************
* @brief:  Enables the selected ADC software start conversion of the regular channels.
* @param:  None
* @return: None
******************************************************************************/
void ADC_RegularSoftwareStart(void)
{
    /* Enable the selected ADC conversion for regular group */
    ADC->CR1 |= ADC_CR1_SWSTART;
}

/******************************************************************************
* @brief:  Gets the selected ADC Software start regular conversion Status.
* @param:  None
* @return: The new state of ADC software start conversion (SET or RESET).
******************************************************************************/
FlagStatus ADC_GetRegularSoftwareStartStatus(void)
{
    FlagStatus bitstatus = RESET;

    /* Check the status of SWSTART bit */
    if ((ADC->CR1 & ADC_CR1_SWSTART) != RESET)
    {
        /* SWSTART bit is set */
        bitstatus = SET;
    }
    else
    {
        /* SWSTART bit is reset */
        bitstatus = RESET;
    }

    /* Return the SWSTART bit status */
    return  bitstatus;
}

/******************************************************************************
* @brief:  Configures the ADCx external trigger for regular channels conversion.
* @param:  Trigger: specifies the ADC trigger to start injected conversion.                        
* @return: None
******************************************************************************/
void ADC_RegularExternalTriggerConfig(uint32_t Trigger)
{
    /* Check the parameters */
    assert_param(IS_ADC_TRIG(Trigger));
    /* Set the external event selection for regular */
    ADC->CR1 = (ADC->CR1 &= (~ADC_CR1_EXTSEL_Msk))| (Trigger << ADC_CR1_EXTSEL_Pos);
}

/******************************************************************************
* @brief:  Configures the discontinuous mode for the selected ADC regular group 
*          channel.
* @param:  Number: specifies the discontinuous mode regular channel count value.
*          This number must be between 1 and 16.
* @return: None
******************************************************************************/
void ADC_DiscModeChannelCountConfig(uint8_t Number)
{
    /* Check the parameters */
    assert_param(IS_ADC_REGULAR_DISC_NUMBER(Number));

    /* Set the discontinuous mode channel count */
    ADC->CR1 = (ADC->CR1 & (~ADC_CR1_DISCNUM_Msk)) | ((Number - 1) << ADC_CR1_DISCNUM_Pos);
}

/******************************************************************************
* @brief:  Enables or disables the discontinuous mode on regular group channel 
*          for the specified ADC
* @param:  NewState: new state of the selected ADC discontinuous mode on 
*          regular group channel.
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_DiscModeCmd(uint32_t NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));

    if (NewState != ADC_STATE_DISABLE)
    {
        /* Enable the selected ADC regular discontinuous mode */
        ADC->CR1 |= ADC_CR1_DISCEN;
    }
    else
    {
        /* Disable the selected ADC regular discontinuous mode */
        ADC->CR1 &= (~ADC_CR1_DISCEN);
    }
}

/******************************************************************************
* @brief:  Returns the last ADCx conversion result data for regular channel.
* @param:  None.
* @return: Data conversion value and channel number.
******************************************************************************/
uint32_t ADC_GetRegularConversionValue(void)
{
    /* Return the selected ADC conversion value */
    return ADC->DR;
}

/******************************************************************************
* @brief:  Enables or disables the BUFFER.   
* @param:  NewState: new state of the BUFFER.
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_BufferCmd(uint32_t NewState)                             
{
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));
    if (NewState != ADC_STATE_DISABLE)
    {    
        ADC->CR2 |= ADC_CR2_ENBUF;
    }
    else
    {
        ADC->CR2 &= (~ADC_CR2_ENBUF);
    }
}

/******************************************************************************
* @brief:  Configure ADC Buffer Stability Time.   
* @param:  Time: Stability Time.
* @return: None
******************************************************************************/
void ADC_BufferStabilityTimeConfig(uint32_t Time)                             
{
    /* Check the parameters */
    assert_param(IS_ADC_BUFFER_STABILITY_TIME(Time));
  
    ADC->CR2 = (ADC->CR2 & (~ADC_CR2_BUFSTIME_Msk)) | (Time << ADC_CR2_BUFSTIME_Pos);

}

/******************************************************************************
* @brief:  Configure temperature sensor conversion times.
* @param:  Time: conversion times.
* @return: None
******************************************************************************/
void ADC_TempSensorConversionTime(uint32_t Time)                
{
    /* Check the parameters */
    assert_param(IS_ADC_TS_CONVERT_TIME(Time));
    ADC->TSREF = (ADC->TSREF & (~ADC_TSREF_ALGMEAN_Msk)) | Time;
}

/******************************************************************************
* @brief:  Enables or disables the temperature sensor channel.
* @param:  NewState: new state of the temperature sensor channel.
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_TempSensorCmd(uint32_t NewState)                
{
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));
    if (NewState != ADC_STATE_DISABLE)
    {
        /* Enable the temperature sensor channel */
        ADC->TSREF |= ADC_TSREF_ENTS;
    }
    else
    {
        /* Disable the temperature sensor channel */
        ADC->TSREF &= (~ADC_TSREF_ENTS);
    }
}

/******************************************************************************
* @brief:  Enable or disable the output of 1.2V reference voltage to the ADC BUF channel.
* @param:  NewState: new state of the 1.2V reference voltage.
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_VREF1P2Cmd(uint32_t NewState)                
{
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));
    if (NewState != ADC_STATE_DISABLE)
    {
        /* Enable the 1.2v to the buffer channel */
        ADC->TSREF |= ADC_TSREF_VREF1P2EN;
    }
    else
    {
        /* Disable Enable the 1.2v to the buffer channel */
        ADC->TSREF &= (~ADC_TSREF_VREF1P2EN);
    }
}

/******************************************************************************
* @brief:  Enables or disables the specified ADC DMA request.
* @param:  NewState: new state of the selected ADC DMA transfer.
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_DMACmd(uint32_t NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));
    if (NewState != ADC_STATE_DISABLE)
    {
        /* Enable the selected ADC DMA request */
        ADC->CR1 |= ADC_CR1_DMA;
    }
    else
    {
        /* Disable the selected ADC DMA request */
        ADC->CR1 &= (~ADC_CR1_DMA);
    }
}

/******************************************************************************
* @brief:  Configures for the selected ADC injected channel its corresponding
*          rank in the sequencer and its sample time.
* @param:  Channel: the ADC channel to configure.                     
* @param:  SampleTime: The sample time value to be set for the selected channel. 
* @return: None
******************************************************************************/
void ADC_InjectedChannelConfig(uint8_t Channel, uint8_t SampleTime)
{
    /* Check the parameters */
    assert_param(IS_ADC_CHANNEL(Channel));
    assert_param(IS_ADC_SMPCLOCK(SampleTime));
    /*---------------------------- ADCx SMPR3 Configuration -----------------*/
    if (Channel > ADC_CHANNEL_15)/* ADC_Channel include in ADC_Channel_[16..19] */
    {
        /* Clear the old sample time */
        ADC->SMPR3 &= (~(ADC_SMPR3_SMP16_Msk << (4 * (Channel - 16))));

        /* Set the new sample time */
        ADC->SMPR3 |= (SampleTime << (4 * (Channel - 16)));
    }
    /*---------------------------- ADCx SMPR1 Configuration -----------------*/
    else if(Channel < ADC_CHANNEL_8)/* ADC_Channel include in ADC_Channel_[0..7] */
    {
        /* Clear the old sample time */
        ADC->SMPR1 &= (~(ADC_SMPR1_SMP0_Msk << (4 * Channel)));
        
        /* Set the new sample time */
        ADC->SMPR1 |= (SampleTime << (4 * Channel));

    }
    /*---------------------------- ADCx SMPR2 Configuration -----------------*/
    else /* ADC_Channel include in ADC_Channel_[8..15] */
    {
        /* Clear the old sample time */
        ADC->SMPR2 &= (~(ADC_SMPR2_SMP8_Msk << (4 * (Channel - 8))));

        /* Set the new sample time */
        ADC->SMPR2 |= (SampleTime << (4 * (Channel - 8)));
    }
  
    /*---------------------------- ADCx JSQR Configuration -----------------*/
    ADC->JSQR = (ADC->JSQR & (~ADC_JSQR_JSQ_Msk)) | Channel;

}

/******************************************************************************
* @brief:  Enables or disables the Injection channel group conversion.
* @param:  NewState: new state of of injecting channel group transitions.
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_InjectedConvertCmd(uint32_t NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));
    if (NewState != ADC_STATE_DISABLE)
    {
        ADC->CR1 |= ADC_CR1_JEN;
    }
    else
    {
        ADC->CR1 &= (~ADC_CR1_JEN);
    }
}

/******************************************************************************
* @brief:  Configures the ADCx external trigger for injected channels conversion.
* @param:  Trigger: specifies the ADC trigger to start injected conversion.                        
* @return: None
******************************************************************************/
void ADC_InjectedExternalTriggerConfig(uint32_t Trigger)
{
    /* Check the parameters */
    assert_param(IS_ADC_TRIG(Trigger));
    /* Set the external event selection for injected */
    ADC->CR1 = (ADC->CR1 &= (~ADC_CR1_JEXTSEL_Msk))| (Trigger << ADC_CR1_JEXTSEL_Pos);
}


/******************************************************************************
* @brief:  Enables the selected ADC software start conversion of the injected channels.
* @param:  None.
* @return: None
******************************************************************************/
void ADC_InjectedSoftwareStart(void)
{
    /* Enable the selected ADC conversion for injected group */
    ADC->CR1 |= ADC_CR1_JSWSTART;
}

/******************************************************************************
* @brief:  Gets the selected ADC Software start injected conversion Status.
* @param:  None.
* @return: None
******************************************************************************/
FlagStatus ADC_GetInjectedSoftwareStartStatus(void)
{
    FlagStatus bitstatus = RESET;

    /* Check the status of JSWSTART bit */
    if ((ADC->CR1 & ADC_CR1_JSWSTART) != RESET)
    {
        /* JSWSTART bit is set */
        bitstatus = SET;
    }
    else
    {
        /* JSWSTART bit is reset */
        bitstatus = RESET;
    }
    /* Return the JSWSTART bit status */
    return  bitstatus;
}

/******************************************************************************
* @brief:  Returns the ADC injected channel conversion result
* @param:  None.
* @return: Data conversion value and channel number.
******************************************************************************/
uint32_t ADC_GetInjectedConversionValue(void)
{
    /* Returns the selected injected channel conversion data value */
    return (ADC->JDR); 
}

/******************************************************************************
* @brief:  Enable or disable embedded VREF.
* @param:  NewState: new state of of embedded VREF.
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None
******************************************************************************/
void ADC_EmbeddedVREFCmd(uint32_t NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_STATE(NewState));
    if (NewState != ADC_STATE_DISABLE)
    {
        ADC->TSREF |= ADC_TSREF_VREFBIEN;
        System_Delay(5000);
    }
    else
    {
        ADC->TSREF &= (~ADC_TSREF_VREFBIEN);
        /* VREFBI signal high resistance enable */
        ADC->TSREF |= ADC_TSREF_HIZEN;
    }
}

/******************************************************************************
* @brief:  Configure ADC embedded VREF voltage.
* @param:  Voltage: embedded VREF voltage.
* @return: None
******************************************************************************/
void ADC_EmbeddedVREFVoltageConfig(uint32_t Voltage)
{
    /* Check the parameters */
    assert_param(IS_ADC_EMBEDDED_VREF(Voltage));

    ADC->TSREF = (ADC->TSREF & (~ADC_TSREF_VREFBISEL_Msk)) | Voltage;

}

/******************************************************************************
* @brief:  Enables or disables the specified ADC interrupts.
* @param:  ADC_IT: specifies the ADC interrupt sources to be enabled or disabled.                   
* @param:  NewState: new state of the specified ADC interrupts.
*          This parameter can be: ADC_STATE_ENABLE or ADC_STATE_DISABLE.
* @return: None.
******************************************************************************/
void ADC_ITConfig(uint16_t ADC_IT, uint32_t NewState)  
{
    /* Check the parameters */
    assert_param(IS_ADC_IT_FLAG(ADC_IT));    

    if (NewState != ADC_STATE_DISABLE)
    {
        /* Enable the selected ADC interrupts */
        ADC->IE |= ADC_IT;
    }
    else
    {
        /* Disable the selected ADC interrupts */
        ADC->IE &= (~ADC_IT);
    }
}

/******************************************************************************
* @brief:  Checks whether the specified ADC flag is set or not.
* @param:  ADC_FLAG: specifies the flag to check.                                               
* @return: The new state of ADC_FLAG (SET or RESET).
******************************************************************************/
FlagStatus ADC_GetFlagStatus(uint8_t ADC_FLAG)
{
    FlagStatus bitstatus = RESET;
    /* Check the parameters */
    assert_param(IS_ADC_IT_FLAG(ADC_FLAG));

    /* Check the status of the specified ADC flag */
    if ((ADC->SR & ADC_FLAG) != RESET)
    {
        /* ADC_FLAG is set */
        bitstatus = SET;
    }
    else
    {
        /* ADC_FLAG is reset */
        bitstatus = RESET;
    }
    /* Return the ADC_FLAG status */
    return  bitstatus;
}

/******************************************************************************
* @brief:  Clears the ADCx's pending flags.
* @param:  ADC_FLAG: specifies the flag to clear.                       
* @return: None
******************************************************************************/
void ADC_ClearFlag(uint8_t ADC_FLAG)
{
    /* Check the parameters */
    assert_param(IS_ADC_IT_FLAG(ADC_FLAG));

    /* Clear the selected ADC flags */
    ADC->SR = ADC_FLAG;
}

/******************************************************************************
* @brief:  Checks whether the specified ADC interrupt has occurred or not.
* @param:  ADC_IT: specifies the ADC interrupt source to check.                       
* @return: The new state of ADC_FLAG (SET or RESET).
******************************************************************************/
ITStatus ADC_GetITStatus(uint16_t ADC_IT)
{
    ITStatus bitstatus = RESET;
    uint32_t enablestatus = 0;

    /* Check the parameters */
    assert_param(IS_ADC_IT_FLAG(ADC_IT));

    /* Get the ADC_IT enable bit status */
    enablestatus = (ADC->IE & ADC_IT) ;

    /* Check the status of the specified ADC interrupt */
    if (((ADC->SR & ADC_IT) != RESET) && enablestatus)
    {
        /* ADC_IT is set */
        bitstatus = SET;
    }
    else
    {
        /* ADC_IT is reset */
        bitstatus = RESET;
    }
    /* Return the ADC_IT status */
    return  bitstatus;
}

/******************************************************************************
* @brief:  Clears the ADC's interrupt pending bits.
* @param:  ADC_IT: specifies the ADC interrupt pending bit to clear.
* @return: none
******************************************************************************/
void ADC_ClearITPendingBit(uint32_t ADC_IT)
{
    /* Check the parameters */
    assert_param(IS_ADC_IT_FLAG(ADC_IT));
    
    if((ADC->IE & ADC_IT)!= RESET)
    {
        /* Clear the interrupt pending bits in the RTC_SR register */
        ADC->SR = ADC_IT;
    } 
}
                







/************************ (C) COPYRIGHT AISINOCHIP *****END OF FILE****/
