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

#ifdef __cplusplus
extern "C"
{
#endif
/**
 * @page misra_violations MISRA-C:2012 violations List
 * PRQA S 2985 Rule 2.2: The operation here is redundant as the result's Value is always that of the left-hand operand.
 * PRQA S 2986 Rule 2.2: This operation is redundant. The value of the result is always that of the right-hand operand.
 * PRQA S 4700 CMN-0.2: Metric value out of threshold range: %s.
 * PRQA S 0306 Rule 11.4: A conversion should not be performed between a pointer to object and an integer type.
 */


/*==================================================================================================
 *                                          INCLUDE FILES
==================================================================================================*/
#include "Mcu_Lld_Reg.h"
#include "Mcu_Lld.h"
#include "Platform.h"

#if (MCU_ENABLE_DEM_REPORT_ERROR_STATUS == STD_ON)
#include "Dem.h"
#endif /* MCU_ENABLE_DEM_REPORT_ERROR_STATUS == STD_ON */
/*==================================================================================================
 *                                 SOURCE FILE VERSION INFORMATION
==================================================================================================*/
#define MCU_LLD_VENDOR_ID_C                      (180)
#define MCU_LLD_AR_RELEASE_MAJOR_VERSION_C       (4)
#define MCU_LLD_AR_RELEASE_MINOR_VERSION_C       (4)
#define MCU_LLD_AR_RELEASE_REVISION_VERSION_C    (0)
#define MCU_LLD_SW_MAJOR_VERSION_C               (0)
#define MCU_LLD_SW_MINOR_VERSION_C               (8)
#define MCU_LLD_SW_PATCH_VERSION_C               (0)
/*==================================================================================================
 *                                       FILE VERSION CHECKS
==================================================================================================*/
/* Mcu_Lld_Reg.h version check */
#if (MCU_LLD_VENDOR_ID_C != MCU_LLD_REG_VENDOR_ID)
#error "Mcu_Lld.c and Mcu_Lld_Reg.h have different vendor ids"
#endif

#if ((MCU_LLD_AR_RELEASE_MAJOR_VERSION_C != MCU_LLD_REG_AR_RELEASE_MAJOR_VERSION) || \
     (MCU_LLD_AR_RELEASE_MINOR_VERSION_C != MCU_LLD_REG_AR_RELEASE_MINOR_VERSION) || \
     (MCU_LLD_AR_RELEASE_REVISION_VERSION_C != MCU_LLD_REG_AR_RELEASE_REVISION_VERSION) \
    )
#error "AutoSar Version Numbers of Mcu_Lld.c and Mcu_Lld_Reg.h are different"
#endif

#if ((MCU_LLD_SW_MAJOR_VERSION_C != MCU_LLD_REG_SW_MAJOR_VERSION) || \
     (MCU_LLD_SW_MINOR_VERSION_C != MCU_LLD_REG_SW_MINOR_VERSION) || \
     (MCU_LLD_SW_PATCH_VERSION_C != MCU_LLD_REG_SW_PATCH_VERSION) \
    )
#error "Software Version Numbers of Mcu_Lld.c and Mcu_Lld_Reg.h are different"
#endif

/* Mcu_Lld.h version check */
#if (MCU_LLD_VENDOR_ID_C != MCU_LLD_VENDOR_ID)
#error "Mcu_Lld.c and Mcu_Lld.h have different vendor ids"
#endif

#if ((MCU_LLD_AR_RELEASE_MAJOR_VERSION_C != MCU_LLD_AR_RELEASE_MAJOR_VERSION) || \
     (MCU_LLD_AR_RELEASE_MINOR_VERSION_C != MCU_LLD_AR_RELEASE_MINOR_VERSION) || \
     (MCU_LLD_AR_RELEASE_REVISION_VERSION_C != MCU_LLD_AR_RELEASE_REVISION_VERSION) \
    )
#error "AutoSar Version Numbers of Mcu_Lld.c and Mcu_Lld.h are different"
#endif

#if ((MCU_LLD_SW_MAJOR_VERSION_C != MCU_LLD_SW_MAJOR_VERSION) || \
     (MCU_LLD_SW_MINOR_VERSION_C != MCU_LLD_SW_MINOR_VERSION) || \
     (MCU_LLD_SW_PATCH_VERSION_C != MCU_LLD_SW_PATCH_VERSION) \
    )
#error "Software Version Numbers of Mcu_Lld.c and Mcu_Lld.h are different"
#endif


/*==================================================================================================
 *                                         GLOBAL VARIABLES
==================================================================================================*/
/*==================================================================================================
 *                                         LOCAL VARIABLES
==================================================================================================*/

#define MCU_START_SEC_VAR_CLEARED_32
#include "Mcu_MemMap.h"

#if (MCU_LLD_PCU_ISR_USED == STD_ON)
/* Store the Pcu notification functions */
MCU_VAR static Mcu_NotificationType Mcu_PcuNotiList[MCU_PCU_DOMAIN_NUMS];
#endif

#if (MCU_LLD_SCU_ISR_USED == STD_ON)
/* Store the cmu enable state */
MCU_VAR static boolean Mcu_CmuIntEnableList[MCU_CMU_CHANNEL_NUMS];
/* Store the Cmu notification function */
MCU_VAR static Mcu_CmuNotificationType Mcu_CmuNotiList[MCU_CMU_CHANNEL_NUMS];
#endif

#define MCU_STOP_SEC_VAR_CLEARED_32
#include "Mcu_MemMap.h"


#define MCU_START_SEC_VAR_INIT_32
#include "Mcu_MemMap.h"
/* Store last reset reason when reset is empty */
MCU_VAR static Mcu_RawResetType Mcu_ResetStatusValue = 0U;
#define MCU_STOP_SEC_VAR_INIT_32
#include "Mcu_MemMap.h"

/*==================================================================================================
 *                                         LOCAL CONSTANTS
==================================================================================================*/

/*==================================================================================================
 *                                           LOCAL MACROS
==================================================================================================*/
#define MCU_START_SEC_CONST_UNSPECIFIED
#include "Mcu_MemMap.h"
MCU_CONST static volatile SCU_Type *const Mcu_ScuBasePtr[SCU_INSTANCE_COUNT] = SCU_BASE_PTRS;
MCU_CONST static volatile RCU_Type *const Mcu_RcuBasePtr[RCU_INSTANCE_COUNT] = RCU_BASE_PTRS;
MCU_CONST static volatile EFM_Type *const Mcu_EfmBasePtr[EFM_INSTANCE_COUNT] = EFM_BASE_PTRS;
MCU_CONST static volatile PCU_Type *const Mcu_PcuBasePtr[PCU_INSTANCE_COUNT] = PCU_BASE_PTRS;
MCU_CONST static volatile IPC_Type *const Mcu_IpcBasePtr[IPC_INSTANCE_COUNT] = IPC_BASE_PTRS;
#if defined (CPU_YTM32B1MD2)
MCU_CONST static volatile CMU_Type *const Mcu_CmuBasePtr[CMU_INSTANCE_COUNT] = CMU_BASE_PTRS;
MCU_CONST static volatile CFMU_Type *const Mcu_CfmuBasePtr[CFMU_INSTANCE_COUNT] = CFMU_BASE_PTRS;
#endif
#if defined (CPU_YTM32B1ME1)
MCU_CONST static volatile EEPROM_Type *const Mcu_EepromBasePtr[EEPROM_INSTANCE_COUNT] = EEPROM_BASE_PTRS;
#endif

#define MCU_STOP_SEC_CONST_UNSPECIFIED
#include "Mcu_MemMap.h"

#define MCU_REG_ADDR32_AREA_WRITE(register, mask, value) ((register) = ((register) & (~(mask))) | (value))

#define MCU_CMU_ENABLE_AREA_OFFSET (uint32)(8U)
#define MCU_CMU_REFERENCE_AREA_OFFSET (uint32)(16U)
#define SCU_CMUSTS_CMUX_LOSR_MASK(Channel) (uint32)(((uint32)SCU_CMUSTS_CMU0_LOSR_MASK) << (Channel))
#define SCU_CMUSTS_CMUX_OUTRNG_MASK(Channel) (uint32)(((uint32)SCU_CMUSTS_CMU0_OUTRNG_MASK) << (Channel))
#define SCU_CMUSTS_CMUX_LOSC_MASK(Channel) (uint32)(((uint32)SCU_CMUSTS_CMU0_LOSC_MASK) << (Channel))
#define SCU_CMU_CTRL_CMUX_RE(Channel) (uint32)((uint32)(SCU_CMU_CTRL_CMU0_RE_MASK) << (Channel))
#define SCU_CMUSTS_MASK (0x000F0F0FU)

#define MCU_FXOSC_SWEEP_GAIN_ADD (0U)
#define MCU_FXOSC_SWEEP_GAIN_SUB (1U)
/*==================================================================================================
 *                                         LOCAL FUNCTIONS
==================================================================================================*/
/**
 * MR12 RULE 2.2 VIOLATION: The operation here is redundant as the result's value is always that
 * of the left-hand operand.This line of code has been maintained for the sake of code clarity and
 * readability.
 */
#define MCU_START_SEC_CODE
#include "Mcu_MemMap.h"
/**
 * @brief         Disable all Clock Monitor Unit (CMU) channels on the device.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_DisableAllCmu(void)
{
#if defined (CPU_YTM32B1MD2)
    volatile CMU_Type *CmuBase = Mcu_CmuBasePtr[0];
    CmuBase->CTRL &= ~(CMU_CTRL_EN_MASK);
#elif defined(CPU_YTM32B1MC0)
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    ScuBase->CMU_CTRL = ScuBase->CMU_CTRL & ~(SCU_CMU_CTRL_CMU0_EN_MASK | SCU_CMU_CTRL_CMU1_EN_MASK);
#else
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    ScuBase->CMU_CTRL &= ~(SCU_CMU_CTRL_CMU0_EN_MASK | SCU_CMU_CTRL_CMU1_EN_MASK | SCU_CMU_CTRL_CMU2_EN_MASK | SCU_CMU_CTRL_CMU3_EN_MASK);
#endif
}

/**
 * @brief         Enable and configure the Fast Internal RC (FIRC) according to the provided configuration.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Asynchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     Config: Parameter description
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_FircEnable(const Mcu_FircConfigType *Config)
{
#if (MCU_FIRC_DELAY_SUPPORT == STD_ON)
    const uint32 FircCtrlMask = SCU_FIRC_CTRL_FIRC_EN_MASK |
                                SCU_FIRC_CTRL_FIRC_DS_EN_MASK  |
                                SCU_FIRC_CTRL_FIRC_DLY_EN_MASK;
#else
    const uint32 FircCtrlMask = SCU_FIRC_CTRL_FIRC_EN_MASK | SCU_FIRC_CTRL_FIRC_DS_EN_MASK;
#endif

    uint32 RegVal = SCU_FIRC_CTRL_FIRC_EN_MASK;
    if (TRUE == Config->FircDeepSleepEnable)
    {
        RegVal |= SCU_FIRC_CTRL_FIRC_DS_EN_MASK;
    }
#if (MCU_FIRC_DELAY_SUPPORT == STD_ON)
    if (TRUE == Config->FircDelayEnable)
    {
        RegVal |= SCU_FIRC_CTRL_FIRC_DLY_EN_MASK;
    }
#endif
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];

    ScuBase->FIRC_CTRL = (ScuBase->FIRC_CTRL & ~(FircCtrlMask)) | RegVal;
}

/**
 * @brief         Disable the FIRC oscillator.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Asynchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_FircDisable(void)
{
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    ScuBase->FIRC_CTRL &= ~(SCU_FIRC_CTRL_FIRC_EN_MASK);
}

/**
 * @brief         Disable the external oscillator (FXOSC).
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Asynchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_FxoscDisable(void)
{
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    ScuBase->FXOSC_CTRL &= ~(SCU_FXOSC_CTRL_FXOSC_EN_MASK);
}



#if (MCU_HAS_SXOSC == STD_ON)
/**
 * @brief         Disable the secondary oscillator (SXOSC) when present.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Asynchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_SxoscDisable(void)
{
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    ScuBase->SXOSC_CTRL &= ~(SCU_SXOSC_CTRL_SXOSC_EN_MASK);
}
#endif

/**
 * @brief         Set the embedded flash memory prescaler and wait-state (WRS) settings.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     EfmPrescaleValue: Value to configure EFM Prescaler
 * @param[in]     EfmWRSValue: Value to configure EFM WRS
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_EfmPrescaler(uint32 EfmPrescaleValue, uint32 EfmWRSValue)
{
    volatile EFM_Type *EfmBase = Mcu_EfmBasePtr[0];
    EfmBase->CTRL = (EfmBase->CTRL
                     & ~(EFM_CTRL_PRESCALER_MASK | EFM_CTRL_RWS_MASK))
                    | EFM_CTRL_PRESCALER(EfmPrescaleValue) | EFM_CTRL_RWS(EfmWRSValue);
}

#if (MCU_EEPROM_SUPPORT == STD_ON)
/**
 * @brief Configures EEPROM Prescalers
 * @param[in] EEPROMPrescaleValue - Value to configure EFM Prescaler
 * @param[in] EEPROMRwsValue - Value to configure EFM WRS
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_EEPROMPrescaler(uint32 EEPROMPrescaleValue, uint32 EEPROMRwsValue)
{
    volatile EEPROM_Type *EepromBase = Mcu_EepromBasePtr[0];
    EepromBase->CTRL = (EepromBase->CTRL
                        & ~(EEPROM_CTRL_PRESCALER_MASK | EEPROM_CTRL_RWS_MASK))
                       | EEPROM_CTRL_PRESCALER(EEPROMPrescaleValue) | EEPROM_CTRL_RWS(EEPROMRwsValue);
}
#endif

/**
 * @brief         Disable the clock output (CLKO) and related configuration.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_ClkOutDisable(void)
{
#if defined (CPU_YTM32B1MD2)
    volatile CFMU_Type *CfmuBase = Mcu_CfmuBasePtr[0];
    CfmuBase->CTRL &= ~(CFMU_CTRL_CLK_OUTEN_MASK);
#else
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    ScuBase->CLKO &= ~(SCU_CLKO_CLKOSEL_MASK);
#endif
}

/**
 * @brief         Select the system clock source (FIRC, PLL, FXOSC, etc.).
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     SystemClockSource: system clock source selection
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_SetSystemClockSource(Mcu_SystemClockSourceType SystemClockSource)
{
    /* Set clock source */
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    /* PRQA S 2985 ++ */
    ScuBase->CLKS = (ScuBase->CLKS
                     & ~(SCU_CLKS_CLKSRCSEL_MASK))
                    | SCU_CLKS_CLKSRCSEL(SystemClockSource);
    /* PRQA S 2985 -- */
}

/**
 * @brief         Read status bits that indicate the current system clock source and its status.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return        uint32 Status bits masked for clock source/status.
 */
MCU_FUNC LOCAL_INLINE uint32 Mcu_Lld_GetSystemClockStatus(void)
{
    /* Get clock source */
    volatile const SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    return ScuBase->STS & SCU_CLKS_CLKSRCSEL_MASK;
}

#if (MCU_NO_PLL == STD_OFF)
/**
 * @brief         Disable PLL operation.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Asynchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_PllDisable(void)
{
    /* Only clear EN bit will lead to some error in PLL test */
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    ScuBase->PLL_CTRL &= ~(SCU_PLL_CTRL_PLL_EN_MASK);
}
#endif

/**
 * @brief         Return the current core clock source (enum).
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return        Mcu_SystemClockSourceType Current selected core clock source.
 */
MCU_FUNC LOCAL_INLINE Mcu_SystemClockSourceType Mcu_Lld_GetCoreClockSource(void)
{
    volatile const SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    Mcu_SystemClockSourceType Ret;
    switch (ScuBase->STS & SCU_STS_CLKST_MASK)
    {
        case MCU_CLOCK_SOURCE_FIRC:
            Ret = MCU_SYSTEM_CLOCK_SOURCE_FIRC;
            break;
        case MCU_CLOCK_SOURCE_PLL:
            Ret = MCU_SYSTEM_CLOCK_SOURCE_PLL;
            break;
        case MCU_CLOCK_SOURCE_FXOSC:
            Ret = MCU_SYSTEM_CLOCK_SOURCE_FXOSC;
            break;
        default:
            Ret = MCU_SYSTEM_CLOCK_SOURCE_SIRC;
            break;
    }
    return Ret;
}

#if (MCU_NO_PLL == STD_OFF)
/**
 * @brief         Read the PLL feedback divider value (as configured).
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return        uint32 PLL feedback divider + 1 (per implementation).
 */
MCU_FUNC LOCAL_INLINE uint32 Mcu_Lld_GetPllFbDiv(void)
{
    volatile const SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    return ((ScuBase->PLL_CTRL & SCU_PLL_CTRL_FBDIV_MASK) >> SCU_PLL_CTRL_FBDIV_SHIFT) + 1U;
}
#endif
/**
 * @brief         Set core/fast-bus/slow-bus clock dividers.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     CoreClockDiv: Value of core clock divider
 * @param[in]     FastBusClockDiv: Value of fast bus clock divider
 * @param[in]     SlowBusClockDiv: Value of slow bus clock divider
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_SetClockDivider(uint32 CoreClockDiv, uint32 FastBusClockDiv, uint32 SlowBusClockDiv)
{
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    /* PRQA S 2985 ++ */
    ScuBase->DIV = (ScuBase->DIV
                    & ~(SCU_DIV_CPDIVS_MASK | SCU_DIV_FBDIVS_MASK | SCU_DIV_SBDIVS_MASK))
                   | SCU_DIV_CPDIVS(CoreClockDiv) | SCU_DIV_FBDIVS(FastBusClockDiv) | SCU_DIV_SBDIVS(SlowBusClockDiv);
    /* PRQA S 2985 -- */
}

/**
 * @brief         Get the status of clock divider updates (status bits).
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return        uint32 Divider status flags.
 */
MCU_FUNC LOCAL_INLINE uint32 Mcu_Lld_GetDividerStatus(void)
{
    volatile const SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    MCAL_QUA_FAULT_INJECTION(MCU_ERROR_INJECT_1);
    return ScuBase->DIVSTS;
}

#if (MCU_NO_PLL == STD_OFF)
/**
 * @brief         Return the PLL reference clock type (enum).
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return        Mcu_PllClockRefType PLL reference clock selection.
 */
MCU_FUNC LOCAL_INLINE Mcu_PllClockRefType Mcu_Lld_GetPllRef(void)
{
    volatile const SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    Mcu_PllClockRefType Ret = MCU_PLL_CLOCK_REFERENCE_FXOSC;
    if (0U != (ScuBase->PLL_CTRL & SCU_PLL_CTRL_REFCLKSRCSEL_MASK))
    {
        Ret = MCU_PLL_CLOCK_REFERENCE_FIRC;
    }
    return Ret;
}

/**
 * @brief         Return the PLL reference divider value.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return        uint32 PLL reference divider + 1.
 */
MCU_FUNC LOCAL_INLINE uint32 Mcu_Lld_GetPllRefDiv(void)
{
    volatile const SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    return ((ScuBase->PLL_CTRL & SCU_PLL_CTRL_REFDIV_MASK) >> SCU_PLL_CTRL_REFDIV_SHIFT) + 1U;
}
#endif

/**
 * @brief         Return current core clock divider.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @return        uint32 Core divider value.
 */
MCU_FUNC LOCAL_INLINE uint32 Mcu_Lld_GetCoreDiv(void)
{
    volatile const SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    return ((ScuBase->DIV & SCU_DIV_CPDIVS_MASK) >> SCU_DIV_CPDIVS_SHIFT) + 1U;
}

/**
 * @brief         Configure and enable the FXOSC (external) oscillator per configuration.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Asynchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ConfigPtr: Pointer to the struct containing the configurations of the FXOSC.
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_SetFxoscClock(const Mcu_FxoscConfigType *ConfigPtr)
{
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    boolean ByPassMode;
    boolean NotBypassMode;
    if (TRUE == ConfigPtr->BypassMode)
    {
        ByPassMode = 1U;
        NotBypassMode = 0U;
    }
    else
    {
        ByPassMode = 0U;
        NotBypassMode = 1U;
    }
#if defined(CPU_YTM32B1MC0) || defined(CPU_YTM32B1MD2)
    /* PRQA S 2985 ++ */
    ScuBase->FXOSC_CTRL = (ScuBase->FXOSC_CTRL
                           & ~(SCU_FXOSC_CTRL_FXOSC_MODE_MASK |
                               SCU_FXOSC_CTRL_GMSEL_MASK |
                               SCU_FXOSC_CTRL_ALCDIS_MASK |
                               SCU_FXOSC_CTRL_FXOSC_DS_EN_MASK |
                               SCU_FXOSC_CTRL_DLY_SEL_MASK))
                          | SCU_FXOSC_CTRL_FXOSC_MODE(NotBypassMode) |
                          SCU_FXOSC_CTRL_GMSEL(ConfigPtr->GainSelection) |
                          SCU_FXOSC_CTRL_ALCDIS(ByPassMode) |
                          SCU_FXOSC_CTRL_FXOSC_DS_EN(ConfigPtr->DeepSleepEnable) |
                          SCU_FXOSC_CTRL_DLY_SEL((uint32)ConfigPtr->DelaySelect);
    /* PRQA S 2985 -- */
#elif defined(CPU_YTM32B1ME1)
    /* PRQA S 2985 ++ */
    ScuBase->FXOSC_CTRL = (ScuBase->FXOSC_CTRL
                           & ~(SCU_FXOSC_CTRL_FXOSC_DS_EN_MASK |
                               SCU_FXOSC_CTRL_FXOSC_MODE_MASK |
                               SCU_FXOSC_CTRL_GMSEL_MASK |
                               SCU_FXOSC_CTRL_ALCDIS_MASK |
                               SCU_FXOSC_CTRL_FXOSC_DLY_SEL_MASK))
                          | SCU_FXOSC_CTRL_FXOSC_DS_EN(ConfigPtr->DeepSleepEnable) |
                          SCU_FXOSC_CTRL_FXOSC_MODE(NotBypassMode) |
                          SCU_FXOSC_CTRL_GMSEL(ConfigPtr->GainSelection) |
                          SCU_FXOSC_CTRL_ALCDIS(ByPassMode) |
                          SCU_FXOSC_CTRL_FXOSC_DLY_SEL((uint32)ConfigPtr->DelaySelect);
    /* PRQA S 2985 -- */
#else
    /* PRQA S 2985 ++ */
    ScuBase->FXOSC_CTRL = (ScuBase->FXOSC_CTRL
                           & ~(SCU_FXOSC_CTRL_FXOSC_MODE_MASK |
                               SCU_FXOSC_CTRL_HYSTDIS_MASK |
                               SCU_FXOSC_CTRL_GMSEL_MASK |
                               SCU_FXOSC_CTRL_ALCDIS_MASK |
                               SCU_FXOSC_CTRL_FXOSC_DS_EN_MASK |
                               SCU_FXOSC_CTRL_COMPEN_MASK))
                          | SCU_FXOSC_CTRL_FXOSC_MODE(NotBypassMode) |
                          SCU_FXOSC_CTRL_HYSTDIS(ByPassMode) |
                          SCU_FXOSC_CTRL_GMSEL(ConfigPtr->GainSelection) |
                          SCU_FXOSC_CTRL_ALCDIS(ByPassMode) |
                          SCU_FXOSC_CTRL_FXOSC_DS_EN(ConfigPtr->DeepSleepEnable) |
                          SCU_FXOSC_CTRL_COMPEN(NotBypassMode);
    /* PRQA S 2985 -- */
#endif
    ScuBase->FXOSC_CTRL |= (SCU_FXOSC_CTRL_FXOSC_EN_MASK);
}

/**
 * @brief         Set the FXOSC amplifier gain setting.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     Gain: FXOSC gain value.
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_SetFxoscGain(uint8 Gain)
{
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    ScuBase->FXOSC_CTRL = (ScuBase->FXOSC_CTRL
                           & ~(SCU_FXOSC_CTRL_GMSEL_MASK))
                          | SCU_FXOSC_CTRL_GMSEL(Gain);
}

#if (MCU_NO_PLL == STD_OFF)

/**
 * @brief         Configure PLL parameters (feedback, reference, fractional, modes) from the provided
 *                configuration. It also enables the PLL module after configuration.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ConfigPtr: Pointer to a structure containing initialization data for PLL.
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_SetPll(const Mcu_PllConfigType *ConfigPtr)
{
    if (NULL_PTR != ConfigPtr)
    {
        volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
        /* Configure PLL control registers */
        ScuBase->PLL_CTRL = (ScuBase->PLL_CTRL
                             & ~(SCU_PLL_CTRL_REFCLKSRCSEL_MASK |
                                 SCU_PLL_CTRL_FBDIV_MASK        |
                                 SCU_PLL_CTRL_REFDIV_MASK))
                            | SCU_PLL_CTRL_REFCLKSRCSEL(ConfigPtr->ClockRef) |
                            SCU_PLL_CTRL_FBDIV(ConfigPtr->FeedbackDiv)     |
                            SCU_PLL_CTRL_REFDIV(ConfigPtr->RefDiv);
#if (MCU_PLL_ADVANCED_MODE_SUPPORT == STD_ON)
        /* PRQA S 2985 ++ */
        /* Configure PLL CFG register */
        ScuBase->PLL_CFG = (ScuBase->PLL_CFG
                            & ~(SCU_PLL_CFG_DITHER_EN_MASK |
                                SCU_PLL_CFG_DITHER_GAIN_MASK |
                                SCU_PLL_CFG_FM_EN_MASK |
                                SCU_PLL_CFG_FD_EN_MASK))
                           | SCU_PLL_CFG_DITHER_EN(ConfigPtr->PLLDitherEnable) |
                           SCU_PLL_CFG_DITHER_GAIN(ConfigPtr->PLLDitherGain) |
                           SCU_PLL_CFG_FM_EN(ConfigPtr->PLLFMModeEnable) |
                           SCU_PLL_CFG_FD_EN(ConfigPtr->PLLFracModeEnable);
        /* Configure PLL FM register */
        ScuBase->PLL_FM = (ScuBase->PLL_FM
                           & ~(SCU_PLL_FM_FM_STEP_MASK | SCU_PLL_FM_FM_NO_MASK))
                          | SCU_PLL_FM_FM_STEP(ConfigPtr->PLLFMStepSize) | SCU_PLL_FM_FM_NO(ConfigPtr->PLLFMStepNum);
        /* Configure PLL FD register */
        ScuBase->PLL_FD = (ScuBase->PLL_FD
                           & ~(SCU_PLL_FD_FD_FRAC_MASK))
                          | SCU_PLL_FD_FD_FRAC(ConfigPtr->PLLFracLoopDivFactor);
        /* PRQA S 2985 -- */
#endif
        /* Enable PLL */
        ScuBase->PLL_CTRL |= (SCU_PLL_CTRL_PLL_EN_MASK);
    }
}
#endif

#if (MCU_HAS_SXOSC == STD_ON)
/**
 * @brief         Configure and enable the secondary oscillator (SXOSC).
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ConfigPtr: A pointer to a structure containing the Sxosc configuration parameters
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_SetSxoscClock(const Mcu_SxoscConfigType *ConfigPtr)
{
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
#if defined (CPU_YTM32B1ME1)
    /* SXOSC control */
    MCU_REG_ADDR32_AREA_WRITE(ScuBase->SXOSC_CTRL,
                              SCU_SXOSC_CTRL_SXOSC_MODE_MASK |
                              SCU_SXOSC_CTRL_SXOSC_HIGAIN_EN_MASK |
                              SCU_SXOSC_CTRL_SXOSC_PD_EN_MASK |
                              SCU_SXOSC_CTRL_SXOSC_DS_EN_MASK |
                              SCU_SXOSC_CTRL_SXOSC_STB_EN_MASK,
                              SCU_SXOSC_CTRL_SXOSC_MODE(ConfigPtr->BypassMode) |
                              SCU_SXOSC_CTRL_SXOSC_HIGAIN_EN(ConfigPtr->GainSelection) |
                              SCU_SXOSC_CTRL_SXOSC_PD_EN(ConfigPtr->PowerDownEnable) |
                              SCU_SXOSC_CTRL_SXOSC_DS_EN(ConfigPtr->DeepSleepEnable) |
                              SCU_SXOSC_CTRL_SXOSC_STB_EN(ConfigPtr->StandbyEnable));
#else
    /* SXOSC control */
    ScuBase->SXOSC_CTRL = (ScuBase->SXOSC_CTRL
                           & ~(SCU_SXOSC_CTRL_SXOSC_MODE_MASK |
                               SCU_SXOSC_CTRL_GMSEL_MASK |
                               SCU_SXOSC_CTRL_SXOSC_PD_EN_MASK |
                               SCU_SXOSC_CTRL_SXOSC_DS_EN_MASK |
                               SCU_SXOSC_CTRL_SXOSC_STB_EN_MASK))
                          | SCU_SXOSC_CTRL_SXOSC_MODE(ConfigPtr->BypassMode) |
                          SCU_SXOSC_CTRL_GMSEL(ConfigPtr->GainSelection) |
                          SCU_SXOSC_CTRL_SXOSC_PD_EN(ConfigPtr->PowerDownEnable) |
                          SCU_SXOSC_CTRL_SXOSC_DS_EN(ConfigPtr->DeepSleepEnable) |
                          SCU_SXOSC_CTRL_SXOSC_STB_EN(ConfigPtr->StandbyEnable);
#endif
    /* Enable SXOSC */
    ScuBase->SXOSC_CTRL |= (SCU_SXOSC_CTRL_SXOSC_EN_MASK);

}
#endif

/**
 * @brief         Configure the clock output (source and divider).
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ConfigPtr: Pointer to a Mcu_ClockOutConfigType structure containing the configuration information for CLKOUT.
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_SetClockOut(const Mcu_ClockOutConfigType *ConfigPtr)
{
    if (NULL_PTR != ConfigPtr)
    {
#if defined (CPU_YTM32B1MD2)
        volatile CFMU_Type *CfmuBase = Mcu_CfmuBasePtr[0];
        /** Note CLK_DIV can only be modified when CLK_SEL is 0. */
        CfmuBase->CTRL &= ~(CFMU_CTRL_CLK_SEL_MASK);
        /* PRQA S 2985 ++ */
        /** Set configuration to register */
        CfmuBase->CTRL = (CfmuBase->CTRL
                          & ~(CFMU_CTRL_CLK_DIV_MASK |
                              CFMU_CTRL_CLK_OUTEN_MASK))
                         | CFMU_CTRL_CLK_DIV(ConfigPtr->ClockOutDiv) |
                         CFMU_CTRL_CLK_OUTEN(STD_ON);
        /** Set CLK_SEL value */
        CfmuBase->CTRL = (CfmuBase->CTRL
                          & ~(CFMU_CTRL_CLK_SEL_MASK))
                         | CFMU_CTRL_CLK_SEL(ConfigPtr->Source);
        /* PRQA S 2985 -- */
#else
        volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
        /* PRQA S 2985 ++ */
        ScuBase->CLKO = (ScuBase->CLKO
                         & ~(SCU_CLKO_CLKODIV_MASK |
                             SCU_CLKO_CLKOSEL_MASK))
                        | SCU_CLKO_CLKODIV(ConfigPtr->ClockOutDiv) |
                        SCU_CLKO_CLKOSEL(ConfigPtr->Source);
        /* PRQA S 2985 -- */
#endif
    }
}

/**
 * @brief         Configure Clock Monitor Unit channels and comparator thresholds per the configuration set.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ConfigPtr: Pointer to a structure containing user configurations.
 * @param[in]     Len:  The length of given configuration array pointer.
 * @return        void
 */
MCU_FUNC LOCAL_INLINE void Mcu_Lld_SetCmu(const Mcu_ClockMonitorConfigType *ConfigPtr, const uint8 Len)
{
    Mcu_ClockMonitorConfigType const *CmuConfigPtr = NULL_PTR;
    uint32 CmuCtrlRegVal = 0U;

    /* PRQA S 2985 ++ */
    if ((ConfigPtr != NULL_PTR) && (Len <= MCU_CMU_CHANNEL_NUMS))
    {
        CmuConfigPtr = ConfigPtr;
        for (uint8 Idx = 0U; Idx < Len; ++Idx)
        {
            const uint32 CmuIdx = CmuConfigPtr->CmuChannelIdx;
            /* Enable */
            CmuCtrlRegVal |= ((uint32)(CmuConfigPtr->Enable) << CmuIdx);
            /* Enable or Disable CMU reset enable */
            CmuCtrlRegVal |= ((uint32)(CmuConfigPtr->ResetEnable) << (CmuIdx + 8U));
#if (MCU_CMU_REFERENCE_CHANGEABLE == STD_ON)
            /* Set CMU clock reference */
            if (MCU_CMU_CLOCK_REFERENCE_FXOSC == CmuConfigPtr->ClockReference)
            {
                CmuCtrlRegVal |= ((uint32)1U << (CmuIdx + 16U));
            }
#endif
#if defined (CPU_YTM32B1MD2)
            volatile CMU_Type *CmuBase = Mcu_CmuBasePtr[0];
            /* Set CMUxCMPH */
            CmuBase->CMP[CmuIdx].HIGH = (CmuBase->CMP[CmuIdx].HIGH
                                         & ~(CMU_CMP_HIGH_VAL_MASK))
                                        | CMU_CMP_HIGH_VAL(CmuConfigPtr->CmuCmpHValue);
            /* Set CMUxCMPL */
            CmuBase->CMP[CmuIdx].LOW = (CmuBase->CMP[CmuIdx].LOW
                                        & ~(CMU_CMP_LOW_VAL_MASK))
                                       | CMU_CMP_LOW_VAL(CmuConfigPtr->CmuCmpLValue);
            /* Set valid delay register, CMU0 is not support CLKVLDDLY */
            if (0U != CmuIdx)
            {
                CmuBase->CLKVLDDLY[CmuIdx] = (CmuBase->CLKVLDDLY[CmuIdx]
                                              & ~(CMU_CLKVLDDLY_VAL_MASK))
                                             | CMU_CLKVLDDLY_VAL(CmuConfigPtr->CmuVldDlyValue);
            }
#else
            /* Set CMUxCMPH */
            volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
            ScuBase->CMUCMP[CmuIdx].HIGH = (ScuBase->CMUCMP[CmuIdx].HIGH
                                            & ~(SCU_CMUCMP_HIGH_VAL_MASK))
                                           | SCU_CMUCMP_HIGH_VAL(CmuConfigPtr->CmuCmpHValue);
            /* Set CMUxCMPL */
            ScuBase->CMUCMP[CmuIdx].LOW = (ScuBase->CMUCMP[CmuIdx].LOW
                                           & ~(SCU_CMUCMP_LOW_VAL_MASK))
                                          | SCU_CMUCMP_LOW_VAL(CmuConfigPtr->CmuCmpLValue);
#endif
#if (MCU_LLD_SCU_ISR_USED == STD_ON)
            /* Store the interrpt enable flags */
            Mcu_CmuIntEnableList[CmuIdx] = CmuConfigPtr->CmuIntEnable;
            /* Store the notification */
            Mcu_CmuNotiList[CmuIdx] = CmuConfigPtr->NotificationPtr;
#endif
            /* Set next CMU channel */
            ++CmuConfigPtr;
        }
#if (MCU_LLD_SCU_ISR_USED == STD_ON)
        /* Use this function to get raw reset value */
        (void)Mcu_Lld_GetResetValue();
        /* Verify if the chip has been reset by CMU and decide whether to trigger a notification */
        if (0U != (Mcu_ResetStatusValue & RCU_RSSR_CMU_MASK))
        {
            Mcu_Lld_Cmu_ChannelIrqProcess();
        }
#endif
        /* Start CMU */
#if defined (CPU_YTM32B1MD2)
        volatile CMU_Type *CmuBase = Mcu_CmuBasePtr[0];
        CmuBase->CTRL = 0x0U;
        CmuBase->CTRL |= (CmuCtrlRegVal);
#else
        volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
        MCAL_QUA_FAULT_INJECTION(MCU_ERROR_INJECT_3);
        ScuBase->CMU_CTRL = 0x0U;
        ScuBase->CMU_CTRL |= (CmuCtrlRegVal);
#endif
    }
    /* PRQA S 2985 -- */
}

/**
 * @brief         Return clock monitor status bits masked by the provided ClockMask.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ClockMask: relative clock mask, which is specified by chip
 * @return        uint32 Masked status bits.
 */
MCU_FUNC LOCAL_INLINE uint32 Mcu_Lld_GetClockStatus(uint32 ClockMask)
{
    /* Set clock source */
    volatile const SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    MCAL_QUA_FAULT_INJECTION(MCU_ERROR_INJECT_0);
    return ScuBase->STS & ClockMask;
}


/**
 * @brief         Initialize and enable the SIRC (Slow Internal RC) clock source using configuration data.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ConfigPtr: Pointer to the configuration of type Mcu_ClockConfigType.
 * @return        Std_ReturnType E_OK on success, E_NOT_OK on failure.
 */

MCU_FUNC LOCAL_INLINE Std_ReturnType Mcu_Lld_InitSirc(const Mcu_ClockConfigType *ConfigPtr)
{
#if (MCU_POWERDOWN_MODE_SUPPORT == STD_ON)
    const uint32 SircCtrlMask = SCU_SIRC_CTRL_SIRC_DS_EN_MASK |
                                SCU_SIRC_CTRL_SIRC_STB_EN_MASK |
                                SCU_SIRC_CTRL_SIRC_PD_EN_MASK;
#else
    const uint32 SircCtrlMask = SCU_SIRC_CTRL_SIRC_DS_EN_MASK | SCU_SIRC_CTRL_SIRC_STB_EN_MASK;
#endif

    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    Std_ReturnType Res = E_OK;
    if (TRUE == ConfigPtr->SircUnderUserCtrl)
    {
        uint32 RegCtrl = 0U;
        if (TRUE == ConfigPtr->SircConfig->SircDeepSleepEnable)
        {
            RegCtrl |= SCU_SIRC_CTRL_SIRC_DS_EN_MASK;
        }
#if (MCU_POWERDOWN_MODE_SUPPORT == STD_ON)
        if (TRUE == ConfigPtr->SircConfig->SircPowerDownEnable)
        {
            RegCtrl |= SCU_SIRC_CTRL_SIRC_PD_EN_MASK;
        }
#endif
        if (TRUE == ConfigPtr->SircConfig->SircStandbyEnable)
        {
            RegCtrl |= SCU_SIRC_CTRL_SIRC_STB_EN_MASK;
        }

        ScuBase->SIRC_CTRL = (ScuBase->SIRC_CTRL & ~(SircCtrlMask)) | RegCtrl;
    }
    return Res;
}

/**
 * @brief         Initialize and enable the FIRC clock source.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ConfigPtr: Pointer to the configuration of type Mcu_ClockConfigType.
 * @return        Std_ReturnType E_OK on success, E_NOT_OK on failure.
 */
MCU_FUNC LOCAL_INLINE Std_ReturnType Mcu_Lld_InitFirc(const Mcu_ClockConfigType *ConfigPtr)
{
    Std_ReturnType Res = E_OK;
    if (TRUE == ConfigPtr->FircUnderUserCtrl)
    {
        if (TRUE == ConfigPtr->FircEnable)
        {
            uint32 TimeOutTempCnt = 0U;
            uint32 RegVal = 0U;
            Mcu_Lld_FircEnable(ConfigPtr->FircConfig);
            RegVal = Mcu_Lld_GetClockStatus(SCU_STS_FIRC_VALID_MASK);
            while ((RegVal != SCU_STS_FIRC_VALID_MASK) && (TimeOutTempCnt < MCU_CLOCK_TIMEOUT_COUNT))
            {
                RegVal = Mcu_Lld_GetClockStatus(SCU_STS_FIRC_VALID_MASK);
                ++TimeOutTempCnt;
            }
            if (TimeOutTempCnt >= MCU_CLOCK_TIMEOUT_COUNT)
            {
                Res = E_NOT_OK;
            }
        }
        else
        {
            Mcu_Lld_FircDisable();
        }
    }
    return Res;
}

#if (MCU_HAS_SXOSC == STD_ON)
/**
 * @brief         Initialize and enable the SXOSC clock source when supported.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ConfigPtr: Pointer to the configuration of type Mcu_ClockConfigType.
 * @return        Std_ReturnType E_OK on success, E_NOT_OK on failure.
 * @note          This function is asynchronour if MCU_WAIT_SXOSC_STABLE is STD_OFF.
 */
MCU_FUNC LOCAL_INLINE Std_ReturnType Mcu_Lld_InitSxosc(const Mcu_ClockConfigType *ConfigPtr)
{
    Std_ReturnType Res = E_OK;
    if (TRUE == ConfigPtr->SxoscUnderUserCtrl)
    {
        if ((TRUE == ConfigPtr->SxoscEnable) && (NULL_PTR != ConfigPtr->SxoscConfig))
        {
            /* Sxosc startup is too slow, Dont wait for it in the driver */
            Mcu_Lld_SetSxoscClock(ConfigPtr->SxoscConfig);
#if (MCU_WAIT_SXOSC_STABLE == STD_ON)
            uint32 RegVal;
            uint32 TimeOutTempCnt = 0U;
            RegVal = Mcu_Lld_GetClockStatus(SCU_STS_SXOSC_VALID_MASK);
            while ((RegVal != SCU_STS_SXOSC_VALID_MASK) && (TimeOutTempCnt < MCU_CLOCK_TIMEOUT_COUNT))
            {
                RegVal = Mcu_Lld_GetClockStatus(SCU_STS_SXOSC_VALID_MASK);
                ++TimeOutTempCnt;
            }
            if (TimeOutTempCnt >= MCU_CLOCK_TIMEOUT_COUNT)
            {
                Res = E_NOT_OK;
            }
#endif
        }
        else
        {
            Mcu_Lld_SxoscDisable();
        }
    }
    return Res;
}
#endif

#if (MCU_NO_PLL == STD_OFF)
/**
 * @brief         Initialize PLL according to provided clock configuration.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ConfigPtr: Pointer to the configuration of type Mcu_ClockConfigType.
 * @return        Std_ReturnType E_OK on success, E_NOT_OK on failure.
 *
 * @note          - `Mcu_Lld_InitPll()` operation requires PllUnderUserCtrl.
 *                - PLL needs a reference clock to lock, please confirm the reference clock is valid.
 */
MCU_FUNC LOCAL_INLINE Std_ReturnType Mcu_Lld_InitPll(const Mcu_ClockConfigType *ConfigPtr)
{
    Std_ReturnType Res = E_OK;
    if (TRUE == ConfigPtr->PllUnderUserCtrl)
    {
        /* SetPll need the Pll EN flag is false, and check the flag. Too fast to run enable the PLL will made error */
        Mcu_Lld_PllDisable();
        if (TRUE == ConfigPtr->PllEnable)
        {
            /* Pll startup too slow, don't wait for it lock */
            Mcu_Lld_SetPll(ConfigPtr->PllConfig);
        }
    }
    return Res;
}
#endif
/**
 * @brief         Initialize and enable the FXOSC clock based on configuration.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ConfigPtr: Pointer to the configuration of type Mcu_ClockConfigType.
 * @return        Std_ReturnType E_OK on success, E_NOT_OK on failure.
 */
MCU_FUNC LOCAL_INLINE Std_ReturnType Mcu_Lld_InitFxosc(const Mcu_ClockConfigType *ConfigPtr)
{
    Std_ReturnType Res = E_OK;
    if (TRUE == ConfigPtr->FxoscUnderUserCtrl)
    {
        if ((TRUE == ConfigPtr->FxoscEnable) && (NULL_PTR != ConfigPtr->FxoscConfig))
        {
            uint32 TimeOutTempCnt = 0U;
            uint32 RegVal = 0U;
            uint8 TempGain = 1U;
            uint8 MaxGain = (uint8)(SCU_FXOSC_CTRL_GMSEL_MASK >> SCU_FXOSC_CTRL_GMSEL_SHIFT);
            uint8 GainDirection = MCU_FXOSC_SWEEP_GAIN_ADD;
            Mcu_Lld_SetFxoscClock(ConfigPtr->FxoscConfig);
            RegVal = Mcu_Lld_GetClockStatus(SCU_STS_FXOSC_VALID_MASK);
            while ((RegVal != SCU_STS_FXOSC_VALID_MASK) && (TimeOutTempCnt < MCU_CLOCK_TIMEOUT_COUNT))
            {
                RegVal = Mcu_Lld_GetClockStatus(SCU_STS_FXOSC_VALID_MASK);
                Mcu_Lld_SetFxoscGain(TempGain);
                /**
                 * @note FXOSC may failed to start when OSC not match to MCU gain setting, to get a
                 *       more stable FXOSC startup, software should sweep FXOSC gain setting when
                 *       start FXOSC, when FXOSC ready, software set gain back to user setting.
                 *
                 */
                if (MCU_FXOSC_SWEEP_GAIN_ADD == GainDirection)
                {
                    TempGain += 1U;
                }
                else
                {
                    TempGain -= 1U;
                }
                if ((0U == TempGain) || (MaxGain == TempGain))
                {
                    GainDirection = (1U - GainDirection);
                }
                ++TimeOutTempCnt;
            }
            if (TimeOutTempCnt >= MCU_CLOCK_TIMEOUT_COUNT)
            {
                Res = E_NOT_OK;
            }
            Mcu_Lld_SetFxoscGain(ConfigPtr->FxoscConfig->GainSelection);
        }
        else
        {
            Mcu_Lld_FxoscDisable();
        }
    }
    return Res;
}

/**
 * @brief         Initialize clock divider logic as part of clock setup.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ConfigPtr: Pointer to the configuration of type Mcu_ClockConfigType.
 * @return        Std_ReturnType E_OK on success, E_NOT_OK on failure.
 */
MCU_FUNC LOCAL_INLINE Std_ReturnType Mcu_Lld_InitClockDivider(const Mcu_ClockConfigType *ConfigPtr)
{
    Std_ReturnType Res = E_OK;
    uint32 TimeOutTempCnt = 0U;
    uint32 RegVal = 0U;
    Mcu_Lld_SetClockDivider(ConfigPtr->CoreClockDiv, ConfigPtr->FastBusClockDiv, ConfigPtr->SlowBusClockDiv);
    RegVal = Mcu_Lld_GetDividerStatus();
    while ((RegVal != (SCU_DIVSTS_CPDIVST(ConfigPtr->CoreClockDiv) |
                       SCU_DIVSTS_FBDIVST(ConfigPtr->FastBusClockDiv) |
                       SCU_DIVSTS_SBDIVST(ConfigPtr->SlowBusClockDiv))) && (TimeOutTempCnt < MCU_CLOCK_TIMEOUT_COUNT))
    {
        RegVal = Mcu_Lld_GetDividerStatus();
        ++TimeOutTempCnt;
    }
    if (TimeOutTempCnt >= MCU_CLOCK_TIMEOUT_COUNT)
    {
        Res = E_NOT_OK;
    }
    return Res;
}

/**
 * @brief         Switch the system clock to the requested source and handle any required sequencing.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     SystemClockSource: Specified clock name.
 * @return        Std_ReturnType E_OK when the switch succeeded, E_NOT_OK otherwise.
 */
MCU_FUNC LOCAL_INLINE Std_ReturnType Mcu_Lld_SwitchSystemClock(Mcu_SystemClockSourceType SystemClockSource)
{
    Std_ReturnType Res = E_OK;
    uint32 TimeOutTempCnt = 0U;
    uint32 TargetSystemClock = (uint32)SystemClockSource;
    Mcu_Lld_SetSystemClockSource(SystemClockSource);
    uint32 CurSystemClock = Mcu_Lld_GetSystemClockStatus() >> SCU_CLKS_CLKSRCSEL_SHIFT;
    while ((CurSystemClock != TargetSystemClock) && (TimeOutTempCnt < MCU_CLOCK_TIMEOUT_COUNT))
    {
        CurSystemClock = (Mcu_Lld_GetSystemClockStatus() >> SCU_CLKS_CLKSRCSEL_SHIFT); /* PRQA S 2985 */
        ++TimeOutTempCnt;
    }
    if (TimeOutTempCnt >= MCU_CLOCK_TIMEOUT_COUNT)
    {
        Res = E_NOT_OK;
    }
    MCAL_QUA_FAULT_INJECTION(MCU_ERROR_INJECT_2);
    return Res;
}

/**
 * @brief         Init all clock sources for MCU system clock.
 * @autosar       N/A
 *
 * @details       Service ID: --
 *                Sync/Async: Synchronous
 *                Reentrancy: Non Reentrant
 *                Available via: Mcu_Lld.c
 *
 * @param[in]     ConfigPtr: Clock config ptr.
 * @return        Std_ReturnType E_OK when the switch succeeded, E_NOT_OK otherwise.
 */
MCU_FUNC LOCAL_INLINE Std_ReturnType Mcu_Lld_InitClockSources(const Mcu_ClockConfigType *ConfigPtr)
{
    Std_ReturnType ReturnValue;
    ReturnValue = Mcu_Lld_InitSirc(ConfigPtr);
    ReturnValue |= Mcu_Lld_InitFirc(ConfigPtr);
    ReturnValue |= Mcu_Lld_InitFxosc(ConfigPtr);
#if (MCU_HAS_SXOSC == STD_ON)
    ReturnValue |= Mcu_Lld_InitSxosc(ConfigPtr);
#endif
#if (MCU_NO_PLL == STD_OFF)
    ReturnValue |= Mcu_Lld_InitPll(ConfigPtr);
#endif
    return ReturnValue;
}
/*==================================================================================================
 *                                         GLOBAL FUNCTIONS
==================================================================================================*/
#if (MCU_NO_PLL == STD_OFF)
MCU_FUNC void Mcu_Lld_SetCmuChannel2(void)
{
#if defined (CPU_YTM32B1MD2)
    volatile CMU_Type *CmuBase = Mcu_CmuBasePtr[0];
    CmuBase->CTRL |= (CMU_CTRL_EN(4U));
#else
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    ScuBase->CMU_CTRL |= (SCU_CMU_CTRL_CMU2_EN_MASK);
#endif
}
#endif


#if (MCU_NO_PLL == STD_OFF)
MCU_FUNC Mcu_PllStatusType Mcu_Lld_GetPllStatus(void)
{
    uint32 RegVal = 0U;
    Mcu_PllStatusType PllStatus;
    /* Get PLL lock Status */
    volatile const SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    RegVal = ScuBase->STS & SCU_STS_PLL_LOCK_MASK;
    if (RegVal != 0U)
    {
        PllStatus = MCU_PLL_LOCKED;
    }
    else
    {
        PllStatus = MCU_PLL_UNLOCKED;
    }
    return PllStatus;
}
#endif

#if (MCU_GET_SXOSC_STATUS_API == STD_ON)
MCU_FUNC Mcu_SxoscStatusType Mcu_Lld_GetSxoscStatus(void)
{
    uint32 RegVal = Mcu_Lld_GetClockStatus(SCU_STS_SXOSC_VALID_MASK);
    Mcu_SxoscStatusType SxoscStatus = MCU_SXOSC_INVALID;
    if (RegVal > 0U)
    {
        SxoscStatus = MCU_SXOSC_VALID;
    }
    else
    {
        SxoscStatus = MCU_SXOSC_INVALID;
    }
    return SxoscStatus;
}
#endif

/**
 * GCOVR_EXCL_START: The 'Mcu_Lld_SystemReset' function performs a chip reset, preventing testing
 * in integration tests.
 */
/**
 * MR12 DIR 4.3 VIOLATION: The function 'Mcu_Lld_SystemReset' contains a mixture of in-line
 * assembler statements and C statements. In this specific case, due to the need for low-level
 * hardware access or specific performance requirements, we had to use inline assembly code
 * alongside C statements, thus we couldn't adhere to this rule.
 */
/* PRQA S 0306 ++ */
MCU_FUNC void Mcu_Lld_SystemReset(void)
{
    uint32 AircrValue;
    /** asm("dsb"); */
    /* Read Application Interrupt and Reset Control Register */
    AircrValue = SCB->AIRCR;
    /* Clear register key */
    AircrValue &= ~SCB_AIRCR_VECTKEY_Msk;
    /* Configure System reset request bit and Register Key */
    AircrValue |= (uint32)0x05FAU << SCB_AIRCR_VECTKEY_Pos;
    AircrValue |= SCB_AIRCR_SYSRESETREQ_Msk;
    /* Write back to Application Interrupt and Reset Control Register */
    SCB->AIRCR = AircrValue;
    /**
     * MR12 RULE 1.2 VIOLATION: This line uses the __ASM() macro for inline assembly which is not
     * a part of standard C. In this specific case, we are executing a 'dsb' instruction for ensuring
     * all previous instructions have been completed before continuing, hence we couldn't adhere to
     * the rule 1.2
     */
    __ASM("dsb");
}
/* GCOVR_EXCL_STOP */
/* PRQA S 0306 -- */

MCU_FUNC void Mcu_Lld_SetRcu(const Mcu_ResetConfigType *ConfigPtr)
{
    if (NULL_PTR != ConfigPtr)
    {
        volatile RCU_Type *RcuBase = Mcu_RcuBasePtr[0];
        /* PRQA S 2985 ++ */
        RcuBase->RPFR = (RcuBase->RPFR
                         & ~(RCU_RPFR_FLTEN_MASK | RCU_RPFR_RSTPIN_OBEN_MASK | RCU_RPFR_FLTVAL_MASK))
                        | RCU_RPFR_FLTEN(ConfigPtr->HwResetPinFilterEnable) |
                        RCU_RPFR_RSTPIN_OBEN(ConfigPtr->HwResetPinOutputEnable) |
                        RCU_RPFR_FLTVAL(ConfigPtr->HwResetPinFilterCount);
        /* PRQA S 2985 -- */
    }
}

/**
 * GCOVR_EXCL_START: The 'Mcu_Lld_SetRamSection' function is designed to clear the RAM section data to the default values
 * configured by the PB file. Due to the potential risk of unintentionally erasing critical data, this function is excluded
 * from coverage testing to prevent inadvertent impacts during the testing process.
 */
MCU_FUNC void Mcu_Lld_SetRamSection(const Mcu_RamSectionConfigType *ConfigPtr)
{
    /**
     * MR12 RULE 11.4 VIOLATION: We cast the object pointer to an integer.
     */
    uint32 RamSectionAddress = (uint32)(ConfigPtr->BaseAddress);
    uint8 WriteSize = ConfigPtr->SectionWriteSize;

    uint64 Val = (uint64)ConfigPtr->DefaultValue;
    Val |= Val << 8U;
    Val |= Val << 16U;
    Val |= Val << 32U;

    for (uint32 AddressOffset = 0U; AddressOffset < ConfigPtr->SectionSize; AddressOffset += WriteSize)
    {
        /* PRQA S 0306 ++ */
        switch (WriteSize)
        {
            case MCU_RAM_WRITE_SIZE_8:
            {
                (*(uint64 *)(RamSectionAddress + AddressOffset)) = Val;
                break;
            }
            case MCU_RAM_WRITE_SIZE_4:
            {
                (*(uint32 *)(RamSectionAddress + AddressOffset)) = (uint32)Val;
                break;
            }
            case MCU_RAM_WRITE_SIZE_2:
            {
                (*(uint16 *)(RamSectionAddress + AddressOffset)) = (uint16)Val;
                break;
            }
            /* case MCU_RAM_WRITE_SIZE_1: */
            default:
            {
                (*(uint8 *)(RamSectionAddress + AddressOffset)) = (uint8)Val;
                break;
            }
        }
        /* PRQA S 0306 -- */
    }
}
/* GCOVR_EXCL_STOP */

/**
 * GCOVR_EXCL_START: The function 'Mcu_Lld_SetMode' modifies the chip's operating mode. In coverage testing,
 * ensuring the normal operation of the chip's testing framework after changing the operating mode is crucial.
 * Therefore, this function has been excluded from coverage testing.
 */
/**
 * MR12 DIR 4.3 VIOLATION: The function 'Mcu_Lld_SetMode' contains a mixture of in-line assembler statements
 * and C statements. In this specific case, due to the need for low-level hardware access or specific
 * performance requirements, we had to use inline assembly code alongside C statements, thus we couldn't
 * adhere to this rule.
 */
/* PRQA S 0306 ++ */
MCU_FUNC void Mcu_Lld_SetMode(Mcu_PowerModeType McuMode)
{
    volatile EFM_Type *EfmBase = Mcu_EfmBasePtr[0];
    volatile PCU_Type *PcuBase = Mcu_PcuBasePtr[0];
    /* Clear Efm DeepSleep Mode Enable */
#if defined(CPU_YTM32B1MC0) || defined (CPU_YTM32B1MD2) || defined (CPU_YTM32B1ME1)
    EfmBase->CTRL &= ~(EFM_CTRL_LPEN_MASK);
#else
    EfmBase->CTRL &= ~(EFM_CTRL_DPD_EN_MASK);
#endif
    if (MCU_POWER_MODE_RUN == McuMode)
    {
        SCB->SCR &= ~(SCB_SCR_SLEEPONEXIT_Msk);
    }
    else
    {
        uint32 TempSystick;
        Mcu_Lld_DisableAllCmu();
        /* Switch to the set mode */
        switch (McuMode)
        {
#if defined(CPU_YTM32B1MC0) || defined (CPU_YTM32B1MD2)
            case MCU_POWER_MODE_SLEEP:
                SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
                break;
            case MCU_POWER_MODE_DEEPSLEEP:
                SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
                PcuBase->CSR &= ~(PCU_CSR_PMCLPEN_MASK);
                break;
            case MCU_POWER_MODE_STANDBY:
                EfmBase->CTRL |= (EFM_CTRL_LPEN_MASK);
                SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
                PcuBase->CSR |= (PCU_CSR_PMCLPEN_MASK);
                break;
#elif defined (CPU_YTM32B1ME1)
            case MCU_POWER_MODE_SLEEP:
                SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
                break;
            case MCU_POWER_MODE_DEEPSLEEP:
                SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
                PcuBase->CTRL0 &= ~(PCU_CTRL0_PWR_MODE_MASK);
                break;
            case MCU_POWER_MODE_STANDBY:
                SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
                PcuBase->CTRL0 &= ~(PCU_CTRL0_PWR_MODE_MASK);
                PcuBase->CTRL0 |= PCU_CTRL0_PWR_MODE(0x01);
                break;
            case MCU_POWER_MODE_POWERDOWN:
                SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
                PcuBase->CTRL0 &= ~(PCU_CTRL0_PWR_MODE_MASK);
                PcuBase->CTRL0 |= PCU_CTRL0_PWR_MODE(0x02);
                break;
            case MCU_POWER_MODE_DEPP_POWERDOWN:
                SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
                PcuBase->CTRL0 &= ~(PCU_CTRL0_PWR_MODE_MASK);
                PcuBase->CTRL0 |= PCU_CTRL0_PWR_MODE(0x03);
                break;
#else
            case MCU_POWER_MODE_SLEEP:
                SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
                break;
            case MCU_POWER_MODE_DEEPSLEEP:
                SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
                EfmBase->CTRL |= (EFM_CTRL_DPD_EN_MASK);
                PcuBase->CTRL &= ~(PCU_CTRL_RPMEN_MASK | PCU_CTRL_STANDBYEN_MASK);
                break;
            case MCU_POWER_MODE_POWERDOWN:
                EfmBase->CTRL |= (EFM_CTRL_DPD_EN_MASK);
                SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
                PcuBase->CTRL &= ~(PCU_CTRL_STANDBYEN_MASK);
                PcuBase->CTRL |= (PCU_CTRL_RPMEN_MASK);
                break;
            case MCU_POWER_MODE_STANDBY:
                SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
                EfmBase->CTRL |= (EFM_CTRL_DPD_EN_MASK);
                PcuBase->CTRL |= (PCU_CTRL_RPMEN_MASK | PCU_CTRL_STANDBYEN_MASK);

                break;
#endif
            default:
                /* Nothing to do */
                break;
        }
        /* Disable systick, store current CMU Ctrl register value to temp value */
        TempSystick = SysTick->CTRL;
        SysTick->CTRL = 0x00U;

#if defined (CPU_YTM32B1MD1) || defined (CPU_YTM32B1ME0) || defined (CPU_YTM32B1ME1) || defined (CPU_YTM32B1HA0)
        /* ERRATA_E220004, it's better to wait for flash idle before entering low power mode. */
        uint32 Cnt = 0U;
        while ((Cnt < MCU_LPM_EFM_IDLE_TIMEOUT) && (0U == (EFM->STS & EFM_STS_IDLE_MASK)))
        {
            Cnt++;
        }
#endif
        /* When interrupt happen, exit low power mode to run mode: */
        SCB->SCR &= ~(SCB_SCR_SLEEPONEXIT_Msk);
        /**
         * MR12 RULE 1.2 VIOLATION: This line uses the __ASM() macro for inline assembly which is not a part of standard C.
         * In this specific case, we are executing a 'wfi' instruction to put the processor into low power state or sleep
         * mode until the next interrupt is fired, hnce we couldn't adhere to the rule 1.2
         */
        __ASM("wfi\n");
        /* Restore systick */
        SysTick->CTRL = TempSystick;
        /* Clear the DEEPSLEEP flag */
        SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
        /**
         * NOTE:
         * After the `Mcu_Lld_SetMode()` function returns, the enabled clocks become effective. Due to the inclusion of multiple
         * clocks, the setting is not performed in the `Mcu_Lld_SetMode()` function. Instead, users need to re-invoke
         * `Mcu_InitClock()` for clock initialization.
         */
    }
}
/* GCOVR_EXCL_STOP */
/* PRQA S 0306 -- */

MCU_FUNC Std_ReturnType Mcu_Lld_SetClockSource(const Mcu_ClockConfigType *ConfigPtr)
{
    Std_ReturnType ReturnValue = (Std_ReturnType)E_OK;
    ReturnValue = Mcu_Lld_SwitchSystemClock(ConfigPtr->SystemClockSource);
    if ((Std_ReturnType)E_OK == ReturnValue)
    {
        /* Set CMU */
        Mcu_Lld_SetCmu(ConfigPtr->ClockMonitorConfig, ConfigPtr->ClockMonitorConfigNums);
        /* Init Clock output */
        /* Disable Clock output */
        Mcu_Lld_ClkOutDisable();
        if (TRUE == ConfigPtr->ClockOutEnable)
        {
            Mcu_Lld_SetClockOut(ConfigPtr->ClockOutConfig);
        }
    }
    return ReturnValue;
}


MCU_FUNC void Mcu_Lld_SetPeripheralClock(const Mcu_PeripheralClockConfigType *ConfigPtr)
{
    if (NULL_PTR != ConfigPtr)
    {
        Mcu_IpcConfigType const *IpcConfigPtr = ConfigPtr->IpcConfig;
        volatile IPC_Type *IpcBase = Mcu_IpcBasePtr[0];
        if (NULL_PTR != IpcConfigPtr)
        {
            for (uint8 IpcIndex = 0U; IpcIndex < ConfigPtr->IpcCount; ++IpcIndex)
            {
                /* Disable the peripheral clock */
                IpcBase->CTRL[IpcConfigPtr->PeripheralIndex] &= ~(IPC_CTRL_CLKEN_MASK);
                /* Set peripheral clock config and enable the peripheral clock */
                /* PRQA S 2985 ++ */
                IpcBase->CTRL[IpcConfigPtr->PeripheralIndex] = (IpcBase->CTRL[IpcConfigPtr->PeripheralIndex]
                        & ~(IPC_CTRL_SRCSEL_MASK | IPC_CTRL_DIV_MASK | IPC_CTRL_CLKEN_MASK))
                        | IPC_CTRL_SRCSEL(IpcConfigPtr->ClockSource) |
                        IPC_CTRL_DIV(IpcConfigPtr->ClockDiv) |
                        IPC_CTRL_CLKEN(IpcConfigPtr->ClockEnable);
                /* PRQA S 2985 -- */
                ++IpcConfigPtr;
            }
        }
    }
}


MCU_FUNC Std_ReturnType Mcu_Lld_InitClock(const Mcu_ClockConfigType *ConfigPtr)
{
    Std_ReturnType ReturnValue = (Std_ReturnType)E_NOT_OK;
    if (NULL_PTR != ConfigPtr)
    {
        Mcu_Lld_DisableAllCmu();
        /* Set the system clock to SIRC and ensure that the following functions run correctly */
        ReturnValue = Mcu_Lld_SwitchSystemClock(MCU_SYSTEM_CLOCK_SOURCE_SIRC);
        if (E_OK == ReturnValue)
        {
            /* Init peripheral clock */
            Mcu_Lld_SetPeripheralClock(ConfigPtr->PeripheralClockConfig);
            /* Init all system clock sources */
            ReturnValue = Mcu_Lld_InitClockSources(ConfigPtr);
            /* Set EFM prescaler configuration and RWS value */
            Mcu_Lld_EfmPrescaler(ConfigPtr->EfmPrescaleValue, ConfigPtr->EfmWRSValue);
#if (MCU_EEPROM_SUPPORT == STD_ON)
            Mcu_Lld_EEPROMPrescaler(ConfigPtr->EEPROMPrescaleValue, ConfigPtr->EEPROMWRSValue);
#endif
            ReturnValue |= Mcu_Lld_InitClockDivider(ConfigPtr);
        }
        /* Pll end wait clock stable, others clock can init directly */
        if ((E_OK == ReturnValue) && (ConfigPtr->SystemClockSource != MCU_SYSTEM_CLOCK_SOURCE_PLL))
        {
            /* Set the clock source of diferent IP */
            ReturnValue = Mcu_Lld_SetClockSource(ConfigPtr);
        }
    }
    return ReturnValue;
}

MCU_FUNC Mcu_RawResetType Mcu_Lld_GetResetRawValue(void)
{
    Mcu_RawResetType ResetReasonRawValue;
    volatile RCU_Type *RcuBase = Mcu_RcuBasePtr[0];

    ResetReasonRawValue = RcuBase->RSSR & RCU_RSSR_MASK;
    /* Clear reset source status register, RSSR register is clear by writen 1 */
    RcuBase->RSSR = RCU_RSSR_MASK;
    return ResetReasonRawValue;
}

/**
 * M3CM 4700 VALIDATION: This function needs to handle multiple reset reason types with conditional
 * compilation directives and contains a large switch statement to map raw reset values to
 * standardized reset types. The complexity is necessary to properly handle all possible reset
 * scenarios across different Mcu variants.
 */
MCU_FUNC Mcu_ResetType Mcu_Lld_GetResetValue(void) /* PRQA S 4700 */
{
    Mcu_ResetType ResetReason;
    Mcu_RawResetType ResetReasonRawValue = Mcu_Lld_GetResetRawValue();
    /* If reset reason is zero, use the value from Mcu_ResetStatusValue */
    if (0U == ResetReasonRawValue)
    {
        ResetReasonRawValue = Mcu_ResetStatusValue;
    }
    else
    {
        Mcu_ResetStatusValue = ResetReasonRawValue;
    }
    switch (ResetReasonRawValue)
    {

#if defined(RCU_RSSR_LVD_MASK)
        case RCU_RSSR_LVD_MASK:
            ResetReason = MCU_LVD_RESET;
            break;
#endif
#if defined(RCU_RSSR_HVD_MASK)
        case RCU_RSSR_HVD_MASK:
            ResetReason = MCU_HVD_RESET;
            break;
#endif
        case RCU_RSSR_LPACK_MASK:
            ResetReason = MCU_DEEPSLEEP_ACK_RESET;
            break;
        case RCU_RSSR_WDG_MASK:
            ResetReason = MCU_WATCHDOG_RESET;
            break;
        case RCU_RSSR_CMU_MASK:
            ResetReason = MCU_CMU_RESET;
            break;
        case RCU_RSSR_LOCKUP_MASK:
            ResetReason = MCU_CORE_LOCK_RESET;
            break;
        case RCU_RSSR_DBG_MASK:
            ResetReason = MCU_DEBUG_RESET;
            break;
        case RCU_RSSR_SW_MASK:
            ResetReason = MCU_SW_RESET;
            break;
        case RCU_RSSR_PIN_MASK:
            ResetReason = MCU_RESETB_RESET;
            break;
#if defined(RCU_RSSR_POR_BOR_MASK)
        case RCU_RSSR_POR_BOR_MASK:
            ResetReason = MCU_POR_BOR_RESET;
            break;
#endif
#if defined(RCU_RSSR_POR_LVD_MASK)
        case RCU_RSSR_POR_LVD_MASK:
            ResetReason = MCU_POWER_ON_RESET;
            break;
#endif
#if (MCU_FMU_SUPPORT == STD_ON)
        case RCU_RSSR_FMU_FAIL_REACT_MASK:
            ResetReason = MCU_FMU_FAIL_REACT_RESET;
            break;
        case RCU_RSSR_FMU_FUNC_MASK:
            ResetReason = MCU_FMU_FUNC_RESET;
            break;
#endif
        default:
            ResetReason = MCU_MUTI_REASON_RESET;
            break;
    }
    return ResetReason;
}

#if (MCU_NO_PLL == STD_OFF)
MCU_FUNC uint32 Mcu_Lld_GetPllClockFrequency(const Mcu_ClockConfigType *ConfigPtr)
{
    uint32 PllClockFrequency = 0U;
    Mcu_PllClockRefType PllClockRef = MCU_PLL_CLOCK_REFERENCE_FXOSC;
    uint32 PllRefClockFrequency = 0U;
    uint32 PllFbDiv = 0U;
    uint32 PllRefDiv = 0U;
    uint32 PllFixDiv = 2U;
    if ((MCU_PLL_LOCKED == Mcu_Lld_GetPllStatus()) && (ConfigPtr != NULL_PTR))
    {
        /* Get pll reference clock source */
        PllClockRef = Mcu_Lld_GetPllRef();
        switch (PllClockRef)
        {
            case MCU_PLL_CLOCK_REFERENCE_FXOSC:
                PllRefClockFrequency = ConfigPtr->FxoscConfig->ClockRefPointFrequency;
                break;
            case MCU_PLL_CLOCK_REFERENCE_FIRC:
                PllRefClockFrequency = ConfigPtr->FircConfig->FircClockRefPointFrequency;
                break;
            default:
                PllRefClockFrequency = 0U;
                break;
        }
        PllFbDiv = Mcu_Lld_GetPllFbDiv();
        PllRefDiv = Mcu_Lld_GetPllRefDiv();
        PllClockFrequency = (PllRefClockFrequency * PllFbDiv) / (PllFixDiv * PllRefDiv);
    }
    return PllClockFrequency;
}
#endif

MCU_FUNC uint32 Mcu_Lld_GetCoreClockFrequency(const Mcu_ClockConfigType *ConfigPtr)
{
    Mcu_SystemClockSourceType CoreClockSrc = MCU_SYSTEM_CLOCK_SOURCE_FIRC;
    uint32 CoreClockSrcFrequency = 0U;
    uint32 CoreClockDiv = 0U;
    uint32 CoreClockFrequency = 0U;
    /* Get core clock source */
    CoreClockSrc = Mcu_Lld_GetCoreClockSource();
    switch (CoreClockSrc)
    {
        case MCU_SYSTEM_CLOCK_SOURCE_FIRC:
            CoreClockSrcFrequency = ConfigPtr->FircConfig->FircClockRefPointFrequency;
            break;
#if (MCU_NO_PLL == STD_OFF)
        case MCU_SYSTEM_CLOCK_SOURCE_PLL:
            CoreClockSrcFrequency = Mcu_Lld_GetPllClockFrequency(ConfigPtr);
            break;
#endif
        case MCU_SYSTEM_CLOCK_SOURCE_FXOSC:
            CoreClockSrcFrequency = ConfigPtr->FxoscConfig->ClockRefPointFrequency;
            break;
        case MCU_SYSTEM_CLOCK_SOURCE_SIRC:
            /* MCU_SYSTEM_CLOCK_SOURCE_SIRC */
            CoreClockSrcFrequency = ConfigPtr->SircConfig->SircClockRefPointFrequency;
            break;
        default:
            /** Nothing to do */
            break;
    }
    if (0U != CoreClockSrcFrequency)
    {
        /* Get core clock divider */
        CoreClockDiv = Mcu_Lld_GetCoreDiv();
        /* Caculate core clock frequency */
        CoreClockFrequency = CoreClockSrcFrequency / CoreClockDiv;
    }
    return CoreClockFrequency;
}


#if defined(CPU_YTM32B1MC0) || defined (CPU_YTM32B1MD2)
MCU_FUNC void Mcu_Lld_SetPcu(const Mcu_PcuConfigType *ConfigPtr)
{
    /* Check the configPtr */
    if (ConfigPtr != NULL_PTR)
    {
        volatile PCU_Type *PcuBase = Mcu_PcuBasePtr[0];
        /* LVDCR register */
        uint32 RegValue = 0U;

        /* PRQA S 2986, 2985 ++ */
        RegValue |= PCU_LVDCR_LVD5VEN(
            (((ConfigPtr->LvdConfigPtr->EnableBitList & MCU_LVD5V_ENABLE_MASK)) != 0x00U) ? 1U : 0U
        );
        RegValue |= PCU_LVDCR_LVD5VLPMD(
            (((ConfigPtr->LvdConfigPtr->EnableBitList & MCU_LVD5V_LPM_ENABLE_MASK)) != 0x00U) ? 1U : 0U
        );
        RegValue |= PCU_LVDCR_LVD5VFLTEN(
            (((ConfigPtr->LvdConfigPtr->EnableBitList & MCU_LVD5V_FILTER_MASK)) != 0x00U) ? 1U : 0U
        );
        RegValue |= PCU_LVDCR_LVD5VRE(
            (((ConfigPtr->LvdConfigPtr->EnableBitList & MCU_LVD5V_RESET_MASK)) != 0x00U) ? 1U : 0U
        );
        RegValue |= PCU_LVDCR_LVD5VIE(
            (((ConfigPtr->LvdConfigPtr->EnableBitList & MCU_LVD5V_INT_ENABLE_MASK)) != 0x00U) ? 1U : 0U
        );
        RegValue |= PCU_LVDCR_LVD5VHYS(ConfigPtr->LvdConfigPtr->LVD5VHysteresis);
        RegValue |= PCU_LVDCR_LVD5VTRIM(ConfigPtr->LvdConfigPtr->LVD5VTrim);
        PcuBase->LVDCR |= (PCU_LVDCR_LVD5VFLAG_MASK);
        PcuBase->LVDCR = (PcuBase->LVDCR
                          & ~(PCU_LVDCR_LVD5VEN_MASK        |
                              PCU_LVDCR_LVD5VLPMD_MASK      |
                              PCU_LVDCR_LVD5VFLTEN_MASK     |
                              PCU_LVDCR_LVD5VRE_MASK        |
                              PCU_LVDCR_LVD5VIE_MASK        |
                              PCU_LVDCR_LVD5VHYS_MASK       |
                              PCU_LVDCR_LVD5VTRIM_MASK))
                         | RegValue;
        /* PRQA S 2986, 2985 -- */
#if (MCU_LLD_PCU_ISR_USED == STD_ON)
        Mcu_PcuNotiList[MCU_PCU_LVD5V_NOTIFICATION_IDX] = ConfigPtr->LvdConfigPtr->LVD5VNotificationPtr;
#endif
    }
}

/**
 * GCOVR_EXCL_START
 * The function `Mcu_Lld_Pcu_ChannelIrqProcess` is called during a voltage abnormality interrupt.
 * This function checks the relevant voltage status registers of the PCU, making it suitable for
 * coverage testing in integrated testing scenarios.
 */
#if (MCU_LLD_PCU_ISR_USED == STD_ON)
MCU_FUNC void Mcu_Lld_Pcu_ChannelIrqProcess(void)
{
    volatile PCU_Type *PcuBase = Mcu_PcuBasePtr[0];
    uint32 RegVal = 0U;
    RegVal = PcuBase->LVDCR;
    MCAL_QUA_FAULT_INJECTION(MCU_ERROR_INJECT_4);
    /* If IFlag and IEnable */
    if ((0U != (RegVal & PCU_LVDCR_LVD5VFLAG_MASK)) && (0U != (RegVal & PCU_LVDCR_LVD5VIE_MASK)))
    {
        /* Clear the LVD5V Flag */
        PcuBase->LVDCR |= (PCU_LVDCR_LVD5VFLAG_MASK);
        if (NULL_PTR != Mcu_PcuNotiList[MCU_PCU_LVD5V_NOTIFICATION_IDX])
        {
            Mcu_PcuNotiList[MCU_PCU_LVD5V_NOTIFICATION_IDX]();
        }
    }
}
#else
MCU_FUNC void Mcu_Lld_Pcu_ChannelIrqProcess(void)
{
    volatile PCU_Type *PcuBase = Mcu_PcuBasePtr[0];
    PcuBase->LVDCR |= (PCU_LVDCR_LVD5VFLAG_MASK);
}
/* GCOVR_EXCL_STOP */
#endif /* #if ( MCU_LLD_PCU_ISR_USED == STD_ON) */
#elif defined (CPU_YTM32B1ME1)
MCU_FUNC void Mcu_Lld_SetPcu(const Mcu_PcuConfigType *ConfigPtr)
{
    /* Check the configPtr */
    if (ConfigPtr != NULL_PTR)
    {
        volatile PCU_Type *PcuBase = Mcu_PcuBasePtr[0];
        uint32 RegValue = 0U;
        /* INTE register */
        RegValue = PCU_INTE_HVDIE(ConfigPtr->HVDIntEnable);
        RegValue |= PCU_INTE_LVDIE(ConfigPtr->LVDIntEnable);

        PcuBase->INTE = RegValue;

        /* CTRL register */
        RegValue = PCU_CTRL0_HVD50EN(ConfigPtr->HVD50Enable);
        RegValue |= PCU_CTRL0_LVD50EN(ConfigPtr->LVD50Enable);
        RegValue |= PCU_CTRL0_LVD12EN(ConfigPtr->LVD12Enable);
        RegValue |= PCU_CTRL0_HVDRE(ConfigPtr->HVDResetEnable);
        RegValue |= PCU_CTRL0_LVDRE(ConfigPtr->LVDResetEnable);
        RegValue |= PCU_CTRL0_PKE(ConfigPtr->PadKeepEnable);
        PcuBase->CTRL0 &= ~(PCU_CTRL0_HVD50EN_MASK |
                            PCU_CTRL0_LVD50EN_MASK |
                            PCU_CTRL0_LVD12EN_MASK |
                            PCU_CTRL0_HVDRE_MASK |
                            PCU_CTRL0_LVDRE_MASK |
                            PCU_CTRL0_PKE_MASK);
        PcuBase->CTRL0 |= RegValue;

#if (MCU_LLD_PCU_ISR_USED == STD_ON)
        /* Global notification list initialize*/
        Mcu_PcuNotiList[MCU_PCU_HVD50_NOTIFICATION_IDX] = ConfigPtr->HVD50IntNotificationPtr;
        Mcu_PcuNotiList[MCU_PCU_LVD50_NOTIFICATION_IDX] = ConfigPtr->LVD50IntNotificationPtr;
        Mcu_PcuNotiList[MCU_PCU_LVD12_NOTIFICATION_IDX] = ConfigPtr->LVD12IntNotificationPtr;
#endif
    }
}
#if (MCU_LLD_PCU_ISR_USED == STD_ON)
MCU_FUNC void Mcu_Lld_Pcu_ChannelIrqProcess(void)
{
    volatile PCU_Type *PcuBase = Mcu_PcuBasePtr[0];
    uint32 RegSSTS = PcuBase->SSTS;
    uint32 RegINTE = PcuBase->INTE;
    MCAL_QUA_FAULT_INJECTION(MCU_ERROR_INJECT_4);
    /* if(High voltage detected) && (Interrupt enabled) */
    if (((RegSSTS & PCU_SSTS_HVD50F_MASK) != 0U) && ((RegINTE & PCU_INTE_HVDIE_MASK) != 0U))
    {
        /* Clear the SSTS register to prevent the continuous triggering of interrupts. */
        PcuBase->SSTS = PCU_SSTS_HVD50F_MASK;
        if (Mcu_PcuNotiList[MCU_PCU_HVD50_NOTIFICATION_IDX] != NULL_PTR)
        {
            Mcu_PcuNotiList[MCU_PCU_HVD50_NOTIFICATION_IDX]();
        }
    }
    if (((RegSSTS & PCU_SSTS_LVD50F_MASK) != 0U) && ((RegINTE & PCU_INTE_LVDIE_MASK) != 0U))
    {
        PcuBase->SSTS = PCU_SSTS_LVD50F_MASK;
        if (Mcu_PcuNotiList[MCU_PCU_LVD50_NOTIFICATION_IDX] != NULL_PTR)
        {
            Mcu_PcuNotiList[MCU_PCU_LVD50_NOTIFICATION_IDX]();
        }
    }
    if (((RegSSTS & PCU_SSTS_LVD12F_MASK) != 0U) && ((RegINTE & PCU_INTE_LVDIE_MASK) != 0U))
    {
        PcuBase->SSTS = PCU_SSTS_LVD12F_MASK;
        if (Mcu_PcuNotiList[MCU_PCU_LVD12_NOTIFICATION_IDX] != NULL_PTR)
        {
            Mcu_PcuNotiList[MCU_PCU_LVD12_NOTIFICATION_IDX]();
        }
    }
}
#else /** #if (MCU_LLD_PCU_ISR_USED == STD_ON) */
MCU_FUNC void Mcu_Lld_Pcu_ChannelIrqProcess(void)
{
    volatile PCU_Type *PcuBase = Mcu_PcuBasePtr[0];
    PcuBase->SSTS = PCU_SSTS_HVD50F_MASK | PCU_SSTS_LVD50F_MASK | PCU_SSTS_LVD12F_MASK;
}
#endif /** #if (MCU_LLD_PCU_ISR_USED == STD_ON) */

#else /**  defined(CPU_YTM32B1MC0) || defined (CPU_YTM32B1MD2) */
MCU_FUNC void Mcu_Lld_SetPcu(const Mcu_PcuConfigType *ConfigPtr)
{
    /* Check the configPtr */
    if (ConfigPtr != NULL_PTR)
    {
        volatile PCU_Type *PcuBase = Mcu_PcuBasePtr[0];
        PcuBase->INTE = (PcuBase->INTE
                         & ~(PCU_INTE_HVD11IE_MASK  |
                             PCU_INTE_HVD25IE_MASK  |
                             PCU_INTE_HVD50IE_MASK))
                        | PCU_INTE_HVD11IE(ConfigPtr->HvdConfigPtr->HVD11IntEnable) |
                        PCU_INTE_HVD25IE(ConfigPtr->HvdConfigPtr->HVD25IntEnable) |
                        PCU_INTE_HVD50IE(ConfigPtr->HvdConfigPtr->HVD50IntEnable);

        /* CTRL register */
#if (MCU_HAS_PKE == STD_ON)
        const uint32 PcuCtrlMask = PCU_CTRL_HVDRE_MASK | PCU_CTRL_FASTREC_MASK | PCU_CTRL_PKE_MASK;
#else
        const uint32 PcuCtrlMask = PCU_CTRL_HVDRE_MASK | PCU_CTRL_FASTREC_MASK;
#endif
        uint32 RegValue = 0U;
        RegValue = PCU_CTRL_HVDRE(ConfigPtr->HvdConfigPtr->ResetEnable);
        RegValue |= PCU_CTRL_FASTREC(ConfigPtr->FastRecoveryEnable);
#if (MCU_HAS_PKE == STD_ON)
        RegValue |= PCU_CTRL_PKE(ConfigPtr->PadKeepEnable);
#endif
        PcuBase->CTRL = (PcuBase->CTRL
                         & ~(PcuCtrlMask))
                        | RegValue;
#if (MCU_LLD_PCU_ISR_USED == STD_ON)
        /* Global notification list initialize*/
        Mcu_PcuNotiList[MCU_PCU_HVD11_NOTIFICATION_IDX] = ConfigPtr->HvdConfigPtr->HVD11NotificationPtr;
        Mcu_PcuNotiList[MCU_PCU_HVD25_NOTIFICATION_IDX] = ConfigPtr->HvdConfigPtr->HVD25NotificationPtr;
        Mcu_PcuNotiList[MCU_PCU_HVD50_NOTIFICATION_IDX] = ConfigPtr->HvdConfigPtr->HVD50NotificationPtr;
#endif
    }
}
/**
 * GCOVR_EXCL_START
 * The function `Mcu_Lld_Pcu_ChannelIrqProcess` is called during a voltage abnormality interrupt.
 * This function checks the relevant voltage status registers of the PCU, making it suitable for
 * coverage testing in integrated testing scenarios.
 */
#if (MCU_LLD_PCU_ISR_USED == STD_ON)
MCU_FUNC void Mcu_Lld_Pcu_ChannelIrqProcess(void)
{
    volatile PCU_Type *PcuBase = Mcu_PcuBasePtr[0];

    uint32 RegSSTS = 0U;
    uint32 RegINTE = 0U;
    RegSSTS = PcuBase->SSTS;
    MCAL_QUA_FAULT_INJECTION(MCU_ERROR_INJECT_4);
    /* Clear the SSTS register to prevent the continuous triggering of interrupts. */
    PcuBase->SSTS = PCU_SSTS_HVD50F_MASK | PCU_SSTS_HVD25F_MASK | PCU_SSTS_HVD11F_MASK;
    RegINTE = PcuBase->INTE;
    /* if(High voltage detected) && (Interrupt enabled) */
    if (((RegSSTS & PCU_SSTS_HVD50F_MASK) != 0U) && ((RegINTE & PCU_INTE_HVD50IE_MASK) != 0U))
    {
        if (Mcu_PcuNotiList[MCU_PCU_HVD50_NOTIFICATION_IDX] != NULL_PTR)
        {
            Mcu_PcuNotiList[MCU_PCU_HVD50_NOTIFICATION_IDX]();
        }
    }
    if (((RegSSTS & PCU_SSTS_HVD25F_MASK) != 0U) && ((RegINTE & PCU_INTE_HVD25IE_MASK) != 0U))
    {
        if (Mcu_PcuNotiList[MCU_PCU_HVD25_NOTIFICATION_IDX] != NULL_PTR)
        {
            Mcu_PcuNotiList[MCU_PCU_HVD25_NOTIFICATION_IDX]();
        }
    }
    if (((RegSSTS & PCU_SSTS_HVD11F_MASK) != 0U) && ((RegINTE & PCU_INTE_HVD11IE_MASK) != 0U))
    {
        if (Mcu_PcuNotiList[MCU_PCU_HVD11_NOTIFICATION_IDX] != NULL_PTR)
        {
            Mcu_PcuNotiList[MCU_PCU_HVD11_NOTIFICATION_IDX]();
        }
    }
}
#else /* #if ( MCU_LLD_PCU_ISR_USED == STD_ON) */
MCU_FUNC void Mcu_Lld_Pcu_ChannelIrqProcess(void)
{
    volatile PCU_Type *PcuBase = Mcu_PcuBasePtr[0];
    /* SSTS register is write 1 clear */
    PcuBase->SSTS = (PCU_SSTS_HVD11F_MASK | PCU_SSTS_HVD25F_MASK | PCU_SSTS_HVD50F_MASK);
}
/*GCOVR_EXCL_STOP*/
#endif /* #if ( MCU_LLD_PCU_ISR_USED == STD_ON) */
#endif

#if (MCU_LLD_SCU_ISR_USED == STD_ON)
/**
* CPU_YTM32B1MD2 changed CMU register name, It's better to rewrite whole function.
 */
MCU_FUNC void Mcu_Lld_Cmu_ChannelIrqProcess(void)
{
#if defined (CPU_YTM32B1MD2)
    volatile CMU_Type *CmuBase = Mcu_CmuBasePtr[0];
    uint32 RegSts = 0U;
    /* Read the STS register */
    RegSts = CmuBase->STS;
    /* Clear the STS register */
    CmuBase->STS = CMU_STS_LOSV_MASK | CMU_STS_LOSC_MASK | CMU_STS_LOSR_MASK | CMU_STS_OUTRNG_MASK;
#else
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    uint32 RegSts = 0U;
    /* Read the STS register */
    RegSts = ScuBase->CMUSTS;
    /* Clear the STS register */
    ScuBase->CMUSTS = SCU_CMUSTS_MASK;
#endif
    MCAL_QUA_FAULT_INJECTION(MCU_ERROR_INJECT_5);
    /**
    * The notification function will be call when the fellowing conditions are met:
    * - CMUx interrupt is enabled in configuration.
    * - CMUx notification function is not NULL_PTR.
    * - CMUx flag is detected.
    */
    for (uint8 Idx = 0U; Idx < MCU_CMU_CHANNEL_NUMS; ++Idx)
    {
        if ((Mcu_CmuIntEnableList[Idx] != (boolean)STD_OFF) && (Mcu_CmuNotiList[Idx] != NULL_PTR))
        {
            /* Set the raw RegSts value to `Mcu_CmuErrorType` value */
            Mcu_CmuErrorType CmuError = (RegSts >> Idx) & MCU_CMU_FLAG_MASK;
            if (CmuError != 0U)
            {
#if (MCU_ENABLE_DEM_REPORT_ERROR_STATUS == STD_ON)
                Mcu_ReportCmuFailure();
#endif
                Mcu_CmuNotiList[Idx](CmuError);
            }
        }
    }
}
#else /** #if (MCU_LLD_SCU_ISR_USED == STD_ON) */
MCU_FUNC void Mcu_Lld_Cmu_ChannelIrqProcess(void)
{
#if defined (CPU_YTM32B1MD2)
    /* Clear the STS register */
    volatile CMU_Type *CmuBase = Mcu_CmuBasePtr[0];
    CmuBase->STS = CMU_STS_LOSV_MASK | CMU_STS_LOSC_MASK | CMU_STS_LOSR_MASK | CMU_STS_OUTRNG_MASK;
#else
    /* Clear the STS register */
    volatile SCU_Type *ScuBase = Mcu_ScuBasePtr[0];
    ScuBase->CMUSTS = SCU_CMUSTS_MASK;
#endif
}
#endif /* #if (MCU_LLD_SCU_ISR_USED == STD_ON) */


#define MCU_STOP_SEC_CODE
#include "Mcu_MemMap.h"

#ifdef __cplusplus
}
#endif

/* End of file Mcu_Lld.c */

