#include "gw3323_saradc.h"

/**
  * @brief  Initializes the sadc peripheral according to the specified
  *         parameters in the spi_init_struct.
  * @param  sadc_init_struct: pointer to a sadc_init_typedef structure that
  *         contains the configuration information for the specified SADC peripheral.
  * @retval None
  */
void sadc_init(sadc_init_typedef* sadc_init_struct)
{
    uint32_t temp = 0;
    CLKCON0     |= ((uint32_t)sadc_init_struct->clk)<<28;       //select saradc_clk  x26m_clkdiv4
    SADC->baud  = sadc_init_struct->baud;                       //Fadc clock / [2(SADCBAUD+1)] , SARADC bit clock maximum is 1MH
    temp        |= SADC_CON_ADCAEN;                             //hardware auto control analog adc enable
    temp        |= SADC_CON_ADCEN;                              //saradc enable
    SADC->con   = temp;
}

/**
  * @brief  Configures the SADC channel.
  * @param  adc_chx: where x can be (0..15) to select the SADC channel.
  * @param  setup_timing: sadc setup timing.
  * @retval None
  */
void sadc_channel_config(uint8_t adc_chx, SADC_ST_TYPEDEF setup_timing)
{
    //电池电压检测
    if (adc_chx ==ADCCH_VBAT) {
        PWRCON0  |= (uint32_t)(1 << 8);                                     //VBATDIV2 enable
    }
    if (adc_chx == ADCCH_BGOP) {
        PWRCON0  |= (uint32_t)(1 << 22);                                    //BG output enable
    }
    SADC->cst |= ((uint32_t)setup_timing)<<(adc_chx*2);          //延时采样配置
}

/**
  * @brief  Enable or disable the specified SADC peripheral.
  * @param  state: state of the SADC peripheral.
            This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void sadc_cmd(FUNCTIONAL_STATE state)
{
    if(state) {
        SADC->con |= SADC_CON_ADCEN;
    } else {
        SADC->con &= (uint32_t)~SADC_CON_ADCEN;
    }
}

/**
  * @brief  Enable or disable the specified SADC interrupts.
  * @param  state: state of the SADC interrupts.
            This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void sadc_it_cmd(FUNCTIONAL_STATE state)
{
    if(state) {
        SADC->con |= SADC_CON_ADCIEN;
    } else {
        SADC->con &= (uint32_t)~SADC_CON_ADCIEN;
    }
}

/**
  * @brief  Set the SADC baud register value.
  * @param  div: specifies the baud register new value.
  * @retval None
  */
void sadc_set_baud(uint16_t div)
{
    SADC->baud = div;
}

/**
  * @brief  SADC start kick.
  * @param  adc_ch: the adc channels.
  * @param  auto_anl_en: saradc auto enable analog IO enable.
  * @retval None
  */
void sadc_kick_start(uint16_t adc_ch, uint8_t auto_anl_en)
{
    uint32_t temp;
    if (!adc_ch) {
        return;
    }
    temp = SADC->con;
    if (auto_anl_en) {
        temp |= SADC_CON_ADCANGIOEN;          //saradc auto enable analog IO enable
    } else {
        temp &= (uint32_t)~SADC_CON_ADCANGIOEN;
    }
    temp |= SADC_CON_ADCEN;              //saradc enable
    SADC->ch  = 0;                       //clear pending
    SADC->con = temp;
    SADC->ch  = adc_ch;
}

/**
  * @brief  Get the sadc pending.
  * @param  sadc_flag: specifies the flag to set.
  *         this parameter can be one of the following values:
  *             @arg SADC_FLAG_PENDING: SADC pending.
  * @retval The state of sadc_flag (SET or RESET).
  */
FLAG_STATE sadc_get_flag(uint32_t sadc_flag)
{
    if ((SADC->ch & sadc_flag) != RESET) {
        return SET;
    }
    return RESET;
}

/**
  * @brief  Clear the SADC pending.
  * @param  sadc_flag: specifies the flag to clear.
  *         this parameter can be one of the following values:
  *             @arg SADC_FLAG_PENDING: SADC pending.
  * @retval None
  */
void sadc_clear_flag(uint32_t sadc_flag)
{
     SADC->ch |= sadc_flag;
}

/**
  * @brief  Get the sadc data.
  * @param  adc_chx: where x can be (0..15) to select the SADC channel.
  * @retval sadc data.
  */
uint32_t sadc_get_data(u8 adc_chx)
{
    return SADC->dat[adc_chx];
}
