

#include "r_typedefs.h"
#include "dr7f701401.dvf.h"
#include "rh850_macros.h"
#include "ADC.h"

/*
1. The A/D Converter (ADCE) requires a minimum operating frequency of 8 MHz.
Make sure that C_ISO_ADCE is not below 8 MHz.
Refer to the Data Sheet for details.
8M~~40M
2. The CKSC_IADCED_CTL register must be set so that the relationship between
frequency of the C_ISO_PCLK and C_ISO_ADCE clocks is retained within the
range of "C_ISO_PCLK/C_ISO_ADCE = 1 to 2.4".
*/

static uint8_t ADC_Get_Physical_Channel(uint8_t u8ADCPhysicalChannelIndex)
{
    uint8_t u8ADCPhysicalChannel = 0XFFU; /* Error  don't use */
    if ( u8ADCPhysicalChannelIndex <= 15U )
    {
        u8ADCPhysicalChannel = u8ADCPhysicalChannelIndex + 0x10;
    }
    else
    {
        u8ADCPhysicalChannel = 0XFFU;
    }
    return u8ADCPhysicalChannel;
}

static uint16_t ADC_Get_Channel_Result(uint8_t u8ADCVirtualChannel)
{
    uint32_t u32ADCRegisterAddress = 0xFFF20000U + 0x100U + 0X02U * u8ADCVirtualChannel;

    return (*( uint16_t * )u32ADCRegisterAddress);
}

static void ADC_Virtual_Channel_Config(uint8_t u8ADCVirtualChannel, uint8_t enADCPhysicalChannel)
{
    uint32_t u32ADCRegisterAddress = 0xFFF20000U + 0X04U * u8ADCVirtualChannel;

    (*( uint16_t * )u32ADCRegisterAddress) = enADCPhysicalChannel;
}

void ADC_Init(const uint8_t u8ChList [], uint8_t u8ChNum)
{

    /*uint32_t u32ADCRegisterValue = SYSMRSTC;*/
    uint8_t i = 0U;

    /*  release  reset*/
    /*
    u32ADCRegisterValue |= 0X10U;
    ADC_PROTECTED_WRITE(SYSPROTCMDMRST, SYSPROTSMRST, SYSMRSTC, u32ADCRegisterValue);
*/
    /* 	GPIO Config , port mode , direction input	*/

    /* Clock Config */
    if ( (u8ChList != 0U) && (u8ChNum <= 15U) )
    {
        /* Virtual Channel Config */
        for ( i = 0U; i < u8ChNum; i++ )
        {
            ADC_Virtual_Channel_Config(i, ADC_Get_Physical_Channel(u8ChList [ i ]));
        }
        /* 12-bit,right align*/
        ADCE0ADCRLL = 0x0U;
        /*sampling time 24 cycles*/
        ADCE0SMPT = 0x18U;
        /* Multicycle,interrupt disable,Hardware trigger disable,repeat once*/
        ADCE0SGCR1LL = 0x0U; /*0x10U  interrupt enable*/
        /*Start Virtual Channel*/
        ADCE0SGVCSP1LL = 0U;
        /* End Virtual Channel*/
        ADCE0SGVCEP1LL = u8ChNum - 1U;
        /* Number of scans is 1*/
        ADCE0MCYC = 0x0U;
    }
    else
    {
        i = 0U;
    }
}
/**/
void ADC_DeInit(void)
{
    while ( ADCE0SGSTRL & 0x200U )
    {
        ADCE0HALT = 0x01U;
    }

    /*Start Virtual Channel*/
    ADCE0SGVCSP1LL = 0U;
    /* End Virtual Channel*/
    ADCE0SGVCEP1LL = 0U;
    /*Virtual Channel0 config  power channel ISOVDD*/
    ADC_Virtual_Channel_Config(0, 0X0FU);
}
void ADC_Start_Conversion(void)
{
    /*A/D conversion for SG1 is completed*/
    if ( (ADCE0SGSTRL & 0x200U) == 0U )
    {
        ADCE0SEFC = 0X01U; /*clear SG1 Scan End Flag*/
        ADCE0SGST = 0x01U; /*start*/
        nop( );
        nop( );
        nop( );
        nop( );
        nop( );
        nop( );
        nop( );
        nop( );
    }
}
void ADC_Stop_Conversion(void)
{
    if ( ADCE0SGSTRL & 0x200U )
    {
        ADCE0HALT = 0x01U;
    }
}
/**************************************************************************/ /**
                                                                              * \brief      Get ADC conversion status
                                                                              * \retval     0 - ADC is idle
                                                                              *             1 - ADC is busy
                                                                              ******************************************************************************/
uint8_t ADC_Get_Conversion_Status(void)
{
    uint8_t u8Status = 0U;

    if ( ADCE0SGSTRL & 0x200U )
    {
        u8Status = 1U;
    }
    else /*A/D conversion for SG1 is completed*/
    {
        u8Status = 0U;
    }
    return u8Status;
}
void ADC_Get_Conversion_Result(uint16_t *pu16Data, uint8_t u8ChNum)
{
    uint8_t i;

    if ( (pu16Data != 0U) && (u8ChNum > 0U) && (u8ChNum <= 16U) )
    {
        if ( ADC_Get_Conversion_Status( ) == 0U )
        {
            for ( i = 0U; i < u8ChNum; i++ )
            {
                pu16Data [ i ] = ADC_Get_Channel_Result(i);
            }
        }
    }
}
