/*!
* @file     Icu_Tmr.c
*
* @version  1.0.0
*
* @brief    Icu driver code by TMR code
*
* @attention
*
* Project Name      : AUTOSAR MCAL
*
* Platform          : Arm
*
* Autosar Standard  : Classic Platform 4.4.0
*
* Compiled Version  : G32A10xx_MCAL_1_0_0_01-Otc-25
*
* Copyright (C) 2026 Geehy Semiconductor
*
* You may not use this file except in compliance with the
* GEEHY COPYRIGHT NOTICE (Geehy Semiconductor Software License Agreement).
*
* The program is only for reference, which is distributed in the hope
* that it will be usefull and instructional for customers to develop
* their software. Unless required by applicable law or agreed to in
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
* See the Geehy Semiconductor Software License Agreement for the governing permissions
* and limitations under the License.
*/

/*
* MISRA-C:2012 compliance checks
*
*      Icu_Tmr_c_MISRA_REF1
*          Breaks the required M3CM Rule-1.3 of MISRA 2012 guidelines,
*          There shall be no occurrence of undefined or critical unspecified behaviour.
*
*      Icu_Tmr_c_MISRA_REF2
*          Breaks the required M3CM Rule-13.2 of MISRA 2012 guidelines,
*          The value of an expression and its persistent side-effects shall be the same under all permitted evaluation orders and shall be independent from thread interleaving.
*
*      Icu_Tmr_c_MISRA_REF3
*          Breaks the required M3CM Rule-13.5 of MISRA 2012 guidelines,
*          The right hand operand of a logical && or || operator shall not contain persistent side effects.
*/

#ifdef __cplusplus
extern "C"{
#endif

#include "Compiler.h"
#include "Std_Types.h"
#include "StdRegMacros.h"
#include "Mcu_DbgMcuReg.h"
#include "Mcu_RcmTypes.h"
#include "SchM_Icu.h"
#include "Icu_Tmr.h"
#include "Icu.h"
#include "Icu_Irq.h"

/** @addtogroup G32A10xx_StdPeriphDriver
  @{
*/

/** @defgroup ICU_Driver
  * @brief ICU driver modules
  @{
*/

/** @defgroup ICU_Macros
  @{
*/
/**************************************************************************
                  VENDOR ID & AUTOSAR VERSION INFO
**************************************************************************/
/** Vendor ID (vendorId) of the dedicated implementation of this module according to the AUTOSAR vendor list. */
#define ICU_TMR_VENDOR_ID                      0x00C1U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define ICU_TMR_AR_RELEASE_MAJOR_VERSION       0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define ICU_TMR_AR_RELEASE_MINOR_VERSION       0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define ICU_TMR_AR_RELEASE_REVISION_VERSION    0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define ICU_TMR_SW_MAJOR_VERSION               0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define ICU_TMR_SW_MINOR_VERSION               0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define ICU_TMR_SW_PATCH_VERSION               0x00U

/**@} end of group ICU_Macros */

/**************************************************************************
                    VERSION INFOMATION VERIFICATION
**************************************************************************/
#ifdef ENABLE_INTERMODULE_MCAL_CHECK

    /* Make sure the AUTOSAR major version number is the same between Icu_Tmr.c and StdRegMacros.h */
    #if (ICU_TMR_AR_RELEASE_MAJOR_VERSION != STD_REG_MACROS_H_AR_RELEASE_MAJOR_VERSION)
        #error "AUTOSAR Major Version Number mismatch between Icu_Tmr.c and StdRegMacros.h "
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Icu_Tmr.c and StdRegMacros.h */
    #if (ICU_TMR_AR_RELEASE_MINOR_VERSION != STD_REG_MACROS_H_AR_RELEASE_MINOR_VERSION)
        #error "AUTOSAR Minor Version Number mismatch between Icu_Tmr.c and StdRegMacros.h "
    #endif

    /* Make sure the AUTOSAR major version number is the same between Icu_Tmr.c and Std_Types.h */
    #if (ICU_TMR_AR_RELEASE_MAJOR_VERSION != STD_TYPES_H_AR_RELEASE_MAJOR_VERSION)
        #error "AUTOSAR Major Version Number mismatch between Icu_Tmr.c and Std_Types.h "
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Icu_Tmr.c and Std_Types.h */
    #if (ICU_TMR_AR_RELEASE_MINOR_VERSION != STD_TYPES_H_AR_RELEASE_MINOR_VERSION)
        #error "AUTOSAR Minor Version Number mismatch between Icu_Tmr.c and Std_Types.h "
    #endif

    /* Make sure the AUTOSAR major version number is the same between Icu_Tmr.c and SchM_Icu.h */
    #if (ICU_TMR_AR_RELEASE_MAJOR_VERSION != SCHM_ICU_H_AR_RELEASE_MAJOR_VERSION)
        #error "AUTOSAR Major Version Number mismatch between Icu_Tmr.c and SchM_Icu.h "
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Icu_Tmr.c and SchM_Icu.h */
    #if (ICU_TMR_AR_RELEASE_MINOR_VERSION != SCHM_ICU_H_AR_RELEASE_MINOR_VERSION)
        #error "AUTOSAR Minor Version Number mismatch between Icu_Tmr.c and SchM_Icu.h "
    #endif

    /* Make sure the AUTOSAR major version number is the same between Icu_Tmr.c and Compiler.h */
    #if (ICU_TMR_AR_RELEASE_MAJOR_VERSION != COMPILER_H_AR_RELEASE_MAJOR_VERSION)
        #error "AUTOSAR Major Version Number mismatch between Icu_Tmr.c and Compiler.h "
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Icu_Tmr.c and Compiler.h */
    #if (ICU_TMR_AR_RELEASE_MINOR_VERSION != COMPILER_H_AR_RELEASE_MINOR_VERSION)
        #error "AUTOSAR Minor Version Number mismatch between Icu_Tmr.c and Compiler.h "
    #endif

#endif

/* Make sure the vendor id is the same between Icu_Tmr.c and Icu_Tmr.h */
#if (ICU_TMR_VENDOR_ID != ICU_TMR_H_VENDOR_ID)
    #error "Vendor id mismatch between Icu_Tmr.c and Icu_Tmr.h "
#endif
/* Make sure the AUTOSAR major version number is the same between Icu_Tmr.c and Icu_Tmr.h */
#if (ICU_TMR_AR_RELEASE_MAJOR_VERSION != ICU_TMR_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Icu_Tmr.c and Icu_Tmr.h "
#endif
/* Make sure the AUTOSAR minor version number is the same between Icu_Tmr.c and Icu_Tmr.h */
#if (ICU_TMR_AR_RELEASE_MINOR_VERSION != ICU_TMR_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Icu_Tmr.c and Icu_Tmr.h "
#endif
/* Make sure the AUTOSAR revision version number is the same between Icu_Tmr.c and Icu_Tmr.h */
#if (ICU_TMR_AR_RELEASE_REVISION_VERSION != ICU_TMR_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Icu_Tmr.c and Icu_Tmr.h "
#endif
/* Make sure the software major version number is the same between Icu_Tmr.c and Icu_Tmr.h */
#if (ICU_TMR_SW_MAJOR_VERSION != ICU_TMR_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Icu_Tmr.c and Icu_Tmr.h "
#endif
/* Make sure the software minor version number is the same between Icu_Tmr.c and Icu_Tmr.h */
#if (ICU_TMR_SW_MINOR_VERSION != ICU_TMR_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Icu_Tmr.c and Icu_Tmr.h "
#endif
/* Make sure the software patch version number is the same between Icu_Tmr.c and Icu_Tmr.h */
#if (ICU_TMR_SW_PATCH_VERSION != ICU_TMR_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Icu_Tmr.c and Icu_Tmr.h "
#endif

/* Make sure the vendor id is the same between Icu_Tmr.c and Icu_Types.h */
#if (ICU_TMR_VENDOR_ID != ICU_TYPE_H_VENDOR_ID)
    #error "Vendor id mismatch between Icu_Tmr.c and Icu_Types.h "
#endif
/* Make sure the AUTOSAR major version number is the same between Icu_Tmr.c and Icu_Types.h */
#if (ICU_TMR_AR_RELEASE_MAJOR_VERSION != ICU_TYPE_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Icu_Tmr.c and Icu_Types.h "
#endif
/* Make sure the AUTOSAR minor version number is the same between Icu_Tmr.c and Icu_Types.h */
#if (ICU_TMR_AR_RELEASE_MINOR_VERSION != ICU_TYPE_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Icu_Tmr.c and Icu_Types.h "
#endif
/* Make sure the AUTOSAR revision version number is the same between Icu_Tmr.c and Icu_Types.h */
#if (ICU_TMR_AR_RELEASE_REVISION_VERSION != ICU_TYPE_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Icu_Tmr.c and Icu_Types.h "
#endif
/* Make sure the software major version number is the same between Icu_Tmr.c and Icu_Types.h */
#if (ICU_TMR_SW_MAJOR_VERSION != ICU_TYPE_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Icu_Tmr.c and Icu_Types.h "
#endif
/* Make sure the software minor version number is the same between Icu_Tmr.c and Icu_Types.h */
#if (ICU_TMR_SW_MINOR_VERSION != ICU_TYPE_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Icu_Tmr.c and Icu_Types.h "
#endif
/* Make sure the software patch version number is the same between Icu_Tmr.c and Icu_Types.h */
#if (ICU_TMR_SW_PATCH_VERSION != ICU_TYPE_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Icu_Tmr.c and Icu_Types.h "
#endif

/* Make sure the vendor id is the same between Icu_Tmr.c and Icu_Irq.h */
#if (ICU_TMR_VENDOR_ID != ICU_IRQ_H_VENDOR_ID)
    #error "Vendor id mismatch between Icu_Tmr.c and Icu_Irq.h "
#endif
/* Make sure the AUTOSAR major version number is the same between Icu_Tmr.c and Icu_Irq.h */
#if (ICU_TMR_AR_RELEASE_MAJOR_VERSION != ICU_IRQ_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Icu_Tmr.c and Icu_Irq.h "
#endif
/* Make sure the AUTOSAR minor version number is the same between Icu_Tmr.c and Icu_Irq.h */
#if (ICU_TMR_AR_RELEASE_MINOR_VERSION != ICU_IRQ_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Icu_Tmr.c and Icu_Irq.h "
#endif
/* Make sure the AUTOSAR revision version number is the same between Icu_Tmr.c and Icu_Irq.h */
#if (ICU_TMR_AR_RELEASE_REVISION_VERSION != ICU_IRQ_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Icu_Tmr.c and Icu_Irq.h "
#endif
/* Make sure the software major version number is the same between Icu_Tmr.c and Icu_Irq.h */
#if (ICU_TMR_SW_MAJOR_VERSION != ICU_IRQ_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Icu_Tmr.c and Icu_Irq.h "
#endif
/* Make sure the software minor version number is the same between Icu_Tmr.c and Icu_Irq.h */
#if (ICU_TMR_SW_MINOR_VERSION != ICU_IRQ_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Icu_Tmr.c and Icu_Irq.h "
#endif
/* Make sure the software patch version number is the same between Icu_Tmr.c and Icu_Irq.h */
#if (ICU_TMR_SW_PATCH_VERSION != ICU_IRQ_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Icu_Tmr.c and Icu_Irq.h "
#endif

/* Make sure the vendor id is the same between Icu_Tmr.c and Icu_Cfg.h */
#if (ICU_TMR_VENDOR_ID != ICU_CFG_H_VENDOR_ID)
    #error "Vendor id mismatch between Icu_Tmr.c and Icu_Cfg.h "
#endif
/* Make sure the AUTOSAR major version number is the same between Icu_Tmr.c and Icu_Cfg.h */
#if (ICU_TMR_AR_RELEASE_MAJOR_VERSION != ICU_CFG_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Icu_Tmr.c and Icu_Cfg.h "
#endif
/* Make sure the AUTOSAR minor version number is the same between Icu_Tmr.c and Icu_Cfg.h */
#if (ICU_TMR_AR_RELEASE_MINOR_VERSION != ICU_CFG_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Icu_Tmr.c and Icu_Cfg.h "
#endif
/* Make sure the AUTOSAR revision version number is the same between Icu_Tmr.c and Icu_Cfg.h */
#if (ICU_TMR_AR_RELEASE_REVISION_VERSION != ICU_CFG_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Icu_Tmr.c and Icu_Cfg.h "
#endif
/* Make sure the software major version number is the same between Icu_Tmr.c and Icu_Cfg.h */
#if (ICU_TMR_SW_MAJOR_VERSION != ICU_CFG_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Icu_Tmr.c and Icu_Cfg.h "
#endif
/* Make sure the software minor version number is the same between Icu_Tmr.c and Icu_Cfg.h */
#if (ICU_TMR_SW_MINOR_VERSION != ICU_CFG_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Icu_Tmr.c and Icu_Cfg.h "
#endif
/* Make sure the software patch version number is the same between Icu_Tmr.c and Icu_Cfg.h */
#if (ICU_TMR_SW_PATCH_VERSION != ICU_CFG_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Icu_Tmr.c and Icu_Cfg.h "
#endif

/**************************************************************************
                    LOCAL VARIABLE
**************************************************************************/
#define ICU_START_SEC_VAR_INIT_32
#include "Icu_MemMap.h"

/** @defgroup ICU_Variable
  @{
*/

#if (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE)
static Icu_TmrChICCtrlType s_icuTmrChICCtrl[ICU_TMR_MAX_CH_NUMBER] = {{TMR_IC_IDLE_STS,0,0,0}};
#endif

/**@} end of group ICU_Variable */

#define ICU_STOP_SEC_VAR_INIT_32
#include "Icu_MemMap.h"

#define ICU_START_SEC_VAR_INIT_16
#include "Icu_MemMap.h"

/** @defgroup ICU_Variable
  @{
*/

#if (STD_ON == ICU_EDGE_COUNT_API_ENABLE)
static VAR(uint16, ICU_VAR) s_icuTmrEdgeNumber[ICU_TMR_MAX_CH_NUMBER] = {
(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,
(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,
(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0};
#endif

/**@} end of group ICU_Variable */

#define ICU_STOP_SEC_VAR_INIT_16
#include "Icu_MemMap.h"

#define ICU_START_SEC_VAR_INIT_8
#include "Icu_MemMap.h"

/** @defgroup ICU_Variable
  @{
*/

#if (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE)
static VAR(uint8, ICU_VAR) s_icuTmrFirstEdge[ICU_TMR_MAX_CH_NUMBER] = {
(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,
(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,
(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0};

static VAR(uint32,AUTOMATIC) s_validHighPulseCount[ICU_TMR_MAX_CH_NUMBER] = {
(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,
(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,
(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0};

static VAR(uint32,AUTOMATIC) s_validLowPulseCount[ICU_TMR_MAX_CH_NUMBER] = {
(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,
(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0,
(uint8)0,(uint8)0,(uint8)0,(uint8)0,(uint8)0};

#endif

/**@} end of group ICU_Variable */

#define ICU_STOP_SEC_VAR_INIT_8
#include "Icu_MemMap.h"

#define ICU_START_SEC_VAR_INIT_UNSPECIFIED
#include "Icu_MemMap.h"

/** @defgroup ICU_Variable
  @{
*/

static VAR(Icu_TmrChFeatureStateType, ICU_VAR) s_icuTmrChFeatureState[ICU_TMR_MAX_CH_NUMBER] = {
(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,
(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0,
(uint16)0,(uint16)0,(uint16)0,(uint16)0,(uint16)0};

#if ((STD_ON == ICU_EDGE_DETECT_API_ENABLE) || (STD_ON == ICU_TIMESTAMP_API_ENABLE) ||\
     (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE) || (STD_ON == ICU_EDGE_COUNT_API_ENABLE))
/** The Tmr1 overflow flag */
static volatile VAR(boolean, ICU_VAR) s_icuTmr1OvfFlag = (boolean)FALSE;
#endif

/**@} end of group ICU_Variable */

#define ICU_STOP_SEC_VAR_INIT_UNSPECIFIED
#include "Icu_MemMap.h"

#define ICU_START_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Icu_MemMap.h"

/** @defgroup ICU_Variable
  @{
*/

#if (STD_ON == ICU_TIMESTAMP_API_ENABLE)
static VAR(Icu_ValueType,ICU_VAR) s_icuTmrTimestampBufferPtr[ICU_TMR_MAX_CH_NUMBER];
#endif

/**@} end of group ICU_Variable */

#define ICU_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Icu_MemMap.h"

/**************************************************************************
                    FUNCTION DECLARATION
**************************************************************************/
#define ICU_START_SEC_CODE
#include "Icu_MemMap.h"

/** @defgroup ICU_Fuctions
  @{
*/

#if ((STD_ON == ICU_EDGE_DETECT_API_ENABLE) || (STD_ON == ICU_TIMESTAMP_API_ENABLE) ||\
     (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE) || (STD_ON == ICU_EDGE_COUNT_API_ENABLE) ||\
     (STD_OFF == ICU_TMR_CUSTOM_FEATURE_ENABLE) || (STD_ON == ICU_SET_MODE_API_ENABLE))
LOCAL_INLINE FUNC(Icu_TmrChFeatureStateType, ICU_CODE) Icu_Tmr_GetTmrChFeatureStateBit(VAR(Icu_TmrChType, AUTOMATIC) ch,
                                                        VAR(Icu_TmrChFeatureStateType, AUTOMATIC) aimBit);
#endif

#if (STD_OFF == ICU_TMR_CUSTOM_FEATURE_ENABLE)
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_ClearTmrChInterruptFlagWithProtect(VAR(Icu_TmrChType, AUTOMATIC) ch);
#endif

#if (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE)
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_SetTmrSignalMeasurementChannel(CONST(Icu_TmrChType, AUTOMATIC) ch, 
    CONST(Icu_TmrHwChType, AUTOMATIC) tmrHwCh, CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule, 
    VAR(boolean, AUTOMATIC) ovfFlag);
LOCAL_INLINE FUNC(uint32, ICU_CODE) Icu_Tmr_MeasureChLevel(CONST(Icu_TmrChType, AUTOMATIC) ch, 
    CONST(Icu_TmrHwChType, AUTOMATIC) tmrHwCh, CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule, 
    VAR(Icu_TmrMeasurePropertyType, AUTOMATIC) measureItem);
#endif

#if ((STD_ON == ICU_EDGE_DETECT_API_ENABLE) || (STD_ON == ICU_TIMESTAMP_API_ENABLE) ||\
     (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE) || (STD_ON == ICU_EDGE_COUNT_API_ENABLE))
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_ClearTmrChInterruptFlag(VAR(Icu_TmrChType, AUTOMATIC) ch);
#endif

LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_ClearTmrChFeatureStateBit(VAR(Icu_TmrChType, AUTOMATIC) ch,
                                                                 VAR(Icu_TmrChFeatureStateType, AUTOMATIC) aimBit);

#if ((STD_ON == ICU_TIMESTAMP_API_ENABLE) || (STD_ON == ICU_EDGE_COUNT_API_ENABLE) || \
     (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE))
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_ResetTmrChFunction(VAR(Icu_TmrChType, AUTOMATIC) ch);
#endif

#if (STD_ON == ICU_TIMESTAMP_API_ENABLE)
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_SetTmrTimestampChannel(CONST(Icu_TmrChType, AUTOMATIC) ch, 
    CONST(Icu_TmrHwChType, AUTOMATIC) tmrHwCh, CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule,
     VAR(boolean, AUTOMATIC) ovfFlag);
#endif

#if ((STD_ON == ICU_EDGE_DETECT_API_ENABLE) || (STD_ON == ICU_TIMESTAMP_API_ENABLE) ||\
     (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE) || (STD_ON == ICU_EDGE_COUNT_API_ENABLE))
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_SetTmrChFunctionAndEdge(VAR(Icu_TmrChType, AUTOMATIC) ch);
#endif

LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_SetTmrChFeatureStateBit(VAR(Icu_TmrChType, AUTOMATIC) ch,
                                                               VAR(Icu_TmrChFeatureStateType, AUTOMATIC) aimBit);

#if (STD_OFF == ICU_TMR_CUSTOM_FEATURE_ENABLE)
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_ProcessChInterrupt(CONST(Icu_TmrChType, AUTOMATIC) ch, 
    CONST(Icu_TmrHwChType, AUTOMATIC) tmrHwCh, CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule, VAR(boolean, AUTOMATIC) ovfFlag);

LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_ProcessTofInterrupt(CONST(uint8, AUTOMATIC) moduleId);
#endif

#if (STD_ON == ICU_TIMESTAMP_API_ENABLE)
#if (STD_ON == ICU_TIMESTAMP_USES_DMA_ENABLE)
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_SetDmaHwCh(VAR(Pdl_ChType, AUTOMATIC) pdlDmaChannel, VAR(uint8, AUTOMATIC) dmaChEn, 
                                                 P2CONST(Pdl_DmaChHwConfigType, AUTOMATIC, ICU_APPL_CONST) pDmaChConfig);
#endif
#endif

LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_GlobalConfiguration(VAR(Icu_TmrGlobalCfgType, AUTOMATIC) tmrModuleConfig);

/**************************************************************************
                    LOCAL FUNCTION
**************************************************************************/
#if ((STD_ON == ICU_EDGE_DETECT_API_ENABLE) || (STD_ON == ICU_TIMESTAMP_API_ENABLE) ||\
     (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE) || (STD_ON == ICU_EDGE_COUNT_API_ENABLE) ||\
     (STD_OFF == ICU_TMR_CUSTOM_FEATURE_ENABLE) || (STD_ON == ICU_SET_MODE_API_ENABLE))
/*!
* @brief         This function is used to get s_icuTmrChFeatureState bit according to parameter.
*
* @param[in]     ch       channel id
* @param[in]     aimBit   aim bit
* @param[out]    None
* @param[in,out] None
*
* @retval        Icu_TmrChFeatureStateType
*/
LOCAL_INLINE FUNC(Icu_TmrChFeatureStateType, ICU_CODE) Icu_Tmr_GetTmrChFeatureStateBit(VAR(Icu_TmrChType, AUTOMATIC) ch,
                                                        VAR(Icu_TmrChFeatureStateType, AUTOMATIC) aimBit)
{
    return (s_icuTmrChFeatureState[ch] & aimBit);
}
#endif

#if (STD_OFF == ICU_TMR_CUSTOM_FEATURE_ENABLE)
/*!
* @brief         This function is used to clear TMR channel interrupt register bit with protect.
*
* @param[in]     ch       channel id
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_ClearTmrChInterruptFlagWithProtect(VAR(Icu_TmrChType, AUTOMATIC) ch)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);

    SchM_Enter_Icu_ICU_CRITICAL_SECTION16();

    /* clear TMRx_STS(n=0...4) register CCnIFLG bit */
    REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), 1UL << tmrChannel);
    /* clear TMR_STS register overflow bit */
    SchM_Exit_Icu_ICU_CRITICAL_SECTION16();
}
#endif

#if (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE)
/*!
* @brief         This function is used to set active edge TMR channel.
*
* @param[in]     tmrHwCh          TMR hardware channel id
* @param[in]     tmrModule        TMR module id
* @param[in]     icuActiveEdge    active edge
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_SetTmrHwChActiveEdge(CONST(Icu_TmrHwChType, AUTOMATIC) tmrHwCh, 
    CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule, VAR(Icu_TmrActiveEdgeType, AUTOMATIC) icuActiveEdge)
{
    switch (tmrHwCh)
    {
        case ICU_TMR_HW_CH1:
            /* Set the failing edge */
            REG_RMW32(TMR_CCEN_REG_ADDR(tmrModule), ICU_TMR_ACTIVE_EDGE_IS_BOTH, icuActiveEdge);
            break;
        case ICU_TMR_HW_CH2:
            /* Set the failing edge */
            REG_RMW32(TMR_CCEN_REG_ADDR(tmrModule), (uint32)ICU_TMR_ACTIVE_EDGE_IS_BOTH << TMR_CCEN_CC2EN_SHIFT, 
                (uint32)icuActiveEdge << TMR_CCEN_CC2EN_SHIFT);
            break;
        case ICU_TMR_HW_CH3:
            /* Set the failing edge */
            REG_RMW32(TMR_CCEN_REG_ADDR(tmrModule), (uint32)ICU_TMR_ACTIVE_EDGE_IS_BOTH << TMR_CCEN_CC3EN_SHIFT, 
                (uint32)icuActiveEdge << TMR_CCEN_CC3EN_SHIFT);
            break;
        case ICU_TMR_HW_CH4:
            /* Set the failing edge */
            REG_RMW32(TMR_CCEN_REG_ADDR(tmrModule), (uint32)ICU_TMR_ACTIVE_EDGE_IS_BOTH << TMR_CCEN_CC4EN_SHIFT, 
                (uint32)icuActiveEdge << TMR_CCEN_CC4EN_SHIFT);
            break;
        default:
            {
                /* Do nothing */
            }
            break;
    }
}

/*!
* @brief         This function is used to measure the high or low level of the TMR channel.
*
* @param[in]     ch             channel id
* @param[in]     tmrHwCh        TMR hardware channel id
* @param[in]     tmrModule      TMR module id
* @param[in]     measureItem    measure item
* @param[out]    None
* @param[in,out] None
*
* @retval        The measured high or low level value (unit : timer clock cycles)
*/
LOCAL_INLINE FUNC(uint32, ICU_CODE) Icu_Tmr_MeasureChLevel(CONST(Icu_TmrChType, AUTOMATIC) ch,
    CONST(Icu_TmrHwChType, AUTOMATIC) tmrHwCh, CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule,
    VAR(Icu_TmrMeasurePropertyType, AUTOMATIC) measureItem)
{
    VAR(uint32,AUTOMATIC) ccRegVal = 0U;
    VAR(uint32,AUTOMATIC) validPulseCount = 0U;
    VAR(Icu_ChannelType, AUTOMATIC) icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[ch];

    ccRegVal = Icu_Tmr_ReadTmrCCnRegValue(tmrHwCh, tmrModule);
    /* ICU_TMR_MEASURE_HIGH_LEVEL measure */
    if((((uint32)((*(g_icuCfgPtr->icuChCfgPtr))[icuCh].icuCHActiveEdgeAndWakeup) & (uint32)ICU_CH_ACTIVE_EDGE_MASK_VAL) >> (uint32)ICU_CH_ACTIVE_EDGE_BIT_OFFSET)
        == (uint32)ICU_RISING_EDGE)
    {
        if(s_icuTmrChICCtrl[ch].icuTmrIcSts == TMR_IC_FIRST_STS)
        {
            s_icuTmrChICCtrl[ch].icuTmrIcSts = TMR_IC_SECOND_STS;
            s_icuTmrChICCtrl[ch].icuTmrIcOfCnt = 0U;
            /* clear the channel update flag */
            REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_UIFLG_MASK);
            s_icuTmrChICCtrl[ch].icuTmrIcValFirst = (uint16)ccRegVal;
            Icu_Tmr_SetTmrHwChActiveEdge(tmrHwCh, tmrModule, ICU_TMR_ACTIVE_EDGE_IS_FALLING);
        }
        else if(s_icuTmrChICCtrl[ch].icuTmrIcSts == TMR_IC_SECOND_STS)
        {
            if(measureItem == ICU_TMR_MEASURE_DUTYCYCLE)
            {
                s_icuTmrChICCtrl[ch].icuTmrIcSts = TMR_IC_THIRD_STS;
                /* clear the channel update flag */
                REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_UIFLG_MASK);
            }
            else
            {
                s_icuTmrChICCtrl[ch].icuTmrIcSts = TMR_IC_END_STS;
            }
            
            s_icuTmrChICCtrl[ch].icuTmrIcValSecond = (uint16)ccRegVal;
            /* Continue capture:for next measure */
            Icu_Tmr_SetTmrHwChActiveEdge(tmrHwCh, tmrModule, ICU_TMR_ACTIVE_EDGE_IS_RISING);
            /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
            /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
            if((0U == s_icuTmrChICCtrl[ch].icuTmrIcOfCnt) && (s_icuTmrChICCtrl[ch].icuTmrIcValSecond < s_icuTmrChICCtrl[ch].icuTmrIcValFirst))
            {
                /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
                /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
                validPulseCount = (ICU_TMR_CC_REG_MAX_VAL + (uint32)1) + s_icuTmrChICCtrl[ch].icuTmrIcValSecond - s_icuTmrChICCtrl[ch].icuTmrIcValFirst;
            }
            /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
            /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
            else if((1U == s_icuTmrChICCtrl[ch].icuTmrIcOfCnt) && (s_icuTmrChICCtrl[ch].icuTmrIcValSecond > s_icuTmrChICCtrl[ch].icuTmrIcValFirst))
            {
                /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
                /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
                validPulseCount = (uint32)(s_icuTmrChICCtrl[ch].icuTmrIcValSecond) - (uint32)(s_icuTmrChICCtrl[ch].icuTmrIcValFirst);
            }
            else
            {
                /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
                /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
                validPulseCount = (uint32)((s_icuTmrChICCtrl[ch].icuTmrIcOfCnt * (ICU_TMR_CC_REG_MAX_VAL + (uint32)1)) +
                s_icuTmrChICCtrl[ch].icuTmrIcValSecond - s_icuTmrChICCtrl[ch].icuTmrIcValFirst);
            }

            s_icuTmrChICCtrl[ch].icuTmrIcOfCnt = 0U;
        }
        else
        {
            /* Do nothing */
        }
    }
    else if(((((*(g_icuCfgPtr->icuChCfgPtr))[icuCh].icuCHActiveEdgeAndWakeup) & (uint32)ICU_CH_ACTIVE_EDGE_MASK_VAL) >> (uint32)ICU_CH_ACTIVE_EDGE_BIT_OFFSET)
        == (uint32)ICU_FALLING_EDGE)
    {
        if(s_icuTmrChICCtrl[ch].icuTmrIcSts == TMR_IC_FIRST_STS)
        {
            s_icuTmrChICCtrl[ch].icuTmrIcSts = TMR_IC_SECOND_STS;
            s_icuTmrChICCtrl[ch].icuTmrIcOfCnt = 0U;
            /* clear the channel update flag */
            REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_UIFLG_MASK);
            s_icuTmrChICCtrl[ch].icuTmrIcValFirst = (uint16)ccRegVal;
            Icu_Tmr_SetTmrHwChActiveEdge(tmrHwCh, tmrModule, ICU_TMR_ACTIVE_EDGE_IS_RISING);
        }
        else if(s_icuTmrChICCtrl[ch].icuTmrIcSts == TMR_IC_SECOND_STS)
        {
            if(measureItem == ICU_TMR_MEASURE_DUTYCYCLE)
            {
                s_icuTmrChICCtrl[ch].icuTmrIcSts = TMR_IC_THIRD_STS;
                /* clear the channel update flag */
                REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_UIFLG_MASK);
            }
            else
            {
                s_icuTmrChICCtrl[ch].icuTmrIcSts = TMR_IC_END_STS;
            }
            s_icuTmrChICCtrl[ch].icuTmrIcValSecond = (uint16)ccRegVal;
            /* Continue capture:for next measure */
            Icu_Tmr_SetTmrHwChActiveEdge(tmrHwCh, tmrModule, ICU_TMR_ACTIVE_EDGE_IS_FALLING);
            /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
            /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
            if((0U == s_icuTmrChICCtrl[ch].icuTmrIcOfCnt) && (s_icuTmrChICCtrl[ch].icuTmrIcValSecond < s_icuTmrChICCtrl[ch].icuTmrIcValFirst))
            {
                /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
                /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
                validPulseCount = (ICU_TMR_CC_REG_MAX_VAL + (uint32)1) + s_icuTmrChICCtrl[ch].icuTmrIcValSecond - s_icuTmrChICCtrl[ch].icuTmrIcValFirst;
            }
            /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
            /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
            else if((1U == s_icuTmrChICCtrl[ch].icuTmrIcOfCnt) && (s_icuTmrChICCtrl[ch].icuTmrIcValSecond > s_icuTmrChICCtrl[ch].icuTmrIcValFirst))
            {
                /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
                /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
                validPulseCount = (uint32)s_icuTmrChICCtrl[ch].icuTmrIcValSecond - (uint32)s_icuTmrChICCtrl[ch].icuTmrIcValFirst;
            }
            else
            {
                /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
                /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
                validPulseCount = (uint32)((s_icuTmrChICCtrl[ch].icuTmrIcOfCnt * (ICU_TMR_CC_REG_MAX_VAL + (uint32)1)) +
                s_icuTmrChICCtrl[ch].icuTmrIcValSecond - s_icuTmrChICCtrl[ch].icuTmrIcValFirst);
            }
 
            s_icuTmrChICCtrl[ch].icuTmrIcOfCnt = 0U;
        }
        else
        {
            /* Do nothing */
        }
    }
    else 
    {
        /* Do nothing */
    }

    return validPulseCount;
}

/*!
* @brief         This function is used to set signal measurement TMR channel.
*
* @param[in]     ch           channel id
* @param[in]     tmrHwCh      TMR hardware channel id
* @param[in]     tmrModule    TMR module id
* @param[in]     ovfFlag      overflow capability
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_SetTmrSignalMeasurementChannel(CONST(Icu_TmrChType, AUTOMATIC) ch, 
    CONST(Icu_TmrHwChType, AUTOMATIC) tmrHwCh, CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule, 
    VAR(boolean, AUTOMATIC) ovfFlag)
{
    VAR(Icu_TmrMeasurePropertyType, AUTOMATIC) measureItem =
       (Icu_TmrMeasurePropertyType)(Icu_Tmr_GetTmrChFeatureStateBit(ch, (uint16)TMR_ICU_MEA_ITEM_MASK_VAL) >> 
                                                                           (uint8)TMR_ICU_MEA_ITEM_BIT_OFFSET);
    VAR(uint32,AUTOMATIC) validPulseCount = 0;
    VAR(uint32,AUTOMATIC) periodCount = 0;
    VAR(volatile uint32,AUTOMATIC) ccRegVal = 0;
    VAR(uint32,AUTOMATIC) ccRegValDuty = 0;
    VAR(Icu_ChannelType, AUTOMATIC) icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[ch];

    if ((ICU_TMR_MEASURE_HIGH_LEVEL == measureItem) || (ICU_TMR_MEASURE_LOW_LEVEL == measureItem))
    {
        validPulseCount = Icu_Tmr_MeasureChLevel(ch, tmrHwCh, tmrModule, ICU_TMR_MEASURE_HIGH_LEVEL | ICU_TMR_MEASURE_LOW_LEVEL);

        if(s_icuTmrChICCtrl[ch].icuTmrIcSts == TMR_IC_END_STS)
        {
            /* Continue capture:for next measure */
            s_icuTmrChICCtrl[ch].icuTmrIcSts = TMR_IC_FIRST_STS;
            Icu_Ipw_SignalMeasurement(TMR_ICU_CH_ID_BASE_TMR((uint16)(ch)), (Icu_ValueType)validPulseCount, (uint16)0, ovfFlag);
        }
        else
        {
            /* Do nothing */
        }
    }
    else if (ICU_TMR_MEASURE_PERIOD_TIME == measureItem)
    {
        ccRegVal = Icu_Tmr_ReadTmrCCnRegValue(tmrHwCh, tmrModule);

        /* judge edge is the first edge or the second edge */
        if (s_icuTmrFirstEdge[ch] != (uint8)0)
        {
            s_icuTmrChICCtrl[ch].icuTmrIcValFirst = (uint16)ccRegVal;
            s_icuTmrFirstEdge[ch] = (uint8)0;
            /* The s_icuTmrChICCtrl[ch].icuTmrIcOfCnt will be added */
            s_icuTmrChICCtrl[ch].icuTmrIcSts = TMR_IC_SECOND_STS;
        }
        else
        {
            /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
            /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
            /*** @warning Icu_Tmr_c_MISRA_REF3 Right hand operand of '&&' or '||' is an expression with persistent side effects. */
            if((0U == s_icuTmrChICCtrl[ch].icuTmrIcOfCnt) && (ccRegVal < s_icuTmrChICCtrl[ch].icuTmrIcValFirst))
            {
                /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
                /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
                periodCount = (ICU_TMR_CC_REG_MAX_VAL + (uint32)1) + ccRegVal - s_icuTmrChICCtrl[ch].icuTmrIcValFirst;
            }
            /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
            /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
            /*** @warning Icu_Tmr_c_MISRA_REF3 Right hand operand of '&&' or '||' is an expression with persistent side effects. */
            else if((1U == s_icuTmrChICCtrl[ch].icuTmrIcOfCnt) && (ccRegVal > s_icuTmrChICCtrl[ch].icuTmrIcValFirst))
            {
                /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
                /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
                periodCount = ccRegVal - s_icuTmrChICCtrl[ch].icuTmrIcValFirst;
            }
            else
            {
                /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
                /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
                periodCount = (uint32)((s_icuTmrChICCtrl[ch].icuTmrIcOfCnt * (ICU_TMR_CC_REG_MAX_VAL + (uint32)1)) +
                ccRegVal - s_icuTmrChICCtrl[ch].icuTmrIcValFirst);
            }

            /* Continue capture:for next measure */
            s_icuTmrChICCtrl[ch].icuTmrIcOfCnt = 0U;
            /* clear the channel update flag */
            REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_UIFLG_MASK);
            s_icuTmrChICCtrl[ch].icuTmrIcValFirst = (uint16)ccRegVal;

            Icu_Ipw_SignalMeasurement(TMR_ICU_CH_ID_BASE_TMR(ch), (uint16)0, (Icu_ValueType)periodCount, ovfFlag);
        }
    }
    else if (ICU_TMR_MEASURE_DUTYCYCLE == measureItem)
    {
            /* First edge detection is rising */
            if(((((uint32)(*(g_icuCfgPtr->icuChCfgPtr))[icuCh].icuCHActiveEdgeAndWakeup) & (uint32)ICU_CH_ACTIVE_EDGE_MASK_VAL) >> (uint32)ICU_CH_ACTIVE_EDGE_BIT_OFFSET)
                == (uint32)ICU_RISING_EDGE)
            {
                if((s_icuTmrChICCtrl[ch].icuTmrIcSts == TMR_IC_FIRST_STS) || (s_icuTmrChICCtrl[ch].icuTmrIcSts == TMR_IC_SECOND_STS))
                {
                    s_validHighPulseCount[ch] = Icu_Tmr_MeasureChLevel(ch, tmrHwCh, tmrModule, ICU_TMR_MEASURE_DUTYCYCLE);
                }
                else if(s_icuTmrChICCtrl[ch].icuTmrIcSts == TMR_IC_THIRD_STS)
                {
                    ccRegValDuty = Icu_Tmr_ReadTmrCCnRegValue(tmrHwCh, tmrModule);
                    
                    if((0U == s_icuTmrChICCtrl[ch].icuTmrIcOfCnt) && (ccRegValDuty < s_icuTmrChICCtrl[ch].icuTmrIcValSecond))
                    {
                        s_validLowPulseCount[ch] = (ICU_TMR_CC_REG_MAX_VAL + (uint32)1) + ccRegValDuty - s_icuTmrChICCtrl[ch].icuTmrIcValSecond;
                    }
                    else if((1U == s_icuTmrChICCtrl[ch].icuTmrIcOfCnt) && (ccRegValDuty > s_icuTmrChICCtrl[ch].icuTmrIcValSecond))
                    {
                        s_validLowPulseCount[ch] = ccRegValDuty - s_icuTmrChICCtrl[ch].icuTmrIcValSecond;
                    }
                    else
                    {
                        /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
                        /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
                        s_validLowPulseCount[ch] = (uint32)((s_icuTmrChICCtrl[ch].icuTmrIcOfCnt * (ICU_TMR_CC_REG_MAX_VAL + (uint32)1)) +
                        ccRegValDuty - s_icuTmrChICCtrl[ch].icuTmrIcValSecond);
                    }

                    periodCount = s_validLowPulseCount[ch] + s_validHighPulseCount[ch];
                    Icu_Ipw_SignalMeasurement(TMR_ICU_CH_ID_BASE_TMR((uint16)(ch)),
                        (Icu_ValueType)s_validHighPulseCount[ch], (Icu_ValueType)periodCount, ovfFlag);
                     /* Continue capture:for next measure,do not change the active edge,next duty measure 
                     *  maintain the same active edge as the first edge(rising edge)
                     */
                    s_icuTmrChICCtrl[ch].icuTmrIcSts = TMR_IC_FIRST_STS;
                    s_icuTmrChICCtrl[ch].icuTmrIcOfCnt = 0U;
                    s_validHighPulseCount[ch] = 0;
                    s_validLowPulseCount[ch] = 0;
                }
                else
                {
                    /* Do nothing */
                }
            }
            else if(((((uint32)(*(g_icuCfgPtr->icuChCfgPtr))[icuCh].icuCHActiveEdgeAndWakeup) & (uint32)ICU_CH_ACTIVE_EDGE_MASK_VAL) >> (uint32)ICU_CH_ACTIVE_EDGE_BIT_OFFSET)
                    == (uint32)ICU_FALLING_EDGE)
            {
                if((s_icuTmrChICCtrl[ch].icuTmrIcSts == TMR_IC_FIRST_STS) || (s_icuTmrChICCtrl[ch].icuTmrIcSts == TMR_IC_SECOND_STS))
                {
                    s_validLowPulseCount[ch] = Icu_Tmr_MeasureChLevel(ch, tmrHwCh, tmrModule, ICU_TMR_MEASURE_DUTYCYCLE);
                }
                else if(s_icuTmrChICCtrl[ch].icuTmrIcSts == TMR_IC_THIRD_STS)
                {
                    ccRegValDuty = Icu_Tmr_ReadTmrCCnRegValue(tmrHwCh, tmrModule);

                    if((0U == s_icuTmrChICCtrl[ch].icuTmrIcOfCnt) && (ccRegValDuty < s_icuTmrChICCtrl[ch].icuTmrIcValSecond))
                    {
                        s_validHighPulseCount[ch] = (ICU_TMR_CC_REG_MAX_VAL + (uint32)1) + ccRegValDuty - s_icuTmrChICCtrl[ch].icuTmrIcValSecond;
                    }
                    else if((1U == s_icuTmrChICCtrl[ch].icuTmrIcOfCnt) && (ccRegValDuty > s_icuTmrChICCtrl[ch].icuTmrIcValSecond))
                    {
                        s_validHighPulseCount[ch] = ccRegValDuty - s_icuTmrChICCtrl[ch].icuTmrIcValSecond;
                    }
                    else
                    {
                        /*** @warning Icu_Tmr_c_MISRA_REF1 [U] More than one read access to volatile objects between sequence points. */
                        /*** @warning Icu_Tmr_c_MISRA_REF2 [U] More than one read access to volatile objects between sequence points. */
                        s_validHighPulseCount[ch] = (uint32)((s_icuTmrChICCtrl[ch].icuTmrIcOfCnt * (ICU_TMR_CC_REG_MAX_VAL + (uint32)1)) +
                        ccRegValDuty - s_icuTmrChICCtrl[ch].icuTmrIcValSecond);
                    }

                    periodCount = s_validLowPulseCount[ch] + s_validHighPulseCount[ch];
                    Icu_Ipw_SignalMeasurement(TMR_ICU_CH_ID_BASE_TMR((uint16)(ch)),
                        (Icu_ValueType)s_validHighPulseCount[ch], (Icu_ValueType)periodCount, ovfFlag);

                    /*  Continue capture:for next measure,do not change the active edge,next duty measure 
                     *  maintain the same active edge as the first edge(failing edge)
                     */
                    s_icuTmrChICCtrl[ch].icuTmrIcSts = TMR_IC_FIRST_STS;
                    s_icuTmrChICCtrl[ch].icuTmrIcOfCnt = 0U;
                    s_validHighPulseCount[ch] = 0;
                    s_validLowPulseCount[ch] = 0;
                }
                else
                {
                    /* Do nothing */
                }
            }
            else 
            {
                /* Do nothing */
            }
    }
    else
    {
        /* do nothing*/
    }
}
#endif

#if ((STD_ON == ICU_EDGE_DETECT_API_ENABLE) || (STD_ON == ICU_TIMESTAMP_API_ENABLE) ||\
     (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE) || (STD_ON == ICU_EDGE_COUNT_API_ENABLE))
/*!
* @brief         This function is used to clear TMR channel interrupt register bit.
*
* @param[in]     ch       channel id
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_ClearTmrChInterruptFlag(VAR(Icu_TmrChType, AUTOMATIC) ch)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    CONST(uint8, ICU_CONST) intEnBitMask  = (uint8)(1U << tmrChannel);

    /* clear the channnel capture interrupt flag */
    /*** @warning Icu_Tmr_c_MISRA_REF3 [I] Cast between a pointer to volatile object and an integral type. */
    REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), (uint32)intEnBitMask);
    /* clear the channel update flag */
    /*** @warning Icu_Tmr_c_MISRA_REF3 [I] Cast between a pointer to volatile object and an integral type. */
    REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_UIFLG_MASK);
}
#endif

/*!
* @brief         This function is used to clear s_icuTmrChFeatureState bit according to parameter.
*
* @param[in]     ch       channel id
* @param[in]     aimBit   aim bit
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_ClearTmrChFeatureStateBit(VAR(Icu_TmrChType, AUTOMATIC) ch,
                                                                 VAR(Icu_TmrChFeatureStateType, AUTOMATIC) aimBit)
{
    SchM_Enter_Icu_ICU_CRITICAL_SECTION22();
    s_icuTmrChFeatureState[ch]  &= ((Icu_TmrChFeatureStateType)(~aimBit));
    SchM_Exit_Icu_ICU_CRITICAL_SECTION22();
}

#if ((STD_ON == ICU_TIMESTAMP_API_ENABLE) || (STD_ON == ICU_EDGE_COUNT_API_ENABLE) || \
     (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE))
/*!
* @brief         This function is used to reset TMR channel function.
*
* @param[in]     ch       channel id
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_ResetTmrChFunction(VAR(Icu_TmrChType, AUTOMATIC) ch)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);

    VAR(uint8, ICU_CONST) bitShift = 0;

    if(tmrChannel > 0U)
    {
        bitShift = (uint8)((tmrChannel - 1U) * 4U);
    }
    else
    {
        /* nothing to do */
    }

    SchM_Enter_Icu_ICU_CRITICAL_SECTION31();
    /* Disable the input capture */
    REG_BIT_CLEAR32(TMR_CCEN_REG_ADDR(tmrModule), TMR_CCEN_CC1EN_MASK << bitShift);
    SchM_Exit_Icu_ICU_CRITICAL_SECTION31();
}
#endif

#if (STD_ON == ICU_TIMESTAMP_API_ENABLE)
/*!
* @brief         This function is used to set time stamp TMR channel.
*
* @param[in]     ch           channel id
* @param[in]     tmrHwCh      TMR hardware channel id
* @param[in]     tmrModule    TMR module id
* @param[in]     ovfFlag      overflow capability
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_SetTmrTimestampChannel(CONST(Icu_TmrChType, AUTOMATIC) ch, 
    CONST(Icu_TmrHwChType, AUTOMATIC) tmrHwCh, CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule,
     VAR(boolean, AUTOMATIC) ovfFlag)
{
    VAR(uint8,   AUTOMATIC) captureCnt = 1U;

    switch (tmrHwCh)
    {
        case ICU_TMR_HW_CH1:
            s_icuTmrTimestampBufferPtr[ch] = (uint32)REG_READ32(TMR_CC1_REG_ADDR(tmrModule));
            break;
        case ICU_TMR_HW_CH2:
            s_icuTmrTimestampBufferPtr[ch] = (uint32)REG_READ32(TMR_CC2_REG_ADDR(tmrModule));
            break;
        case ICU_TMR_HW_CH3:
            s_icuTmrTimestampBufferPtr[ch] = (uint32)REG_READ32(TMR_CC3_REG_ADDR(tmrModule));
            break;
        case ICU_TMR_HW_CH4:
            s_icuTmrTimestampBufferPtr[ch] = (uint32)REG_READ32(TMR_CC4_REG_ADDR(tmrModule));
            break;
        default:
            {
                /* nothing to do */
            }
            break;
    }

    Icu_Ipw_Timestamp(TMR_ICU_CH_ID_BASE_TMR(ch), captureCnt, &s_icuTmrTimestampBufferPtr[ch], ovfFlag);
}
#endif

#if ((STD_ON == ICU_EDGE_DETECT_API_ENABLE) || (STD_ON == ICU_TIMESTAMP_API_ENABLE) ||\
     (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE) || (STD_ON == ICU_EDGE_COUNT_API_ENABLE))
/*!
* @brief         This function is used to set TMR channel function and active edge.
*
* @param[in]     ch       channel id
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_SetTmrChFunctionAndEdge(VAR(Icu_TmrChType, AUTOMATIC) ch)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    VAR(uint8, ICU_CONST)  chShift = 0;

    if(tmrChannel > 0U)
    {
        chShift = (uint8)((tmrChannel - 1U) * 4U);
    }
    else
    {
        /* nothing to do */
    }

    SchM_Enter_Icu_ICU_CRITICAL_SECTION30();

    /*** @warning Icu_Tmr_c_MISRA_REF3 [I] Cast between a pointer to volatile object and an integral type. */
    /* Select the active edge */
    REG_RMW32(TMR_CCEN_REG_ADDR(tmrModule), (uint32)ICU_TMR_ACTIVE_EDGE_IS_BOTH << chShift, 
        ((uint32)(Icu_Tmr_GetTmrChFeatureStateBit(ch, (uint16)TMR_ICU_ACTIVE_EDGE_MASK_VAL))  >>
                                                (uint8)TMR_ICU_ACTIVE_EDGE_BIT_OFFSET) << chShift);
    /* Enable the input capture */
    REG_BIT_SET32(TMR_CCEN_REG_ADDR(tmrModule), TMR_CCEN_CC1EN_MASK << chShift);

    SchM_Exit_Icu_ICU_CRITICAL_SECTION30();
}
#endif

/*!
* @brief         This function is used to set s_icuTmrChFeatureState bit according to parameter.
*
* @param[in]     ch       channel id
* @param[in]     aimBit   aim bit
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_SetTmrChFeatureStateBit(VAR(Icu_TmrChType, AUTOMATIC) ch,
                                                                  VAR(Icu_TmrChFeatureStateType, AUTOMATIC) aimBit)
{
    SchM_Enter_Icu_ICU_CRITICAL_SECTION21();
    s_icuTmrChFeatureState[ch] |= aimBit;
    SchM_Exit_Icu_ICU_CRITICAL_SECTION21();
}

#if (STD_OFF == ICU_TMR_CUSTOM_FEATURE_ENABLE)
/*!
* @brief         This function is used to process the channel interrupt.
*
* @param[in]     ch           channel id
* @param[in]     tmrHwCh      timer hardware channel id
* @param[in]     tmrModule    timer module id
* @param[in]     ovfFlag      overflow capability
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_ProcessChInterrupt(CONST(Icu_TmrChType, AUTOMATIC) ch, 
    CONST(Icu_TmrHwChType, AUTOMATIC) tmrHwCh, CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule, VAR(boolean, AUTOMATIC) ovfFlag)
{
#if ((STD_ON == ICU_EDGE_DETECT_API_ENABLE) || (STD_ON == ICU_TIMESTAMP_API_ENABLE) ||\
     (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE) || (STD_ON == ICU_EDGE_COUNT_API_ENABLE))

    VAR(Icu_TmrChModeType, AUTOMATIC) meaItem = 0;

#if (STD_ON == ICU_EDGE_COUNT_API_ENABLE)
    VAR(boolean, AUTOMATIC) temp = TRUE;
#endif

    if ((uint16)TMR_ICU_INIT_MASK_VAL == Icu_Tmr_GetTmrChFeatureStateBit(ch, (uint16)TMR_ICU_INIT_MASK_VAL))
    {
        meaItem = (Icu_TmrChModeType)
                  (Icu_Tmr_GetTmrChFeatureStateBit(ch, (uint16)TMR_ICU_MEA_MODE_MASK_VAL) >> (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET);

#if (STD_ON == ICU_EDGE_DETECT_API_ENABLE)
        if(ICU_TMR_EDGE_DETECT_FUNCTION == meaItem)
        {
            Icu_Ipw_ReportEvents(TMR_ICU_CH_ID_BASE_TMR(ch), ovfFlag);
        }
        else
        {
            /* nothing to do */
        }
#endif

#if (STD_ON == ICU_TIMESTAMP_API_ENABLE)
        if(ICU_TMR_TIMESTAMP_WITHOUT_DMA_FUNCTION == meaItem)
        {
            Icu_Tmr_SetTmrTimestampChannel(ch, tmrHwCh, tmrModule, ovfFlag);
        }
        else
        {
            /* nothing to do */
        }
#endif

#if (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE)
        if(ICU_TMR_MEASUREMENT_FUNCTION == meaItem)
        {
            Icu_Tmr_SetTmrSignalMeasurementChannel(ch, tmrHwCh, tmrModule, ovfFlag);
        }
        else
        {
            /* nothing to do */
        }
#endif

#if (STD_ON == ICU_EDGE_COUNT_API_ENABLE)
        if(ICU_TMR_EDGE_COUNT_FUNCTION == meaItem)
        {
            s_icuTmrEdgeNumber[ch]++;
            temp = (boolean)((0U == s_icuTmrEdgeNumber[ch]) ? TRUE : FALSE );
            Icu_Ipw_ReportWakeupAndOverflow(TMR_ICU_CH_ID_BASE_TMR(ch), temp);
        }
        else
        {
            /* nothing to do */
        }
#endif

    }
    else
    {
        /* nothing to do */
    }
#endif
    Icu_Tmr_ClearTmrChInterruptFlagWithProtect(ch);
}
#endif

#if (STD_ON == ICU_TIMESTAMP_API_ENABLE)
#if (STD_ON == ICU_TIMESTAMP_USES_DMA_ENABLE)
/*!
* @brief         This function is used to set the dma channel.
*
* @param[in]     pdlDmaChannel         Dma channel id
* @param[in]     dmaChEn               Dma channel enable/disable
* @param[in]     pDmaChConfig          Dma channel configuration
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_SetDmaHwCh(VAR(Pdl_ChType, AUTOMATIC) pdlDmaChannel, VAR(uint8, AUTOMATIC) dmaChEn, 
    P2CONST(Pdl_DmaChHwConfigType, AUTOMATIC, ICU_APPL_CONST) pDmaChConfig)
{
    if((uint8)ENABLE == dmaChEn)
    {
        Pdl_TopDmaChConfig(pdlDmaChannel, pDmaChConfig);
        Pdl_TopDmaNotifiEn(pdlDmaChannel, PDL_DMA_TRAN_COMPLETED);
        Pdl_TopDmaChEn(pdlDmaChannel);
    }
    else
    {
        Pdl_TopDmaChDis(pdlDmaChannel);
        Pdl_TopDmaNotifiDis(pdlDmaChannel, PDL_DMA_TRAN_COMPLETED);
    }
}
#endif
#endif

#if (STD_OFF == ICU_TMR_CUSTOM_FEATURE_ENABLE)
/*!
* @brief         ProcessTofInterrupt function of the Icu TMR Low-level driver.
*
* @param[in]     moduleId          module id
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_ProcessTofInterrupt(CONST(uint8, AUTOMATIC) moduleId)
{
    VAR(uint8,  AUTOMATIC) ch = (moduleId * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH1;

    while( ch <= ((moduleId * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH4))
    {
        VAR(Icu_TmrChModeType, AUTOMATIC) meaItem = (Icu_TmrChModeType)
           (Icu_Tmr_GetTmrChFeatureStateBit(ch, (uint16)TMR_ICU_MEA_MODE_MASK_VAL) >> (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET);

        switch (meaItem)
        {
            case ICU_TMR_TIMESTAMP_WITHOUT_DMA_FUNCTION:
            case ICU_TMR_TIMESTAMP_WITH_DMA_FUNCTION:
                Icu_Ipw_ReportWakeupAndOverflow(TMR_ICU_CH_ID_BASE_TMR(ch), (boolean)TRUE);
                break;

            case ICU_TMR_MEASUREMENT_FUNCTION:
                Icu_Ipw_ReportWakeupAndOverflow(TMR_ICU_CH_ID_BASE_TMR(ch), (boolean)TRUE);
                break;

            default:
                {
                    /* nothing to do */
                }
                break;
        }

        ch++;
    }
}
#endif
/**************************************************************************
                    GLOBAL FUNCTION
**************************************************************************/
/*!
* @brief          Initialization function of the Icu TMR Low-level driver.
* 
* @param[in]      TmrIpConfigPtr    pointer to the tmr configuration
* @param[out]     None
* @param[in,out]  None
*
*/
FUNC(void, ICU_CODE) Icu_Tmr_Init(P2CONST(Icu_TmrIPCfgType, AUTOMATIC, ICU_APPL_CONST) tmrIpConfigPtr)
{
    /* Pointer to tmr channel pre-configuration */
    P2CONST(Icu_TmrChCfgType, AUTOMATIC, ICU_APPL_CONST) icuTmrCHCfgPtr = NULL_PTR;
    VAR(Icu_TmrChType, AUTOMATIC) channelCount = 0;
    VAR(uint8, AUTOMATIC) moduleCount = 0;
    VAR(uint8, AUTOMATIC) tmrModule = 0;
    VAR(uint8, AUTOMATIC) tmrChannel = 0;
    VAR(uint8, AUTOMATIC) icuDefaultActiveEdge = (uint8)ICU_BOTH_EDGES;
    VAR(Icu_TmrActiveEdgeType, AUTOMATIC) icuActiveEdge = ICU_TMR_ACTIVE_EDGE_IS_BOTH;
#if (STD_ON == ICU_EDGE_COUNT_API_ENABLE)
    VAR(Icu_TmrChModeType, AUTOMATIC)      chFunction = 0;
#endif

    /* TMR channel configuration */
    for (channelCount=0U; channelCount < tmrIpConfigPtr->totalNumberChannel; channelCount++)
    {
        icuTmrCHCfgPtr = &(*(tmrIpConfigPtr->icuChannelCfgPtr))[channelCount];
        tmrModule  = (uint8)(TMR_MOD_ID(icuTmrCHCfgPtr->icuChannelId));
        tmrChannel = (uint8)(TMR_CH_ID(icuTmrCHCfgPtr->icuChannelId));

        icuDefaultActiveEdge = icuTmrCHCfgPtr->icuDefaultActiveEdge;
    #if (STD_ON == ICU_EDGE_COUNT_API_ENABLE)
        chFunction = (Icu_TmrChModeType)(icuTmrCHCfgPtr->icuTmrChMode);
    #endif
        icuActiveEdge = (Icu_TmrActiveEdgeType)ICU_TMR_ACTIVE_EDGE_IS_RISING;

        s_icuTmrChFeatureState[(uint8)icuTmrCHCfgPtr->icuChannelId] = 0U;

        if((uint8)ICU_FALLING_EDGE == icuDefaultActiveEdge)
        {
            icuActiveEdge = ICU_TMR_ACTIVE_EDGE_IS_FALLING;
        }
        else if((uint8)ICU_RISING_EDGE == icuDefaultActiveEdge)
        {
            icuActiveEdge = ICU_TMR_ACTIVE_EDGE_IS_RISING;
        }
        else if((uint8)ICU_BOTH_EDGES == icuDefaultActiveEdge)
        {
            icuActiveEdge = ICU_TMR_ACTIVE_EDGE_IS_BOTH;
        }
        else
        {
            /* nothing to do */
        }

        Icu_Tmr_ClearTmrChFeatureStateBit(icuTmrCHCfgPtr->icuChannelId,
        (Icu_TmrChFeatureStateType)((uint16)TMR_ICU_INIT_MASK_VAL | (uint16)TMR_ICU_MEA_MODE_MASK_VAL | 
            (uint16)TMR_ICU_MEA_ITEM_MASK_VAL));

        /*  Config all the channel to be input status to avoid the CCxIFLG
         *  bit is set by the output compare match when the counter starts
         */
        REG_RMW32(TMR_CCM1_REG_ADDR(tmrModule), TMR_CCM1_CC1SEL_MASK, 
            (uint32)ICU_TMR_IC_SELECTION_DIRECT_TI << TMR_CCM1_CC1SEL_SHIFT);
        REG_RMW32(TMR_CCM1_REG_ADDR(tmrModule), TMR_CCM1_CC2SEL_MASK, 
            (uint32)ICU_TMR_IC_SELECTION_DIRECT_TI << TMR_CCM1_CC2SEL_SHIFT);
        REG_RMW32(TMR_CCM2_REG_ADDR(tmrModule), TMR_CCM2_CC3SEL_MASK, 
            (uint32)ICU_TMR_IC_SELECTION_DIRECT_TI << TMR_CCM2_CC3SEL_SHIFT);
        REG_RMW32(TMR_CCM2_REG_ADDR(tmrModule), TMR_CCM2_CC4SEL_MASK, 
            (uint32)ICU_TMR_IC_SELECTION_DIRECT_TI << TMR_CCM2_CC4SEL_SHIFT);

        switch (tmrChannel)
        {
            case (uint8)ICU_TMR_HW_CH1:
            {
                /* Disable the input capture */
                REG_BIT_CLEAR32(TMR_CCEN_REG_ADDR(tmrModule), TMR_CCEN_CC1EN_MASK);
                /* Select the input channel */
                REG_RMW32(TMR_CCM1_REG_ADDR(tmrModule), TMR_CCM1_CC1SEL_MASK, 
                    (uint32)(icuTmrCHCfgPtr->icuTmrChInSel) << TMR_CCM1_CC1SEL_SHIFT);
                /* Select the filter */
                REG_RMW32(TMR_CCM1_REG_ADDR(tmrModule), TMR_CCM1_IC1F_MASK, 
                    (uint32)(icuTmrCHCfgPtr->icuTmrChFilter) << TMR_CCM1_IC1F_SHIFT);
                /* Enable the input capture */
                REG_BIT_SET32(TMR_CCEN_REG_ADDR(tmrModule), TMR_CCEN_CC1EN_MASK);
                /* Set the PSC */
                REG_RMW32(TMR_CCM1_REG_ADDR(tmrModule), TMR_CCM1_IC1PSC_MASK, 
                    (uint32)(icuTmrCHCfgPtr->icuTmrChPsc) << TMR_CCM1_IC1PSC_SHIFT);
                #if (STD_ON == ICU_TIMESTAMP_USES_DMA_ENABLE)
                /* Configure the channel DMA */
                REG_RMW32(TMR_DIEN_REG_ADDR(tmrModule), TMR_DIEN_CC1DEN_MASK, 
                    (uint32)(icuTmrCHCfgPtr->icuTmrChDmaEnable) << TMR_DIEN_CC1DEN_SHIFT);
                #endif
            }
            break;
            case (uint8)ICU_TMR_HW_CH2:
            {
                /* Disable the input capture */
                REG_BIT_CLEAR32(TMR_CCEN_REG_ADDR(tmrModule), TMR_CCEN_CC2EN_MASK);
                /* Select the input channel */
                REG_RMW32(TMR_CCM1_REG_ADDR(tmrModule), TMR_CCM1_CC2SEL_MASK, 
                    (uint32)(icuTmrCHCfgPtr->icuTmrChInSel) << TMR_CCM1_CC2SEL_SHIFT);
                /* Select the filter */
                REG_RMW32(TMR_CCM1_REG_ADDR(tmrModule), TMR_CCM1_IC2F_MASK, 
                    (uint32)(icuTmrCHCfgPtr->icuTmrChFilter) << TMR_CCM1_IC2F_SHIFT);
                /* Enable the input capture */
                REG_BIT_SET32(TMR_CCEN_REG_ADDR(tmrModule), TMR_CCEN_CC2EN_MASK);
                /* Set the PSC */
                REG_RMW32(TMR_CCM1_REG_ADDR(tmrModule), TMR_CCM1_IC2PSC_MASK, 
                    (uint32)(icuTmrCHCfgPtr->icuTmrChPsc) << TMR_CCM1_IC2PSC_SHIFT);
                #if (STD_ON == ICU_TIMESTAMP_USES_DMA_ENABLE)
                /* Configure the channel DMA */
                REG_RMW32(TMR_DIEN_REG_ADDR(tmrModule), TMR_DIEN_CC2DEN_MASK, 
                    (uint32)(icuTmrCHCfgPtr->icuTmrChDmaEnable) << TMR_DIEN_CC2DEN_SHIFT);
                #endif
            }
            break;
        case (uint8)ICU_TMR_HW_CH3:
            {
                /* Disable the input capture */
                REG_BIT_CLEAR32(TMR_CCEN_REG_ADDR(tmrModule), TMR_CCEN_CC3EN_MASK);
                /* Select the input channel */
                REG_RMW32(TMR_CCM2_REG_ADDR(tmrModule), TMR_CCM2_CC3SEL_MASK, 
                (uint32)(icuTmrCHCfgPtr->icuTmrChInSel) << TMR_CCM2_CC3SEL_SHIFT);
                /* Select the filter */
                REG_RMW32(TMR_CCM2_REG_ADDR(tmrModule), TMR_CCM2_IC3F_MASK, 
                (uint32)(icuTmrCHCfgPtr->icuTmrChFilter) << TMR_CCM2_IC3F_SHIFT);
                /* Enable the input capture */
                REG_BIT_SET32(TMR_CCEN_REG_ADDR(tmrModule), TMR_CCEN_CC3EN_MASK);
                /* Set the PSC */
                REG_RMW32(TMR_CCM2_REG_ADDR(tmrModule), TMR_CCM2_IC3PSC_MASK, 
                    (uint32)(icuTmrCHCfgPtr->icuTmrChPsc) << TMR_CCM2_IC3PSC_SHIFT);
                #if (STD_ON == ICU_TIMESTAMP_USES_DMA_ENABLE)
                /* Configure the channel DMA */
                REG_RMW32(TMR_DIEN_REG_ADDR(tmrModule), TMR_DIEN_CC3DEN_MASK, 
                    (uint32)(icuTmrCHCfgPtr->icuTmrChDmaEnable) << TMR_DIEN_CC3DEN_SHIFT);
                #endif
            }
            break;
        case (uint8)ICU_TMR_HW_CH4:
            {
                /* Disable the input capture */
                REG_BIT_CLEAR32(TMR_CCEN_REG_ADDR(tmrModule), TMR_CCEN_CC4EN_MASK);
                /* Select the input channel */
                REG_RMW32(TMR_CCM2_REG_ADDR(tmrModule), TMR_CCM2_CC4SEL_MASK, 
                (uint32)(icuTmrCHCfgPtr->icuTmrChInSel) << TMR_CCM2_CC4SEL_SHIFT);
                /* Select the filter */
                REG_RMW32(TMR_CCM2_REG_ADDR(tmrModule), TMR_CCM2_IC4F_MASK, 
                (uint32)(icuTmrCHCfgPtr->icuTmrChFilter) << TMR_CCM2_IC4F_SHIFT);
                /* Enable the input capture */
                REG_BIT_SET32(TMR_CCEN_REG_ADDR(tmrModule), TMR_CCEN_CC4EN_MASK);
                /* Set the PSC */
                REG_RMW32(TMR_CCM2_REG_ADDR(tmrModule), TMR_CCM2_IC4PSC_MASK, 
                    (uint32)(icuTmrCHCfgPtr->icuTmrChPsc) << TMR_CCM2_IC4PSC_SHIFT);
                #if (STD_ON == ICU_TIMESTAMP_USES_DMA_ENABLE)
                /* Configure the channel DMA */
                REG_RMW32(TMR_DIEN_REG_ADDR(tmrModule), TMR_DIEN_CC4DEN_MASK, 
                    (uint32)(icuTmrCHCfgPtr->icuTmrChDmaEnable) << TMR_DIEN_CC4DEN_SHIFT);
                #endif
            }
            break;
        default:
            {
                /* nothing to do */
            }
            break;
        }

        Icu_Tmr_SetActivationCondition((Icu_TmrChType)icuTmrCHCfgPtr->icuChannelId, icuActiveEdge);

#if (STD_ON == ICU_EDGE_COUNT_API_ENABLE)
        if (ICU_TMR_EDGE_COUNT_FUNCTION == chFunction)
        {
            s_icuTmrEdgeNumber[icuTmrCHCfgPtr->icuChannelId] = 0U;
        }
        else
        {
            /* nothing to do */
        }
#endif
        Icu_Tmr_SetTmrChFeatureStateBit(icuTmrCHCfgPtr->icuChannelId, (uint16)TMR_ICU_INIT_MASK_VAL);
    }

    /* TMR module configuration */
    for (moduleCount = 0U ; moduleCount < tmrIpConfigPtr->totalNumberTmr ; moduleCount++)
    {
        Icu_Tmr_GlobalConfiguration((*(tmrIpConfigPtr->icuTmrGlobalCfgPtr))[moduleCount]);
    }

    /* Clear the status flag */
    REG_WRITE32(TMR_STS_REG_ADDR(tmrModule), 0U);
}

#if (STD_ON == ICU_DE_INIT_API_ENABLE)
/*!
* @brief         DeInit function of the Icu TMR Low-level driver.
*
* @param[in]     channelTmrIpConfigPtr   pointer to the tmr channel configuration
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_Deinit(P2CONST(Icu_TmrIPCfgType, AUTOMATIC, ICU_APPL_CONST) channelTmrIpConfigPtr)
{
    /* Pointer to tmr channel pre-configuration */
    P2CONST(Icu_TmrChCfgType,AUTOMATIC,ICU_APPL_CONST) icuTmrCHCfgPtr;

    VAR(uint8, AUTOMATIC)   moduleCount = 0U;
    VAR(Icu_TmrChType, AUTOMATIC) channelCount = 0U;

    while (moduleCount < channelTmrIpConfigPtr->totalNumberTmr)
    {
        /* Reset the tmr modules */
        switch ((*(channelTmrIpConfigPtr->icuTmrGlobalCfgPtr))[moduleCount].icuTmrModule)
        {
        case ICU_TMR1:
            Mcu_Rcm_OperationPeriphReset(ENABLE, RCM_APB2_PERIPH, RCM_AHBRST2_TMR1);
            Mcu_Rcm_OperationPeriphReset(DISABLE, RCM_APB2_PERIPH, RCM_AHBRST2_TMR1);
            break;
        case ICU_TMR2:
            Mcu_Rcm_OperationPeriphReset(ENABLE, RCM_APB1_PERIPH, RCM_AHBRST1_TMR2);
            Mcu_Rcm_OperationPeriphReset(DISABLE, RCM_APB1_PERIPH, RCM_AHBRST1_TMR2);
            break;
        case ICU_TMR3:
            Mcu_Rcm_OperationPeriphReset(ENABLE, RCM_APB1_PERIPH, RCM_AHBRST1_TMR3);
            Mcu_Rcm_OperationPeriphReset(DISABLE, RCM_APB1_PERIPH, RCM_AHBRST1_TMR3);
            break;
        case ICU_TMR4:
            Mcu_Rcm_OperationPeriphReset(ENABLE, RCM_APB1_PERIPH, RCM_AHBRST1_TMR4);
            Mcu_Rcm_OperationPeriphReset(DISABLE, RCM_APB1_PERIPH, RCM_AHBRST1_TMR4);
            break;
        default:
            {
                /* nothing to do */
            }
            break;
        }

        moduleCount++;
    }

    while (channelCount < channelTmrIpConfigPtr->totalNumberChannel)
    {
        icuTmrCHCfgPtr = &(*channelTmrIpConfigPtr->icuChannelCfgPtr)[channelCount];

        /* clear s_icuTmrChFeatureState's feature flag */
        Icu_Tmr_ClearTmrChFeatureStateBit(icuTmrCHCfgPtr->icuChannelId,(Icu_TmrChFeatureStateType)
        ((uint16)TMR_ICU_INIT_MASK_VAL | (uint16)TMR_ICU_MEA_MODE_MASK_VAL | (uint16)TMR_ICU_MEA_ITEM_MASK_VAL | (uint16)TMR_ICU_ACTIVE_EDGE_MASK_VAL));

        channelCount++;
    }
}
#endif

#if (STD_ON == ICU_SET_MODE_API_ENABLE)
/*!
* @brief         SetSleepMode function of the Icu TMR Low-level driver.
*
* @param[in]     ch   channel id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_SetSleepMode(CONST(Icu_TmrChType, AUTOMATIC) ch)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    VAR(uint8, ICU_CONST) bitShift = 0;

    if(tmrChannel > 0U)
    {
        bitShift = (uint8)((tmrChannel - 1U) * 4U);
    }
    else
    {
        /* nothing to do */
    }

    SchM_Enter_Icu_ICU_CRITICAL_SECTION28();
    /* Disable the input capture */
    REG_BIT_CLEAR32(TMR_CCEN_REG_ADDR(tmrModule), TMR_CCEN_CC1EN_MASK << bitShift);
    SchM_Exit_Icu_ICU_CRITICAL_SECTION28();
}

/*!
* @brief         SetNormalMode function of the Icu TMR Low-level driver.
*
* @param[in]     ch   channel id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_SetNormalMode(CONST(Icu_TmrChType, AUTOMATIC) ch)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    VAR(uint8, ICU_CONST) bitShift = 0;

    if(tmrChannel > 0U)
    {
        bitShift = (uint8)((tmrChannel - 1U) * 4U);
    }
    else
    {
        /* nothing to do */
    }

    if ((uint16)TMR_ICU_INIT_MASK_VAL == Icu_Tmr_GetTmrChFeatureStateBit(ch, (uint16)TMR_ICU_INIT_MASK_VAL))
    {
        SchM_Enter_Icu_ICU_CRITICAL_SECTION27();
        /* Enable the input capture */
        REG_BIT_SET32(TMR_CCEN_REG_ADDR(tmrModule), TMR_CCEN_CC1EN_MASK << bitShift);
        SchM_Exit_Icu_ICU_CRITICAL_SECTION27();
    }
    else
    {
        /* nothing to do */
    }
}
#endif

/*!
* @brief         Set Activation Condition function of the Icu TMR Low-level driver.
*
* @param[in]     ch        channel id
* @param[in]     aimEdge   aim edge
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_SetActivationCondition(CONST(Icu_TmrChType, AUTOMATIC) ch,
                                                    CONST(Icu_TmrActiveEdgeType, AUTOMATIC) aimEdge)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    VAR(uint8, ICU_CONST)  chShift = 0;

    if(tmrChannel > 0U)
    {
        chShift = (uint8)((tmrChannel - 1U) * 4U);
    }
    else
    {
        /* nothing to do */
    }

    /* clear s_icuTmrChFeatureState's bit11 and bit10 */
    Icu_Tmr_ClearTmrChFeatureStateBit(ch, (Icu_TmrChFeatureStateType)TMR_ICU_ACTIVE_EDGE_MASK_VAL);
    /* set s_icuTmrChFeatureState's bit11 and bit10 as aim edge flag */
    Icu_Tmr_SetTmrChFeatureStateBit(ch,(Icu_TmrChFeatureStateType)((Icu_TmrChFeatureStateType)aimEdge << 
        (uint8)TMR_ICU_ACTIVE_EDGE_BIT_OFFSET));

    /* make sure operation process integrally */
    SchM_Enter_Icu_ICU_CRITICAL_SECTION26();
    /* Select the active edge */
    REG_RMW32(TMR_CCEN_REG_ADDR(tmrModule), (uint32)ICU_TMR_ACTIVE_EDGE_IS_BOTH << chShift, (uint32)aimEdge << chShift);
    /* make sure operation process integrally */
    SchM_Exit_Icu_ICU_CRITICAL_SECTION26();
}

#if (STD_ON == ICU_GET_INPUT_STATE_API_ENABLE)
/*!
* @brief         GetInputState function of the Icu TMR Low-level driver.
*
* @param[in]     ch          channel id
* @param[out]    None
* @param[in,out] None
*
* @retval       FALSE / TRUE
*/
FUNC(boolean, ICU_CODE) Icu_Tmr_GetInputState(CONST(Icu_TmrChType, AUTOMATIC) ch)
{
    VAR(boolean, AUTOMATIC) checkResult = (boolean)FALSE;
    CONST(uint8, ICU_CONST) tmrModule   = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel  = (uint8)TMR_CH_ID(ch);
    CONST(uint8, ICU_CONST) intEnBitMask  = (uint8)(1U << tmrChannel);

    CONST(uint32, ICU_CONST) tmrDienRegVal = REG_READ32(TMR_DIEN_REG_ADDR(tmrModule));
    CONST(uint32, ICU_CONST) tmrStsRegVal = REG_READ32(TMR_STS_REG_ADDR(tmrModule));

    if((uint32)ICU_BIT_RESET != (tmrDienRegVal & intEnBitMask))
    {
        /* nothing to do */
    }
    else if((uint32)ICU_BIT_RESET == (tmrStsRegVal & intEnBitMask))
    {
        /* nothing to do */
    }
    else
    {
        checkResult = (boolean)TRUE;

        SchM_Enter_Icu_ICU_CRITICAL_SECTION29();
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), (uint32)intEnBitMask);
        SchM_Exit_Icu_ICU_CRITICAL_SECTION29();
    }

    return checkResult;
}
#endif

#if (STD_ON == ICU_TIMESTAMP_API_ENABLE)
/*!
* @brief         StartTimestamp function of the Icu TMR Low-level driver.
*
* @param[in]     ch        channel id
* @param[in]     dmaCap    dma capability
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_StartTimestamp(CONST(Icu_TmrChType, AUTOMATIC) ch, CONST(boolean, AUTOMATIC) dmaCap)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    CONST(uint8, ICU_CONST) intEnBitMask  = (uint8)(1U << tmrChannel);

    /* Reset time stamp buffer */
    s_icuTmrTimestampBufferPtr[ch] = 0U;

    switch (dmaCap)
    {
        case (boolean)FALSE:
            Icu_Tmr_SetTmrChFeatureStateBit(ch, (Icu_TmrChFeatureStateType)
            ((Icu_TmrChFeatureStateType)ICU_TMR_TIMESTAMP_WITHOUT_DMA_FUNCTION << (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET));
            break;

        default:
            Icu_Tmr_SetTmrChFeatureStateBit(ch,  (Icu_TmrChFeatureStateType)
            ((Icu_TmrChFeatureStateType)ICU_TMR_TIMESTAMP_WITH_DMA_FUNCTION << (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET));
            break;
    }

    Icu_Tmr_SetTmrChFunctionAndEdge(ch);

    SchM_Enter_Icu_ICU_CRITICAL_SECTION20();
    /* Clear pending interrupt */
    Icu_Tmr_ClearTmrChInterruptFlag(ch);
#if defined(ICU_OVERFLOW_NOTIFICATION_API_ENABLE) && (STD_ON == ICU_OVERFLOW_NOTIFICATION_API_ENABLE)
    /* Enable the timer update(overflow) interrupt */
    REG_RMW32(TMR_DIEN_REG_ADDR(tmrModule), TMR_DIEN_UIEN_MASK, (uint32)1U << TMR_DIEN_UIEN_SHIFT);
#endif
    /* Enable the channel interrupt */
    REG_BIT_SET32(TMR_DIEN_REG_ADDR(tmrModule), intEnBitMask);
    SchM_Exit_Icu_ICU_CRITICAL_SECTION20();
}

/*!
* @brief         StopTimestamp function of the Icu TMR Low-level driver.
*
* @param[in]     ch        channel id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_StopTimestamp(CONST(Icu_TmrChType, AUTOMATIC) ch)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    CONST(uint8, ICU_CONST) intEnBitMask  = (uint8)(1U << tmrChannel);

    /* Disable the capture */
    Icu_Tmr_ResetTmrChFunction(ch);

    /* make sure operation process integrally */
    SchM_Enter_Icu_ICU_CRITICAL_SECTION19();
    /* close channel interrupt */
    REG_BIT_CLEAR32(TMR_DIEN_REG_ADDR(tmrModule), (uint32)intEnBitMask);
#if defined(ICU_OVERFLOW_NOTIFICATION_API_ENABLE) && (STD_ON == ICU_OVERFLOW_NOTIFICATION_API_ENABLE)
    /* close channel overflow interrupt */
    REG_BIT_CLEAR32(TMR_DIEN_REG_ADDR(tmrModule), TMR_DIEN_UIEN_MASK);
#endif
    /* make sure operation process integrally */
    SchM_Exit_Icu_ICU_CRITICAL_SECTION19();

    /* clear s_icuTmrChFeatureState's function flag bit */
    Icu_Tmr_ClearTmrChFeatureStateBit(ch, (Icu_TmrChFeatureStateType)
    (((Icu_TmrChFeatureStateType)ICU_TMR_TIMESTAMP_WITHOUT_DMA_FUNCTION |
      (Icu_TmrChFeatureStateType)ICU_TMR_TIMESTAMP_WITH_DMA_FUNCTION) << (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET));
}

#if (STD_ON == ICU_TIMESTAMP_USES_DMA_ENABLE)
/*!
* @brief         Get Start Address function of the Icu TMR Low-level driver.
*
* @param[in]     ch        channel id
* @param[out]    None
* @param[in,out] None
*
* @retval        uint32
*/
FUNC(uint32, ICU_CODE) Icu_Tmr_GetStartAddress(CONST(Icu_TmrChType, AUTOMATIC) ch)
{
    VAR(uint32, AUTOMATIC) ret;

    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    
    /* Get the DMA source address */
    switch (tmrChannel)
    {
        case (uint8)ICU_TMR_HW_CH1:
            ret = TMR_CC1_REG_ADDR(tmrModule);
            break;
        case (uint8)ICU_TMR_HW_CH2:
            ret = TMR_CC2_REG_ADDR(tmrModule);
            break;
        case (uint8)ICU_TMR_HW_CH3:
            ret = TMR_CC3_REG_ADDR(tmrModule);
            break;
        case (uint8)ICU_TMR_HW_CH4:
            ret = TMR_CC4_REG_ADDR(tmrModule);
            break;
        default:
            ret = 0U;
            break;
    }

    return ret;
}

/*!
* @brief         Set the Dma channel function of the Icu TMR Low-level driver.
*
* @param[in]     ch                 channel id
* @param[in]     pDmaChConfig       dma channel configuration
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_SetDmaCh(CONST(Icu_TmrChType, AUTOMATIC) ch, 
    P2CONST(Pdl_DmaChHwConfigType, AUTOMATIC, ICU_APPL_CONST) pDmaChConfig, VAR(uint8, AUTOMATIC) dmaChEn)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    
    /* Set the DMA channel */
    switch (tmrModule)
    {
        case (uint8)ICU_TMR1:
            {
                switch (tmrChannel)
                {
                    case (uint8)ICU_TMR_HW_CH1:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH2, dmaChEn, pDmaChConfig);
                        break;
                    case (uint8)ICU_TMR_HW_CH2:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH3, dmaChEn, pDmaChConfig);
                        break;
                    case (uint8)ICU_TMR_HW_CH3:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH5, dmaChEn, pDmaChConfig);
                        break;
                    case (uint8)ICU_TMR_HW_CH4:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH4, dmaChEn, pDmaChConfig);
                        break;
                    default:
                        {
                            /* nothing to do */
                        }
                        break;
                }
            }
            break;
        case (uint8)ICU_TMR2:
            {
                switch (tmrChannel)
                {
                    case (uint8)ICU_TMR_HW_CH1:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH1, dmaChEn, pDmaChConfig);
                        break;
                    case (uint8)ICU_TMR_HW_CH2:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH3, dmaChEn, pDmaChConfig);
                        break;
                    case (uint8)ICU_TMR_HW_CH3:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH5, dmaChEn, pDmaChConfig);
                        break;
                    case (uint8)ICU_TMR_HW_CH4:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH2, dmaChEn, pDmaChConfig);
                        break;
                    default:
                        {
                            /* nothing to do */
                        }
                        break;
                }
            }
            break;
        case (uint8)ICU_TMR3:
            {
                switch (tmrChannel)
                {
                    case (uint8)ICU_TMR_HW_CH1:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH4, dmaChEn, pDmaChConfig);
                        break;
                    case (uint8)ICU_TMR_HW_CH2:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH5, dmaChEn, pDmaChConfig);
                        break;
                    case (uint8)ICU_TMR_HW_CH3:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH2, dmaChEn, pDmaChConfig);
                        break;
                    case (uint8)ICU_TMR_HW_CH4:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH3, dmaChEn, pDmaChConfig);
                        break;
                    default:
                        {
                            /* nothing to do */
                        }
                        break;
                }
            }
            break;
        case (uint8)ICU_TMR4:
            {
                switch (tmrChannel)
                {
                    case (uint8)ICU_TMR_HW_CH1:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH3, dmaChEn, pDmaChConfig);
                        break;
                    case (uint8)ICU_TMR_HW_CH2:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH2, dmaChEn, pDmaChConfig);
                        break;
                    case (uint8)ICU_TMR_HW_CH3:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH1, dmaChEn, pDmaChConfig);
                        break;
                    case (uint8)ICU_TMR_HW_CH4:
                        Icu_Tmr_SetDmaHwCh(DMA_HW_CH4, dmaChEn, pDmaChConfig);
                        break;
                    default:
                        {
                            /* nothing to do */
                        }
                        break;
                }
            }
            break;
        default:
            {
                /* nothing to do */
            }
            break;
    }
}
#endif
#endif

#if (STD_ON == ICU_EDGE_COUNT_API_ENABLE)
/*!
* @brief         ResetEdgeCount function of the Icu TMR Low-level driver.
*
* @param[in]     ch        channel id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_ResetEdgeCount(CONST(Icu_TmrChType, AUTOMATIC) ch)
{
    s_icuTmrEdgeNumber[ch] = 0U;
}

/*!
* @brief         EnableEdgeCount function of the Icu TMR Low-level driver.
*
* @param[in]     ch        channel id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_EnableEdgeCount(CONST(Icu_TmrChType, AUTOMATIC) ch)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    CONST(uint8, ICU_CONST) intEnBitMask  = (uint8)(1U << tmrChannel);

    /* reset edge count value, prepare for counting */
    s_icuTmrEdgeNumber[ch] = 0U;

    /* set s_icuTmrChFeatureState bit to indicate edge count function */
    Icu_Tmr_SetTmrChFeatureStateBit(ch,(Icu_TmrChFeatureStateType)
     ((Icu_TmrChFeatureStateType)ICU_TMR_EDGE_COUNT_FUNCTION << (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET));
    /* set TMR channel function and active edge on register */
    Icu_Tmr_SetTmrChFunctionAndEdge(ch);

    /* make sure operation process integrally */
    SchM_Enter_Icu_ICU_CRITICAL_SECTION18();
    /* clear tmr channel interrupt flags */
    Icu_Tmr_ClearTmrChInterruptFlag(ch);
#if defined(ICU_OVERFLOW_NOTIFICATION_API_ENABLE) && (STD_ON == ICU_OVERFLOW_NOTIFICATION_API_ENABLE)
    /* Enable the timer update(overflow) interrupt */
    REG_RMW32(TMR_DIEN_REG_ADDR(tmrModule), TMR_DIEN_UIEN_MASK, (uint32)1U << TMR_DIEN_UIEN_SHIFT);
#endif
    /* Enable the channel interrupt */
    REG_BIT_SET32(TMR_DIEN_REG_ADDR(tmrModule), intEnBitMask);
    /* make sure operation process integrally */
    SchM_Exit_Icu_ICU_CRITICAL_SECTION18();
}

/*!
* @brief         DisableEdgeCount function of the Icu TMR Low-level driver.
*
* @param[in]     ch        channel id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_DisableEdgeCount(CONST(Icu_TmrChType, AUTOMATIC) ch)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    CONST(uint8, ICU_CONST) intEnBitMask  = 1U << (uint8)tmrChannel;

    Icu_Tmr_ResetTmrChFunction(ch);

    SchM_Enter_Icu_ICU_CRITICAL_SECTION17();
    /* close channel interrupt on register */
    REG_BIT_CLEAR32(TMR_DIEN_REG_ADDR(tmrModule), (uint32)intEnBitMask);
#if defined(ICU_OVERFLOW_NOTIFICATION_API_ENABLE) && (STD_ON == ICU_OVERFLOW_NOTIFICATION_API_ENABLE)
    /* close tmr channel overflow interrupt */
    REG_BIT_CLEAR32(TMR_DIEN_REG_ADDR(tmrModule), TMR_DIEN_UIEN_MASK);
#endif
    SchM_Exit_Icu_ICU_CRITICAL_SECTION17();

    Icu_Tmr_ClearTmrChFeatureStateBit(ch,(Icu_TmrChFeatureStateType)
    ((Icu_TmrChFeatureStateType)ICU_TMR_EDGE_COUNT_FUNCTION << (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET));
}

/*!
* @brief         GetEdgeNumbers function of the Icu TMR Low-level driver.
*
* @param[in]     ch        channel id
* @param[out]    None
* @param[in,out] None
*
* @retval        uint16
*/
FUNC(uint16, ICU_CODE) Icu_Tmr_GetEdgeNumbers(CONST(Icu_TmrChType, AUTOMATIC) ch)
{
    return s_icuTmrEdgeNumber[ch];
}
#endif

#if (STD_ON == ICU_EDGE_DETECT_API_ENABLE)
/*!
* @brief         EnableEdgeDetection function of the Icu TMR Low-level driver.
*
* @param[in]     ch        channel id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_EnableEdgeDetection(CONST(Icu_TmrChType, AUTOMATIC) ch)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    CONST(uint8, ICU_CONST) intEnBitMask  = (uint8)(1U << tmrChannel);

    Icu_Tmr_SetTmrChFeatureStateBit(ch, (Icu_TmrChFeatureStateType)
    ((Icu_TmrChFeatureStateType)ICU_TMR_EDGE_DETECT_FUNCTION << (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET));
    Icu_Tmr_SetTmrChFunctionAndEdge(ch);
    
    SchM_Enter_Icu_ICU_CRITICAL_SECTION25();
    Icu_Tmr_ClearTmrChInterruptFlag(ch);
    /* Enable the channel interrupt */
    REG_BIT_SET32(TMR_DIEN_REG_ADDR(tmrModule), intEnBitMask);
    SchM_Exit_Icu_ICU_CRITICAL_SECTION25();
}

/*!
* @brief         DisableEdgeDetection function of the Icu TMR Low-level driver.
*
* @param[in]     ch        channel id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_DisableEdgeDetection(CONST(Icu_TmrChType, AUTOMATIC)ch)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    CONST(uint8, ICU_CONST) intEnBitMask  = (uint8)(1U << tmrChannel);

    SchM_Enter_Icu_ICU_CRITICAL_SECTION24();
    /* Disable channel interrupt */
    REG_BIT_CLEAR32(TMR_DIEN_REG_ADDR(tmrModule), (uint32)intEnBitMask);
    SchM_Exit_Icu_ICU_CRITICAL_SECTION24();

    Icu_Tmr_ClearTmrChFeatureStateBit(ch, (Icu_TmrChFeatureStateType)
    ((Icu_TmrChFeatureStateType)ICU_TMR_EDGE_DETECT_FUNCTION << (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET));
}
#endif

#if (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE)
/*!
* @brief         StartSignalMeasurement function of the Icu TMR Low-level driver.
*
* @param[in]     ch         channel id
* @param[in]     meaItem    measurement item
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_StartSignalMeasurement(CONST(Icu_TmrChType, AUTOMATIC) ch,
                                                    CONST(Icu_TmrMeasurePropertyType, AUTOMATIC) meaItem)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    CONST(uint8, ICU_CONST) intEnBitMask  = (uint8)(1U << tmrChannel);

    s_icuTmrFirstEdge[ch] = (uint8)1U;
    s_icuTmrChICCtrl[ch].icuTmrIcSts = TMR_IC_FIRST_STS;
    s_icuTmrChICCtrl[ch].icuTmrIcOfCnt = 0U;
    s_icuTmrChICCtrl[ch].icuTmrIcValFirst = 0U;
    s_icuTmrChICCtrl[ch].icuTmrIcValSecond = 0U;

    Icu_Tmr_SetTmrChFeatureStateBit(ch,(Icu_TmrChFeatureStateType)
            ((Icu_TmrChFeatureStateType)ICU_TMR_MEASUREMENT_FUNCTION << (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET) |
             (Icu_TmrChFeatureStateType)((Icu_TmrChFeatureStateType)meaItem << (uint8)TMR_ICU_MEA_ITEM_BIT_OFFSET));
    Icu_Tmr_SetTmrChFunctionAndEdge(ch);

    SchM_Enter_Icu_ICU_CRITICAL_SECTION13();
    /* clear channel interrupt flag on register */
    Icu_Tmr_ClearTmrChInterruptFlag(ch);
    /* Enable the channel interrupt */
    REG_BIT_SET32(TMR_DIEN_REG_ADDR(tmrModule), intEnBitMask);

#if defined(ICU_OVERFLOW_NOTIFICATION_API_ENABLE) && (STD_ON == ICU_OVERFLOW_NOTIFICATION_API_ENABLE)
    /* Enable the timer update(overflow) interrupt */
    REG_RMW32(TMR_DIEN_REG_ADDR(tmrModule), TMR_DIEN_UIEN_MASK, (uint32)1U << TMR_DIEN_UIEN_SHIFT);
#endif
    SchM_Exit_Icu_ICU_CRITICAL_SECTION13();
}

/*!
* @brief         StopSignalMeasurement function of the Icu TMR Low-level driver.
*
* @param[in]     ch          channel id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_StopSignalMeasurement(CONST(Icu_TmrChType, AUTOMATIC) ch)
{
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    CONST(uint8, ICU_CONST) tmrChannel = (uint8)TMR_CH_ID(ch);
    CONST(uint8, ICU_CONST) intEnBitMask  = (uint8)(1U << tmrChannel);

    Icu_Tmr_ResetTmrChFunction(ch);
    s_icuTmrChICCtrl[ch].icuTmrIcSts = TMR_IC_IDLE_STS;
    s_icuTmrChICCtrl[ch].icuTmrIcOfCnt = 0U;
    s_icuTmrChICCtrl[ch].icuTmrIcValFirst = 0U;
    s_icuTmrChICCtrl[ch].icuTmrIcValSecond = 0U;

    SchM_Enter_Icu_ICU_CRITICAL_SECTION15();
    Icu_Tmr_ClearTmrChInterruptFlag(ch);
    /* Disable channel interrupt */
    REG_BIT_CLEAR32(TMR_DIEN_REG_ADDR(tmrModule), (uint32)intEnBitMask);
 #if defined(ICU_OVERFLOW_NOTIFICATION_API_ENABLE) && (STD_ON == ICU_OVERFLOW_NOTIFICATION_API_ENABLE)
    /* close tmr channel overflow interrupt */
    REG_BIT_CLEAR32(TMR_DIEN_REG_ADDR(tmrModule), TMR_DIEN_UIEN_MASK);
#endif
    SchM_Exit_Icu_ICU_CRITICAL_SECTION15();

    Icu_Tmr_ClearTmrChFeatureStateBit(ch,(Icu_TmrChFeatureStateType)
    ((Icu_TmrChFeatureStateType)ICU_TMR_MEASUREMENT_FUNCTION << (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET)
    | (uint16)TMR_ICU_MEA_ITEM_MASK_VAL);
}
#endif

/*!
* @brief         Get Capture Register Value function of the Icu TMR Low-level driver.
*
* @param[in]     tmrHwCh        Tmr hardware channel
* @param[in]     tmrModule      Tmr module id
* @param[out]    None
* @param[in,out] None
*
* @retval        uint16
*/
FUNC(uint16, ICU_CODE) Icu_Tmr_ReadTmrCCnRegValue(CONST(Icu_TmrHwChType, AUTOMATIC) tmrHwCh, 
    CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule)
{
    VAR(uint16, AUTOMATIC) retVal = (uint16)0U;
    
    switch (tmrHwCh)
    {
        case ICU_TMR_HW_CH1:
        {
            retVal = (uint16)REG_READ32(TMR_CC1_REG_ADDR(tmrModule));
            break;
        }
        case ICU_TMR_HW_CH2:
        {
            retVal = (uint16)REG_READ32(TMR_CC2_REG_ADDR(tmrModule));
            break;
        }
        case ICU_TMR_HW_CH3:
        {
            retVal = (uint16)REG_READ32(TMR_CC3_REG_ADDR(tmrModule));
            break;
        }
        case ICU_TMR_HW_CH4:
        {
            retVal = (uint16)REG_READ32(TMR_CC4_REG_ADDR(tmrModule));
            break;
        }
        default:
            {
                /* nothing to do */
            }
            break;
    }

    return retVal;
}

#if (STD_ON == ICU_DUAL_CLOCK_MODE_API_ENABLE)
/*!
* @brief         Set Clk Prescaler function of the Icu TMR Low-level driver.
*
* @param[in]     moduleId         module id
* @param[in]     preMode          prescaler mode
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_SetClkPrescaler(CONST(Icu_TmrModuleType, AUTOMATIC) moduleId, VAR(Icu_TmrPscType, AUTOMATIC) preMode)
{
    SchM_Enter_Icu_ICU_CRITICAL_SECTION9();
    REG_WRITE32(TMR_PSC_REG_ADDR(moduleId), (uint16)preMode);
    SchM_Exit_Icu_ICU_CRITICAL_SECTION9();
}
#endif

/*!
* @brief         Get Overflow function of the Icu TMR Low-level driver.
*
* @param[in]     ch          channel id
* @param[out]    None
* @param[in,out] None
*
* @retval        FALSE / TRUE
*/
FUNC(boolean, ICU_CODE) Icu_Tmr_GetOverflow(CONST(Icu_TmrChType, AUTOMATIC) ch)
{
    VAR(boolean, AUTOMATIC) checkResult = (boolean)FALSE;
    CONST(uint8, ICU_CONST) tmrModule  = (uint8)TMR_MOD_ID(ch);
    VAR(uint32,  AUTOMATIC) u32regTmrSC = REG_BIT_GET32(TMR_STS_REG_ADDR(tmrModule),TMR_STS_UIFLG_MASK);

    SchM_Enter_Icu_ICU_CRITICAL_SECTION11();
    REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_UIFLG_MASK);
    SchM_Exit_Icu_ICU_CRITICAL_SECTION11();

    if (TMR_STS_UIFLG_MASK == (u32regTmrSC & TMR_STS_UIFLG_MASK))
    {
        checkResult = (boolean)TRUE;
    }
    else
    {
        checkResult = (boolean)FALSE;
    }

    return checkResult;
}

#if (STD_OFF == ICU_TMR_CUSTOM_FEATURE_ENABLE)
/*!
* @brief         Process the TMR1 overflow Interrupt function of the Icu TMR Low-level driver.
*
* @param[in]     tmrModule          Tmr module id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_Tmr1ProcessOfInterrupt(CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule)
{
#if ((STD_ON == ICU_EDGE_DETECT_API_ENABLE) || (STD_ON == ICU_TIMESTAMP_API_ENABLE) ||\
     (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE) || (STD_ON == ICU_EDGE_COUNT_API_ENABLE))
    VAR(uint32, AUTOMATIC) tmrIntFlag = 0U;
    VAR(uint32, AUTOMATIC) tmrIntEnSts = 0U;
#if (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE)
    VAR(Icu_TmrChModeType, AUTOMATIC) meaItem;
    VAR(uint8, AUTOMATIC) chCnt = 0U;
#endif

    s_icuTmr1OvfFlag = FALSE;

    /* Get the interrupt flags  */
    tmrIntFlag = REG_READ32(TMR_STS_REG_ADDR(tmrModule));
    /* Get the interrupt enable status */
    tmrIntEnSts = REG_READ32(TMR_DIEN_REG_ADDR(tmrModule));

    /* Check the overflow bit */
    if((0U == (tmrIntFlag & TMR_STS_UIFLG_MASK)))
    {
        /* nothing to do */
    }
    else if(0U == (tmrIntEnSts & TMR_DIEN_UIEN_MASK))
    {
        /* nothing to do */
    }
    else if(tmrModule != ICU_TMR1)
    {
        /* nothing to do */
    }
    else
    {
        s_icuTmr1OvfFlag = TRUE;
#if (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE)
        /* If in signal measurement mode, and in second edge status, increase the overflow count */
        for(chCnt = ((uint8)tmrModule * TMR_CH_CNT_PER_MODULE);
            chCnt <(((uint8)tmrModule * TMR_CH_CNT_PER_MODULE) + TMR_CH_CNT_PER_MODULE);
            chCnt++)
        {
            meaItem = (Icu_TmrChModeType)(Icu_Tmr_GetTmrChFeatureStateBit(chCnt,
                (uint16)TMR_ICU_MEA_MODE_MASK_VAL) >> (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET);
            if((Icu_TmrChModeType)(meaItem & ICU_TMR_MEASUREMENT_FUNCTION) == ICU_TMR_MEASUREMENT_FUNCTION)
            {
                if(s_icuTmrChICCtrl[chCnt].icuTmrIcSts == TMR_IC_SECOND_STS)
                {
                    /* Avoid the count overflow */
                    if(s_icuTmrChICCtrl[chCnt].icuTmrIcOfCnt < 0xFFFFFFFFU)
                    {
                        s_icuTmrChICCtrl[chCnt].icuTmrIcOfCnt = s_icuTmrChICCtrl[chCnt].icuTmrIcOfCnt + 1U;
                    }
                    else
                    {
                        /* nothing to do */
                    }
                }
                else if(s_icuTmrChICCtrl[chCnt].icuTmrIcSts == TMR_IC_THIRD_STS)
                {
                    /* Avoid the count overflow */
                    if(s_icuTmrChICCtrl[chCnt].icuTmrIcOfCnt < 0xFFFFFFFFU)
                    {
                        s_icuTmrChICCtrl[chCnt].icuTmrIcOfCnt = s_icuTmrChICCtrl[chCnt].icuTmrIcOfCnt + 1U;
                    }
                    else
                    {
                        /* nothing to do */
                    }
                }
                else
                {
                    /* nothing to do */
                }
            }
            else
            {
                /* nothing to do */
            }
        }
#endif
        Icu_Tmr_ProcessTofInterrupt((uint8)tmrModule);
        /* clear the channel update flag */
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_UIFLG_MASK);
    }
#endif
}

/*!
* @brief         Process Interrupt function of the Icu TMR Low-level driver.
*
* @param[in]     tmrModule          Tmr module id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_ProcessInterrupt(CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule)
{
#if ((STD_ON == ICU_EDGE_DETECT_API_ENABLE) || (STD_ON == ICU_TIMESTAMP_API_ENABLE) ||\
     (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE) || (STD_ON == ICU_EDGE_COUNT_API_ENABLE))
    VAR(uint32, AUTOMATIC) tmrIntFlag = 0U;
    VAR(uint32, AUTOMATIC) tmrIntEnSts = 0U;
    VAR(boolean, AUTOMATIC) ovfFlag = FALSE;
    
#if (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE)
    VAR(Icu_TmrChModeType, AUTOMATIC) meaItem;
    VAR(uint8, AUTOMATIC) chCnt = 0U;
#endif

    /* Get the interrupt flags  */
    tmrIntFlag = REG_READ32(TMR_STS_REG_ADDR(tmrModule));
    /* Get the interrupt enable status */
    tmrIntEnSts = REG_READ32(TMR_DIEN_REG_ADDR(tmrModule));

    /* Check the overflow bit */
    if(0U == (tmrIntFlag & TMR_STS_UIFLG_MASK))
    {
        /* nothing to do */
    }
    else if(0U == (tmrIntEnSts & TMR_DIEN_UIEN_MASK))
    {
        /* nothing to do */
    }
    else if(tmrModule == ICU_TMR1)
    {
        /* nothing to do */
    }
    else
    {
        ovfFlag = TRUE;

#if (STD_ON == ICU_SIGNAL_MEASUREMENT_API_ENABLE)
        /* If in signal measurement mode, and in second edge status, increase the overflow count */
        for(chCnt =  ((uint8)tmrModule * TMR_CH_CNT_PER_MODULE);
            chCnt < (((uint8)tmrModule * TMR_CH_CNT_PER_MODULE) + TMR_CH_CNT_PER_MODULE);
            chCnt++)
        {
            meaItem = (Icu_TmrChModeType)(Icu_Tmr_GetTmrChFeatureStateBit(chCnt,
                (uint16)TMR_ICU_MEA_MODE_MASK_VAL) >> (uint8)TMR_ICU_MEA_MODE_BIT_OFFSET);
            if((Icu_TmrChModeType)(meaItem & ICU_TMR_MEASUREMENT_FUNCTION) == ICU_TMR_MEASUREMENT_FUNCTION)
            {
                if(s_icuTmrChICCtrl[chCnt].icuTmrIcSts == TMR_IC_SECOND_STS)
                {
                    /* Avoid the count overflow */
                    if(s_icuTmrChICCtrl[chCnt].icuTmrIcOfCnt < 0xFFFFFFFFU)
                    {
                        s_icuTmrChICCtrl[chCnt].icuTmrIcOfCnt = s_icuTmrChICCtrl[chCnt].icuTmrIcOfCnt + 1U;
                    }
                    else
                    {
                        /* nothing to do */
                    }
                }
                else if(s_icuTmrChICCtrl[chCnt].icuTmrIcSts == TMR_IC_THIRD_STS)
                {
                    /* Avoid the count overflow */
                    if(s_icuTmrChICCtrl[chCnt].icuTmrIcOfCnt < 0xFFFFFFFFU)
                    {
                        s_icuTmrChICCtrl[chCnt].icuTmrIcOfCnt = s_icuTmrChICCtrl[chCnt].icuTmrIcOfCnt + 1U;
                    }
                    else
                    {
                        /* nothing to do */
                    }
                }
                else
                {
                    /* nothing to do */
                }
            }
            else
            {
                /* nothing to do */
            }
        }
#endif

        Icu_Tmr_ProcessTofInterrupt((uint8)tmrModule);
        /* clear the channel update flag */
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_UIFLG_MASK);
    }

    if(ICU_TMR1 == tmrModule)
    {
        ovfFlag = s_icuTmr1OvfFlag;
    }
    else
    {
        /* pass */
    }

    /* Channel 1 interrupt */
    if(0U == (tmrIntFlag & TMR_STS_CC1IFLG_MASK))
    {
        /* nothing to do */
    }
    else if(0U == (tmrIntEnSts & TMR_DIEN_CC1IEN_MASK))
    {
        /* nothing to do */
    }
    else
    {
        Icu_Tmr_ProcessChInterrupt((Icu_TmrChType)(((uint8)tmrModule * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH1), 
            ICU_TMR_HW_CH1, tmrModule, ovfFlag);
        /* clear the channel flag */
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_CC1IFLG_MASK);
    }

    /* Channel 2 interrupt */
    if(0U == (tmrIntFlag & TMR_STS_CC2IFLG_MASK))
    {
        /* nothing to do */
    }
    else if(0U == (tmrIntEnSts & TMR_DIEN_CC2IEN_MASK))
    {
        /* nothing to do */
    }
    else
    {
        Icu_Tmr_ProcessChInterrupt((Icu_TmrChType)(((uint8)tmrModule * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH2), ICU_TMR_HW_CH2, 
            tmrModule, ovfFlag);
        /* clear the channel flag */
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_CC2IFLG_MASK);
    }

    /* Channel 3 interrupt */
    if(0U == (tmrIntFlag & TMR_STS_CC3IFLG_MASK))
    {
        /* nothing to do */
    }
    else if(0U == (tmrIntEnSts & TMR_DIEN_CC3IEN_MASK))
    {
        /* nothing to do */
    }
    else
    {
        Icu_Tmr_ProcessChInterrupt((Icu_TmrChType)(((uint8)tmrModule * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH3), ICU_TMR_HW_CH3, 
            tmrModule, ovfFlag);
        /* clear the channel flag */
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_CC3IFLG_MASK);
    }

    /* Channel 4 interrupt */
    if(0U == (tmrIntFlag & TMR_STS_CC4IFLG_MASK))
    {
        /* nothing to do */
    }
    else if(0U == (tmrIntEnSts & TMR_DIEN_CC4IEN_MASK))
    {
        /* nothing to do */
    }
    else
    {
        Icu_Tmr_ProcessChInterrupt((Icu_TmrChType)(((uint8)tmrModule * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH4), ICU_TMR_HW_CH4, 
            tmrModule, ovfFlag);
        /* clear the channel flag */
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_CC4IFLG_MASK);
    }
#endif
}
#endif

/*!
* @brief         GlobalConfiguration function of the Icu TMR Low-level driver.
*
* @param[in]     tmrModuleConfig          Tmr module configuration
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_Tmr_GlobalConfiguration(VAR(Icu_TmrGlobalCfgType, AUTOMATIC) tmrModuleConfig)
{
    VAR(uint8, AUTOMATIC) moduleId = (uint8)tmrModuleConfig.icuTmrModule;

    SchM_Enter_Icu_ICU_CRITICAL_SECTION12();

    /* Set count direction on register */
    REG_RMW32(TMR_CTRL1_REG_ADDR(moduleId), TMR_CTRL1_CNTDIR_MASK, 
        ((uint32)tmrModuleConfig.icuTmrCnterMode << TMR_CTRL1_CNTDIR_SHIFT));
    /* Set filter clock division on register */
    REG_RMW32(TMR_CTRL1_REG_ADDR(moduleId), TMR_CTRL1_CLKDIV_MASK, 
        ((uint32)tmrModuleConfig.icuTmrFilClkDiv << TMR_CTRL1_CLKDIV_SHIFT));
    /* Set auto reload value on register */
    REG_WRITE32(TMR_AUTORLD_REG_ADDR(moduleId), tmrModuleConfig.icuTmrAutoReloadVal);
    /* Set prescaler value on register */
    REG_WRITE32(TMR_PSC_REG_ADDR(moduleId), tmrModuleConfig.icuTmrClkPrescale);
    /* Enable update event generation */
    REG_RMW32(TMR_CEG_REG_ADDR(moduleId), TMR_CEG_UEG_MASK, (uint32)ICU_BIT_SET);

    /* Enable the counter */
    REG_RMW32(TMR_CTRL1_REG_ADDR(moduleId), TMR_CTRL1_CNTEN_MASK, 
        ((uint32)ICU_BIT_SET << TMR_CTRL1_CNTEN_SHIFT));

    SchM_Exit_Icu_ICU_CRITICAL_SECTION12();
}

#if (STD_ON == ICU_TMR_CUSTOM_FEATURE_ENABLE)
/*!
* @brief         High Precision Function Overflow Irq of the Icu TMR Low-level driver.
*
* @param[in]     tmrModule          Tmr module id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_CustomFunctionOvfIrq(CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule)
{
    VAR(uint32, AUTOMATIC) tmrIntFlag = 0U;
    VAR(uint32, AUTOMATIC) tmrIntEnSts = 0U;
    P2CONST(Icu_TmrIPCfgType, AUTOMATIC, ICU_APPL_CONST)  tmrIPCfgPtr = 
        g_icuCfgPtr->moduleAchieveWayCfg.channelTmrIpConfigPtr;
    VAR(uint8, AUTOMATIC) tmrCfgIndex = tmrIPCfgPtr->tmrHwModuleIdToCfgIndexPtr[(uint8)tmrModule - 1U];
    
    /* Get the interrupt flags  */
    tmrIntFlag = REG_READ32(TMR_STS_REG_ADDR(tmrModule));
    /* Get the interrupt enable status */
    tmrIntEnSts = REG_READ32(TMR_DIEN_REG_ADDR(tmrModule));

    if((tmrIntFlag & TMR_STS_UIFLG_MASK) == (uint32)RESET)
    {
        /* nothing to do */
    }
    else if((tmrIntEnSts & TMR_DIEN_UIEN_MASK) == (uint32)RESET)
    {
        /* nothing to do */
    }
    else
    {
        if(NULL_PTR != ((*(tmrIPCfgPtr->icuTmrGlobalCfgPtr))[tmrCfgIndex].icuTmrOvfNotification))
        {
            ((*(tmrIPCfgPtr->icuTmrGlobalCfgPtr))[tmrCfgIndex].icuTmrOvfNotification)(tmrModule);
        }
        else
        {
            /* Do nothing */
        }
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_UIFLG_MASK);
    }
}

/*!
* @brief         High Precision FunctionIrq function of the Icu TMR Low-level driver.
*
* @param[in]     tmrModule          Tmr module id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_CustomFunctionIrq(CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule)
{
    VAR(uint32, AUTOMATIC) tmrIntFlag = 0U;
    VAR(uint32, AUTOMATIC) tmrIntEnSts = 0U;
    VAR(Icu_ChannelType, AUTOMATIC) icuCh = 0U;
    P2CONST(Icu_TmrIPCfgType, AUTOMATIC, ICU_APPL_CONST)  tmrIPCfgPtr = 
        g_icuCfgPtr->moduleAchieveWayCfg.channelTmrIpConfigPtr;
    P2CONST(Icu_TmrChCfgType, AUTOMATIC, ICU_APPL_CONST)  tmrCHCfgPtr = NULL_PTR;
    VAR(uint8, AUTOMATIC) tmrCfgIndex = tmrIPCfgPtr->tmrHwModuleIdToCfgIndexPtr[(uint8)tmrModule - 1U];
    VAR(uint8, AUTOMATIC) workChannel = 0U;

    /* Get the interrupt flags  */
    tmrIntFlag = REG_READ32(TMR_STS_REG_ADDR(tmrModule));
    /* Get the interrupt enable status */
    tmrIntEnSts = REG_READ32(TMR_DIEN_REG_ADDR(tmrModule));

    switch (tmrModule)
    {
        case ICU_TMR1:
            {
                if((tmrIntFlag & TMR_STS_CC1IFLG_MASK) == (uint32)RESET)
                {
                    /* nothing to do */
                }
                else if((tmrIntEnSts & TMR_DIEN_CC1IEN_MASK) == (uint32)RESET)
                {
                    /* nothing to do */
                }
                else
                {
                    icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR1 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH1)];
                    workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                    tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                    if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                    {
                        tmrCHCfgPtr->icuTmrChNotification(ICU_TMR1, ICU_TMR_HW_CH1);
                    }
                    else
                    {
                        /* Do nothing */
                    }
                    REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR1), TMR_STS_CC1IFLG_MASK);
                }

                if((tmrIntFlag & TMR_STS_CC2IFLG_MASK) == (uint32)RESET)
                {
                    /* nothing to do */
                }
                else if((tmrIntEnSts & TMR_DIEN_CC2IEN_MASK) == (uint32)RESET)
                {
                    /* nothing to do */
                }
                else
                {
                    icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR1 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH2)];
                    workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                    tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                    if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                    {
                        tmrCHCfgPtr->icuTmrChNotification(ICU_TMR1, ICU_TMR_HW_CH2);
                    }
                    else
                    {
                        /* Do nothing */
                    }
                    REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR1), TMR_STS_CC2IFLG_MASK);
                }

                if((tmrIntFlag & TMR_STS_CC3IFLG_MASK) == (uint32)RESET)
                {
                    /* nothing to do */
                }
                else if((tmrIntEnSts & TMR_DIEN_CC3IEN_MASK) == (uint32)RESET)
                {
                    /* nothing to do */
                }
                else
                {
                    icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR1 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH3)];
                    workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                    tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                    if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                    {
                        tmrCHCfgPtr->icuTmrChNotification(ICU_TMR1, ICU_TMR_HW_CH3);
                    }
                    else
                    {
                        /* Do nothing */
                    }
                    REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR1), TMR_STS_CC3IFLG_MASK);
                }

                if((tmrIntFlag & TMR_STS_CC4IFLG_MASK) == (uint32)RESET)
                {
                    /* nothing to do */
                }
                else if((tmrIntEnSts & TMR_DIEN_CC4IEN_MASK) == (uint32)RESET)
                {
                    /* nothing to do */
                }
                else
                {
                    icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR1 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH4)];
                    workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                    tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                    if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                    {
                        tmrCHCfgPtr->icuTmrChNotification(ICU_TMR1, ICU_TMR_HW_CH4);
                    }
                    else
                    {
                        /* Do nothing */
                    }
                    REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR1), TMR_STS_CC4IFLG_MASK);
                }
            }
            break;
        case ICU_TMR2:
            {
                if (((tmrIntFlag & TMR_STS_UIFLG_MASK) != (uint32)RESET) && ((tmrIntEnSts & TMR_DIEN_UIEN_MASK) != (uint32)RESET))
                {
                    if(NULL_PTR != ((*(tmrIPCfgPtr->icuTmrGlobalCfgPtr))[tmrCfgIndex].icuTmrOvfNotification))
                    {
                        ((*(tmrIPCfgPtr->icuTmrGlobalCfgPtr))[tmrCfgIndex].icuTmrOvfNotification)(ICU_TMR2);
                    }
                    else
                    {
                        /* Do nothing */
                    }
                    REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR2), TMR_STS_UIFLG_MASK);
                }
                else 
                {
                    if((tmrIntFlag & TMR_STS_CC1IFLG_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else if((tmrIntEnSts & TMR_DIEN_CC1IEN_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else
                    {
                        icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR2 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH1)];
                        workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                        tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                        if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                        {
                            tmrCHCfgPtr->icuTmrChNotification(ICU_TMR2, ICU_TMR_HW_CH1);
                        }
                        else
                        {
                            /* Do nothing */
                        }
                        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR2), TMR_STS_CC1IFLG_MASK);
                    }

                    if((tmrIntFlag & TMR_STS_CC2IFLG_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else if((tmrIntEnSts & TMR_DIEN_CC2IEN_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else
                    {
                        icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR2 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH2)];
                        workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                        tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                        if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                        {
                            tmrCHCfgPtr->icuTmrChNotification(ICU_TMR2, ICU_TMR_HW_CH2);
                        }
                        else
                        {
                            /* Do nothing */
                        }
                        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR2), TMR_STS_CC2IFLG_MASK);
                    }

                    if((tmrIntFlag & TMR_STS_CC3IFLG_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else if((tmrIntEnSts & TMR_DIEN_CC3IEN_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else
                    {
                        icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR2 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH3)];
                        workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                        tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                        if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                        {
                            tmrCHCfgPtr->icuTmrChNotification(ICU_TMR2, ICU_TMR_HW_CH3);
                        }
                        else
                        {
                            /* Do nothing */
                        }
                        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR2), TMR_STS_CC3IFLG_MASK);
                    }

                    if((tmrIntFlag & TMR_STS_CC4IFLG_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else if((tmrIntEnSts & TMR_DIEN_CC4IEN_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else
                    {
                        icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR2 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH4)];
                        workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                        tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                        if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                        {
                            tmrCHCfgPtr->icuTmrChNotification(ICU_TMR2, ICU_TMR_HW_CH4);
                        }
                        else
                        {
                            /* Do nothing */
                        }
                        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR2), TMR_STS_CC4IFLG_MASK);
                    }
                }
            }
            break;
        case ICU_TMR3:
            {
                if (((tmrIntFlag & TMR_STS_UIFLG_MASK) != (uint32)RESET) && ((tmrIntEnSts & TMR_DIEN_UIEN_MASK) != (uint32)RESET))
                {
                    if(NULL_PTR != ((*(tmrIPCfgPtr->icuTmrGlobalCfgPtr))[tmrCfgIndex].icuTmrOvfNotification))
                    {
                        ((*(tmrIPCfgPtr->icuTmrGlobalCfgPtr))[tmrCfgIndex].icuTmrOvfNotification)(ICU_TMR3);
                    }
                    else
                    {
                        /* Do nothing */
                    }
                    REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR3), TMR_STS_UIFLG_MASK);
                }
                else 
                {
                    if((tmrIntFlag & TMR_STS_CC1IFLG_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else if((tmrIntEnSts & TMR_DIEN_CC1IEN_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else
                    {
                        icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR3 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH1)];
                        workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                        tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                        if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                        {
                            tmrCHCfgPtr->icuTmrChNotification(ICU_TMR3, ICU_TMR_HW_CH1);
                        }
                        else
                        {
                            /* Do nothing */
                        }
                        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR3), TMR_STS_CC1IFLG_MASK);
                    }

                    if((tmrIntFlag & TMR_STS_CC2IFLG_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else if((tmrIntEnSts & TMR_DIEN_CC2IEN_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else
                    {
                        icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR3 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH2)];
                        workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                        tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                        if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                        {
                            tmrCHCfgPtr->icuTmrChNotification(ICU_TMR3, ICU_TMR_HW_CH2);
                        }
                        else
                        {
                            /* Do nothing */
                        }
                        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR3), TMR_STS_CC2IFLG_MASK);
                    }

                    if((tmrIntFlag & TMR_STS_CC3IFLG_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else if((tmrIntEnSts & TMR_DIEN_CC3IEN_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else
                    {
                        icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR3 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH3)];
                        workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                        tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                        if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                        {
                            tmrCHCfgPtr->icuTmrChNotification(ICU_TMR3, ICU_TMR_HW_CH3);
                        }
                        else
                        {
                            /* Do nothing */
                        }
                        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR3), TMR_STS_CC3IFLG_MASK);
                    }

                    if((tmrIntFlag & TMR_STS_CC4IFLG_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else if((tmrIntEnSts & TMR_DIEN_CC4IEN_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else
                    {
                        icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR3 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH4)];
                        workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                        tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                        if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                        {
                            tmrCHCfgPtr->icuTmrChNotification(ICU_TMR3, ICU_TMR_HW_CH4);
                        }
                        else
                        {
                            /* Do nothing */
                        }
                        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR3), TMR_STS_CC4IFLG_MASK);
                    }
                }
            }
            break;
        case ICU_TMR4:
            {
                if (((tmrIntFlag & TMR_STS_UIFLG_MASK) != (uint32)RESET) && ((tmrIntEnSts & TMR_DIEN_UIEN_MASK) != (uint32)RESET))
                {
                    if(NULL_PTR != ((*(tmrIPCfgPtr->icuTmrGlobalCfgPtr))[tmrCfgIndex].icuTmrOvfNotification))
                    {
                        ((*(tmrIPCfgPtr->icuTmrGlobalCfgPtr))[tmrCfgIndex].icuTmrOvfNotification)(ICU_TMR4);
                    }
                    else
                    {
                        /* Do nothing */
                    }
                    REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR4), TMR_STS_UIFLG_MASK);
                }
                else 
                {
                    if((tmrIntFlag & TMR_STS_CC1IFLG_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else if((tmrIntEnSts & TMR_DIEN_CC1IEN_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else
                    {
                        icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR4 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH1)];
                        workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                        tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                        if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                        {
                            tmrCHCfgPtr->icuTmrChNotification(ICU_TMR4, ICU_TMR_HW_CH1);
                        }
                        else
                        {
                            /* Do nothing */
                        }
                        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR4), TMR_STS_CC1IFLG_MASK);
                    }

                    if((tmrIntFlag & TMR_STS_CC2IFLG_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else if((tmrIntEnSts & TMR_DIEN_CC2IEN_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else
                    {
                        icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR4 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH2)];
                        workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                        tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                        if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                        {
                            tmrCHCfgPtr->icuTmrChNotification(ICU_TMR4, ICU_TMR_HW_CH2);
                        }
                        else
                        {
                            /* Do nothing */
                        }
                        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR4), TMR_STS_CC2IFLG_MASK);
                    }

                    if((tmrIntFlag & TMR_STS_CC3IFLG_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else if((tmrIntEnSts & TMR_DIEN_CC3IEN_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else
                    {
                        icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR4 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH3)];
                        workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                        tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                        if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                        {
                            tmrCHCfgPtr->icuTmrChNotification(ICU_TMR4, ICU_TMR_HW_CH3);
                        }
                        else
                        {
                            /* Do nothing */
                        }
                        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR4), TMR_STS_CC3IFLG_MASK);
                    }

                    if((tmrIntFlag & TMR_STS_CC4IFLG_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else if((tmrIntEnSts & TMR_DIEN_CC4IEN_MASK) == (uint32)RESET)
                    {
                        /* nothing to do */
                    }
                    else
                    {
                        icuCh = (*(g_icuCfgPtr->icuHwMapPtr))[(Icu_TmrChType)(((uint8)ICU_TMR4 * TMR_CH_CNT_PER_MODULE) + (uint8)ICU_TMR_HW_CH4)];
                        workChannel = (*(g_icuCfgPtr->moduleAchieveWayCfg.channelWorkingIpAndIdPtr))[icuCh].channelWorkingId;
                        tmrCHCfgPtr = &(*tmrIPCfgPtr->icuChannelCfgPtr)[workChannel];
                        if(NULL_PTR != tmrCHCfgPtr->icuTmrChNotification)
                        {
                            tmrCHCfgPtr->icuTmrChNotification(ICU_TMR4, ICU_TMR_HW_CH4);
                        }
                        else
                        {
                            /* Do nothing */
                        }
                        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ICU_TMR4), TMR_STS_CC4IFLG_MASK);
                    }
                }
            }
            break;
        default:
            {
                /* Do nothing */
            }
            break;
    }
}

/*!
* @brief         This function is used to enable/disable TMR interrupts.
*
* @param[in]     tmrChannel          TMR channel id
* @param[in]     tmrModule           TMR module id
* @param[in]     interrupt           TMR interrupt type
* @param[in]     enable              ENABLE/DISABLE
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_InterruptSet(CONST(Icu_TmrHwChType, AUTOMATIC) tmrChannel, 
    CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule, CONST(Icu_TmrIcInterruptType, AUTOMATIC) interrupt, 
    CONST(uint8, AUTOMATIC) enable)
{
    CONST(uint8, ICU_CONST) intEnBitMask  = (uint8)(1U << (uint8)tmrChannel);

    SchM_Enter_Icu_ICU_CRITICAL_SECTION10();
    
    switch (interrupt)
    {
        case ICU_TMR_UI_INT:
            if((uint8)ENABLE == enable)
            {
                /* Enable the Update interrupt */
                REG_BIT_SET32(TMR_DIEN_REG_ADDR(tmrModule), TMR_DIEN_UIEN_MASK);
            }
            else
            {
                /* Disable the Update interrupt */
                REG_BIT_CLEAR32(TMR_DIEN_REG_ADDR(tmrModule), TMR_DIEN_UIEN_MASK);
            }
            break;

        case ICU_TMR_CC_INT:
            if((uint8)ENABLE == enable)
            {
                /* Enable the channel interrupt */
                REG_BIT_SET32(TMR_DIEN_REG_ADDR(tmrModule), intEnBitMask);
            }
            else
            {
                /* Disable the channel interrupt */
                REG_BIT_CLEAR32(TMR_DIEN_REG_ADDR(tmrModule), (uint32)intEnBitMask);
            }
            break;

        default:
            {
                /* Do nothing */
            }
            break;
    }

    SchM_Exit_Icu_ICU_CRITICAL_SECTION10();
}

/*!
* @brief         This function is used to set active edge TMR channel.
*
* @param[in]     tmrHwCh        TMR hardware channel id
* @param[in]     tmrModule      TMR module id
* @param[in]     icuActiveEdge  active edge:
*                               ICU_TMR_ACTIVE_EDGE_IS_FALLING
*                               ICU_TMR_ACTIVE_EDGE_IS_RISING
*                               ICU_TMR_ACTIVE_EDGE_IS_BOTH
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_Tmr_SetHwChActiveEdge(CONST(Icu_TmrHwChType, AUTOMATIC) tmrHwCh, 
    CONST(Icu_TmrModuleType, AUTOMATIC) tmrModule, VAR(Icu_TmrActiveEdgeType, AUTOMATIC) icuActiveEdge)
{
    switch (tmrHwCh)
    {
        case ICU_TMR_HW_CH1:
            /* Set the failing edge */
            REG_RMW32(TMR_CCEN_REG_ADDR(tmrModule), ICU_TMR_ACTIVE_EDGE_IS_BOTH, icuActiveEdge);
            break;
        case ICU_TMR_HW_CH2:
            /* Set the failing edge */
            REG_RMW32(TMR_CCEN_REG_ADDR(tmrModule), (uint32)ICU_TMR_ACTIVE_EDGE_IS_BOTH << TMR_CCEN_CC2EN_SHIFT, 
                (uint32)icuActiveEdge << TMR_CCEN_CC2EN_SHIFT);
            break;
        case ICU_TMR_HW_CH3:
            /* Set the failing edge */
            REG_RMW32(TMR_CCEN_REG_ADDR(tmrModule), (uint32)ICU_TMR_ACTIVE_EDGE_IS_BOTH << TMR_CCEN_CC3EN_SHIFT, 
                (uint32)icuActiveEdge << TMR_CCEN_CC3EN_SHIFT);
            break;
        case ICU_TMR_HW_CH4:
            /* Set the failing edge */
            REG_RMW32(TMR_CCEN_REG_ADDR(tmrModule), (uint32)ICU_TMR_ACTIVE_EDGE_IS_BOTH << TMR_CCEN_CC4EN_SHIFT, 
                (uint32)icuActiveEdge << TMR_CCEN_CC4EN_SHIFT);
            break;
        default:
            {
                /* Do nothing */
            }
            break;
    }
}

#endif

/**@} end of group ICU_Fuctions */

#define ICU_STOP_SEC_CODE
#include "Icu_MemMap.h"

#ifdef __cplusplus
}
#endif

/**@} end of group ICU_Driver */
/**@} end of group G32A10xx_StdPeriphDriver */
