/*!
* @file     Ocu_Tmr.c
*
* @version  1.0.0
*
* @brief    The TMR driver source file of Ocu moudle.
*           This file includes TMR driver functions implement of Ocu moudle.
* @attention
*
* Project Name      : AUTOSAR MCAL
*
* Platform          : Arm
*
* Autosar Standard  : Classic Platform 4.4.0
*
* Compiled Version  : G32A10xx_MCAL_1_0_0_15-Nov-2
*
* 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.
*/

#ifdef __cplusplus
extern "C"{
#endif  /* ifdef __cplusplus */

#include "Std_Types.h"
#include "Ocu_Tmr.h"
#include "SchM_Ocu.h"
#include "Pdl_TmrReg.h"
#include  "Ocu.h"

#include "StdRegMacros.h"
/** @addtogroup G32A10xx_StdPeriphDriver
  @{
*/

/** @defgroup OCU_Driver
  * @brief OCU driver modules
  @{
*/

/** @defgroup OCU_Macros
  @{
*/
/***********************************************************************************************************************
                                    VENDOR ID & AUTOSAR VERSION INFO
***********************************************************************************************************************/
/** Vendor ID (vendorId) of the dedicated implementation of this module according to the AUTOSAR vendor list. */
#define OCU_TMR_VENDOR_ID                                 0x00C1U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define OCU_TMR_AR_RELEASE_MAJOR_VERSION                  0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define OCU_TMR_AR_RELEASE_MINOR_VERSION                  0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define OCU_TMR_AR_RELEASE_REVISION_VERSION               0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define OCU_TMR_SW_MAJOR_VERSION                          0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define OCU_TMR_SW_MINOR_VERSION                          0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define OCU_TMR_SW_PATCH_VERSION                          0x00U
/**@} end of group OCU_Macros */
/***********************************************************************************************************
                                  VERSION INFOMATION VERIFICATION
*************************************************************************************************************/
#ifdef ENABLE_INTERMODULE_MCAL_CHECK
 /* Make sure the AUTOSAR major version number is the same between Ocu_Tmr.c and Std_Types.h */
 #if (OCU_TMR_AR_RELEASE_MAJOR_VERSION != STD_TYPES_H_AR_RELEASE_MAJOR_VERSION)
     #error "AUTOSAR Major Version Number mismatch between Ocu_Tmr.c and Std_Types.h"
 #endif
 /* Make sure the AUTOSAR minor version number is the same between Ocu_Tmr.c and Std_Types.h */
 #if (OCU_TMR_AR_RELEASE_MINOR_VERSION != STD_TYPES_H_AR_RELEASE_MINOR_VERSION)
     #error "AUTOSAR Minor Version Number mismatch between Ocu_Tmr.c and Std_Types.h"
 #endif

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

 /* Make sure the AUTOSAR major version number is the same between Ocu_Tmr.c and SchM_Ocu.h */
 #if (OCU_TMR_AR_RELEASE_MAJOR_VERSION != SCHM_OCU_H_AR_RELEASE_MAJOR_VERSION)
     #error "AUTOSAR Major Version Number mismatch between Ocu_Tmr.c and SchM_Ocu.h"
 #endif
 /* Make sure the AUTOSAR minor version number is the same between Ocu_Tmr.c and SchM_Ocu.h */
 #if (OCU_TMR_AR_RELEASE_MINOR_VERSION != SCHM_OCU_H_AR_RELEASE_MINOR_VERSION)
     #error "AUTOSAR Minor Version Number mismatch between Ocu_Tmr.c and SchM_Ocu.h"
 #endif
#endif

/* Make sure the vendor ids are the same between Ocu_Tmr.c and Ocu_Tmr.h */
#if (OCU_TMR_VENDOR_ID != OCU_TMR_H_VENDOR_ID)
 #error "Vendor ids mismatch between Ocu_Tmr.c and Ocu_Tmr.h"
#endif  /* {if (OCU_TMR_VENDOR_ID != OCU_TMR_H_VENDOR_ID)} */

/* Make sure the AUTOSAR major version number is the same between Ocu_Tmr.c and Ocu_Tmr.h */
#if (OCU_TMR_AR_RELEASE_MAJOR_VERSION != OCU_TMR_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Ocu_Tmr.c and Ocu_Tmr.h"
#endif
/* Make sure the AUTOSAR minor version number is the same between Ocu_Tmr.c and Ocu_Tmr.h */
#if (OCU_TMR_AR_RELEASE_MINOR_VERSION != OCU_TMR_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Ocu_Tmr.c and Ocu_Tmr.h"
#endif
/* Make sure the AUTOSAR revision version number is the same between Ocu_Tmr.c and Ocu_Tmr.h */
#if (OCU_TMR_AR_RELEASE_REVISION_VERSION != OCU_TMR_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Ocu_Tmr.c and Ocu_Tmr.h"
#endif

/* Make sure the software major version number is the same between Ocu_Tmr.c and Ocu_Tmr.h */
#if (OCU_TMR_SW_MAJOR_VERSION != OCU_TMR_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Ocu_Tmr.c and Ocu_Tmr.h"
#endif
/* Make sure the software minor version number is the same between Ocu_Tmr.c and Ocu_Tmr.h */
#if (OCU_TMR_SW_MINOR_VERSION != OCU_TMR_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Ocu_Tmr.c and Ocu_Tmr.h"
#endif
/* Make sure the software patch version number is the same between Ocu_Tmr.c and Ocu_Tmr.h */
#if (OCU_TMR_SW_PATCH_VERSION != OCU_TMR_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Ocu_Tmr.c and Ocu_Tmr.h"
#endif

/* Make sure the vendor ids are the same between Ocu_Tmr.c and Ocu.h */
#if (OCU_TMR_VENDOR_ID != OCU_H_VENDOR_ID)
 #error "Vendor ids mismatch between Ocu_Tmr.c and Ocu.h"
#endif  /* {if (OCU_TMR_VENDOR_ID != OCU_H_VENDOR_ID)} */

/* Make sure the AUTOSAR major version number is the same between Ocu_Tmr.c and Ocu.h */
#if (OCU_TMR_AR_RELEASE_MAJOR_VERSION != OCU_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Ocu_Tmr.c and Ocu.h"
#endif
/* Make sure the AUTOSAR minor version number is the same between Ocu_Tmr.c and Ocu.h */
#if (OCU_TMR_AR_RELEASE_MINOR_VERSION != OCU_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Ocu_Tmr.c and Ocu.h"
#endif
/* Make sure the AUTOSAR revision version number is the same between Ocu_Tmr.c and Ocu.h */
#if (OCU_TMR_AR_RELEASE_REVISION_VERSION != OCU_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Ocu_Tmr.c and Ocu.h"
#endif

/* Make sure the software major version number is the same between Ocu_Tmr.c and Ocu.h */
#if (OCU_TMR_SW_MAJOR_VERSION != OCU_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Ocu_Tmr.c and Ocu.h"
#endif
/* Make sure the software minor version number is the same between Ocu_Tmr.c and Ocu.h */
#if (OCU_TMR_SW_MINOR_VERSION != OCU_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Ocu_Tmr.c and Ocu.h"
#endif
/* Make sure the software patch version number is the same between Ocu_Tmr.c and Ocu.h */
#if (OCU_TMR_SW_PATCH_VERSION != OCU_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Ocu_Tmr.c and Ocu.h"
#endif

/**********************************************************************************************************************
                                             GLOBAL VARIABLE
***********************************************************************************************************************/
/** @defgroup OCU_Variable
  @{
*/
#define OCU_START_SEC_VAR_NO_INIT_16
#include "Ocu_MemMap.h"

#if ((STD_ON == OCU_SET_RELATIVE_THRESHOLD_API) || (STD_ON == OCU_SET_ABSOLUTE_THRESHOLD_API))
/** The arrays  of the Tmr channel max counter value */
static  VAR(uint16, OCU_VAR) g_ocuTmrMaxCntVal[OCU_TMR_HW_CH_MAX_COUNT];
#endif 

#define OCU_STOP_SEC_VAR_NO_INIT_16
#include "Ocu_MemMap.h"

#define OCU_START_SEC_VAR_NO_INIT_8
#include "Ocu_MemMap.h"
/** The arrays of the Ocu channels actions */
static  VAR(uint8, OCU_VAR) g_ocuTmrChActArr[OCU_TMR_HW_CH_MAX_COUNT];

#define OCU_STOP_SEC_VAR_NO_INIT_8
#include "Ocu_MemMap.h"
/**@} end of group OCU_Variable */
/**********************************************************************************************************************
                                                  LOCAL FUNCTION
***********************************************************************************************************************/
/** @defgroup OCU_Fuctions
  @{
*/
#define OCU_START_SEC_CODE
#include "Ocu_MemMap.h"

/*!
 * @brief         The function is to get the Tmr module id and channel id.
 *
 * @param[in]     ChannelIndex        The Ocu channel id
 * @param[in]     OcuTmrIpConfigPtr   The pointer of the Ocu Tmr configuration parameters
 * @param[in]     ModIdPtr             The Tmr module id
 * @param[in]     ChIdPtr              The Tmr channel id
 * @param[in]     ChannelIndex        The Ocu channel id
 *
 * @retval        void
 */
static FUNC(void, OCU_CODE) Ocu_Tmr_GetIds(CONSTP2CONST(Ocu_TmrHwConfigType, OCU_CONST, OCU_APPL_CONST) OcuTmrIpConfigPtr, 
    P2VAR(uint8, AUTOMATIC, OCU_APPL_DATA) ModIdPtr, P2VAR(uint8, AUTOMATIC, OCU_APPL_DATA) ChIdPtr, CONST(uint8, AUTOMATIC) ChannelIndex)
{
    VAR(uint8, AUTOMATIC) ocuTmrHwChannelId = 0;
    P2CONST(Ocu_TmrChConfigType,   AUTOMATIC, OCU_APPL_CONST) ocuTmrChannelConfigPtr = NULL_PTR;
  
   if((NULL_PTR != OcuTmrIpConfigPtr) && (NULL_PTR != ModIdPtr) && (NULL_PTR != ChIdPtr))
   {
       ocuTmrChannelConfigPtr = &((*(OcuTmrIpConfigPtr->ocuTmrChConfigPtr))[ChannelIndex]);
       ocuTmrHwChannelId = ocuTmrChannelConfigPtr->ocuTmrHwChannelId;

       /* Get the Tmr module id and channel id of the current Ocu channel */
       *ModIdPtr = ((Ocu_TmrHwModType)((ocuTmrHwChannelId & TMR_MODULE_MASK_BITS) >> TMR_MODULE_SHIFT_VAL));
       *ChIdPtr = (ocuTmrHwChannelId & TMR_CHANNEL_MASK_BITS);
   }
   else
   {
       /* do nothing */
   }
}

/*!
 * @brief         The function is to start the Tmr channel of the Ocu driver(operation registers).
 *
 * @param[in]     ChannelIndex            The Ocu channel index
 * @param[in]     OcuTmrChId             The Tmr channel id
 * @param[in]     OcuTmrModId            The Tmr module id
 *
 * @retval        None
 */
static FUNC(void, OCU_CODE) Ocu_Tmr_StartChReg(CONST(uint8, AUTOMATIC) ChannelIndex,\
    CONST(uint8, AUTOMATIC) OcuTmrChId, CONST(uint8, AUTOMATIC) OcuTmrModId)
{
    VAR(uint32, AUTOMATIC) address = TMR_CCM1_REG_ADDR((uint32)OcuTmrModId) + (((uint32)OcuTmrChId >> 1u) << 2u);
    VAR(uint32, AUTOMATIC) mask = TMR_CCM1_OC1MOD_MASK << (8u * (OcuTmrChId % 2u));
    VAR(uint32, AUTOMATIC) value = 0;
    
    SchM_Enter_Ocu_OCU_CRITICAL_SECTION8();

    switch(g_ocuTmrChActArr[ChannelIndex])
    {
        case (uint8)OCU_DISABLE:
            value = (uint32)OCU_DISABLE << (TMR_CCM1_OC1MOD_SHIFT + (8u * (OcuTmrChId % 2u)));
            break;
        case (uint8)OCU_SET_HIGH:
            value = (uint32)OCU_SET_HIGH << (TMR_CCM1_OC1MOD_SHIFT + (8u * (OcuTmrChId % 2u)));
            break;
        case (uint8)OCU_SET_LOW:
            value = (uint32)OCU_SET_LOW << (TMR_CCM1_OC1MOD_SHIFT + (8u * (OcuTmrChId % 2u)));
            break;
        case (uint8)OCU_TOGGLE:
            value = (uint32)OCU_TOGGLE << (TMR_CCM1_OC1MOD_SHIFT + (8u * (OcuTmrChId % 2u)));
            break;
        case (uint8)OCU_FORCE_LOW:
            value = (uint32)OCU_FORCE_LOW << (TMR_CCM1_OC1MOD_SHIFT + (8u * (OcuTmrChId % 2u)));
            break;
        case (uint8)OCU_FORCE_HIGH:
            value = (uint32)OCU_FORCE_HIGH << (TMR_CCM1_OC1MOD_SHIFT + (8u * (OcuTmrChId % 2u)));
            break;
        case (uint8)OCU_PWM1:
            value = (uint32)OCU_PWM1 << (TMR_CCM1_OC1MOD_SHIFT + (8u * (OcuTmrChId % 2u)));
            break;
        case (uint8)OCU_PWM2:
            value = (uint32)OCU_PWM2 << (TMR_CCM1_OC1MOD_SHIFT + (8u * (OcuTmrChId % 2u)));
            break;
        default:
            /* nothing */
            break;
    }
    REG_RMW32(address, mask, value);
    REG_BIT_SET32(TMR_CCEN_REG_ADDR(OcuTmrModId),(uint32)(((uint32)1U) << ((uint8)((uint8)OcuTmrChId) << 2)));
    REG_BIT_SET32(TMR_CTRL1_REG_ADDR(OcuTmrModId), 1u << TMR_CTRL1_CNTEN_SHIFT);
    REG_BIT_SET32(TMR_DIEN_REG_ADDR(OcuTmrModId), TMR_DIEN_UIEN_MASK | ((uint32)2u << (uint32)OcuTmrChId));
    SchM_Exit_Ocu_OCU_CRITICAL_SECTION8();
}

#if ((STD_ON == OCU_SET_ABSOLUTE_THRESHOLD_API) || (STD_ON == OCU_SET_RELATIVE_THRESHOLD_API))
/*!
 * @brief         The function is to determine the compare match event status after the new shreshold value setted.
 *
 * @param[in]     CurrCntVal          The current counter value after the shreshold value setted
 * @param[in]     InterOriginCntVal    The start counter value of the interval
 * @param[in]     InterTerminateCntVal      The end counter value of the interval
 *
 * @retval        OCU_CM_IN_REF_INTERVAL: The compare match event will occur inside the current reference interval.
 *                OCU_CM_OUT_REF_INTERVAL: The compare match event will not occur inside the current reference interval.
 */
static FUNC(Ocu_ReturnType, OCU_CODE) Ocu_Tmr_MatchEventState(VAR(Ocu_ValueType, AUTOMATIC) CurrCntVal,\
   VAR(Ocu_ValueType, AUTOMATIC) InterOriginCntVal, VAR(Ocu_ValueType, AUTOMATIC) InterTerminateCntVal)
{
    VAR(Ocu_ReturnType, AUTOMATIC) matchEventState = OCU_CM_OUT_REF_INTERVAL;

    if (InterOriginCntVal > InterTerminateCntVal)
    {        
        matchEventState = ((CurrCntVal < InterOriginCntVal) && (CurrCntVal > InterTerminateCntVal)) ? OCU_CM_OUT_REF_INTERVAL : OCU_CM_IN_REF_INTERVAL;
    
    }else
    {       
       matchEventState = ((InterOriginCntVal <= CurrCntVal) && (CurrCntVal <= InterTerminateCntVal)) ? OCU_CM_IN_REF_INTERVAL : OCU_CM_OUT_REF_INTERVAL;
    }

    return matchEventState;      
}
#endif 
#if (STD_ON == OCU_DEINIT_API_ENABLE)
/*!
 * @brief         The function is to deinitialize the registers and variables of the Ocu Tmr driver.
 *
 * @param[in]     OcuTmrIpConfigPtr     The configuration parameters pointer of the Ocu Tmr driver.
 *
 * @retval        void
 */
static FUNC(void, OCU_CODE) Ocu_Tmr_HwChDeInit(CONSTP2CONST(Ocu_TmrHwConfigType, AUTOMATIC, OCU_APPL_CONST) OcuTmrIpConfigPtr)
{
    P2CONST(Ocu_TmrChConfigType, AUTOMATIC, OCU_APPL_CONST) ocuTmrChannelConfigPtr = NULL_PTR; 
    VAR(Ocu_TmrHwModType, AUTOMATIC) ocuTmrModuleId = 0U;
    VAR(Ocu_TmrHwChType, AUTOMATIC) ocuTmrCurChannel = 0U;
    VAR(Ocu_TmrHwChType, AUTOMATIC) ocuTmrHwChannel = 0U;

    while(ocuTmrCurChannel < OcuTmrIpConfigPtr->ocuTmrChCount)
    {
        g_ocuTmrChActArr[ocuTmrCurChannel]=0U;
    #if ((STD_ON == OCU_SET_RELATIVE_THRESHOLD_API) || (STD_ON == OCU_SET_ABSOLUTE_THRESHOLD_API))
        g_ocuTmrMaxCntVal[ocuTmrCurChannel]=0U;
    #endif 

        ocuTmrChannelConfigPtr = &(*OcuTmrIpConfigPtr->ocuTmrChConfigPtr)[ocuTmrCurChannel];    
        /* Get current Ocu Tmr hw channel Id */
        ocuTmrHwChannel = ((ocuTmrChannelConfigPtr->ocuTmrHwChannelId) & TMR_CHANNEL_MASK_BITS);    
        /* Get current Ocu Tmr hw module Id*/
        ocuTmrModuleId = (((ocuTmrChannelConfigPtr->ocuTmrHwChannelId) & TMR_MODULE_MASK_BITS) >> TMR_MODULE_SHIFT_VAL);
        /* Reset the TMRx_CCx register and TMR_CHnV registers */
        REG_WRITE32(TMR_CC1_REG_ADDR(ocuTmrModuleId) + ((uint32)ocuTmrHwChannel << 2U), 0U);
        /* Reset the TMRx_CCEN register of the given channel */
        REG_BIT_CLEAR32(TMR_CCEN_REG_ADDR(ocuTmrModuleId),(uint32)(((uint32)1U) << ((uint8)((uint8)ocuTmrHwChannel) << 2)));

        ocuTmrCurChannel++;  
    }
    REG_WRITE32(TMR_AUTORLD_REG_ADDR(ocuTmrModuleId), 0xFFFFu);
    REG_WRITE32(TMR_PSC_REG_ADDR(ocuTmrModuleId), 0);
    REG_BIT_CLEAR32(TMR_BDT_REG_ADDR(ocuTmrModuleId), (uint32)1u << TMR_BDT_MOEN_SHIFT);
}

/*!
 * @brief         The function is to deinitialize the registers and variables of the Ocu Tmr driver.
 *
 * @param[in]     OcuTmrIpConfigPtr     The configuration parameters pointer of the Ocu Tmr driver.
 *
 * @retval        void
 */
static FUNC(void, OCU_CODE) Ocu_Tmr_HwModDeInit(CONSTP2CONST(Ocu_TmrHwConfigType, AUTOMATIC, OCU_APPL_CONST) OcuTmrIpConfigPtr)
{
    P2CONST(Ocu_TmrModConfigType, AUTOMATIC, OCU_APPL_CONST) ocuTmrModuleConfigPtr = NULL_PTR;
    VAR(Ocu_TmrHwModType, AUTOMATIC) ocuTmrModuleId = (uint8)0U;
    VAR(Ocu_TmrHwModType, AUTOMATIC) ocuTmrHwModuleId;

    while(ocuTmrModuleId < (OcuTmrIpConfigPtr->ocuTmrModCount))
    {
        ocuTmrModuleConfigPtr = &(*OcuTmrIpConfigPtr->ocuTmrModConfigPtr)[ocuTmrModuleId];
        ocuTmrHwModuleId = ocuTmrModuleConfigPtr->ocuTmrModuleId;
        /* Reset the CTRL1 register */
        REG_WRITE32(TMR_CTRL1_REG_ADDR(ocuTmrHwModuleId), 0U);
        /* Reset the CTRL2 register */
        REG_WRITE32(TMR_CTRL2_REG_ADDR(ocuTmrHwModuleId), 0U);
        /* Reset the SMCTRL register */
        REG_WRITE32(TMR_SMCTRL_REG_ADDR(ocuTmrHwModuleId), 0);

        ocuTmrModuleId++;
    }    
}
#endif  /* {if (STD_ON == OCU_DEINIT_API_ENABLE)} */

#if (STD_ON == OCU_SET_ABSOLUTE_THRESHOLD_API)
/*!
 * @brief         The function is to set the value of the channel threshold with an absolute input data(operate the register).
 *
 * @param[in]     OcuTmrChannel           The Tmr channel index
 * @param[in]     OcuTmrMod               The Tmr module  index
 * @param[in]     ReferenceCompareValue    The reference compare value
 * @param[in]     AbsoluteCompareValue     The absolute compare value
 * 
 *
 * @retval        OCU_CM_OUT_REF_INTERVAL: The compare match event will not occur inside the current
 *                reference interval.
 *                OCU_CM_IN_REF_INTERVAL: The compare match event will occur inside the current reference interval.
 */
static FUNC(Ocu_ReturnType, OCU_CODE) Ocu_Tmr_SetAbsThrReg(CONST(uint8, AUTOMATIC) OcuTmrChannel, CONST(uint8, AUTOMATIC) OcuTmrMod,\
    VAR(Ocu_ValueType, AUTOMATIC) ReferenceCompareValue, VAR(Ocu_ValueType, AUTOMATIC) AbsoluteCompareValue)
{
    VAR(Ocu_ReturnType, AUTOMATIC) ocuMatchEventState = OCU_CM_IN_REF_INTERVAL;
    VAR(uint16, AUTOMATIC) ocuTmrCurrentCnt = 0U;

    SchM_Enter_Ocu_OCU_CRITICAL_SECTION13();
    
    /* Set the compare value to TMR_CHnV register */
    REG_WRITE32(TMR_CC1_REG_ADDR(OcuTmrMod) + ((uint32)OcuTmrChannel << 2U), AbsoluteCompareValue);
    
    /* Get the Counter current value */
    ocuTmrCurrentCnt = (uint16)REG_READ32(TMR_CNT_REG_ADDR(OcuTmrMod));

    SchM_Exit_Ocu_OCU_CRITICAL_SECTION13();
    
    ocuMatchEventState = Ocu_Tmr_MatchEventState(ocuTmrCurrentCnt, ReferenceCompareValue, AbsoluteCompareValue);
    
    return ocuMatchEventState;   
}
#endif  /* {if (STD_ON == OCU_SET_ABSOLUTE_THRESHOLD_API)} */

/*!
 * @brief         The function is to stop the Tmr channel of the Ocu driver(operate the register).
 *
 * @param[in]     ChannelIndex          The index of the Tmr channels in configuration array.
 * @param[in]     ModIndex              The index of the Tmr module in configuration array.
 * 
 * @retval        void
 */
static FUNC(void, OCU_CODE) Ocu_Tmr_StopChReg(CONST(uint8, AUTOMATIC) ChannelIndex, CONST(uint8, AUTOMATIC) ModIndex)
{
    SchM_Enter_Ocu_OCU_CRITICAL_SECTION9();

    REG_RMW32(TMR_CCM1_REG_ADDR(ModIndex) + (((uint32)ChannelIndex >> 1u) << 2u), (uint32)TMR_CCM1_OC1MOD_MASK << (8u * ((uint32)ChannelIndex % 2u)), (uint32)OCU_DISABLE << (TMR_CCM1_OC1MOD_SHIFT + (8u * ((uint32)ChannelIndex % 2u))));
    REG_BIT_CLEAR32(TMR_CCEN_REG_ADDR(ModIndex),(uint32)(((uint32)1U) << ((uint8)((uint8)ChannelIndex) << 2)));
    REG_BIT_CLEAR32(TMR_DIEN_REG_ADDR(ModIndex), TMR_DIEN_UIEN_MASK | (TMR_DIEN_CC1IEN_MASK << ChannelIndex)); 

    SchM_Exit_Ocu_OCU_CRITICAL_SECTION9();
}


#if (STD_ON == OCU_SET_PIN_STATE_API)

/*!
 * @brief         The function is to set the Tmr channel of the Ocu driver(operate the register).
 *
 * @param[in]     ChannelIndex          The index of the Tmr channels in configuration array.
 * @param[in]     ModIndex              The index of the Tmr module in configuration array.
 * @param[in]     OcuPinStateType        The pin state.
 * 
 * @retval        void
 */
static FUNC(void, OCU_CODE) Ocu_Tmr_SetPinStsReg(CONST(uint8, AUTOMATIC) ChannelIndex, CONST(uint8, AUTOMATIC) ModIndex)
{
    VAR(uint32, AUTOMATIC) regSwoctrlVal;
  
    /* Get the current value of the TMRx_CCEN register */
    regSwoctrlVal = REG_READ32(TMR_CCEN_REG_ADDR(ModIndex));

    /* Refresh the value of the TMRx_CCEN register to enable Output of the current channel */  
    regSwoctrlVal |=  (uint32)(((uint32)1U)<<((ChannelIndex << 2)));
    
    SchM_Enter_Ocu_OCU_CRITICAL_SECTION11();
   
    REG_WRITE32(TMR_CCEN_REG_ADDR(ModIndex),regSwoctrlVal);

    SchM_Exit_Ocu_OCU_CRITICAL_SECTION11();
}
#endif /* {if (STD_ON == OCU_SET_PIN_STATE_API)} */

#if (STD_ON == OCU_SET_RELATIVE_THRESHOLD_API)
/*!
 * @brief         The function is to set the value of the channel relative threshold with an input data(operation registers).
 *
 * @param[in]     OcuChId                 The Ocu channel index
 * @param[in]     RelativeCompareValue    The relative compare value
 * @param[in]     OcuTmrChId             The Tmr channel id
 * @param[in]     OcuTmrModId            The Tmr module id
 *
 * @retval        OCU_CM_OUT_REF_INTERVAL: The compare match event will not occur inside the current
 *                reference interval.
 *                OCU_CM_IN_REF_INTERVAL: The compare match event will occur inside the current reference interval.
 */
static FUNC(Ocu_ReturnType, OCU_CODE) Ocu_Tmr_SetRelThrReg(CONST(uint8, AUTOMATIC) OcuChId, VAR(Ocu_ValueType, AUTOMATIC) RelativeCompareValue, \
    CONST(uint8, AUTOMATIC) OcuTmrChId, CONST(uint8, AUTOMATIC) OcuTmrModId)
{
    VAR(uint16, AUTOMATIC) ocuTmrCntIntervalStart = 0;
    VAR(uint16, AUTOMATIC) ocuTmrCurrentCnt = 0;
    VAR(Ocu_ReturnType, AUTOMATIC) ocuMatchEventState = OCU_CM_IN_REF_INTERVAL; 
    VAR(uint16, AUTOMATIC) ocuMatchValIntervalEnd = 0;

    SchM_Enter_Ocu_OCU_CRITICAL_SECTION12();
    
    /* Get the value of the counter register */
    ocuTmrCntIntervalStart = (uint16)REG_READ32(TMR_CNT_REG_ADDR(OcuTmrModId));
    /* Calculate the ocuMatchValIntervalEnd value, matching event can occur at current cycle or next cycle */
    ocuMatchValIntervalEnd = (uint16)(((uint32)ocuTmrCntIntervalStart + (uint32)RelativeCompareValue) % g_ocuTmrMaxCntVal[OcuChId]);
    /* Set the compare value to TMR_CHnV register*/
    REG_WRITE32(TMR_CC1_REG_ADDR(OcuTmrModId) + ((uint32)OcuTmrChId << 2u), ocuMatchValIntervalEnd);
    /* Get the value of the counter register again */
    ocuTmrCurrentCnt = (uint16)REG_READ32(TMR_CNT_REG_ADDR(OcuTmrModId));

    SchM_Exit_Ocu_OCU_CRITICAL_SECTION12();
    
    /* Verify if compare match event will happen before counter roll-over */
    ocuMatchEventState = Ocu_Tmr_MatchEventState(ocuTmrCurrentCnt, ocuTmrCntIntervalStart, ocuMatchValIntervalEnd);
    
    return ocuMatchEventState;
}
#endif /* {if (STD_ON == OCU_SET_RELATIVE_THRESHOLD_API)} */


#if (STD_ON == OCU_SET_PIN_ACTION_API)

/*!
 * @brief         The function is to set the value of the channel relative threshold with an input data(operation registers).
 *
 * @param[in]     OcuChId                 The Ocu channel index
 * @param[in]     OcuPinActionType        The output pin action linked to the Ocu channel
 * @param[in]     OcuTmrChId             The Tmr channel id
 * @param[in]     OcuTmrModId            The Tmr module id
 * @param[in]     ChannelIsRunning        The flag of the channel running state
 *
 * @retval        OCU_CM_OUT_REF_INTERVAL: The compare match event will not occur inside the current
 *                reference interval.
 *                OCU_CM_IN_REF_INTERVAL: The compare match event will occur inside the current reference interval.
 */
static FUNC(void, OCU_CODE) Ocu_Tmr_SetPinActReg(CONST(uint8, AUTOMATIC) OcuChId, VAR(Ocu_PinActionType, AUTOMATIC) OcuPinActionType, \
    CONST(uint8, AUTOMATIC) OcuTmrChId, CONST(uint8, AUTOMATIC) OcuTmrModId, VAR(boolean, AUTOMATIC) ChannelIsRunning)
{
    VAR(uint32, AUTOMATIC) address = TMR_CCM1_REG_ADDR(OcuTmrModId) + (((uint32)OcuTmrChId >> 1u) << 2u);
    VAR(uint32, AUTOMATIC) mask = TMR_CCM1_OC1MOD_MASK << (8u * ((uint32)OcuTmrChId % 2u));
    VAR(uint32, AUTOMATIC) value = 0;
    SchM_Enter_Ocu_OCU_CRITICAL_SECTION10();

    if ((boolean)TRUE == ChannelIsRunning)
    {
        switch(OcuPinActionType)
        {
            case OCU_DISABLE:
                value = (uint32)OCU_DISABLE << (uint32)(TMR_CCM1_OC1MOD_SHIFT + (8u * ((uint32)OcuTmrChId % 2u)));
                g_ocuTmrChActArr[OcuChId] = (uint8)OCU_DISABLE;
                break;
            case OCU_SET_HIGH:
                value = (uint32)OCU_SET_HIGH << (uint32)(TMR_CCM1_OC1MOD_SHIFT + (8u * ((uint32)OcuTmrChId % 2u)));
                g_ocuTmrChActArr[OcuChId] = (uint8)OCU_SET_HIGH;
                break;
            case OCU_SET_LOW:
                value = (uint32)OCU_SET_LOW << (uint32)(TMR_CCM1_OC1MOD_SHIFT + (8u * ((uint32)OcuTmrChId % 2u)));
                g_ocuTmrChActArr[OcuChId] = (uint8)OCU_SET_LOW;
                break;
            case OCU_TOGGLE:
                value = (uint32)OCU_TOGGLE << (uint32)(TMR_CCM1_OC1MOD_SHIFT + (8u * ((uint32)OcuTmrChId % 2u)));
                g_ocuTmrChActArr[OcuChId] = (uint8)OCU_TOGGLE;
                break;
            case OCU_FORCE_LOW:
                value = (uint32)OCU_FORCE_LOW << (uint32)(TMR_CCM1_OC1MOD_SHIFT + (8u * ((uint32)OcuTmrChId % 2u)));
                g_ocuTmrChActArr[OcuChId] = (uint8)OCU_FORCE_LOW;
                break;
            case OCU_FORCE_HIGH:
                value = (uint32)OCU_FORCE_HIGH << (uint32)(TMR_CCM1_OC1MOD_SHIFT + (8u * ((uint32)OcuTmrChId % 2u)));
                g_ocuTmrChActArr[OcuChId] = (uint8)OCU_FORCE_HIGH;
                break;
            case OCU_PWM1:
                value = (uint32)OCU_PWM1 << (uint32)(TMR_CCM1_OC1MOD_SHIFT + (8u * ((uint32)OcuTmrChId % 2u)));
                g_ocuTmrChActArr[OcuChId] = (uint8)OCU_PWM1;
                break;
            case OCU_PWM2:
                value = (uint32)OCU_PWM2 << (uint32)(TMR_CCM1_OC1MOD_SHIFT + (8u * ((uint32)OcuTmrChId % 2u)));
                g_ocuTmrChActArr[OcuChId] = (uint8)OCU_PWM2;
                break;
            default:
                /* nothing */
                break;
        }
        REG_RMW32(address, mask, value);
    }
    else
    {
        /* do nothing */
    }
    
    SchM_Exit_Ocu_OCU_CRITICAL_SECTION10();

}
#endif  /* {if (STD_ON == OCU_SET_PIN_ACTION_API)} */
/**********************************************************************************************************************
                                                    GLOBAL FUNCTION
***********************************************************************************************************************/
/*!
 * @brief         The function is to start the Tmr channel of the Ocu driver.
 *
 * @param[in]     OcuTmrIpConfigPtr     The configuration parameters pointer of the Ocu Tmr driver.
 *                ChannelIndex          The index of the Tmr channels in configuration array.
 * @retval        void
 */
FUNC(void, OCU_CODE) Ocu_Tmr_HwStartCh(CONST(uint8, AUTOMATIC)  ChannelIndex,\
    CONSTP2CONST(Ocu_TmrHwConfigType, OCU_CONST, OCU_APPL_CONST)   OcuTmrIpConfigPtr
)
{
    VAR(uint8, AUTOMATIC)  ocuTmrModuleId = 0;
    VAR(uint8, AUTOMATIC)  ocuTmrChannelId = 0;

    Ocu_Tmr_GetIds(OcuTmrIpConfigPtr, &ocuTmrModuleId, &ocuTmrChannelId, ChannelIndex);
    Ocu_Tmr_StartChReg(ChannelIndex, ocuTmrChannelId, ocuTmrModuleId);
}

#if (STD_ON == OCU_SET_CLOCK_MODE_API_ENABLE)
/*!
 * @brief         The function is to set the clock mode of the Ocu Tmr.
 *
 * @param[in]     OcuTmrIpConfigPtr      The pointer of the Ocu Tmr configuration parameters
 * @param[in]     OcuTmrPrescalerType    The prescaler type of Ocu Tmr
 *
 * @retval        void
 */
FUNC(void, OCU_CODE) Ocu_Tmr_HwSetClkPsc(\
    CONSTP2CONST(Ocu_TmrHwConfigType, AUTOMATIC, OCU_APPL_CONST) OcuTmrIpConfigPtr,\
    VAR(Ocu_TmrPrescalerType, AUTOMATIC) OcuTmrPrescalerType)
{
    VAR(uint8, AUTOMATIC) ocuTmrModuleId = 0;
    VAR(uint8, AUTOMATIC) ocuTmrCounter = 0U;
    P2CONST(Ocu_TmrModConfigType, AUTOMATIC, OCU_APPL_CONST) ocuTmrModuleConfigPtr = NULL_PTR;

    SchM_Enter_Ocu_OCU_CRITICAL_SECTION14();
    
    while(ocuTmrCounter < OcuTmrIpConfigPtr->ocuTmrModCount)
    {
        ocuTmrModuleConfigPtr = &(*OcuTmrIpConfigPtr->ocuTmrModConfigPtr)[ocuTmrCounter];
        ocuTmrModuleId = ocuTmrModuleConfigPtr->ocuTmrModuleId; 
      
        switch(OcuTmrPrescalerType)
        {
            case OCU_AL_PSC:
                REG_RMW32(TMR_CTRL1_REG_ADDR(ocuTmrModuleId), TMR_CTRL1_CLKDIV_MASK, (uint32)ocuTmrModuleConfigPtr->ocuTmrClkSrcCtrl);
                break;
            default:
                /* nothing */
                break;
        }

        ocuTmrCounter++;
    }

    SchM_Exit_Ocu_OCU_CRITICAL_SECTION14();  
}
#endif /* {if (STD_ON == OCU_SET_CLOCK_MODE_API_ENABLE)} */

#if ((STD_ON == OCU_SET_RELATIVE_THRESHOLD_API) || (STD_ON == OCU_SET_ABSOLUTE_THRESHOLD_API))
/*!
 * @brief         The function is to get the max counter value of the Ocu Tmr channel.
 *
 * @param[in]     ChannelConfigIndex      The index of the channel configuration parameters
 *
 * @retval        Ocu_ValueType           The max counter value of the Ocu Tmr channel
 */
FUNC (Ocu_ValueType, OCU_CODE) Ocu_Tmr_GetMaxCntVal(VAR(Ocu_ChannelType, AUTOMATIC) ChannelConfigIndex)
{
    return (g_ocuTmrMaxCntVal[ChannelConfigIndex]);
}
#endif

#if (STD_ON == OCU_NOTIFICATION_EN)
/*!
 * @brief         The function is to call notification functions and if the notification functions is configured null, 
 *                an error will be reported.
 *
 * @param[in]     OcuTmrChannel      The channel of the Ocu Tmr moudle
 *
 * @retval        void
 */
FUNC(void, OCU_CODE) Ocu_Tmr_HandleInt(CONST(uint8, AUTOMATIC) OcuTmrChannel)
{
    VAR(Ocu_TmrHwModType, AUTOMATIC) ocuTmrChId = 0;
    VAR(Ocu_TmrHwModType, AUTOMATIC) ocuTmrModId = 0;
    VAR(uint32, AUTOMATIC) chevflgBitsVal = 0;
    VAR(uint32, AUTOMATIC) chienBitsVal = 0;
    VAR(Ocu_TmrHwChType, AUTOMATIC) chArrOffVal = 0;

    ocuTmrChId = ((OcuTmrChannel) & TMR_CHANNEL_MASK_BITS);
    ocuTmrModId = (((OcuTmrChannel) & TMR_MODULE_MASK_BITS) >> TMR_MODULE_SHIFT_VAL);
    SchM_Enter_Ocu_OCU_CRITICAL_SECTION15();
    switch(ocuTmrChId)
    {
        case (uint8)OCU_TMR_CH1:
                chienBitsVal = ((REG_READ32(TMR_CCEN_REG_ADDR(ocuTmrModId))) & TMR_CCEN_CC1EN_MASK);
                chevflgBitsVal = ((REG_READ32(TMR_STS_REG_ADDR(ocuTmrModId))) & TMR_STS_CC1IFLG_MASK);
                REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ocuTmrModId), TMR_STS_CC1IFLG_MASK);
            break;
        case (uint8)OCU_TMR_CH2:
                chienBitsVal = ((REG_READ32(TMR_CCEN_REG_ADDR(ocuTmrModId))) & TMR_CCEN_CC2EN_MASK);
                chevflgBitsVal = ((REG_READ32(TMR_STS_REG_ADDR(ocuTmrModId))) & TMR_STS_CC2IFLG_MASK);
                REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ocuTmrModId), TMR_STS_CC2IFLG_MASK);
            break;
        case (uint8)OCU_TMR_CH3:
                chienBitsVal = ((REG_READ32(TMR_CCEN_REG_ADDR(ocuTmrModId))) & TMR_CCEN_CC3EN_MASK);
                chevflgBitsVal = ((REG_READ32(TMR_STS_REG_ADDR(ocuTmrModId))) & TMR_STS_CC3IFLG_MASK);
                REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ocuTmrModId), TMR_STS_CC3IFLG_MASK);
            break;
        case (uint8)OCU_TMR_CH4:
                chienBitsVal = ((REG_READ32(TMR_CCEN_REG_ADDR(ocuTmrModId))) & TMR_CCEN_CC4EN_MASK);
                chevflgBitsVal = ((REG_READ32(TMR_STS_REG_ADDR(ocuTmrModId))) & TMR_STS_CC4IFLG_MASK);
                REG_BIT_CLEAR32(TMR_STS_REG_ADDR(ocuTmrModId), TMR_STS_CC4IFLG_MASK);
            break;
        default:
            /* nothing */
            break;
    }

    SchM_Exit_Ocu_OCU_CRITICAL_SECTION15();
    
    chArrOffVal = ((Ocu_TmrHwChType)OCU_TMR_MODULE_CHANNEL_COUNT * (Ocu_TmrHwChType)(ocuTmrModId - 1U)) + ocuTmrChId;

    if(((uint32)0U)!= chienBitsVal)
    {
        if(((uint32)0U)  != chevflgBitsVal)
        {
            Ocu_Notification((Ocu_ChannelType)chArrOffVal);
        }
        else
        {
            /* do nothing */
        }
    }
    else
    {
        /* do nothing */
    }
}

#endif /* {if (STD_ON == OCU_NOTIFICATION_EN)} */

#if (STD_ON == OCU_SET_ABSOLUTE_THRESHOLD_API)
/*!
 * @brief         The function is to set the value of the channel threshold with an absolute input data.
 *
 * @param[in]     ChannelIndex             The Ocu channel index
 * @param[in]     ReferenceCompareValue    The reference compare value
 * @param[in]     AbsoluteCompareValue     The absolute compare value
 * @param[in]     OcuTmrIpConfigPtr        The pointer of the Ocu Tmr configuration parameters
 *
 * @retval        OCU_CM_OUT_REF_INTERVAL: The compare match event will not occur inside the current
 *                reference interval.
 *                OCU_CM_IN_REF_INTERVAL: The compare match event will occur inside the current reference interval.
 */
FUNC(Ocu_ReturnType, OCU_CODE) Ocu_Tmr_SetAbsThrd(CONST(uint8, AUTOMATIC) ChannelIndex, \
    VAR(Ocu_ValueType,  AUTOMATIC) ReferenceCompareValue, VAR(Ocu_ValueType,  AUTOMATIC) AbsoluteCompareValue, \
    CONSTP2CONST(Ocu_TmrHwConfigType, OCU_CONST, OCU_APPL_CONST)   OcuTmrIpConfigPtr)
{
    VAR(uint8, AUTOMATIC) ocuTmrModuleId = 0;
    VAR(uint8, AUTOMATIC) ocuTmrChannelId = 0;

    Ocu_Tmr_GetIds(OcuTmrIpConfigPtr, &ocuTmrModuleId, &ocuTmrChannelId, ChannelIndex);
    return (Ocu_Tmr_SetAbsThrReg(ocuTmrChannelId, ocuTmrModuleId, ReferenceCompareValue, AbsoluteCompareValue));
}
#endif /* {if (STD_ON == OCU_SET_ABSOLUTE_THRESHOLD_API)} */

/*!
 * @brief         The function is to stop the Tmr channel of the Ocu driver.
 *
 * @param[in]     OcuTmrIpConfigPtr     The configuration parameters pointer of the Ocu Tmr driver.
 *                ChannelIndex          The index of the Tmr channels in configuration array.
 * @retval        void
 */
FUNC(void, OCU_CODE) Ocu_Tmr_StopChannel(CONST(uint8, AUTOMATIC) ChannelIndex, \
    CONSTP2CONST(Ocu_TmrHwConfigType, OCU_CONST, OCU_APPL_CONST)  OcuTmrIpConfigPtr)
{
    VAR(uint8, AUTOMATIC) ocuTmrModuleId = 0;
    VAR(uint8, AUTOMATIC) ocuTmrChannelId = 0;

    Ocu_Tmr_GetIds(OcuTmrIpConfigPtr, &ocuTmrModuleId, &ocuTmrChannelId, ChannelIndex);
    Ocu_Tmr_StopChReg(ocuTmrChannelId, ocuTmrModuleId);
}

/*!
 * @brief         The function is to initialize the registers and variables of the Ocu Tmr driver.
 *
 * @param[in]     OcuTmrIpConfigPtr     The configuration parameters pointer of the Ocu Tmr driver.
 *
 * @retval        void
 */
FUNC (void, OCU_CODE) Ocu_Tmr_HwInit(CONSTP2CONST(Ocu_TmrHwConfigType, AUTOMATIC, OCU_APPL_CONST) OcuTmrIpConfigPtr)
{
    /* The logic id of the Ocu Tmr moudle */
    VAR(Ocu_TmrHwModType,AUTOMATIC) ocuTmrModuleId = 0U;
    /* The hardware id of the Ocu Tmr moudle */
    VAR(Ocu_TmrHwModType,AUTOMATIC) ocuTmrHwModuleId = 0U;
    /* The total number of Ocu Tmr moudles */
    VAR(Ocu_TmrHwModType,AUTOMATIC) ocuTmrModuleNum = 0U;
    /* The total number of Ocu Tmr channels */
    VAR(Ocu_TmrHwChType,AUTOMATIC) ocuTmrChannelNum = 0U;
    /* The index of the current logic channel */
    VAR(Ocu_TmrHwChType,AUTOMATIC) ocuTmrCurChannel = 0U;
    /* The index of the current hardware channel */
    VAR(Ocu_TmrHwChType,AUTOMATIC) ocuTmrHwChannel = 0U;
    /* The Tmr moudle id the channel linked */
    VAR(Ocu_TmrHwModType,AUTOMATIC)  ocuTmrInternalModuleId = 0U;
    /* The channel controling value of the configuration parameter */
    VAR(Ocu_TmrChCtrlType,AUTOMATIC)  ocuTmrChannelControlVal = 0U;
    /* The max counter value configured */
    VAR(uint16,AUTOMATIC)  ocuTmrMaxCnt = 0U;
    /* The action of the pin channel linked */
    VAR(uint8, AUTOMATIC) ocuLinkedPinAction = 0U;
    /* The pointer of the channel configuration parameter */
    P2CONST(Ocu_TmrChConfigType,   AUTOMATIC, OCU_APPL_CONST) ocuTmrChannelConfig = NULL_PTR;   
    /* The pointer of the Tmr module configuration parameter */    
    P2CONST(Ocu_TmrModConfigType,    AUTOMATIC, OCU_APPL_CONST) ocuTmrModuleConfig = NULL_PTR;    
    
    ocuTmrModuleNum = OcuTmrIpConfigPtr->ocuTmrModCount;
    ocuTmrChannelNum = OcuTmrIpConfigPtr->ocuTmrChCount;   

    while(ocuTmrCurChannel < ocuTmrChannelNum)
    {
        g_ocuTmrChActArr[ocuTmrCurChannel] = 0U;
        ocuTmrCurChannel++;
    }
    
    while(ocuTmrModuleId < ocuTmrModuleNum)
    {
        ocuTmrModuleConfig = &(*OcuTmrIpConfigPtr->ocuTmrModConfigPtr)[ocuTmrModuleId];
        ocuTmrHwModuleId = ocuTmrModuleConfig->ocuTmrModuleId;
        ocuTmrMaxCnt = ocuTmrModuleConfig->ocuTmrMaxCnt;

        REG_WRITE32(TMR_AUTORLD_REG_ADDR(ocuTmrHwModuleId), ocuTmrMaxCnt);
        REG_WRITE32(TMR_PSC_REG_ADDR(ocuTmrHwModuleId), ocuTmrModuleConfig->ocuTmrPsc);
        REG_BIT_SET32(TMR_BDT_REG_ADDR(ocuTmrHwModuleId), (uint32)1U << (uint32)TMR_BDT_MOEN_SHIFT);
  
        ocuTmrCurChannel = (uint8)0U;
        
        while(ocuTmrCurChannel < ocuTmrChannelNum)
        {
            ocuTmrChannelConfig = &(*OcuTmrIpConfigPtr->ocuTmrChConfigPtr)[ocuTmrCurChannel];
            ocuTmrInternalModuleId = ((Ocu_TmrHwModType)(((ocuTmrChannelConfig->ocuTmrHwChannelId) & TMR_MODULE_MASK_BITS) >> TMR_MODULE_SHIFT_VAL));
            ocuTmrHwChannel = ((ocuTmrChannelConfig->ocuTmrHwChannelId) & TMR_CHANNEL_MASK_BITS);
            ocuTmrChannelControlVal = ocuTmrChannelConfig->ocuTmrChCtrl;
            
            /* Verify whether the current hw channel belongs to the current hardware Ocu TMR module */
            if (ocuTmrInternalModuleId == ocuTmrHwModuleId)
            {
                /* Set the default threshold value */
                REG_WRITE32(TMR_CC1_REG_ADDR(ocuTmrHwModuleId) + ((uint32)ocuTmrHwChannel << 2U), ((uint32)ocuTmrChannelConfig->ocuTmrChThreDef));
                /* Set the default linked pin action */
                switch (ocuTmrHwChannel)
                {
                    case (uint8)OCU_TMR_CH1:
                        ocuLinkedPinAction = (uint8)(((uint32)ocuTmrChannelControlVal & (uint32)OCU_TMR_CHANNEL1_PIN_ACTION_MASK_BITS) >> (uint32)OCU_TMR_CHANNEL1_PIN_ACTION_SHIFT_BITS);
                        break;
                    case (uint8)OCU_TMR_CH2:
                        ocuLinkedPinAction = (uint8)((uint32)(ocuTmrChannelControlVal & (uint32)OCU_TMR_CHANNEL2_PIN_ACTION_MASK_BITS) >> (uint32)OCU_TMR_CHANNEL2_PIN_ACTION_SHIFT_BITS);
                        break;
                    case (uint8)OCU_TMR_CH3:
                        ocuLinkedPinAction = (uint8)((uint32)(ocuTmrChannelControlVal & (uint32)OCU_TMR_CHANNEL3_PIN_ACTION_MASK_BITS) >> (uint32)OCU_TMR_CHANNEL3_PIN_ACTION_SHIFT_BITS);
                        break;
                    case (uint8)OCU_TMR_CH4:
                        ocuLinkedPinAction = (uint8)((uint32)(ocuTmrChannelControlVal & (uint32)OCU_TMR_CHANNEL4_PIN_ACTION_MASK_BITS) >> (uint32)OCU_TMR_CHANNEL4_PIN_ACTION_SHIFT_BITS);
                        break;
                    default:
                        /* nothing */
                        break;
                }

                switch(ocuLinkedPinAction)
                {
                    case (uint8)OCU_DISABLE:
                        g_ocuTmrChActArr[ocuTmrCurChannel] = (uint8)OCU_DISABLE;
                        break;
                    case (uint8)OCU_SET_HIGH:
                        g_ocuTmrChActArr[ocuTmrCurChannel] = (uint8)OCU_SET_HIGH;
                        break;
                    case (uint8)OCU_SET_LOW:
                        g_ocuTmrChActArr[ocuTmrCurChannel] = (uint8)OCU_SET_LOW;
                        break;
                    case (uint8)OCU_TOGGLE:
                        g_ocuTmrChActArr[ocuTmrCurChannel] = (uint8)OCU_TOGGLE;
                        break;
                    case (uint8)OCU_FORCE_LOW:
                        g_ocuTmrChActArr[ocuTmrCurChannel] = (uint8)OCU_FORCE_LOW;
                        break;
                    case (uint8)OCU_FORCE_HIGH:
                        g_ocuTmrChActArr[ocuTmrCurChannel] = (uint8)OCU_FORCE_HIGH;
                        break;
                    case (uint8)OCU_PWM1:
                        g_ocuTmrChActArr[ocuTmrCurChannel] = (uint8)OCU_PWM1;
                        break;
                    case (uint8)OCU_PWM2:
                        g_ocuTmrChActArr[ocuTmrCurChannel] = (uint8)OCU_PWM2;
                        break;
                    default:
                        /* nothing */
                        break;
                }
            #if ((STD_ON == OCU_SET_RELATIVE_THRESHOLD_API) || (STD_ON == OCU_SET_ABSOLUTE_THRESHOLD_API))
                g_ocuTmrMaxCntVal[ocuTmrCurChannel] = ocuTmrMaxCnt;
            #endif  

            }
            else
            {
                /* do nothing */
            }

            ocuTmrCurChannel++;
        }
        
        ocuTmrModuleId++;
    }
}

#if (STD_ON == OCU_DEINIT_API_ENABLE)
/*!
 * @brief         The function is to deinitialize the registers and variables of the Ocu Tmr driver.
 *
 * @param[in]     OcuTmrIpConfigPtr     The configuration parameters pointer of the Ocu Tmr driver.
 *
 * @retval        void
 */
FUNC (void, OCU_CODE) Ocu_Tmr_HwDeInit(CONSTP2CONST(Ocu_TmrHwConfigType, AUTOMATIC, OCU_APPL_CONST) OcuTmrIpConfigPtr)
{    
    Ocu_Tmr_HwChDeInit(OcuTmrIpConfigPtr);
    Ocu_Tmr_HwModDeInit(OcuTmrIpConfigPtr);
}
#endif /* {if (STD_ON == OCU_DEINIT_API_ENABLE)} */



#if (STD_ON == OCU_GET_COUNTER_API)
/*!
 * @brief         The function is to read the Tmr channel counter register.
 *
 * @param[in]     OcuTmrIpConfigPtr     The configuration parameters pointer of the Ocu Tmr driver.
 *                ChannelIndex          The index of the Tmr channels in configuration array.
 * @retval        The value of the Tmr channel counter register.
 */
FUNC(uint16, OCU_CODE) Ocu_Tmr_HwGetCnt(CONST(uint8, AUTOMATIC) ChannelIndex, \
    CONSTP2CONST(Ocu_TmrHwConfigType, OCU_CONST, OCU_APPL_CONST) OcuTmrIpConfigPtr)
{
    VAR(uint16, AUTOMATIC) countRegVal = 0;
    VAR(uint8, AUTOMATIC)  ocuTmrModuleId = 0;
    VAR(uint8, AUTOMATIC) ocuTmrChannelId = 0;

    Ocu_Tmr_GetIds(OcuTmrIpConfigPtr, &ocuTmrModuleId, &ocuTmrChannelId, ChannelIndex);

    /* Get the TMR_CNT register value */
    countRegVal = (uint16)(REG_READ32(TMR_CNT_REG_ADDR(ocuTmrModuleId)));
   
    return(countRegVal);
}
#endif /* {if (STD_ON == OCU_GET_COUNTER_API)} */

#if (STD_ON == OCU_SET_PIN_ACTION_API)
/*!
 * @brief         The function is to set the pin action linked to the Ocu channel.
 *
 * @param[in]     ChannelIndex        The Ocu channel id
 * @param[in]     OcuPinActionType    The output pin action linked to the Ocu channel
 * @param[in]     ChannelIsRunning    The flag of the channel running state
 * @param[in]     OcuTmrIpConfigPtr   The pointer of the Ocu Tmr configuration parameters
 *
 * @retval        void
 */
FUNC(void, OCU_CODE) Ocu_Tmr_HwSetPinAct(CONST(uint8, AUTOMATIC) ChannelIndex, \
    VAR(Ocu_PinActionType, AUTOMATIC) OcuPinActionType, VAR(boolean, AUTOMATIC) ChannelIsRunning, \
    CONSTP2CONST(Ocu_TmrHwConfigType, OCU_CONST, OCU_APPL_CONST) OcuTmrIpConfigPtr)
{
    VAR(uint8, AUTOMATIC) ocuTmrChannelId = 0;
    VAR(uint8, AUTOMATIC) ocuTmrModuleId = 0;

    Ocu_Tmr_GetIds(OcuTmrIpConfigPtr, &ocuTmrModuleId, &ocuTmrChannelId, ChannelIndex);
    Ocu_Tmr_SetPinActReg(ChannelIndex, OcuPinActionType, ocuTmrChannelId, ocuTmrModuleId, ChannelIsRunning);
}
#endif /* {if (STD_ON == OCU_SET_PIN_ACTION_API)} */

#if (STD_ON == OCU_SET_PIN_STATE_API)
/*!
 * @brief         The function is to set the pin state linked to the Ocu channel.
 *
 * @param[in]     ChannelIndex        The Ocu channel id
 * @param[in]     OcuPinStateType     The output pin state linked to the Ocu channel
 * @param[in]     OcuTmrIpConfigPtr   The pointer of the Ocu Tmr configuration parameters
 *
 * @retval        void
 */
FUNC(void, OCU_CODE) Ocu_Tmr_HwSetPinState(CONST(uint8, AUTOMATIC) ChannelIndex, \
    CONST(Ocu_PinStateType, AUTOMATIC) OcuPinStateType, \
    CONSTP2CONST(Ocu_TmrHwConfigType, OCU_CONST, OCU_APPL_CONST) OcuTmrIpConfigPtr)
{
    VAR(uint8, AUTOMATIC) ocuTmrChannelId = 0;
    VAR(uint8, AUTOMATIC) ocuTmrModuleId = 0;
    
    Ocu_Tmr_GetIds(OcuTmrIpConfigPtr, &ocuTmrModuleId, &ocuTmrChannelId, ChannelIndex);
    Ocu_Tmr_SetPinStsReg(ocuTmrChannelId, ocuTmrModuleId);
    (void)OcuPinStateType;
}
#endif /* {if (STD_ON == OCU_SET_PIN_STATE_API)} */

#if (STD_ON == OCU_SET_RELATIVE_THRESHOLD_API)
/*!
 * @brief         The function is to set the value of the channel relative threshold with an input data.
 *
 * @param[in]     ChannelIndex            The Ocu channel index
 * @param[in]     RelativeCompareValue    The relative compare value
 * @param[in]     OcuTmrIpConfigPtr       The pointer of the Ocu Tmr configuration parameters
 *
 * @retval        OCU_CM_OUT_REF_INTERVAL: The compare match event will not occur inside the current
 *                reference interval.
 *                OCU_CM_IN_REF_INTERVAL: The compare match event will occur inside the current reference interval.
 */
FUNC(Ocu_ReturnType, OCU_CODE) Ocu_Tmr_HwSetRelThrd(CONST(uint8, AUTOMATIC) ChannelIndex, \
    VAR(Ocu_ValueType, AUTOMATIC) RelativeCompareValue, \
    CONSTP2CONST(Ocu_TmrHwConfigType, OCU_CONST, OCU_APPL_CONST) OcuTmrIpConfigPtr)
{
    VAR(uint8, AUTOMATIC) ocuTmrModuleId = 0;
    VAR(uint8, AUTOMATIC) ocuTmrChannelId = 0;

    Ocu_Tmr_GetIds(OcuTmrIpConfigPtr, &ocuTmrModuleId, &ocuTmrChannelId, ChannelIndex);
    return (Ocu_Tmr_SetRelThrReg(ChannelIndex, RelativeCompareValue, ocuTmrChannelId, ocuTmrModuleId));
}
#endif /* {if (STD_ON == OCU_SET_RELATIVE_THRESHOLD_API)} */

/*!
* @brief         Process Interrupt function of the Icu TMR Low-level driver.
*
* @param[in]     tmrModule          -Tmr module id
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, OCU_CODE) Ocu_Tmr_ProcessInterrupt(CONST(Ocu_TmrModuleType, AUTOMATIC) tmrModule)
{
    VAR(uint32, AUTOMATIC) tmrIntFlag = 0U;
    VAR(uint32, AUTOMATIC) tmrIntEnSts = 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));

    /* Check the overflow bit */
    if((0U != (tmrIntFlag & TMR_STS_UIFLG_MASK)) && (0U != (tmrIntEnSts & TMR_DIEN_UIEN_MASK)) && (tmrModule != OCU_TMR1))
    {
        /* clear the channel update flag */
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_UIFLG_MASK);
    }
    else
    {
        /* nothing to do */
    }

    /* Channel 1 interrupt */
    if((0U != (tmrIntFlag & TMR_STS_CC1IFLG_MASK)) && (0U != (tmrIntEnSts & TMR_DIEN_CC1IEN_MASK)))
    {
        Ocu_Tmr_HandleInt((uint8)((((uint32)OCU_TMR_CH1 & (uint32)TMR_CHANNEL_MASK_BITS) << (uint32)TMR_CHANNEL_SHIFT_VAL) | \
                         (((uint32)tmrModule << (uint32)TMR_MODULE_SHIFT_VAL) & (uint32)TMR_MODULE_MASK_BITS)));
        /* clear the channel flag */
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_CC1IFLG_MASK);
    }
    else
    {
        /* nothing to do */
    }

    /* Channel 2 interrupt */
    if((0U != (tmrIntFlag & TMR_STS_CC2IFLG_MASK)) && (0U != (tmrIntEnSts & TMR_DIEN_CC2IEN_MASK)))
    {
        Ocu_Tmr_HandleInt((uint8)((((uint32)OCU_TMR_CH2 & (uint32)TMR_CHANNEL_MASK_BITS) << (uint32)TMR_CHANNEL_SHIFT_VAL) | \
                         (((uint32)tmrModule << (uint32)TMR_MODULE_SHIFT_VAL) & (uint32)TMR_MODULE_MASK_BITS)));
        /* clear the channel flag */
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_CC2IFLG_MASK);
    }
    else
    {
        /* nothing to do */
    }

    /* Channel 3 interrupt */
    if((0U != (tmrIntFlag & TMR_STS_CC3IFLG_MASK)) && (0U != (tmrIntEnSts & TMR_DIEN_CC3IEN_MASK)))
    {
        Ocu_Tmr_HandleInt((uint8)((((uint32)OCU_TMR_CH3 & (uint32)TMR_CHANNEL_MASK_BITS) << (uint32)TMR_CHANNEL_SHIFT_VAL) | \
                          (((uint32)tmrModule << (uint32)TMR_MODULE_SHIFT_VAL) & (uint32)TMR_MODULE_MASK_BITS)));
        /* clear the channel flag */
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_CC3IFLG_MASK);
    }
    else
    {
        /* nothing to do */
    }

    /* Channel 4 interrupt */
    if((0U != (tmrIntFlag & TMR_STS_CC4IFLG_MASK)) && (0U != (tmrIntEnSts & TMR_DIEN_CC4IEN_MASK)))
    {
        Ocu_Tmr_HandleInt((uint8)((((uint32)OCU_TMR_CH4 & (uint32)TMR_CHANNEL_MASK_BITS) << (uint32)TMR_CHANNEL_SHIFT_VAL) | \
                          (((uint32)tmrModule << (uint32)TMR_MODULE_SHIFT_VAL) & (uint32)TMR_MODULE_MASK_BITS)));
        /* clear the channel flag */
        REG_BIT_CLEAR32(TMR_STS_REG_ADDR(tmrModule), TMR_STS_CC4IFLG_MASK);
    }
    else
    {
        /* nothing to do */
    }
}

#define OCU_STOP_SEC_CODE
#include "Ocu_MemMap.h"
/**@} end of group OCU_Fuctions */
#ifdef __cplusplus
}
#endif  /* ifdef __cplusplus */
/**@} end of group OCU_Driver */
/**@} end of group G32A10xx_StdPeriphDriver */
