/**
  ******************************************************************************
 *
 * @file        Sample_MID_ADC_GetVrefVoltage.c
 *
 * @brief       Get MCU Vref voltage by sampling VBUF.(Middlwware level)
 *
 * @par         Project
 *              MG32
 * @version     V1.01
 * @date        2021/05/27
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2017 MegaWin Technology Co., Ltd.
 *              All rights reserved.
 *
 ******************************************************************************
* @par Disclaimer
 * The Demo software is provided "AS IS" without any warranty, either
 * expressed or implied, including, but not limited to, the implied warranties
 * of merchantability and fitness for a particular purpose. The author will
 * not be liable for any special, incidental, consequential or indirect
 * damages due to loss of data or any other reason.
 * These statements agree with the world wide and local dictated laws about
 * authorship and violence against these laws.
 *******************************************************************************
 ******************************************************************************
 */


/* Includes ------------------------------------------------------------------*/
#include "MG32_ADC_MID.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static ADC_HandleTypeDef   mADC;

/* Private function prototypes -----------------------------------------------*/
uint16_t Sample_MID_ADC_GetVrefVoltage(void);

/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External vairables --------------------------------------------------------*/



/**
 *******************************************************************************
 * @brief	    ADC enable sum and window detection function.
 * @details     1.Enable internal VBUF 1.4V analog module.   
 *    \n        2.Config ADC base parameter.  
 *    \n        3.Select ADC convert channels.
 *    \n        4.Trigger ADC convert. (for ADC_ONESHOT mode)
 *    \n        5.Convert Vdd Volatge
 * @return      None
 *******************************************************************************
 */
uint16_t Sample_MID_ADC_GetVrefVoltage(void)
{  
    ADC_ChannelConfTypeDef      ADCCh;
    __IO uint32_t VddVoltage;
    __IO uint16_t CalVal;

    // make sure :
    
    //===Set CSC init====
    //MG32_CSC_Init.h(Configuration Wizard)
    //Select CK_HS source = CK_IHRCO
    //Select IHRCO = 12M
    //  Select CK_PLLI Divider = CK_HS/2
    //  Select CK_PLL Multiplication factor = CK_PLLIx16
    //  Select CK_PLLO Divider = CK_PLL/4
    //Select CK_MAIN Source = CK_PLLO
    //Configure PLL->Select APB Prescaler = CK_MAIN/1
    //Configure Peripheral On Mode Clock->ADC = Enable
    //Configure Peripheral On Mode Clock->DMA = Enable
    //Configure Peripheral On Mode Clock->Port A = Enable
    
    
    // User must run 'Systick' routine. (for delay routine)
    // 1. Run 'MID_Init();'
    // 2. Enable 'Systick' in MG32_IRQ_Handler of 'Manage Run-Time Enviroment'
    // 3. Enable 'IRQ Handler' in MG32_ChipInit_Wizard of 'Manage Run-Time Enviroment'
	
    // ------------------------------------------------------------------------
    // 1.Enable internal VBUF 1.4V analog module.  
    // ------------------------------------------------------------------------
    MID_UnProtectModuleReg(PWmodule);
    __DRV_PW_ENANLE_VBUF();
    MID_ProtectModuleReg(PWmodule);
    
    // for VBUF 1.4V settling time
    MID_Delay(1);
    
    // ------------------------------------------------------------------------
    // 2.Config ADC base parameter.  
    // ------------------------------------------------------------------------
    mADC.Instance                   = ADC0;                     // for ADC0
    mADC.Init.ADCConType            = ADC_CONV_SINGLE;          // Single-end type
    mADC.Init.ADCClock              = ADC_CLOCKPROC_DIV16;      // ADC_Clock = ADC_PROC/16 
    mADC.Init.Resolution            = ADC_RESOLUTION_12B;       // ADC conversion resolution
    mADC.Init.DataAlign             = ADC_DATAALIGN_RIGHT;      // ADC data is Right-justified
    mADC.Init.ConversionMode        = ADC_ONESHOT;              // ADC One-Shot mode to converion 
    mADC.Init.LowPowerAutoWait      = ADC_CONTINUE_NEXT;        // ADC will replace the older conversion data (WAIT_EN for scan/loop mode)
    mADC.Init.TriggerConverionSrc   = ADC_SOFTWARE_START;       // ADC trigger event from software command
    mADC.Init.TriggerConverionEdge  = ADC_TRIGCONVEDGE_NONE;    // ADC convert signal from external trigger event edge select
    mADC.Init.Overrun               = ADC_ACCEPT_OVERRUN;       // It will overrun the conversion data   
    mADC.Init.ExtendSamplingTime    = 0;                       // Extend time of 'Sample & Hold' of ADC conversion state (0 ADC_Clock)
    mADC.Init.PGACmd                = PGA_DISABLE;              // Disable ADC PGA
    mADC.Init.PGAGain               = 0;                        // PGA Gain=x1, ADC Gain is equal : (1+(ADC0_GAIN_PGA*3)/(63+(63-ADC0_GAIN_PGA)*3))
    
    MID_ADC_Init(&mADC);
        
    // for ADC settling time
    MID_Delay(1);
    
    // ------------------------------------------------------------------------
    // 3.Select ADC convert channels.
    // ------------------------------------------------------------------------
    ADCCh.Channel                   = ADC_CHANNEL_19;           // select conversion channel mux for ADC_ONESHOT or ADC_REPITIVE_CHANNEL conversion mode
    MID_ADC_ConfigChannel(&mADC, &ADCCh);
    
    // ------------------------------------------------------------------------
    // 4.Trigger ADC convert. (for ADC_ONESHOT mode)
    // ------------------------------------------------------------------------
    MID_ADC_Start(&mADC);
    
    // poll ADC flag within 10ms
    MID_ADC_PollForConversion(&mADC, 10);
    
    // ------------------------------------------------------------------------
    // 5.Convert Vdd Volatge
    // ------------------------------------------------------------------------
    // Convert Vdd voltage (unit:10mV)
    CalVal = (uint16_t) MID_ADC_GetValue(&mADC);
    VddVoltage = (uint32_t) (140 * 4096) ;
    VddVoltage = VddVoltage / CalVal ;
    
    return (uint16_t) VddVoltage;
        
    
}

