#include <stdio.h>
#include "Nano100Series.h"
#include "NuEdu-Basic01_Volume_Knob.h"

#define _ADC_Source_Clock   12000000            // from 12MHz XTAL
uint32_t ADC_Clock = 300000;                    // 300 kHz, ADC_F_Max = 42M
uint32_t Open_Volume_Knob_Fail = FALSE;

void Open_Volume_Knob(void)
{
    uint32_t ADC_Source_Clock_DIV;

    //Initial ADC Function Pin
    SYS->PA_L_MFP = (SYS->PA_L_MFP & ~SYS_PA_L_MFP_PA0_MFP_Msk) | SYS_PA_L_MFP_PA0_MFP_ADC_CH0;
    GPIO_DISABLE_DIGITAL_PATH(PA, BIT0);

    //Initial ADC Clock Source
    while(ADC_IS_BUSY(ADC));                    //Safe for other unknown ADC device
    SYS_UnlockReg();
    ADC_Source_Clock_DIV = _ADC_Source_Clock / ADC_Clock;
    if(ADC_Source_Clock_DIV>256)
    {
        Open_Volume_Knob_Fail = TRUE;
        ADC_Source_Clock_DIV = 256;
        ADC_Clock = _ADC_Source_Clock / 256;
        printf("\nADC Clock Initial Fail!\n");
    }
    else
    {
        Open_Volume_Knob_Fail = FALSE;
        //  printf("\nADC Clock Initial Pass!\n");
    }

//  SYS_ResetModule(ADC_RST);                   //Donot Reset ADC, Safe for other unknown ADC device
    CLK_SetModuleClock(ADC_MODULE, CLK_CLKSEL1_ADC_S_HXT, CLK_ADC_CLK_DIVIDER(ADC_Source_Clock_DIV));
    CLK_EnableModuleClock(ADC_MODULE);
    SYS_LockReg();

    //Initial ADC Peripheral
    ADC_Open(ADC, ADC_INPUT_MODE_SINGLE_END, ADC_OPERATION_MODE_SINGLE_CYCLE, ADC_CH_0_MASK);
    ADC_SET_RESOLUTION(ADC, ADC_RESSEL_12_BIT);
    ADC_SET_REF_VOLTAGE(ADC, ADC_REFSEL_POWER);
    ADC_CLR_INT_FLAG(ADC, ADC_ADF_INT);
    ADC_POWER_ON(ADC);
}

void Close_Volume_Knob(void)
{
    //Close ADC Function Pin
    SYS->PA_L_MFP &= ~SYS_PA_L_MFP_PA0_MFP_Msk;
    GPIO_ENABLE_DIGITAL_PATH(PA, BIT0);
//  _ADC_DISABLE_CHANNEL(7);

    if(!(ADC->CHEN&ADC_CHEN_Msk))       //Donot Cloce ADC, Safe for other unknown ADC device
    {
        //Close ADC Clock Source
        SYS_UnlockReg();
        SYS_ResetModule(ADC_RST);
        CLK_DisableModuleClock(ADC_MODULE);
        SYS_LockReg();
    }
}

uint32_t Get_Volume_Knob(void)
{
    uint32_t ADC_Raw_Data;

    //Start ADC Coversion
    ADC_START_CONV(ADC);
    while(!(ADC_GET_INT_FLAG(ADC, ADC_ADF_INT)));
    ADC_CLR_INT_FLAG(ADC, ADC_ADF_INT);
    ADC_Raw_Data = ADC_GET_CONVERSION_DATA(ADC, 0);

    return ADC_Raw_Data;
}
