/******************************************************************************
* Copyright (C) 2017, Huada Semiconductor Co.,Ltd All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file adc.c
 **
 ** ADC driver API.
 **
 **   - 2017-06-28 Alex    First Version
 **
 ******************************************************************************/

/******************************************************************************
 * Include files
 ******************************************************************************/
#include "adc.h"

/**
 ******************************************************************************
 ** \addtogroup AdcGroup
 ******************************************************************************/
//@{

/******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/

/******************************************************************************
 * Global variable definitions (declared in header file with 'extern')
 ******************************************************************************/

/******************************************************************************
 * Local type definitions ('typedef')
 ******************************************************************************/

/******************************************************************************
 * Local function prototypes ('static')
 ******************************************************************************/

/******************************************************************************
 * Local variable definitions ('static')
 ******************************************************************************/

/*****************************************************************************
 * Function implementation - global ('extern') and local ('static')
 *****************************************************************************/
/**
 * \brief
 *          获取ADC中断状态
 *
 * \param   [in]  enAdcIrq  ADC中断类型 @ref en_adc_irq_type_t
 *
 * \retval  中断标志
 */
boolean_t Adc_GetIrqStatus(en_adc_irq_type_t enAdcIrq)
{
    if(M0P_ADC->IFR&enAdcIrq)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

/**
 * \brief
 *          获取ADC中断状态
 *
 * \param   [in]  enAdcIrq  ADC中断类型 @ref en_adc_irq_type_t
 *
 * \retval  Null
 */
void Adc_ClrIrqStatus(en_adc_irq_type_t enAdcIrq)
{
    M0P_ADC->ICR &= ~(uint32_t)enAdcIrq;
}

/**
 * \brief
 *          ADC中断使能
 *
 * \param   无
 *
 * \retval  无
 */
void Adc_EnableIrq(void)
{
    M0P_ADC->CR0_f.IE = 1u;
}

/**
 * \brief
 *          ADC中断禁止
 *
 * \param   无
 *
 * \retval  无
 */
void Adc_DisableIrq(void)
{
    M0P_ADC->CR0_f.IE = 0u;
}

/**
 * \brief
 *          ADC初始化
 *
 * \param   [in]  pstcAdcCfg  ADC配置指针
 *
 * \retval  en_result_t  Ok:  配置成功
 * \retval  en_result_t  ErrorInvalidParameter: 无效参数
 */
en_result_t Adc_Init(stc_adc_cfg_t* pstcAdcCfg)
{
    if (NULL == pstcAdcCfg)
    {
        return ErrorInvalidParameter;
    }

    M0P_ADC->CR0 = 0x1u;    ///< ADC 使能
    delay10us(2);

    M0P_ADC->CR0 |= (uint32_t)pstcAdcCfg->enAdcClkDiv       |
                    (uint32_t)pstcAdcCfg->enAdcRefVolSel    |
                    (uint32_t)pstcAdcCfg->enAdcOpBuf        |
                    (uint32_t)pstcAdcCfg->enAdcSampCycleSel |
                    (uint32_t)pstcAdcCfg->enInRef;

    M0P_ADC->CR1_f.MODE  = pstcAdcCfg->enAdcMode;
    M0P_ADC->CR1_f.ALIGN = pstcAdcCfg->enAdcAlign;

    return Ok;
}


/**
 * \brief
 *          ADC单次转换外部中断触发源配置
 *
 * \param   [in]  enAdcTrigSel  触发源
 *
 * \retval  en_result_t  Null
 */
void Adc_SglExtTrigCfg(en_adc_trig_sel_t enAdcTrigSel, boolean_t bValue)
{
    if(TRUE == bValue)
    {
        M0P_ADC->EXTTRIGGER0 |= (uint32_t)enAdcTrigSel;
    }
    else
    {
        M0P_ADC->EXTTRIGGER0 &= ~(uint32_t)enAdcTrigSel;
    }

}

/**
 * \brief
 *          ADC顺序扫描转换外部中断触发源配置
 *
 * \param   [in]  enAdcTrigSel  触发源
 * \param   [in]  TRUE or FALSE
 *
 * \retval  en_result_t  Null
 */
void Adc_SqrExtTrigCfg(en_adc_trig_sel_t enAdcTrigSel, boolean_t bValue)
{
    if(TRUE == bValue)
    {
        M0P_ADC->EXTTRIGGER0 |= (uint32_t)enAdcTrigSel;
    }
    else
    {
        M0P_ADC->EXTTRIGGER0 &= ~(uint32_t)enAdcTrigSel;
    }

}

/**
 * \brief
 *          ADC插队扫描转换外部中断触发源配置
 *
 * \param   [in]  enAdcTrigSel  触发源
 * \param   [in]  TRUE or FALSE
 *
 * \retval  en_result_t  Null
 */
void Adc_JqrExtTrigCfg(en_adc_trig_sel_t enAdcTrigSel, boolean_t bValue)
{
    if(TRUE == bValue)
    {
        M0P_ADC->EXTTRIGGER1 |= (uint32_t)enAdcTrigSel;
    }
    else
    {
        M0P_ADC->EXTTRIGGER1 &= ~(uint32_t)enAdcTrigSel;
    }

}


/**
 * \brief
 *          ADC 单次转换开始
 *
 * \param   无
 *
 * \retval  无
 */

void Adc_SGL_Start(void)
{
    M0P_ADC->SGLSTART = 1u;
}

/**
 * \brief
 *          ADC 单次转换停止
 *
 * \param   无
 *
 * \retval  无
 */
void Adc_SGL_Stop(void)
{
    M0P_ADC->SGLSTART = 0u;
}

/**
 * \brief
 *          ADC 单次转换一直转换开始
 *
 * \param   无
 *
 * \retval  无
 */

void Adc_SGL_Always_Start(void)
{
    M0P_ADC->ALLSTART = 1u;
}

/**
 * \brief
 *          ADC 单次转换一直转换停止
 *
 * \param   无
 *
 * \retval  无
 */

void Adc_SGL_Always_Stop(void)
{
    M0P_ADC->ALLSTART = 0u;
}

/**
 * \brief
 *          ADC 顺序扫描转换开始
 *
 * \param   无
 *
 * \retval  无
 */

void Adc_SQR_Start(void)
{
    M0P_ADC->SQRSTART = 1u;
}

/**
 * \brief
 *          ADC 顺序扫描转换停止
 *
 * \param   无
 *
 * \retval  无
 */
void Adc_SQR_Stop(void)
{
    M0P_ADC->SQRSTART = 0u;
}
/**
 * \brief
 *          ADC 插队扫描转换开始
 *
 * \param   无
 *
 * \retval  无
 */

void Adc_JQR_Start(void)
{
    M0P_ADC->JQRSTART = 1u;
}

/**
 * \brief
 *          ADC 插队扫描转换停止
 *
 * \param   无
 *
 * \retval  无
 */
void Adc_JQR_Stop(void)
{
    M0P_ADC->JQRSTART = 0u;
}

/**
 * \brief
 *          ADC使能
 *
 * \param   无
 *
 * \retval  无
 */
void Adc_Enable(void)
{
    M0P_ADC->CR0_f.EN = 1u;
}

/**
 * \brief
 *          ADC除能
 *
 * \param   无
 *
 * \retval  无
 */
void Adc_Disable(void)
{
    M0P_ADC->CR0_f.EN = 0u;
}

/**
 * \brief
 *          配置顺序扫描转换模式
 *
 * \param   [in]  pstcAdcCfg   ADC配置指针
 * \param   [in]  pstcAdcNormCfg  连续转换模式配置指针
 *
 * \retval  en_result_t  Ok:  配置成功
 * \retval  en_result_t  ErrorInvalidParameter: 无效参数
 */
en_result_t Adc_SqrModeCfg(stc_adc_sqr_cfg_t* pstcAdcSqrCfg)
{
    if ((NULL == pstcAdcSqrCfg) || (pstcAdcSqrCfg->u8SqrCnt > 16))
    {
        return ErrorInvalidParameter;
    }

    M0P_ADC->CR1_f.RACCCLR = 0; //ADC转换结果累加寄存器（ADC_ResultAcc）清零
    M0P_ADC->CR1_f.RACCEN  = pstcAdcSqrCfg->enResultAcc;
    M0P_ADC->CR1_f.DMASQR  = pstcAdcSqrCfg->bSqrDmaTrig;

    M0P_ADC->SQR2_f.CNT  = pstcAdcSqrCfg->u8SqrCnt - 1;

    return Ok;
}

/**
 * \brief
 *          配置插队扫描转换模式
 *
 * \param   [in]  pstcAdcCfg   ADC配置指针
 * \param   [in]  pstcAdcNormCfg  扫描转换模式配置指针
 *
 * \retval  en_result_t  Ok:  配置成功
 * \retval  en_result_t  ErrorInvalidParameter: 无效参数
 */
en_result_t Adc_JqrModeCfg(stc_adc_jqr_cfg_t* pstcAdcJqrCfg)
{
    if ((NULL == pstcAdcJqrCfg) || (pstcAdcJqrCfg->u8JqrCnt > 4))
    {
        return ErrorInvalidParameter;
    }

    M0P_ADC->CR1_f.DMASQR  = pstcAdcJqrCfg->bJqrDmaTrig;

    M0P_ADC->JQR_f.CNT  = pstcAdcJqrCfg->u8JqrCnt - 1;

    return Ok;
}

/**
 * \brief
 *          配置单次转换通道
 *
 * \param   [in]enstcAdcSampCh 转换通道
 *
 * \retval  en_result_t  Ok:  成功
 * \retval  en_result_t  ErrorInvalidParameter: 无效参数
 */
en_result_t Adc_CfgSglChannel( en_adc_samp_ch_sel_t enstcAdcSampCh)
{
    M0P_ADC->CR0_f.SGLMUX = enstcAdcSampCh;

    return Ok;
}

/**
 * \brief
 *          配置顺序扫描转换通道
 *
 * \param   [in]enstcAdcSqrChMux 顺序扫描转换通道顺序
 * \param   [in]enstcAdcSampCh   转换通道
 *
 * \retval  en_result_t  Ok:  成功
 * \retval  en_result_t  ErrorInvalidParameter: 无效参数
 */
en_result_t Adc_CfgSqrChannel(en_adc_sqr_chmux_t enstcAdcSqrChMux, en_adc_samp_ch_sel_t enstcAdcSampCh)
{
    en_result_t enResult = Ok;
    
    switch(enstcAdcSqrChMux)
    {
        case AdcSQRCH0MUX:
            M0P_ADC->SQR0_f.CH0MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH1MUX:
            M0P_ADC->SQR0_f.CH1MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH2MUX:
            M0P_ADC->SQR0_f.CH2MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH3MUX:
            M0P_ADC->SQR0_f.CH3MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH4MUX:
            M0P_ADC->SQR0_f.CH4MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH5MUX:
            M0P_ADC->SQR0_f.CH5MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH6MUX:
            M0P_ADC->SQR1_f.CH6MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH7MUX:
            M0P_ADC->SQR1_f.CH7MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH8MUX:
            M0P_ADC->SQR1_f.CH8MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH9MUX:
            M0P_ADC->SQR1_f.CH9MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH10MUX:
            M0P_ADC->SQR1_f.CH10MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH11MUX:
            M0P_ADC->SQR1_f.CH11MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH12MUX:
            M0P_ADC->SQR2_f.CH12MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH13MUX:
            M0P_ADC->SQR2_f.CH13MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH14MUX:
            M0P_ADC->SQR2_f.CH14MUX = enstcAdcSampCh;
        break;
        case AdcSQRCH15MUX:
            M0P_ADC->SQR2_f.CH15MUX = enstcAdcSampCh;
        break;
        default:
            enResult = ErrorInvalidParameter;
        break;

    }
    
    return enResult;
}
/**
 * \brief
 *          配置插队扫描转换通道
 *
 * \param   [in]enstcAdcSqrChMux 插队扫描转换通道顺序
 * \param   [in]enstcAdcSampCh   转换通道
 *
 * \retval  en_result_t  Ok:  成功
 * \retval  en_result_t  ErrorInvalidParameter: 无效参数
 */
en_result_t Adc_CfgJqrChannel(en_adc_jqr_chmux_t enstcAdcJqrChMux, en_adc_samp_ch_sel_t enstcAdcSampCh)
{
    en_result_t enResult = Ok;
    
    switch(enstcAdcJqrChMux)
    {
        case AdcJQRCH0MUX:
            M0P_ADC->JQR_f.CH0MUX = enstcAdcSampCh;
        break;
        case AdcJQRCH1MUX:
            M0P_ADC->JQR_f.CH1MUX = enstcAdcSampCh;
        break;
        case AdcJQRCH2MUX:
            M0P_ADC->JQR_f.CH2MUX = enstcAdcSampCh;
        break;
        case AdcJQRCH3MUX:
            M0P_ADC->JQR_f.CH3MUX = enstcAdcSampCh;
        break;
        default:
            enResult = ErrorInvalidParameter;
        break;
    }
    
    return enResult;
}

/**
 * \brief
 *          获取采样值
 *
 *
 * \retval  en_result_t  采样值
 */
uint32_t Adc_GetSglResult(void)
{
    return M0P_ADC->RESULT;
}

/**
 * \brief
 *          获取采样值
 *
 * \param   [in] enstcAdcSqrChMux  顺序扫描通道序号 @ref en_adc_sqr_chmux_t
 *
 * \retval  en_result_t  采样值
 */
uint32_t Adc_GetSqrResult(en_adc_sqr_chmux_t enstcAdcSqrChMux)
{
    volatile uint32_t *BaseSqrResultAddress = &(M0P_ADC->SQRRESULT0);

    return *(BaseSqrResultAddress + enstcAdcSqrChMux);

}

/**
 * \brief
 *          获取插队扫描采样值
 *
 * \param   [in] enstcAdcJqrChMux  插队扫描通道序号@ref en_adc_jqr_chmux_t
 *
 * \retval  en_result_t  采样值
 */
uint32_t Adc_GetJqrResult(en_adc_jqr_chmux_t enstcAdcJqrChMux)
{
      volatile uint32_t *BaseJqrResultAddress = &(M0P_ADC->JQRRESULT0);

      return *(BaseJqrResultAddress + enstcAdcJqrChMux);

}

/**
 * \brief
 *          获取累加采样值
 *
 *
 * \retval  en_result_t  累加采样结果
 */
uint32_t Adc_GetAccResult(void)
{
    return M0P_ADC->RESULTACC;

}

/**
 * \brief
 *          清零累加采样值
 *
 * \param   无
 *
 * \retval  无
 */
void Adc_ClrAccResult(void)
{
    M0P_ADC->CR1_f.RACCCLR = 0u;
}

/**
 * \brief
 *          ADC比较使能(比较中断)
 *
 * \param   [in]  pstcAdcIrqCfg  ADC比较配置 @ref stc_adc_threshold_cfg_t
 *
 * \retval  无
 */

void Adc_ThresholdCfg(stc_adc_threshold_cfg_t* pstcAdcThrCfg)
{
    M0P_ADC->HT = pstcAdcThrCfg->u32AdcHighThd;
    M0P_ADC->LT = pstcAdcThrCfg->u32AdcLowThd;

    M0P_ADC->CR1_f.THCH = pstcAdcThrCfg->enSampChSel;

    M0P_ADC->CR1_f.REGCMP = pstcAdcThrCfg->bAdcRegCmp;
    M0P_ADC->CR1_f.HTCMP  = pstcAdcThrCfg->bAdcHtCmp;
    M0P_ADC->CR1_f.LTCMP  = pstcAdcThrCfg->bAdcLtCmp;

}


//@} // AdcGroup


/******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/

