/*!
* @file     Gpt_Tmr.c
*
* @version  1.0.0
*
* @brief    The source file of the gpt timer driver.
*
* @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.
*/

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

#include "Gpt_Hw.h"
#include "Gpt_Tmr.h"
#include "Pdl_TmrReg.h"
#include "EcuM_Cbk.h"

/** @addtogroup G32A10xx_StdPeriphDriver
  @{
*/

/** @defgroup GPT_Driver
  * @brief GPT driver modules
  @{
*/

/** @defgroup GPT_Macros
  @{
*/
/*******************************************************************************
                    VENDOR ID & AUTOSAR VERSION INFO
*******************************************************************************/
/** Vendor ID (vendorId) of the dedicated implementation of this module according to the AUTOSAR vendor list. */
#define GPT_TMR_VENDOR_ID                              0x00C1U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define GPT_TMR_AR_RELEASE_MAJOR_VERSION               0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define GPT_TMR_AR_RELEASE_MINOR_VERSION               0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define GPT_TMR_AR_RELEASE_REVISION_VERSION            0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */ 
#define GPT_TMR_SW_MAJOR_VERSION                       0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define GPT_TMR_SW_MINOR_VERSION                       0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define GPT_TMR_SW_PATCH_VERSION                       0x00U

/**@} end of group GPT_Macros */
/*******************************************************************************
                              GLOBAL FUNCTION
*******************************************************************************/
#define GPT_START_SEC_CODE
#include "Gpt_MemMap.h"

/** @defgroup GPT_Fuctions
  @{
*/

/*!
* @brief       gpt interrupt user callback handler function
*
* @param       hwUnitId     Target timer hardware ID
* @param       ChannelId    channel ID
*
* @retval      tempRetVal   continuous or oneshot
*/
static FUNC(Gpt_CountModeType, GPT_CODE) Gpt_Tmr_ProcessGeneralInterrupt(Gpt_TimerHwIdType hwUnitId,Gpt_ChannelType ChannelId)
{
    Gpt_CountModeType tempRetVal = GPT_COUNT_MODE_CONTINUOUS;
    
    VAR(Gpt_ChannelType, AUTOMATIC) ch = gs_gptConfigPtr->gptHwMapPtr[(((uint8)hwUnitId - 1u) * 4u) + (ChannelId - 1u)];
    
#if(STD_ON == GPT_ENABLE_DISABLE_NOTIFICATION_API_ENABLE)
    if (GPT_MODE_NORMAL == gs_GptRuntimeState.ModuleState)
    {
        if (gs_gptChannelInfo[ch].notificationEnabled == (boolean)TRUE)
        {
            gs_gptConfigPtr->ChannelConfig[ch].Notification();
        }
        else
        {
            /* nothing */
        }
    }
    else
    {
        /* nothing */
    }
#endif
#if(STD_ON == GPT_ENABLE_DISABLE_WAKEUP_FUNCTIONALITY_API_ENABLE)
#if(STD_ON == GPT_REPORT_WAKEUP_SOURCE_ENABLE)
    if (GPT_MODE_SLEEP == gs_GptRuntimeState.ModuleState)
    {
        if (gs_gptChannelInfo[ch].wakeupEnabled == TRUE)
        {
            EcuM_CheckWakeup(gs_gptConfigPtr->ChannelConfig[ch].Gpt_WakeupSource);
        }
    }
#endif
#endif
    
    if ((uint32)0 != REG_BIT_GET32(TMR_CTRL1_REG_ADDR(hwUnitId),TMR_CTRL1_SPMEN_MASK))
    {
        tempRetVal = GPT_COUNT_MODE_ONESHOT;
    }
    else
    {
        /* nothing */
    }

    return tempRetVal;
}


/*!
* @brief       GPT interrupt handler function
*
* @param       hwUnitId     Target timer hardware ID
*
* @retval      none
*/
FUNC(void, GPT_CODE) Gpt_Tmr_ProcessInterrupt(Gpt_TimerHwIdType hwUnitId)
{
    VAR(uint32, AUTOMATIC) tmrIntFlag = REG_READ32(TMR_STS_REG_ADDR(hwUnitId));
    VAR(uint32, AUTOMATIC) tmrIntEnSts = REG_READ32(TMR_DIEN_REG_ADDR(hwUnitId));
    
    
    if((0U != (tmrIntFlag & TMR_STS_CC1IFLG_MASK)) && (0U != (tmrIntEnSts & TMR_DIEN_CC1IEN_MASK)))
    {
        if (GPT_COUNT_MODE_ONESHOT == Gpt_Tmr_ProcessGeneralInterrupt(hwUnitId,1))
        {
            Gpt_Hw_OperationSinglePulseMode(hwUnitId,DISABLE);
            Gpt_Hw_ConfigCompareInterrupt(hwUnitId,1,DISABLE);
        }
        else
        {
            /* nothing */
        }
        REG_WRITE32(TMR_STS_REG_ADDR(hwUnitId),0x00);
    }
    else
    {
        /* nothing */
    }

    if((0U != (tmrIntFlag & TMR_STS_CC2IFLG_MASK)) && (0U != (tmrIntEnSts & TMR_DIEN_CC2IEN_MASK)))
    {
        if (GPT_COUNT_MODE_ONESHOT == Gpt_Tmr_ProcessGeneralInterrupt(hwUnitId,2))
        {
            Gpt_Hw_OperationSinglePulseMode(hwUnitId,DISABLE);
            Gpt_Hw_ConfigCompareInterrupt(hwUnitId,2,DISABLE);
        }
        else
        {
            /* nothing */
        }
        REG_WRITE32(TMR_STS_REG_ADDR(hwUnitId),0x00);
    }
    else
    {
        /* nothing */
    }    

    if((0U != (tmrIntFlag & TMR_STS_CC3IFLG_MASK)) && (0U != (tmrIntEnSts & TMR_DIEN_CC3IEN_MASK)))
    {
        if (GPT_COUNT_MODE_ONESHOT == Gpt_Tmr_ProcessGeneralInterrupt(hwUnitId,3))
        {
            Gpt_Hw_OperationSinglePulseMode(hwUnitId,DISABLE);
            Gpt_Hw_ConfigCompareInterrupt(hwUnitId,3,DISABLE);
        }
        else
        {
            /* nothing */
        }
        REG_WRITE32(TMR_STS_REG_ADDR(hwUnitId),0x00);
    }
    else
    {
        /* nothing */
    }    

    if((0U != (tmrIntFlag & TMR_STS_CC4IFLG_MASK)) && (0U != (tmrIntEnSts & TMR_DIEN_CC4IEN_MASK)))
    {
        if (GPT_COUNT_MODE_ONESHOT == Gpt_Tmr_ProcessGeneralInterrupt(hwUnitId,4))
        {
            Gpt_Hw_OperationSinglePulseMode(hwUnitId,DISABLE);
            Gpt_Hw_ConfigCompareInterrupt(hwUnitId,4,DISABLE);
        }
        else
        {
            /* nothing */
        }
        REG_WRITE32(TMR_STS_REG_ADDR(hwUnitId),0x00);
    }
    else
    {
        /* nothing */
    }

    if (gs_gptConfigPtr->gptTmrConfigPtr[0].ChannelMode == GPT_COUNT_MODE_ONESHOT)
    {
        REG_BIT_CLEAR32(TMR_DIEN_REG_ADDR(hwUnitId),TMR_DIEN_CC1IEN_MASK);
        REG_WRITE32(TMR_STS_REG_ADDR(hwUnitId),0x00);
    }
    else
    {
        /* nothing */
    }

}


/*!
* @brief       Interrupt handler function for the basic timer of GPT
*
* @param       hwUnitId     Target timer hardware ID
*
* @retval      none
*/
FUNC(void, GPT_CODE) Gpt_Tmr_BasicTmrProcessInterrupt(Gpt_TimerHwIdType hwUnitId)
{
    VAR(uint32, AUTOMATIC) tmrIntFlag = REG_READ32(TMR_STS_REG_ADDR(hwUnitId));
    VAR(uint32, AUTOMATIC) tmrIntEnSts = REG_READ32(TMR_DIEN_REG_ADDR(hwUnitId));
    
    VAR(Gpt_ChannelType, AUTOMATIC) ch = gs_gptConfigPtr->gptHwMapPtr[(uint8)hwUnitId + (uint8)10];
    
    if((0U != (tmrIntFlag & TMR_STS_UIFLG_MASK)) && (0U != (tmrIntEnSts & TMR_DIEN_UIEN_MASK)))
    {
#if(STD_ON == GPT_ENABLE_DISABLE_NOTIFICATION_API_ENABLE)
        if (GPT_MODE_NORMAL == gs_GptRuntimeState.ModuleState)
        {
            if (gs_gptChannelInfo[ch].notificationEnabled == (boolean)TRUE)
            {
                gs_gptConfigPtr->ChannelConfig[ch].Notification();
            }
            else
            {
                /* nothing */
            }
        }
        else
        {
            /* nothing */
        }
#endif
#if(STD_ON == GPT_ENABLE_DISABLE_WAKEUP_FUNCTIONALITY_API_ENABLE)
#if(STD_ON == GPT_REPORT_WAKEUP_SOURCE_ENABLE)
        if (GPT_MODE_SLEEP == gs_GptRuntimeState.ModuleState)
        {
            if (gs_gptChannelInfo[ch].wakeupEnabled == TRUE)
            {
                EcuM_CheckWakeup(gs_gptConfigPtr->ChannelConfig[ch].Gpt_WakeupSource);
            }
            else
            {
                /* nothing */
            }
        }
        else
        {
            /* nothing */
        }
#endif
#endif
        if ((uint32)0 != REG_BIT_GET32(TMR_CTRL1_REG_ADDR(hwUnitId),TMR_CTRL1_SPMEN_MASK))
        {
            Gpt_Hw_OperationSinglePulseMode(hwUnitId,DISABLE);
            Gpt_Hw_ConfigCompareInterrupt(hwUnitId,2,DISABLE);
        }
        else
        {
            /* nothing */
        }
        
        REG_WRITE32(TMR_STS_REG_ADDR(hwUnitId),0x00);
    }
    else
    {
        /* nothing */
    }
}

/**@} end of group GPT_Fuctions */

#define GPT_STOP_SEC_CODE
#include "Gpt_MemMap.h"

#ifdef __cplusplus
}
#endif  /* ifdef __cplusplus */

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