#include "OB90R32A2.h"
#include "acmp.h"


void ACMP_Open(uint8_t nACMP_NO, uint8_t nPSEL, uint8_t nNSEL, uint8_t nHYS_RANGE)
{
    switch (nACMP_NO)
    {
    case ACMP_NO_0:
        OB_ACMP->CON_b.EN0   = 1;
        OB_ACMP->CON_b.PSEL0 = nPSEL;
        OB_ACMP->CON_b.NSEL0 = nNSEL;
        OB_ACMP->HYS_b.HYS0  = nHYS_RANGE;
        break;
    case ACMP_NO_1:
        OB_ACMP->CON_b.EN1   = 1;
        OB_ACMP->CON_b.PSEL1 = nPSEL;
        OB_ACMP->CON_b.NSEL1 = nNSEL;
        OB_ACMP->HYS_b.HYS1  = nHYS_RANGE;
        break;
    case ACMP_NO_2:
        OB_ACMP->CON_b.EN2   = 1;
        OB_ACMP->CON_b.PSEL2 = nPSEL;
        OB_ACMP->CON_b.NSEL2 = nNSEL;
        OB_ACMP->HYS_b.HYS2  = nHYS_RANGE;
        break;
    default:
        break;
    }

    NVIC_EnableIRQ(ACMP_IRQn);
}

void ACMP_Close(uint8_t nACMP_NO)
{
    switch (nACMP_NO)
    {
    case ACMP_NO_0:
        OB_ACMP->CON_b.EN0 = 0;
        break;
    case ACMP_NO_1:
        OB_ACMP->CON_b.EN1 = 0;
        break;
    case ACMP_NO_2:
        OB_ACMP->CON_b.EN2 = 0;
        break;
    default:
        break;
    }

    NVIC_DisableIRQ(ACMP_IRQn);
}

void ACMP_SetOutputCfg(uint8_t nACMP_NO, uint8_t nLATCHSEL, uint8_t nPinInvert)
{
    switch (nACMP_NO)
    {
    case ACMP_NO_0:
        OB_ACMP->OUT_b.LATCHSEL0 = nLATCHSEL;
        OB_ACMP->OUT_b.INV0      = nPinInvert;
        break;
    case ACMP_NO_1:
        OB_ACMP->OUT_b.LATCHSEL1 = nLATCHSEL;
        OB_ACMP->OUT_b.INV1      = nPinInvert;
        break;
    case ACMP_NO_2:
        OB_ACMP->OUT_b.LATCHSEL2 = nLATCHSEL;
        OB_ACMP->OUT_b.INV2      = nPinInvert;
        break;
    default:
        break;
    }
}

uint8_t ACMP_GetOutputStatus(uint8_t nACMP_NO, uint8_t nOUTSTA_TYPE)
{
    uint8_t nResult = 0;

    switch(nOUTSTA_TYPE)
    {
    case ACMP_OUTSTA_TYPE_OUT:
        nResult = (OB_ACMP->OUTSTA_b.OUT & (0x01 << nACMP_NO));
        break;
    case ACMP_OUTSTA_TYPE_SRC:
        nResult = (OB_ACMP->OUTSTA_b.SRC & (0x01 << nACMP_NO));
        break;
    case ACMP_OUTSTA_TYPE_LATCH:
        nResult = (OB_ACMP->OUTSTA_b.LATCH & (0x01 << nACMP_NO));
        break;
    default:
        break;
    }

    if (nResult > 0)
    {
        return 1;
    }

    return 0;
}

void ACMP_SetTrgADC0(uint8_t nACMP_NO, uint8_t nTRG_TYPE)
{
    uint32_t nValue = OB_ACMP->TADC0;

    switch (nACMP_NO)
    {
    case ACMP_NO_0:
        nValue &= 0xFFFFFF00;
        nValue |= nTRG_TYPE;
        break;
    case ACMP_NO_1:
        nValue &= 0xFFFF00FF;
        nValue |= (nTRG_TYPE << 8);
        break;
    case ACMP_NO_2:
        nValue &= 0xFF00FFFF;
        nValue |= (nTRG_TYPE << 16);
        break;
    case ACMP_NO_3:
        nValue &= 0x00FFFFFF;
        nValue |= (nTRG_TYPE << 24);
        break;
    default:
        break;
    }

    OB_ACMP->TADC0 = nValue;
}

void ACMP_EnableIE(uint8_t nACMP_NO, uint8_t nIE_TYPE)
{
    OB_ACMP->IEENS = (nIE_TYPE << (nACMP_NO*8));
}

void ACMP_DisableIE(uint8_t nACMP_NO, uint8_t nIE_TYPE)
{
    OB_ACMP->IEENC = (nIE_TYPE << (nACMP_NO*8));
}

uint8_t ACMP_GetIEStatus(uint8_t nACMP_NO, uint8_t nIE_TYPE)
{
    uint32_t nMask = (nIE_TYPE << (nACMP_NO * 8));

    if ((OB_ACMP->IEST & nMask) > 0)
        return 1;
    else
        return 0;
}

void ACMP_ClearIEStatus(uint8_t nACMP_NO, uint8_t nIE_TYPE)
{
    OB_ACMP->IESTC = (nIE_TYPE << (nACMP_NO * 8));
}

