/*!
* @file     Icu_PortCi.c
*
* @version  1.0.0
*
* @brief    Icu driver code by port module
*
* @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_PortCi_c_MISRA_REF1
*          Breaks the required M3CM Rule-10.3 of MISRA 2012 guidelines,
*          The value of an expression shall not be assigned to an object with a narrower essential type or of a different essential type category.
*
*      Icu_PortCi_c_MISRA_REF2
*          Breaks the required M3CM Rule-10.5 of MISRA 2012 guidelines,
*          The value of an expression should not be cast to an inappropriate essential type.
*
*      Icu_PortCi_c_MISRA_REF3
*          Breaks the required M3CM Rule-20.7 of MISRA 2012 guidelines,
*          Expressions resulting from the expansion of macro parameters shall be enclosed in parentheses.
*/

#ifdef __cplusplus
extern "C"{
#endif

#include "Mcal.h"
#include "SchM_Icu.h"
#include "Icu_Cfg.h"
#include "Icu_RegPortCi.h"
#include "Icu_PortCi.h"
#include "Icu_Types.h"
#include "Icu_Irq.h"

#include "Mcu_SysCfgTypes.h"
#include "Icu_Eint.h"
#include "Port_Hw.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_PORT_CI_VENDOR_ID                      0x00C1U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define ICU_PORT_CI_AR_RELEASE_MAJOR_VERSION       0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define ICU_PORT_CI_AR_RELEASE_MINOR_VERSION       0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define ICU_PORT_CI_AR_RELEASE_REVISION_VERSION    0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define ICU_PORT_CI_SW_MAJOR_VERSION               0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define ICU_PORT_CI_SW_MINOR_VERSION               0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define ICU_PORT_CI_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_PortCi.c and SchM_Icu.h */
    #if (ICU_PORT_CI_AR_RELEASE_MAJOR_VERSION != SCHM_ICU_H_AR_RELEASE_MAJOR_VERSION)
        #error "AUTOSAR Major Version Number mismatch between Icu_PortCi.c and SchM_Icu.h "
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Icu_PortCi.c and SchM_Icu.h */
    #if (ICU_PORT_CI_AR_RELEASE_MINOR_VERSION != SCHM_ICU_H_AR_RELEASE_MINOR_VERSION)
        #error "AUTOSAR Minor Version Number mismatch between Icu_PortCi.c and SchM_Icu.h "
    #endif

    /* Make sure the AUTOSAR major version number is the same between Icu_PortCi.c and Mcal.h */
    #if (ICU_PORT_CI_AR_RELEASE_MAJOR_VERSION != MCAL_H_AR_RELEASE_MAJOR_VERSION)
        #error "AUTOSAR Major Version Number mismatch between Icu_PortCi.c and Mcal.h "
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Icu_PortCi.c and Mcal.h */
    #if (ICU_PORT_CI_AR_RELEASE_MINOR_VERSION != MCAL_H_AR_RELEASE_MINOR_VERSION)
        #error "AUTOSAR Minor Version Number mismatch between Icu_PortCi.c and Mcal.h "
    #endif

#endif

/* Make sure the vendor id is the same between Icu_PortCi.c and Icu_Types.h */
#if (ICU_PORT_CI_VENDOR_ID != ICU_TYPE_H_VENDOR_ID)
    #error "Vendor id mismatch between Icu_PortCi.c and Icu_Types.h "
#endif
/* Make sure the AUTOSAR major version number is the same between Icu_PortCi.c and Icu_Types.h */
#if (ICU_PORT_CI_AR_RELEASE_MAJOR_VERSION != ICU_TYPE_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Icu_PortCi.c and Icu_Types.h "
#endif
/* Make sure the AUTOSAR minor version number is the same between Icu_PortCi.c and Icu_Types.h */
#if (ICU_PORT_CI_AR_RELEASE_MINOR_VERSION != ICU_TYPE_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Icu_PortCi.c and Icu_Types.h "
#endif
/* Make sure the AUTOSAR revision version number is the same between Icu_PortCi.c and Icu_Types.h */
#if (ICU_PORT_CI_AR_RELEASE_REVISION_VERSION != ICU_TYPE_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Icu_PortCi.c and Icu_Types.h "
#endif
/* Make sure the software major version number is the same between Icu_PortCi.c and Icu_Types.h */
#if (ICU_PORT_CI_SW_MAJOR_VERSION != ICU_TYPE_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Icu_PortCi.c and Icu_Types.h "
#endif
/* Make sure the software minor version number is the same between Icu_PortCi.c and Icu_Types.h */
#if (ICU_PORT_CI_SW_MINOR_VERSION != ICU_TYPE_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Icu_PortCi.c and Icu_Types.h "
#endif
/* Make sure the software patch version number is the same between Icu_PortCi.c and Icu_Types.h */
#if (ICU_PORT_CI_SW_PATCH_VERSION != ICU_TYPE_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Icu_PortCi.c and Icu_Types.h "
#endif

/* Make sure the vendor id is the same between Icu_PortCi.c and Icu_RegPortCi.h */
#if (ICU_PORT_CI_VENDOR_ID != ICU_REG_PORT_CI_H_VENDOR_ID)
    #error "Vendor id mismatch between Icu_PortCi.c and Icu_RegPortCi.h "
#endif
/* Make sure the AUTOSAR major version number is the same between Icu_PortCi.c and Icu_RegPortCi.h */
#if (ICU_PORT_CI_AR_RELEASE_MAJOR_VERSION != ICU_REG_PORT_CI_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Icu_PortCi.c and Icu_RegPortCi.h "
#endif
/* Make sure the AUTOSAR minor version number is the same between Icu_PortCi.c and Icu_RegPortCi.h */
#if (ICU_PORT_CI_AR_RELEASE_MINOR_VERSION != ICU_REG_PORT_CI_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Icu_PortCi.c and Icu_RegPortCi.h "
#endif
/* Make sure the AUTOSAR revision version number is the same between Icu_PortCi.c and Icu_RegPortCi.h */
#if (ICU_PORT_CI_AR_RELEASE_REVISION_VERSION != ICU_REG_PORT_CI_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Icu_PortCi.c and Icu_RegPortCi.h "
#endif
/* Make sure the software major version number is the same between Icu_PortCi.c and Icu_RegPortCi.h */
#if (ICU_PORT_CI_SW_MAJOR_VERSION != ICU_REG_PORT_CI_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Icu_PortCi.c and Icu_RegPortCi.h "
#endif
/* Make sure the software minor version number is the same between Icu_PortCi.c and Icu_RegPortCi.h */
#if (ICU_PORT_CI_SW_MINOR_VERSION != ICU_REG_PORT_CI_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Icu_PortCi.c and Icu_RegPortCi.h "
#endif
/* Make sure the software patch version number is the same between Icu_PortCi.c and Icu_RegPortCi.h */
#if (ICU_PORT_CI_SW_PATCH_VERSION != ICU_REG_PORT_CI_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Icu_PortCi.c and Icu_RegPortCi.h "
#endif

/* Make sure the vendor id is the same between Icu_PortCi.c and Icu_PortCi.h */
#if (ICU_PORT_CI_VENDOR_ID != ICU_PORT_CI_H_VENDOR_ID)
    #error "Vendor id mismatch between Icu_PortCi.c and Icu_PortCi.h "
#endif
/* Make sure the AUTOSAR major version number is the same between Icu_PortCi.c and Icu_PortCi.h */
#if (ICU_PORT_CI_AR_RELEASE_MAJOR_VERSION != ICU_PORT_CI_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Icu_PortCi.c and Icu_PortCi.h "
#endif
/* Make sure the AUTOSAR minor version number is the same between Icu_PortCi.c and Icu_PortCi.h */
#if (ICU_PORT_CI_AR_RELEASE_MINOR_VERSION != ICU_PORT_CI_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Icu_PortCi.c and Icu_PortCi.h "
#endif
/* Make sure the AUTOSAR revision version number is the same between Icu_PortCi.c and Icu_PortCi.h */
#if (ICU_PORT_CI_AR_RELEASE_REVISION_VERSION != ICU_PORT_CI_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Icu_PortCi.c and Icu_PortCi.h "
#endif
/* Make sure the software major version number is the same between Icu_PortCi.c and Icu_PortCi.h */
#if (ICU_PORT_CI_SW_MAJOR_VERSION != ICU_PORT_CI_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Icu_PortCi.c and Icu_PortCi.h "
#endif
/* Make sure the software minor version number is the same between Icu_PortCi.c and Icu_PortCi.h */
#if (ICU_PORT_CI_SW_MINOR_VERSION != ICU_PORT_CI_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Icu_PortCi.c and Icu_PortCi.h "
#endif
/* Make sure the software patch version number is the same between Icu_PortCi.c and Icu_PortCi.h */
#if (ICU_PORT_CI_SW_PATCH_VERSION != ICU_PORT_CI_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Icu_PortCi.c and Icu_PortCi.h "
#endif

/* Make sure the vendor id is the same between Icu_PortCi.c and Icu_Cfg.h */
#if (ICU_PORT_CI_VENDOR_ID != ICU_CFG_H_VENDOR_ID)
    #error "Vendor id mismatch between Icu_PortCi.c and Icu_Cfg.h "
#endif
/* Make sure the AUTOSAR major version number is the same between Icu_PortCi.c and Icu_Cfg.h */
#if (ICU_PORT_CI_AR_RELEASE_MAJOR_VERSION != ICU_CFG_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Icu_PortCi.c and Icu_Cfg.h "
#endif
/* Make sure the AUTOSAR minor version number is the same between Icu_PortCi.c and Icu_Cfg.h */
#if (ICU_PORT_CI_AR_RELEASE_MINOR_VERSION != ICU_CFG_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Icu_PortCi.c and Icu_Cfg.h "
#endif
/* Make sure the AUTOSAR revision version number is the same between Icu_PortCi.c and Icu_Cfg.h */
#if (ICU_PORT_CI_AR_RELEASE_REVISION_VERSION != ICU_CFG_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Icu_PortCi.c and Icu_Cfg.h "
#endif
/* Make sure the software major version number is the same between Icu_PortCi.c and Icu_Cfg.h */
#if (ICU_PORT_CI_SW_MAJOR_VERSION != ICU_CFG_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Icu_PortCi.c and Icu_Cfg.h "
#endif
/* Make sure the software minor version number is the same between Icu_PortCi.c and Icu_Cfg.h */
#if (ICU_PORT_CI_SW_MINOR_VERSION != ICU_CFG_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Icu_PortCi.c and Icu_Cfg.h "
#endif
/* Make sure the software patch version number is the same between Icu_PortCi.c and Icu_Cfg.h */
#if (ICU_PORT_CI_SW_PATCH_VERSION != ICU_CFG_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Icu_PortCi.c and Icu_Cfg.h "
#endif

/* Make sure the vendor id is the same between Icu_PortCi.c and Mcu_SysCfgTypes.h */
#if (ICU_PORT_CI_VENDOR_ID != MCU_SYSCFG_TYPES_H_VENDOR_ID)
    #error "Vendor id mismatch between Icu_PortCi.c and Mcu_SysCfgTypes.h "
#endif
/* Make sure the AUTOSAR major version number is the same between Icu_PortCi.c and Mcu_SysCfgTypes.h */
#if (ICU_PORT_CI_AR_RELEASE_MAJOR_VERSION != MCU_SYSCFG_TYPES_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Icu_PortCi.c and Mcu_SysCfgTypes.h "
#endif
/* Make sure the AUTOSAR minor version number is the same between Icu_PortCi.c and Mcu_SysCfgTypes.h */
#if (ICU_PORT_CI_AR_RELEASE_MINOR_VERSION != MCU_SYSCFG_TYPES_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Icu_PortCi.c and Mcu_SysCfgTypes.h "
#endif
/* Make sure the AUTOSAR revision version number is the same between Icu_PortCi.c and Mcu_SysCfgTypes.h */
#if (ICU_PORT_CI_AR_RELEASE_REVISION_VERSION != MCU_SYSCFG_TYPES_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Icu_PortCi.c and Mcu_SysCfgTypes.h "
#endif
/* Make sure the software major version number is the same between Icu_PortCi.c and Mcu_SysCfgTypes.h */
#if (ICU_PORT_CI_SW_MAJOR_VERSION != MCU_SYSCFG_TYPES_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Icu_PortCi.c and Mcu_SysCfgTypes.h "
#endif
/* Make sure the software minor version number is the same between Icu_PortCi.c and Mcu_SysCfgTypes.h */
#if (ICU_PORT_CI_SW_MINOR_VERSION != MCU_SYSCFG_TYPES_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Icu_PortCi.c and Mcu_SysCfgTypes.h "
#endif
/* Make sure the software patch version number is the same between Icu_PortCi.c and Mcu_SysCfgTypes.h */
#if (ICU_PORT_CI_SW_PATCH_VERSION != MCU_SYSCFG_TYPES_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Icu_PortCi.c and Mcu_SysCfgTypes.h "
#endif

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

/** @defgroup ICU_Variable
  @{
*/

#if ((STD_ON == ICU_SET_MODE_API_ENABLE) || (STD_ON == ICU_EDGE_DETECT_API_ENABLE))
static VAR(uint8, ICU_VAR) s_icu_PortCi_ChActiveEdge[ICU_PORT_CI_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,(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,
(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,(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_32
#include "Icu_MemMap.h"

/** @defgroup ICU_Variable
  @{
*/

static VAR(uint32, ICU_VAR) s_icu_PortCi_ChInitState[6U] = {(uint32)0U,(uint32)0U,(uint32)0U,(uint32)0U,(uint32)0U,(uint32)0U};

/**@} end of group ICU_Variable */

#define ICU_STOP_SEC_VAR_INIT_32
#include "Icu_MemMap.h"

/**************************************************************************
                    CONSTANT DEFINITION
**************************************************************************/
#define ICU_START_SEC_CONST_32
#include "Icu_MemMap.h"

/** @defgroup ICU_Variable
  @{
*/

/** judge port address */
CONST(uint32, ICU_CONST) ICU_MODULE_PORT_CI_BASEADDR[6] =
{
    GPIOA_BASEADDR,
    GPIOB_BASEADDR,
    GPIOC_BASEADDR,
    GPIOD_BASEADDR,
    0,
    GPIOF_BASEADDR
};

/**@} end of group ICU_Variable */

#define ICU_STOP_SEC_CONST_32
#include "Icu_MemMap.h"

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

/** @defgroup ICU_Fuctions
  @{
*/

LOCAL_INLINE FUNC(void, ICU_CODE) Icu_PortCi_DisableIntorEvt(CONST(Icu_Port_CiCHType, AUTOMATIC) ch, 
                                                               VAR(Icu_PortPinModeType, AUTOMATIC) portPinMode);

#if ((STD_ON == ICU_SET_MODE_API_ENABLE) ||(STD_ON == ICU_EDGE_DETECT_API_ENABLE))
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_PortCi_EnableIntorEvt(CONST(Icu_Port_CiCHType, AUTOMATIC) ch, 
                                                              VAR(Icu_PortPinModeType, AUTOMATIC) portPinMode);
#endif

/**************************************************************************
                    LOCAL FUNCTION
**************************************************************************/
/*!
* @brief         This function is used to disable port_ci interrupt.
*
* @param[in]     ch            channel id
* @param[in]     portPinMode   port mode
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_PortCi_DisableIntorEvt(CONST(Icu_Port_CiCHType, AUTOMATIC) ch, 
    VAR(Icu_PortPinModeType, AUTOMATIC) portPinMode)
{
    CONST(uint16, ICU_CONST) pinId  = GET_PORT_CI_CH_PIN_ID(ch);
    CONST(uint32, ICU_CONST) pinMask = (uint32)(BIT0 << pinId);

    SchM_Enter_Icu_ICU_CRITICAL_SECTION41();
    {
        if(ICU_PORT_INTERRUPT_MODE == portPinMode)
        {
            /* Disable Line interrupt */
            Icu_Eint_DisableInt(pinMask);
        }
        else if(ICU_PORT_EVENT_MODE == portPinMode)
        {
            /* Disable Line event */
            Icu_Eint_DisableEvent(pinMask);
        }
        else
        {
            /* Do nothing */
        }
        
        /* Disable both the failing and rising trigger */
        Icu_Eint_DisableRisingTrig(pinMask);
        Icu_Eint_DisableFailingTrig(pinMask);
        /* Clear port channel flag */
        Icu_Eint_ClearIntFlag(pinMask);
    }
    SchM_Exit_Icu_ICU_CRITICAL_SECTION41();
}

#if ((STD_ON == ICU_SET_MODE_API_ENABLE) ||(STD_ON == ICU_EDGE_DETECT_API_ENABLE))
/*!
* @brief         This function is used to enable port_ci interrupt.
*
* @param[in]     ch             channel id
* @param[in]     portPinMode    port mode
* @param[out]    None
* @param[in,out] None
*/
LOCAL_INLINE FUNC(void, ICU_CODE) Icu_PortCi_EnableIntorEvt(CONST(Icu_Port_CiCHType, AUTOMATIC) ch, 
    VAR(Icu_PortPinModeType, AUTOMATIC) portPinMode)
{
    CONST(uint16, ICU_CONST) pinId  = (uint16)GET_PORT_CI_CH_PIN_ID(ch);
    CONST(uint32, ICU_CONST) pinMask = (uint32)(BIT0 << pinId);
    CONST(uint16, ICU_CONST) portId = GET_PORT_CI_CH_PORT_ID(ch);

    SchM_Enter_Icu_ICU_CRITICAL_SECTION45();
    {
        /* Enable port interrupt and set active edge */
        switch (s_icu_PortCi_ChActiveEdge[ch])
        {
            case (uint8)ICU_PORT_CI_CH_ACTIVE_EDGE_IS_FALLING:
                /* Disable the rising trigger */
                Icu_Eint_DisableRisingTrig(pinMask);
                /* Enable the failing trigger  */
                Icu_Eint_EnableFailingTrig(pinMask);
                break;

            case (uint8)ICU_PORT_CI_CH_ACTIVE_EDGE_IS_RISING:
                /* Disable the failing trigger */
                Icu_Eint_DisableFailingTrig(pinMask);
                /* Enable the rising trigger  */
                Icu_Eint_EnableRisingTrig(pinMask);
                break;

            default:
                /* Enable both the failing and rising trigger */
                Icu_Eint_EnableRisingTrig(pinMask);
                Icu_Eint_EnableFailingTrig(pinMask);
                break;
        }

        /* Enable port interrupt-Connect the GPIO and the EINT */
        /*** @warning Icu_PortCi_c_MISRA_REF2 An expression of 'essentially unsigned' type (unsigned short) is being cast to enum type 'Mcu_Sysc_PinType'. */
        /*** @warning Icu_PortCi_c_MISRA_REF2 An expression of 'essentially unsigned' type (unsigned short) is being cast to enum type 'Mcu_Sysc_PortType'. */
        Mcu_Sysc_EintConfig((Mcu_Sysc_PinType)pinId, (Mcu_Sysc_PortType)portId);
        
        if(ICU_PORT_INTERRUPT_MODE == portPinMode)
        {
            /* Enable Line interrupt */
            Icu_Eint_EnableInt(pinMask);
        }
        else if(ICU_PORT_EVENT_MODE == portPinMode)
        {
            /* Enable Line event */
            Icu_Eint_EnableEvent(pinMask);
        }
        else
        {
            /* Do nothing */
        }

        /* Clear port channel flag */
        Icu_Eint_ClearIntFlag(pinMask);
        
    }
    SchM_Exit_Icu_ICU_CRITICAL_SECTION45();
}
#endif

#if (STD_ON == ICU_EINT_NOTIFICATION_SUPPORT)
/*!
* @brief          Get the initialization status of the Icu port_ci channel Low-level driver.
*
* @param[in]      ch      channel id
* @param[out]     None
* @param[in,out]  None
*/
LOCAL_INLINE FUNC(boolean, ICU_CODE) Icu_PortCi_GetChInit(CONST(Icu_Port_CiCHType, AUTOMATIC) ch)
{
    VAR(boolean, AUTOMATIC) result;
    CONST(uint16, ICU_CONST) portId = GET_PORT_CI_CH_PORT_ID(ch);    
    CONST(uint16, ICU_CONST) pinId  = GET_PORT_CI_CH_PIN_ID(ch);
    CONST(uint32, ICU_CONST) pinMask = (uint32)(BIT0 << pinId);

    if(pinMask == (s_icu_PortCi_ChInitState[portId] & pinMask))
    {
        result = (boolean)TRUE;
    }
    else
    {
        result = (boolean)FALSE;
    }

    return result;
}
#endif

/**************************************************************************
                    GLOBAL FUNCTION
**************************************************************************/
/*!
* @brief          Initialization function of the Icu port_ci Low-level driver.
*
* @param[in]      channelPORTCIIpConfigPtr    pointer to the port_ci channel configuration
* @param[out]     None
* @param[in,out]  None
*/
FUNC(void, ICU_CODE) Icu_PortCi_Init(P2CONST(Icu_Port_CiIPCfgType, AUTOMATIC, ICU_APPL_CONST) channelPORTCIIpConfigPtr)
{
    VAR(Icu_Port_CiCHType, AUTOMATIC) count = 0U;
    VAR(uint32, AUTOMATIC)   pinMask = 0U;
    VAR(uint16, AUTOMATIC)   portId = 0U;
    VAR(uint16, AUTOMATIC)   pinId = 0U;
    VAR(Icu_Port_CiCHType, AUTOMATIC)   channelId = 0U;
    P2CONST(Icu_Port_CiCHCfgType,AUTOMATIC,ICU_APPL_CONST) icuPortciCHCfgPtr = NULL_PTR;

    while(count < channelPORTCIIpConfigPtr->totalNumberChannel)
    {
        icuPortciCHCfgPtr = &(*channelPORTCIIpConfigPtr->icuChannelCfgPtr)[count];
        channelId = (Icu_Port_CiCHType)ICU_PORT_CI_CH_ID_BASE_PORT_CI(icuPortciCHCfgPtr->icuChannelId);
        portId = (uint16)(GET_PORT_CI_CH_PORT_ID(channelId));
        pinId  = (uint16)(GET_PORT_CI_CH_PIN_ID(channelId));
        pinMask = (uint32)(BIT0 << pinId);

        /* Disable port Interrupt */
        Icu_PortCi_DisableIntorEvt(channelId, icuPortciCHCfgPtr->icuPortPinMode);
    #if (STD_ON == ICU_PORT_FILTER_ENABLE)
        /* Enable interrupt filter */
        /*** @warning Icu_PortCi_c_MISRA_REF1 An expression of 'essentially unsigned' type (unsigned short) is being converted to enum type, 'Port_PortIdType' on assignment. */
        /*** @warning Icu_PortCi_c_MISRA_REF1 An expression of 'essentially unsigned' type (unsigned short) is being converted to enum type, 'Port_PortPinIdType' on assignment. */
        Port_Hw_ConfigFilter(portId, pinId, ENABLE);
    #endif
        /* Set channel active edge */
        Icu_PortCi_SetActivationCondition(channelId,
                                         (Icu_Port_CiActiveEdgeType)(icuPortciCHCfgPtr->icuDefaultActiveEdge), icuPortciCHCfgPtr->icuPortPinMode);
        /* Set channel initialization flag */
        s_icu_PortCi_ChInitState[portId] |= (uint32)(pinMask);

        count++;
    }
}

#if (STD_ON == ICU_DE_INIT_API_ENABLE)
/*!
* @brief          Deinitialization function of the Icu port_ci Low-level driver.
*
* @param[in]      channelPORTCIIpConfigPtr    pointer to the port_ci channel configuration
* @param[out]     None
* @param[in,out]  None
*/
FUNC (void, ICU_CODE) Icu_PortCi_DeInit
     (P2CONST(Icu_Port_CiIPCfgType, AUTOMATIC, ICU_APPL_CONST) channelPORTCIIpConfigPtr)
{
    /* Pointer to tmr channel pre-configuration */
    VAR(Icu_Port_CiCHType, AUTOMATIC) count = 0U;
    VAR(uint32, AUTOMATIC) pinMask;
    VAR(uint16, AUTOMATIC) portId;
    VAR(uint16, AUTOMATIC) pinId;
    VAR(Icu_Port_CiCHType, AUTOMATIC) channelId;
    P2CONST(Icu_Port_CiCHCfgType,AUTOMATIC,ICU_APPL_CONST) icuPortciCHCfgPtr;

    while(count < channelPORTCIIpConfigPtr->totalNumberChannel)
    {
        icuPortciCHCfgPtr = &(*channelPORTCIIpConfigPtr->icuChannelCfgPtr)[count];
        channelId = (Icu_Port_CiCHType)ICU_PORT_CI_CH_ID_BASE_PORT_CI(icuPortciCHCfgPtr->icuChannelId);
        portId = (uint16)(GET_PORT_CI_CH_PORT_ID(channelId));
        pinId  = (uint16)(GET_PORT_CI_CH_PIN_ID(channelId));
        pinMask = (uint32)(BIT0 << pinId);

        /* Disable port channel interrupt */
        Icu_PortCi_DisableIntorEvt(channelId, icuPortciCHCfgPtr->icuPortPinMode);
        /* Disable interrupt filter */
        REG_RMW32(ICU_GPIOX_FILTER_EN_ADDR(portId), pinMask, (uint32)0U);
        /* Reset channel initialization flag */
        s_icu_PortCi_ChInitState[portId] &= (uint32)(~pinMask);

    #if ((STD_ON == ICU_SET_MODE_API_ENABLE) || (STD_ON == ICU_EDGE_DETECT_API_ENABLE))
        /* Reset channel active edge */
        s_icu_PortCi_ChActiveEdge[channelId] = (uint8)ICU_PORT_CI_CH_ACTIVE_EDGE_IS_NONE;
    #endif

        count++;
    }
}
#endif

#if (STD_ON == ICU_SET_MODE_API_ENABLE)
/*!
* @brief         SetSleepMode function of the Icu port_ci Low-level driver.
*
* @param[in]     ch              channel id
* @param[in]     portPinMode      port mode
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_PortCi_SetSleepMode(VAR(Icu_Port_CiCHType, AUTOMATIC) ch, 
    VAR(Icu_PortPinModeType, AUTOMATIC) portPinMode)
{
    Icu_PortCi_DisableIntorEvt(ch, portPinMode);
}

/*!
* @brief         SetNormalMode function of the Icu port_ci Low-level driver.
*
* @param[in]     ch             channel id
* @param[in]     portPinMode    port mode
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_PortCi_SetNormalMode(VAR(Icu_Port_CiCHType, AUTOMATIC) ch, 
    VAR(Icu_PortPinModeType, AUTOMATIC) portPinMode)
{
    Icu_PortCi_EnableIntorEvt(ch, portPinMode);
}
#endif

/*!
* @brief         SetActivationCondition function of the Icu port_ci Low-level driver.
*
* @param[in]     ch             channel id
* @param[in]     aimEdge        aim edge
* @param[in]     portPinMode    port mode
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_PortCi_SetActivationCondition(VAR(Icu_Port_CiCHType, AUTOMATIC) ch,
    VAR(Icu_Port_CiActiveEdgeType, AUTOMATIC) aimEdge, VAR(Icu_PortPinModeType, AUTOMATIC) portPinMode)
{
    CONST(uint16, ICU_CONST) portId = GET_PORT_CI_CH_PORT_ID(ch);
    CONST(uint16, ICU_CONST) pinId  = GET_PORT_CI_CH_PIN_ID(ch);
    VAR(uint32, AUTOMATIC) pinMask = (uint32)(BIT0 << pinId);

    SchM_Enter_Icu_ICU_CRITICAL_SECTION42();
    {
        if(ICU_PORT_CI_ACTIVE_EDGE_IS_RISING == aimEdge)
        {
            /* Disable the failing trigger */
            Icu_Eint_DisableFailingTrig(pinMask);
            /* Enable the rising trigger  */
            Icu_Eint_EnableRisingTrig(pinMask);
            #if ((STD_ON == ICU_SET_MODE_API_ENABLE) || (STD_ON == ICU_EDGE_DETECT_API_ENABLE))
                s_icu_PortCi_ChActiveEdge[ch] = (uint8)ICU_PORT_CI_CH_ACTIVE_EDGE_IS_RISING;
            #endif
        }
        else if(ICU_PORT_CI_ACTIVE_EDGE_IS_FALLING == aimEdge)
        {
            /* Disable the rising trigger */
            Icu_Eint_DisableRisingTrig(pinMask);
            /* Enable the failing trigger  */
            Icu_Eint_EnableFailingTrig(pinMask);
            #if ((STD_ON == ICU_SET_MODE_API_ENABLE) || (STD_ON == ICU_EDGE_DETECT_API_ENABLE))
                s_icu_PortCi_ChActiveEdge[ch] = (uint8)ICU_PORT_CI_CH_ACTIVE_EDGE_IS_FALLING;
            #endif
        }
        else
        {
            /* Enable both the failing and rising trigger */
            Icu_Eint_EnableFailingTrig(pinMask);
            Icu_Eint_EnableRisingTrig(pinMask);
            #if ((STD_ON == ICU_SET_MODE_API_ENABLE) || (STD_ON == ICU_EDGE_DETECT_API_ENABLE))
                s_icu_PortCi_ChActiveEdge[ch] = (uint8)ICU_PORT_CI_CH_ACTIVE_EDGE_IS_BOTH;
            #endif
        }

        /* Enable port interrupt-Connect the GPIO and the EINT */
        /*** @warning Icu_PortCi_c_MISRA_REF2 An expression of 'essentially unsigned' type (unsigned short) is being cast to enum type 'Mcu_Sysc_PinType'. */
        /*** @warning Icu_PortCi_c_MISRA_REF2 An expression of 'essentially unsigned' type (unsigned short) is being cast to enum type 'Mcu_Sysc_PortType'. */
        Mcu_Sysc_EintConfig((Mcu_Sysc_PinType)pinId, (Mcu_Sysc_PortType)portId);
        
        if(ICU_PORT_INTERRUPT_MODE == portPinMode)
        {
            /* Enable line interrupt */
            Icu_Eint_EnableInt(pinMask);
        }
        else if(ICU_PORT_EVENT_MODE == portPinMode)
        {
            /* Enable line event */
            Icu_Eint_EnableEvent(pinMask);
        }
        else
        {
            /* do nothing */
        }

        /* Clear port channel flag */
        Icu_Eint_ClearIntFlag(pinMask);
    }
    SchM_Exit_Icu_ICU_CRITICAL_SECTION42();
}

#if (STD_ON == ICU_GET_INPUT_STATE_API_ENABLE)
/*!
* @brief         GetInputState function of the Icu port_ci Low-level driver.
*
* @param[in]     ch          channel id
* @param[out]    None
* @param[in,out] None
*
* @retval        FALSE / TRUE
*/
FUNC (boolean, ICU_CODE) Icu_PortCi_GetInputState(VAR(Icu_Port_CiCHType, AUTOMATIC) ch)
{
    VAR(boolean,  AUTOMATIC) result = (boolean)FALSE;
    CONST(uint16, ICU_CONST) pinId  = GET_PORT_CI_CH_PIN_ID(ch);
    CONST(uint32, ICU_CONST) pinMask = (uint32)(BIT0 << pinId);

    /* Get the pin interrupt enable status */
    CONST(uint32, ICU_CONST) interFlagState = (uint32)Icu_Eint_GetIntEnSts(pinMask);
    /* Get the pin interrupt status flag */
    CONST(uint32, ICU_CONST) pinState = (uint32)Icu_Eint_ReadStatusFlag(pinMask);

    /* if interrupt event occur, but interrupt is disable */
    if(0x0U ==  pinState)
    {
        /* nothing to do */
    }
    else if(0x0U != interFlagState)
    {
        /* nothing to do */
    }
    else
    {
        /* Clear interrupt status flag */
        Icu_Eint_ClearStatusFlag(pinMask);
        result = (boolean)TRUE;
    }

    return result;
}
#endif

#if (STD_ON == ICU_EDGE_DETECT_API_ENABLE)
/*!
* @brief         EnableEdgeDetection function of the Icu port_ci Low-level driver.
*
* @param[in]     ch             channel id
* @param[in]     portPinMode    port mode
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_PortCi_EnableEdgeDetection(VAR(Icu_Port_CiCHType, AUTOMATIC) ch, 
    VAR(Icu_PortPinModeType, AUTOMATIC) portPinMode)
{
    Icu_PortCi_EnableIntorEvt(ch, portPinMode);
}

/*!
* @brief         DisableEdgeDetection function of the Icu port_ci Low-level driver.
*
* @param[in]     ch        channel id
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_PortCi_DisableEdgeDetection(VAR(Icu_Port_CiCHType, AUTOMATIC) ch, 
    VAR(Icu_PortPinModeType, AUTOMATIC) portPinMode)
{
    Icu_PortCi_DisableIntorEvt(ch, portPinMode);
}
#endif

#if (STD_ON == ICU_EINT_NOTIFICATION_SUPPORT)
/*!
* @brief         ProcessInterrupt function of the Icu port_ci Low-level driver.
*
* @param[in]     pinMask     port pin mask
* @param[out]    None
* @param[in,out] None
*/
FUNC(void, ICU_CODE) Icu_PortCi_ProcessInterrupt(CONST(Icu_EintChType, AUTOMATIC) pinMask)
{
    VAR(Icu_Port_CiCHType, AUTOMATIC) count = 0U;
    VAR(uint16, AUTOMATIC) pinHwId = 0U;
    VAR(boolean, AUTOMATIC)  initResult = (boolean)FALSE;
    P2CONST(Icu_Port_CiIPCfgType, AUTOMATIC, ICU_APPL_CONST) channelPORTCIIpConfigPtr = 
    g_icuCfgPtr->moduleAchieveWayCfg.channelPORT_CIIpConfigPtr;
    
    while(count < channelPORTCIIpConfigPtr->totalNumberChannel)
    {
        /* Only one port pin configured for one Eint chnnel, and the same pin id of the other port 
         * cannot be configured for the Eint channel.
         */
        /*** @warning Icu_PortCi_c_MISRA_REF3 Macro argument expression may require parentheses. */
        if((((uint32)1U << GET_PORT_CI_CH_PIN_ID((*(channelPORTCIIpConfigPtr->icuChannelCfgPtr))[count].icuChannelId))) == (uint32)pinMask)
        {
            pinHwId = (*(channelPORTCIIpConfigPtr->icuChannelCfgPtr))[count].icuChannelId;
            break;
        }
        else
        {
            /* nothing to do */
        }
        count++;
    }

    initResult = Icu_PortCi_GetChInit((Icu_Port_CiCHType)pinHwId);

    if((boolean)TRUE == initResult)
    {
        Icu_Ipw_ReportEvents(((Icu_Port_CiCHType)pinHwId), (boolean)FALSE);
    }
    else
    {
        /* nothing to do */
    }
}
#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 */

