/**
* @file    Intm_LLd.c
*==================================================================================================
*   Project              : YTMicro AUTOSAR 4.4.0 MCAL
*   Platform             : ARM
*   Peripheral           : Intm_LLd
*   Dependencies         : none
*
*   Autosar Version      : V4.4.0
*   Autosar Revision     : ASR_REL_4_4_REV_0000
*   SW Version           : V2.2.0
*
*   (c) Copyright 2020-2023 Yuntu Microelectronics co.,ltd.
*   All Rights Reserved.
==================================================================================================*/

#ifdef __cplusplus
extern "C"
{
#endif

/*==================================================================================================
                                              INCLUDE FILES
==================================================================================================*/

#include "OsIf.h"
#include "Intm_Lld.h"

/*==================================================================================================
                                      SOURCE FILE VERSION INFORMATION
==================================================================================================*/
#define INTM_LLD_VENDOR_ID_C                    (180)
#define INTM_LLD_AR_REL_MAJOR_VER_C              (4)
#define INTM_LLD_AR_REL_MINOR_VER_C              (4)
#define INTM_LLD_AR_REL_REVISION_VER_C           (0)
#define INTM_LLD_SW_MAJOR_VER_C                  (2)
#define INTM_LLD_SW_MINOR_VER_C                  (2)
#define INTM_LLD_SW_PATCH_VER_C                  (0)
/*==================================================================================================
                                            FILE VERSION CHECKS
==================================================================================================*/
/* Check if source file and INTM_LLD header file are of the same vendor */
#if (INTM_LLD_VENDOR_ID_C != INTM_LLD_VENDOR_ID)
#error "Intm_LLd.c and Intm_LLd.h have different vendor ids"
#endif

/* Check if source file and INTM_LLD header file are of the same Autosar version */
#if (( INTM_LLD_AR_REL_MAJOR_VER_C != INTM_LLD_AR_REL_MAJOR_VER) || \
      ( INTM_LLD_AR_REL_MINOR_VER_C != INTM_LLD_AR_REL_MINOR_VER) || \
      ( INTM_LLD_AR_REL_REVISION_VER_C != INTM_LLD_AR_REL_REVISION_VER))
#error "AutoSar Version Numbers of Intm_LLd.c and Intm_LLd.h are different"
#endif

/* Check if source file and INTM_LLD header file are of the same Software version */
#if (( INTM_LLD_SW_MAJOR_VER_C != INTM_LLD_SW_MAJOR_VER) || \
      ( INTM_LLD_SW_MINOR_VER_C != INTM_LLD_SW_MINOR_VER) || \
      ( INTM_LLD_SW_PATCH_VER_C != INTM_LLD_SW_PATCH_VER))
#error "Software Version Numbers of Intm_LLd.c and Intm_LLd.h are different"
#endif

/*==================================================================================================
                                                GLOBAL VARIABLES
==================================================================================================*/
/*==================================================================================================
                                                LOCAL VARIABLES
==================================================================================================*/
/*==================================================================================================
                                                LOCAL CONSTANTS
==================================================================================================*/
/*==================================================================================================
                                                LOCAL MACROS
==================================================================================================*/

#if ((STD_ON == INTM_PLATFORM_ENABLE_USER_MODE_SUPPORT) && (defined (MCAL_ENABLE_USER_MODE_SUPPORT)))
#define Call_Lld_EnMonitorPrivileged()  \
                OsIf_Trusted_Call(Intm_Lld_EnMonitorPrivileged)
#define Call_Lld_DisMonitorPrivileged()  \
                OsIf_Trusted_Call(Intm_Lld_DisMonitorPrivileged)
#define Call_Lld_AckIrqPrivileged(IrqNumber)  \
                OsIf_Trusted_Call1param(Intm_Lld_AckIrqPrivileged,(IrqNumber))
#define Call_Lld_SelMonitorIrqPrivileged(MonitorIdx, IrqNumber)  \
                OsIf_Trusted_Call2params(Intm_Lld_SelMonitorIrqPrivileged,(MonitorIdx), (IrqNumber))
#define Call_Lld_SetLatencyPrivileged(MonitorIdx, Latency)  \
                OsIf_Trusted_Call2params(Intm_Lld_SetLatencyPrivileged,(MonitorIdx), (Latency))
#define Call_Lld_ResetTimerPrivileged(MonitorIdx)  \
                OsIf_Trusted_Call1param(Intm_Lld_ResetTimerPrivileged,(MonitorIdx))
#define Call_Lld_GetStatusPrivileged(MonitorIdx)  \
                OsIf_Trusted_Call_Return1param(Intm_Lld_GetStatusPrivileged,(MonitorIdx))
#else
#define Call_Lld_EnMonitorPrivileged()  \
                Intm_Lld_EnMonitorPrivileged()
#define Call_Lld_DisMonitorPrivileged()  \
                Intm_Lld_DisMonitorPrivileged()
#define Call_Lld_AckIrqPrivileged(IrqNumber)  \
                Intm_Lld_AckIrqPrivileged(IrqNumber)
#define Call_Lld_SelMonitorIrqPrivileged(MonitorIdx, IrqNumber)  \
                Intm_Lld_SelMonitorIrqPrivileged(MonitorIdx, IrqNumber)
#define Call_Lld_SetLatencyPrivileged(MonitorIdx, Latency)  \
                Intm_Lld_SetLatencyPrivileged(MonitorIdx, Latency)
#define Call_Lld_ResetTimerPrivileged(MonitorIdx)  \
                Intm_Lld_ResetTimerPrivileged(MonitorIdx)
#define Call_Lld_GetStatusPrivileged(MonitorIdx)  \
                Intm_Lld_GetStatusPrivileged(MonitorIdx)
#endif /* (STD_ON == INTM_PLATFORM_ENABLE_USER_MODE_SUPPORT) && (defined (MCAL_ENABLE_USER_MODE_SUPPORT)) */

/*==================================================================================================
                                                LOCAL FUNCTIONS
==================================================================================================*/

#define PLATFORM_START_SEC_CODE
#include "Platform_MemMap.h"

/**
 * @brief         Enables interrupt monitoring feature.
 *
 * @details       This function is non-reentrant and enables the interrupt monitors.
 *
 * @return        void
 *
 * @api
 *
 * @implements    Intm_Lld_EnableMonitor_Activity
 *
 * */
PLATFORM_FUNC static inline void Intm_Lld_EnMonitorPrivileged(void)
{
#if (PLATFORM_INT_MONITOR == STD_ON)
    INTM->GCTRL |= INTM_GCTRL_GEN_MASK;
#endif
}

/**
 * @brief         Disables interrupt monitoring feature.
 *
 * @details       This function is non-reentrant and disables the interrupt monitors.
 *
 * @return        void
 *
 * @api
 *
 * @implements    Intm_Lld_DisableMonitor_Activity
 *
 * */
PLATFORM_FUNC static inline void Intm_Lld_DisMonitorPrivileged(void)
{
#if (PLATFORM_INT_MONITOR == STD_ON)
    INTM->GCTRL &= ~(INTM_GCTRL_GEN_MASK);
#endif
}

/**
 * @brief         Acknowledges a monitored interrupt.
 *
 * @details       This function is reentrant; it acknowledges that a monitored interrupt
 *                has been been served.
 *
 * @param[in]     IrqNumber: The interrupt vector acknowledged.
 * @return void
 *
 * @api
 *
 * @implements    Intm_Lld_AckIrq_Activity
 *
 * */
PLATFORM_FUNC static inline void Intm_Lld_AckIrqPrivileged(IRQn_Type IrqNumber)
{
#if (PLATFORM_INT_MONITOR == STD_ON)
    /* write the IRQ number to ACK the INTM interrupt */
    INTM->GINTACK = ((uint32)IrqNumber) & INTM_GINTACK_SRC_MASK;
    /* clean the ACK IRQ number for the next monitor capture */
    INTM->GINTACK = ((uint32)0U) & INTM_GINTACK_SRC_MASK;
#endif
}

/**
 * @brief         Selects an interrupt to monitor.
 *
 * @details       This function is reentrant; it selects which interrupt is monitored on
 *                a specific interrupt monitor.
 *
 * @param[in]     MonitorIdx: The index of the interrupt monitor used.
 * @param[in]     IrqNumber: The interrupt vector to be monitored.
 * @return void
 *
 * @api
 *
 * @implements    Intm_Lld_SelectMonitoredIrq_Activity
 *
 * */
PLATFORM_FUNC static inline void Intm_Lld_SelMonitorIrqPrivileged(Intm_Lld_MonitorType MonitorIdx, IRQn_Type IrqNumber)
{
#if (PLATFORM_INT_MONITOR == STD_ON)
    INTM->MON[(uint8)MonitorIdx].SEL = INTM_MON_SEL_EN_MASK | ((uint32)IrqNumber & INTM_MON_SEL_IRQ_MASK);
#endif
}

/**
 * @brief         Sets the latency for a monitored interrupt.
 *
 * @details       This function is reentrant; it sets the accepted latency for the
 *                monitored interrupt.
 *
 * @param[in]     MonitorIdx: The index of the interrupt monitor used.
 * @param[in]     Latency: The accepted latency for the monitored interrupt.
 * @return void
 *
 * @api
 *
 * @implements    Intm_Lld_SetLatency_Activity
 *
 * */
PLATFORM_FUNC static inline void Intm_Lld_SetLatencyPrivileged(Intm_Lld_MonitorType MonitorIdx, uint32 Latency)
{
#if (PLATFORM_INT_MONITOR == STD_ON)
    INTM->MON[(uint8)MonitorIdx].THD = (Latency & INTM_MON_THD_THRESHOLD_MASK);
#endif
}

/**
 * @brief         Resets the timer for an interrupt monitor.
 *
 * @details       This function is reentrant; it resets the timer for the interrupt monitor.
 *
 * @param[in]     MonitorIdx: The index of the interrupt monitor used.
 * @return void
 *
 * @api
 *
 * @implements    Intm_Lld_ResetTimer_Activity
 *
 * */
PLATFORM_FUNC static inline void Intm_Lld_ResetTimerPrivileged(Intm_Lld_MonitorType MonitorIdx)
{
#if (PLATFORM_INT_MONITOR == STD_ON)
    INTM->MON[(uint8)MonitorIdx].TMR = 0UL;
#endif
}

/**
 * @brief         Returns the status of an interrupt monitor.
 *
 * @details       This function is reentrant; it returns the status of an interrupt monitor:
 *                0 - latency not exceeded; 1 - timer exceeded latency.
 *
 * @param[in]     MonitorIdx: The index of the interrupt monitor used.
 * @return        uint8: 0 - latency not exceeded; 1 - timer exceeded latency.
 *
 * @api
 *
 * @implements    Intm_Lld_GetStatus_Activity
 *
 * */
PLATFORM_FUNC static inline uint8 Intm_Lld_GetStatusPrivileged(Intm_Lld_MonitorType MonitorIdx)
{
#if (PLATFORM_INT_MONITOR == STD_ON)
    return (uint8)(INTM->MON[(uint8)MonitorIdx].STS);
#else
    return 0U;
#endif
}


/*==================================================================================================
                                                GLOBAL FUNCTIONS
==================================================================================================*/

PLATFORM_FUNC void Intm_Lld_EnableMonitor(void)
{
    Call_Lld_EnMonitorPrivileged();
}

PLATFORM_FUNC void Intm_Lld_DisableMonitor(void)
{
    Call_Lld_DisMonitorPrivileged();
}

PLATFORM_FUNC void Intm_Lld_AckIrq(IRQn_Type IrqNumber)
{
    Call_Lld_AckIrqPrivileged(IrqNumber);
}

PLATFORM_FUNC void Intm_Lld_SelectMonitoredIrq(Intm_Lld_MonitorType MonitorIdx, IRQn_Type IrqNumber)
{
    Call_Lld_SelMonitorIrqPrivileged(MonitorIdx, IrqNumber);
}

PLATFORM_FUNC void Intm_Lld_SetLatency(Intm_Lld_MonitorType MonitorIdx, uint32 Latency)
{
    Call_Lld_SetLatencyPrivileged(MonitorIdx, Latency);
}

PLATFORM_FUNC void Intm_Lld_ResetTimer(Intm_Lld_MonitorType MonitorIdx)
{
    Call_Lld_ResetTimerPrivileged(MonitorIdx);
}

PLATFORM_FUNC uint8 Intm_Lld_GetStatus(Intm_Lld_MonitorType MonitorIdx)
{
    return Call_Lld_GetStatusPrivileged(MonitorIdx);
}

#define PLATFORM_STOP_SEC_CODE
#include "Platform_MemMap.h"

#ifdef __cplusplus
}
#endif

/* End of file Intm_LLd.c */

