/**************************************************************************/ /**
                                                                              * \file     Analog_Circuits.c
                                                                              * \brief    Analog signal processing algorithm library file
                                                                              * \details
                                                                              * \author   Zhang Xuan
                                                                              * \version  V1.0.0
                                                                              * \date     19-Sep-2018
                                                                              * \par      History:
                                                                              *           V1.0.0 Initial release
                                                                              * \par      Copyright:
                                                                              *           (c) Heilongjiang TYW Electronics co., LTD
                                                                              ******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "r_typedefs.h"
#include "Analog_Circuits.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

uint16_t ADC_Input_Voltage_Calc(uint16_t u16ADCSample, uint16_t u16ADCRes, uint16_t u16VRef)
{
    uint32_t u32ADCVoltage;
    uint16_t u16Result;

    if ( u16ADCRes == 0U )
    {
        u16Result = 0x0000U;
    }
    else if ( u16ADCRes <= u16ADCSample )
    {
        u16Result = u16VRef;
    }
    else
    {
        u32ADCVoltage = ( uint32_t )u16ADCSample;
        u32ADCVoltage *= ( uint32_t )u16VRef;
        u32ADCVoltage /= ( uint32_t )u16ADCRes;

        u16Result = ( uint16_t )u32ADCVoltage;
    }

    return u16Result;
}

uint16_t ADC_VRef_Calibrate(uint16_t u16ADCSample, uint16_t u16ADCRes, uint16_t u16ActVoltage)
{
    uint32_t u32RefVoltage;
    uint16_t u16Result;

    if ( (u16ADCSample == 0U) || (u16ADCSample > u16ADCRes) )
    {
        u16Result = 0x0000U;
    }
    else
    {
        u32RefVoltage = ( uint32_t )u16ActVoltage;
        u32RefVoltage *= ( uint32_t )u16ADCRes;
        u32RefVoltage /= ( uint32_t )u16ADCSample;

        if ( u32RefVoltage & 0xFFFF0000UL )
        {
            u16Result = 0xFFFFU;
        }
        else
        {
            u16Result = ( uint16_t )u32RefVoltage;
        }
    }

    return u16Result;
}

uint16_t ADC_Data_Calibrate(uint16_t u16Value, uint8_t u8CalMode, uint16_t u16CalData)
{
    uint16_t u16Result;

    if ( u8CalMode == 1U )
    {
        if ( 0xFFFFU - u16CalData > u16Value )
        {
            u16Result = u16Value + u16CalData;
        }
        else
        {
            u16Result = 0xFFFFU;
        }
    }
    else if ( u8CalMode == 2U )
    {
        if ( u16Value > u16CalData )
        {
            u16Result = u16Value - u16CalData;
        }
        else
        {
            u16Result = 0x0000U;
        }
    }
    else
    {
        u16Result = u16Value;
    }

    return u16Result;
}

uint16_t ADC_Voltage_Calc_Circuit101(uint16_t u16ADCVoltage, uint16_t u16Reference, uint16_t u16Resolution, const ADC_Res_List_st_t *pstResList)
{
    return u16ADCVoltage / u16Resolution;
}

uint16_t ADC_Voltage_Calc_Circuit102(uint16_t u16ADCVoltage, uint16_t u16Reference, uint16_t u16Resolution, const ADC_Res_List_st_t *pstResList)
{
    uint64_t u64ActVoltage;
    uint32_t u32ResSum;
    uint16_t u16Result;

    if ( pstResList->u32Res2 == 0UL )
    {
        u16Result = 0x0000U;
    }
    else
    {
        u32ResSum     = pstResList->u32Res1 + pstResList->u32Res2;
        u64ActVoltage = ( uint64_t )u16ADCVoltage;
        u64ActVoltage *= ( uint64_t )u32ResSum;
        u64ActVoltage /= ( uint64_t )(pstResList->u32Res2);
        u64ActVoltage /= ( uint64_t )u16Resolution;

        if ( u64ActVoltage & 0xFFFFFFFFFFFF0000ULL )
        {
            u16Result = 0xFFFFU;
        }
        else
        {
            u16Result = ( uint16_t )u64ActVoltage;
        }
    }

    return u16Result;
}

uint16_t ADC_Res_Calc_Circuit101(uint16_t u16ADCVoltage, uint16_t u16Reference, uint16_t u16Resolution, const ADC_Res_List_st_t *pstResList)
{
    uint64_t u64CalcRes;
    uint32_t u32ActRes;
    uint16_t u16VDiff;
    uint16_t u16Result;

    if ( (u16ADCVoltage >= u16Reference) || (pstResList->u32Res4 == 0U) )
    {
        u16Result = 0xFFFFU;
    }
    else
    {
        u16VDiff   = u16Reference - u16ADCVoltage;
        u64CalcRes = ( uint64_t )u16ADCVoltage;
        u64CalcRes *= ( uint64_t )(pstResList->u32Res4);
        u64CalcRes /= ( uint64_t )u16VDiff;

        if ( u64CalcRes & 0xFFFFFFFF00000000ULL )
        {
            u16Result = 0xFFFFU;
        }
        else
        {
            u32ActRes = ( uint32_t )u64CalcRes;
            if ( u32ActRes <= pstResList->u32Res5 )
            {
                u16Result = 0x0000U;
            }
            else
            {
                u32ActRes -= pstResList->u32Res5;
                u32ActRes /= ( uint32_t )u16Resolution;
                if ( u32ActRes & 0xFFFF0000UL )
                {
                    u16Result = 0xFFFFU;
                }
                else
                {
                    u16Result = ( uint16_t )u32ActRes;
                }
            }
        }
    }
    return u16Result;
}

uint16_t ADC_Res_Calc_Circuit102(uint16_t u16ADCVoltage, uint16_t u16Reference, uint16_t u16Resolution, const ADC_Res_List_st_t *pstResList)
{
    uint64_t u64TempValM;
    uint64_t u64TempValN;
    uint64_t u64CalcRes;
    uint32_t u32ActRes;
    uint16_t u16VDiff;
    uint16_t u16Result;

    if ( (u16ADCVoltage >= u16Reference) || (pstResList->u32Res2 == 0U) || (pstResList->u32Res4 == 0U) )
    {
        u16Result = 0xFFFFU;
    }
    else
    {
        u16VDiff    = u16Reference - u16ADCVoltage;
        u64TempValM = ( uint64_t )(pstResList->u32Res2);
        u64TempValM *= ( uint64_t )u16VDiff;

        u64TempValN = ( uint64_t )(pstResList->u32Res4);
        u64TempValN *= ( uint64_t )u16ADCVoltage;

        if ( u64TempValM <= u64TempValN )
        {
            u16Result = 0xFFFFU;
        }
        else
        {
            u64CalcRes = ( uint64_t )u16ADCVoltage;
            u64CalcRes *= ( uint64_t )(pstResList->u32Res2);
            u64CalcRes *= ( uint64_t )(pstResList->u32Res4);
            u64CalcRes /= u64TempValM - u64TempValN;

            if ( u64CalcRes & 0xFFFFFFFF00000000ULL )
            {
                u16Result = 0xFFFFU;
            }
            else
            {
                u32ActRes = ( uint32_t )u64CalcRes;
                if ( u32ActRes <= pstResList->u32Res5 )
                {
                    u16Result = 0x0000U;
                }
                else
                {
                    u32ActRes -= pstResList->u32Res5;
                    u32ActRes /= ( uint32_t )u16Resolution;
                    if ( u32ActRes & 0xFFFF0000UL )
                    {
                        u16Result = 0xFFFFU;
                    }
                    else
                    {
                        u16Result = ( uint16_t )u32ActRes;
                    }
                }
            }
        }
    }
    return u16Result;
}

uint16_t ADC_Res_Calc_Circuit103(uint16_t u16ADCVoltage, uint16_t u16Reference, uint16_t u16Resolution, const ADC_Res_List_st_t *pstResList)
{
    uint64_t u64TempValM;
    uint64_t u64TempValN;
    uint64_t u64ActVoltage;
    uint64_t u64CalcRes;
    uint32_t u32ActRes;
    uint32_t u32ResSum;
    uint16_t u16Result;

    if ( (pstResList->u32Res2 == 0U) || (pstResList->u32Res4 == 0U) )
    {
        u16Result = 0xFFFFU;
    }
    else
    {
        u32ResSum     = pstResList->u32Res1 + pstResList->u32Res2;
        u64ActVoltage = ( uint64_t )u16ADCVoltage;
        u64ActVoltage *= ( uint64_t )u32ResSum;
        u64ActVoltage /= ( uint64_t )(pstResList->u32Res2);

        if ( u64ActVoltage >= ( uint64_t )u16Reference )
        {
            u16Result = 0xFFFFU;
        }
        else
        {
            u64TempValM = ( uint64_t )u32ResSum;
            u64TempValM *= ( uint64_t )u16Reference - u64ActVoltage;

            u64TempValN = ( uint64_t )(pstResList->u32Res4);
            u64TempValN *= u64ActVoltage;

            if ( u64TempValM <= u64TempValN )
            {
                u16Result = 0xFFFFU;
            }
            else
            {
                u64CalcRes = u64ActVoltage;
                u64CalcRes *= ( uint64_t )u32ResSum;
                u64CalcRes *= ( uint64_t )(pstResList->u32Res4);
                u64CalcRes /= u64TempValM - u64TempValN;

                if ( u64CalcRes & 0xFFFFFFFF00000000ULL )
                {
                    u16Result = 0xFFFFU;
                }
                else
                {
                    u32ActRes = ( uint32_t )u64CalcRes;
                    if ( u32ActRes <= pstResList->u32Res5 )
                    {
                        u16Result = 0x0000U;
                    }
                    else
                    {
                        u32ActRes -= pstResList->u32Res5;
                        u32ActRes /= ( uint32_t )u16Resolution;
                        if ( u32ActRes & 0xFFFF0000UL )
                        {
                            u16Result = 0xFFFFU;
                        }
                        else
                        {
                            u16Result = ( uint16_t )u32ActRes;
                        }
                    }
                }
            }
        }
    }
    return u16Result;
}

uint16_t ADC_Res_Calc_Circuit201(uint16_t u16ADCVoltage, uint16_t u16Reference, uint16_t u16Resolution, const ADC_Res_List_st_t *pstResList)
{
    uint64_t u64CalcRes;
    uint32_t u32ActRes;
    uint16_t u16VDiff;
    uint16_t u16Result;

    if ( (u16ADCVoltage >= u16Reference) || (u16ADCVoltage == 0U) || (pstResList->u32Res4 == 0U) || (u16Resolution == 0U) )
    {
        u16Result = 0xFFFFU;
    }
    else
    {
        u16VDiff   = u16Reference - u16ADCVoltage;
        u64CalcRes = ( uint64_t )u16VDiff;
        u64CalcRes *= ( uint64_t )(pstResList->u32Res4);
        u64CalcRes /= ( uint64_t )u16ADCVoltage;

        if ( u64CalcRes & 0xFFFFFFFF00000000ULL )
        {
            u16Result = 0xFFFFU;
        }
        else
        {
            u32ActRes = ( uint32_t )u64CalcRes;
            if ( u32ActRes <= pstResList->u32Res5 )
            {
                u16Result = 0x0000U;
            }
            else
            {
                u32ActRes -= pstResList->u32Res5;
                u32ActRes /= ( uint32_t )u16Resolution;
                if ( u32ActRes & 0xFFFF0000UL )
                {
                    u16Result = 0xFFFFU;
                }
                else
                {
                    u16Result = ( uint16_t )u32ActRes;
                }
            }
        }
    }
    return u16Result;
}

uint16_t ADC_Res_Calc_Circuit202(uint16_t u16ADCVoltage, uint16_t u16Reference, uint16_t u16Resolution, const ADC_Res_List_st_t *pstResList)
{
    uint64_t u64CalcRes;
    uint64_t u64ParallelRes;
    uint32_t u32ActRes;
    uint16_t u16VDiff;
    uint16_t u16Result;

    if ( (u16ADCVoltage >= u16Reference) || (u16ADCVoltage == 0U) || (pstResList->u32Res2 == 0U) || (pstResList->u32Res4 == 0U) || (u16Resolution == 0U) )
    {
        u16Result = 0xFFFFU;
    }
    else
    {
        u64ParallelRes = ( uint64_t )(pstResList->u32Res2);
        u64ParallelRes *= ( uint64_t )(pstResList->u32Res4);
        u64ParallelRes /= ( uint64_t )(pstResList->u32Res2) + ( uint64_t )(pstResList->u32Res4);

        u16VDiff   = u16Reference - u16ADCVoltage;
        u64CalcRes = ( uint64_t )u16VDiff;
        u64CalcRes *= u64ParallelRes;
        u64CalcRes /= ( uint64_t )u16ADCVoltage;

        if ( u64CalcRes & 0xFFFFFFFF00000000ULL )
        {
            u16Result = 0xFFFFU;
        }
        else
        {
            u32ActRes = ( uint32_t )u64CalcRes;
            if ( u32ActRes <= pstResList->u32Res5 )
            {
                u16Result = 0x0000U;
            }
            else
            {
                u32ActRes -= pstResList->u32Res5;
                u32ActRes /= ( uint32_t )u16Resolution;
                if ( u32ActRes & 0xFFFF0000UL )
                {
                    u16Result = 0xFFFFU;
                }
                else
                {
                    u16Result = ( uint16_t )u32ActRes;
                }
            }
        }
    }
    return u16Result;
}

uint16_t ADC_Res_Calc_Circuit203(uint16_t u16ADCVoltage, uint16_t u16Reference, uint16_t u16Resolution, const ADC_Res_List_st_t *pstResList)
{
    uint64_t u64ActVoltage;
    uint64_t u64ParallelRes;
    uint64_t u64CalcRes;
    uint32_t u32ActRes;
    uint32_t u32ResSum;
    uint16_t u16Result;

    if ( (u16ADCVoltage >= u16Reference) || (u16ADCVoltage == 0U) || (pstResList->u32Res2 == 0U) || (pstResList->u32Res4 == 0U) || (u16Resolution == 0U) )
    {
        u16Result = 0xFFFFU;
    }
    else
    {
        u32ResSum     = pstResList->u32Res1 + pstResList->u32Res2;
        u64ActVoltage = ( uint64_t )u16ADCVoltage;
        u64ActVoltage *= ( uint64_t )u32ResSum;
        u64ActVoltage /= ( uint64_t )(pstResList->u32Res2);

        if ( u64ActVoltage >= ( uint64_t )u16Reference )
        {
            u16Result = 0xFFFFU;
        }
        else
        {
            u64ParallelRes = ( uint64_t )u32ResSum;
            u64ParallelRes *= ( uint64_t )(pstResList->u32Res4);
            u64ParallelRes /= ( uint64_t )u32ResSum + ( uint64_t )(pstResList->u32Res4);

            u64CalcRes = ( uint64_t )u16Reference - u64ActVoltage;
            u64CalcRes *= u64ParallelRes;
            u64CalcRes /= u64ActVoltage;

            if ( u64CalcRes & 0xFFFFFFFF00000000ULL )
            {
                u16Result = 0xFFFFU;
            }
            else
            {
                u32ActRes = ( uint32_t )u64CalcRes;
                if ( u32ActRes <= pstResList->u32Res5 )
                {
                    u16Result = 0x0000U;
                }
                else
                {
                    u32ActRes -= pstResList->u32Res5;
                    u32ActRes /= ( uint32_t )u16Resolution;
                    if ( u32ActRes & 0xFFFF0000UL )
                    {
                        u16Result = 0xFFFFU;
                    }
                    else
                    {
                        u16Result = ( uint16_t )u32ActRes;
                    }
                }
            }
        }
    }
    return u16Result;
}

uint16_t ADC_Res_Calc_Circuit301(uint16_t u16ADCVoltage, uint16_t u16Reference, uint16_t u16Resolution, const ADC_Res_List_st_t *pstResList)
{
    uint32_t u32ActRes;
    uint16_t u16Result;

    if ( (u16Reference == 0U) || (u16Resolution == 0U) )
    {
        u16Result = 0xFFFFU;
    }
    else
    {
        u32ActRes = ( uint32_t )u16ADCVoltage;
        u32ActRes *= 10000UL;
        u32ActRes /= ( uint32_t )u16Reference;

        if ( u32ActRes <= pstResList->u32Res5 )
        {
            u16Result = 0x0000U;
        }
        else
        {
            u32ActRes -= pstResList->u32Res5;
            u32ActRes /= ( uint32_t )u16Resolution;
            if ( u32ActRes & 0xFFFF0000UL )
            {
                u16Result = 0xFFFFU;
            }
            else
            {
                u16Result = ( uint16_t )u32ActRes;
            }
        }
    }
    return u16Result;
}

uint16_t ADC_Res_Calc_Circuit302(uint16_t u16ADCVoltage, uint16_t u16Reference, uint16_t u16Resolution, const ADC_Res_List_st_t *pstResList)
{
    uint32_t u32ActRes;
    uint32_t u32Bypass;
    uint16_t u16Result;

    if ( (u16Reference == 0U) || (u16Resolution == 0U) || (pstResList->u32Res2 == 0U) )
    {
        u16Result = 0xFFFFU;
    }
    else
    {
        u32Bypass = ( uint32_t )u16ADCVoltage;
        u32Bypass *= 10000UL;
        u32Bypass /= pstResList->u32Res2;

        if ( u32Bypass >= ( uint32_t )u16Reference )
        {
            u16Result = 0xFFFFU;
        }
        else
        {
            u32ActRes = ( uint32_t )u16ADCVoltage;
            u32ActRes *= 10000UL;
            u32ActRes /= ( uint32_t )u16Reference - u32Bypass;

            if ( u32ActRes <= pstResList->u32Res5 )
            {
                u16Result = 0x0000U;
            }
            else
            {
                u32ActRes -= pstResList->u32Res5;
                u32ActRes /= ( uint32_t )u16Resolution;
                if ( u32ActRes & 0xFFFF0000UL )
                {
                    u16Result = 0xFFFFU;
                }
                else
                {
                    u16Result = ( uint16_t )u32ActRes;
                }
            }
        }
    }
    return u16Result;
}

uint16_t ADC_Res_Calc_Circuit303(uint16_t u16ADCVoltage, uint16_t u16Reference, uint16_t u16Resolution, const ADC_Res_List_st_t *pstResList)
{
    uint64_t u64ActVoltage;
    uint32_t u32ActRes;
    uint32_t u32ResSum;
    uint32_t u32Bypass;
    uint16_t u16Result;

    if ( (u16Reference == 0U) || (u16Resolution == 0U) || (pstResList->u32Res2 == 0U) )
    {
        u16Result = 0xFFFFU;
    }
    else
    {
        u32ResSum     = pstResList->u32Res1 + pstResList->u32Res2;
        u64ActVoltage = ( uint64_t )u16ADCVoltage;
        u64ActVoltage *= ( uint64_t )u32ResSum;
        u64ActVoltage /= ( uint64_t )(pstResList->u32Res2);

        u64ActVoltage *= 10000ULL;
        if ( u64ActVoltage & 0x00000000FFFFFFFFULL )
        {
            u16Result = 0xFFFFU;
        }
        else
        {
            u32Bypass = ( uint32_t )u64ActVoltage;
            u32Bypass /= u32ResSum;

            if ( u32Bypass >= ( uint32_t )u16Reference )
            {
                u16Result = 0xFFFFU;
            }
            else
            {
                u32ActRes = ( uint32_t )u64ActVoltage;
                u32ActRes /= ( uint32_t )u16Reference - u32Bypass;

                if ( u32ActRes <= pstResList->u32Res5 )
                {
                    u16Result = 0x0000U;
                }
                else
                {
                    u32ActRes -= pstResList->u32Res5;
                    u32ActRes /= ( uint32_t )u16Resolution;
                    if ( u32ActRes & 0xFFFF0000UL )
                    {
                        u16Result = 0xFFFFU;
                    }
                    else
                    {
                        u16Result = ( uint16_t )u32ActRes;
                    }
                }
            }
        }
    }
    return u16Result;
}