

#include "rba_DemObdBasic_Prv.h"

#include "Dem_EvMemBase.h"

#if (DEM_CFG_SUPPORT_OBD_DEACTIVATION == DEM_CFG_SUPPORT_OBD_DEACTIVATION_ON )
#include "rba_DemObdBasic_ProjectExtension.h"
#endif

#define DEM_START_SEC_RAM_INIT
#include "Dem_Cfg_MemMap.h"

static Dem_IndicatorStatusType rba_DemObdBasic_Mil = DEM_INDICATOR_OFF;

#define DEM_STOP_SEC_RAM_INIT
#include "Dem_Cfg_MemMap.h"

#define DEM_START_SEC_ROM_CODE
#include "Dem_Cfg_MemMap.h"

void rba_DemObdBasic_Mil_Init(void)
{
    rba_DemObdBasic_Mil_CheckIndicatorState();
}

void rba_DemObdBasic_Mil_Request(boolean state)
{
    if (state == TRUE)
    {
        rba_DemObdBasic_Mil = DEM_INDICATOR_CONTINUOUS;
    }
    else
    {
        rba_DemObdBasic_Mil = DEM_INDICATOR_OFF;
    }
}

void rba_DemObdBasic_Mil_Clear(void)
{
    rba_DemObdBasic_Mil_CheckIndicatorState();
}

void rba_DemObdBasic_Mil_CheckIndicatorState(void)
{
    uint16_least MemId = DEM_CFG_EVMEM_MEMID_PRIMARY; /* for now only primary memory supported */
    uint16_least LocId, LocIdStatus;
    boolean MilOn = FALSE;

    for (Dem_EvMemEventMemoryLocIteratorNew(&LocId, MemId); Dem_EvMemEventMemoryLocIteratorIsValid(&LocId, MemId);
            Dem_EvMemEventMemoryLocIteratorNext(&LocId, MemId))
    {
        LocIdStatus = Dem_EvMemGetEventMemStatus(LocId);
        if (Dem_EvMemIsStored(LocIdStatus))
        {
            if ((rba_DemObdBasic_EvMem_GetMilCounter(LocId) > 0)
                    && ((LocIdStatus & DEM_EVMEM_STSMASK_CONFIRMED) == DEM_EVMEM_STSMASK_CONFIRMED))
            {
                MilOn = TRUE;
                break;
            }
        }
    }
    rba_DemObdBasic_Mil_Request(MilOn);
}

void rba_DemObdBasic_Mil_StartDrivingCycle(void)
{
    uint16_least MemId = DEM_CFG_EVMEM_MEMID_PRIMARY; /* for now only primary memory supported */
    uint16_least LocId, LocIdStatus;

    for (Dem_EvMemEventMemoryLocIteratorNew(&LocId, MemId); Dem_EvMemEventMemoryLocIteratorIsValid(&LocId, MemId);
            Dem_EvMemEventMemoryLocIteratorNext(&LocId, MemId))
    {
        LocIdStatus = Dem_EvMemGetEventMemStatus(LocId);

        if (Dem_EvMemIsStored(LocIdStatus)
                && ((LocIdStatus & DEM_EVMEM_STSMASK_CONFIRMED) == DEM_EVMEM_STSMASK_CONFIRMED))
        {
            if (rba_DemObdBasic_EvMem_GetMilCounter(LocId) > 0)
            {
                /* Failed this failure cycle (== OBD driving cycle)? */
                if (Dem_EvMemIsTestFailedTFC(LocIdStatus))
                {
                    rba_DemObdBasic_EvMem_SetMilCounter(LocId, DEM_OBD_MIL_HEALING_CYCLES);
                }
                /* Completed this failure cycle (== OBD driving cycle)? */
                else if (Dem_EvMemIsTestCompleteTFC(LocIdStatus))
                {
                    /* test passed in last driving cycle -> decrement MIL healing counter */
                    rba_DemObdBasic_EvMem_SetMilCounter(LocId, rba_DemObdBasic_EvMem_GetMilCounter(LocId) - 1);

                    if ((rba_DemObdBasic_EvMem_GetMilCounter(LocId) == 0)
                            && (!Dem_EvtIsWIRExternal(Dem_EvMemGetEventMemEventId(LocId))))
                    {
                        /* Event is no more illuminating the mil -> reset warning indicator bit */
                        rba_DemObdBasic_Event_SetWarningIndicator(Dem_EvMemGetEventMemEventId(LocId), FALSE);
                    }
                }
                else
                {
                    /* do nothing if event not tested */
                }
            }
        }
    }
    rba_DemObdBasic_Mil_CheckIndicatorState();
}

boolean rba_DemObdBasic_Mil_IsEvtRequestingMil(Dem_EventIdType EventId)
{
    uint16_least MemId = DEM_CFG_EVMEM_MEMID_PRIMARY; /* for now only primary memory supported */
    uint16_least LocId;

    LocId = Dem_EvMemGetEventMemoryLocIdOfEvent(EventId, MemId);

    return (Dem_EvMemIsEventMemLocIdValid(LocId)) && (rba_DemObdBasic_Mil_IsEvMemLocRequestingMil(LocId, MemId));
}

boolean rba_DemObdBasic_Mil_IsEvMemLocRequestingMil(uint16_least LocId, uint16_least MemId)
{
    boolean MilRequest = FALSE;

    if (MemId == DEM_CFG_EVMEM_MEMID_PRIMARY) /* for now only primary memory supported */
    {
        if ((Dem_EvMemIsStored(Dem_EvMemGetEventMemStatus(LocId))) && (rba_DemObdBasic_EvMem_GetMilCounter(LocId) > 0)
                && ((Dem_EvMemGetEventMemStatus(LocId) & DEM_EVMEM_STSMASK_CONFIRMED) == DEM_EVMEM_STSMASK_CONFIRMED))
        {
            MilRequest = TRUE;
        }
    }
    return MilRequest;
}

Dem_IndicatorStatusType rba_DemObdBasic_Mil_GetIndicatorStatusInternal(void)
{
    return rba_DemObdBasic_Mil;
}

Dem_IndicatorStatusType rba_DemObdBasic_Mil_GetIndicatorStatusExternal(void)
{
    Dem_IndicatorStatusType retVal = rba_DemObdBasic_Mil_GetIndicatorStatusInternal();

#if (DEM_CFG_SUPPORT_OBD_DEACTIVATION == DEM_CFG_SUPPORT_OBD_DEACTIVATION_ON )
    /*This is project specific and if this callback returns TRUE, then MIL output is disabled*/
    if (rba_DemObdBasic_IsObdDeactivatedByVariant())
    {
        retVal = DEM_INDICATOR_OFF;
    }
#endif

    return retVal;
}

#define DEM_STOP_SEC_ROM_CODE
#include "Dem_Cfg_MemMap.h"

