/*!
* @file     Pwm.h
*
* @version  1.0.0
*
* @brief    Header file of AUTOSAR pwm 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.
*/

#ifndef PWM_H
#define PWM_H

#ifdef __cplusplus
extern "C" {
#endif

#include "Mcal.h"
#include "Pwm_TmrTypes.h"

/** @addtogroup G32A10xx_StdPeriphDriver
  @{
*/

/** @defgroup PWM_Driver
  * @brief PWM driver modules
  @{
*/

/** @defgroup PWM_Macros
  @{
*/
/**************************************************************************
                  VENDOR ID & AUTOSAR VERSION INFO
**************************************************************************/
/** Vendor ID (vendorId) of the dedicated implementation of this module according to the AUTOSAR vendor list. */
#define PWM_H_VENDOR_ID                       0x00C1U
/** Module ID of this module, as defined in the BSW Module List. */
#define PWM_H_MODULE_ID                       0x0079U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define PWM_H_AR_RELEASE_MAJOR_VERSION        0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define PWM_H_AR_RELEASE_MINOR_VERSION        0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define PWM_H_AR_RELEASE_REVISION_VERSION     0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define PWM_H_SW_MAJOR_VERSION                0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define PWM_H_SW_MINOR_VERSION                0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define PWM_H_SW_PATCH_VERSION                0x00U

/**@} end of group PWM_Macros */

/**************************************************************************
                    VERSION INFOMATION VERIFICATION
**************************************************************************/
#ifdef ENABLE_INTERMODULE_MCAL_CHECK
    /* Make sure the AUTOSAR major version number is the same between Pwm.h and Mcal.h */
    #if (PWM_H_AR_RELEASE_MAJOR_VERSION != MCAL_H_AR_RELEASE_MAJOR_VERSION)
        #error "AUTOSAR Major Version Number mismatch between Pwm.h and Mcal.h "
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Pwm.h and Mcal.h */
    #if (PWM_H_AR_RELEASE_MINOR_VERSION != MCAL_H_AR_RELEASE_MINOR_VERSION)
        #error "AUTOSAR Minor Version Number mismatch between Pwm.h and Mcal.h "
    #endif
#endif

/* Make sure the vendor id is the same between Pwm.h and Pwm_TmrTypes.h */
#if (PWM_H_VENDOR_ID != PWM_TMR_TYPES_H_VENDOR_ID)
    #error "Vendor id mismatch between Pwm.h and Pwm_TmrTypes.h " 
#endif
/* Make sure the AUTOSAR major version number is the same between Pwm.h and Pwm_TmrTypes.h */
#if (PWM_H_AR_RELEASE_MAJOR_VERSION != PWM_TMR_TYPES_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Pwm.h and Pwm_TmrTypes.h "
#endif
/* Make sure the AUTOSAR minor version number is the same between Pwm.h and Pwm_TmrTypes.h */
#if (PWM_H_AR_RELEASE_MINOR_VERSION != PWM_TMR_TYPES_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Pwm.h and Pwm_TmrTypes.h "
#endif
/* Make sure the AUTOSAR revision version number is the same between Pwm.h and Pwm_TmrTypes.h */
#if (PWM_H_AR_RELEASE_REVISION_VERSION != PWM_TMR_TYPES_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Pwm.h and Pwm_TmrTypes.h "
#endif
/* Make sure the software major version number is the same between Pwm.h and Pwm_TmrTypes.h */
#if (PWM_H_SW_MAJOR_VERSION != PWM_TMR_TYPES_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Pwm.h and Pwm_TmrTypes.h "
#endif
/* Make sure the software minor version number is the same between Pwm.h and Pwm_TmrTypes.h */
#if (PWM_H_SW_MINOR_VERSION != PWM_TMR_TYPES_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Pwm.h and Pwm_TmrTypes.h "
#endif
/* Make sure the software patch version number is the same between Pwm.h and Pwm_TmrTypes.h */
#if (PWM_H_SW_PATCH_VERSION != PWM_TMR_TYPES_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Pwm.h and Pwm_TmrTypes.h "
#endif

/**************************************************************************
                    OTHER TYPE DEFINITION
**************************************************************************/
/** @defgroup PWM_Structure
  @{
*/

/** used for point to pwm channel notification function */
typedef void (*Pwm_ChNotifyType)(void);

/** Definition of the period of a PWM channel. */
typedef uint16 Pwm_PeriodType;

/**@} end of group PWM_Structure */

/**************************************************************************
                    ENUMERATION DEFINITION
**************************************************************************/
/** @defgroup PWM_Enumerations
  @{
*/

/**
 * @brief    macro definition about pwm duty cycle value type
 */
typedef enum
{
    PWM_DUTY_CYCLE_HALF  = (uint16)0x4000U,   //!< duty cycle equals 50%

    PWM_DUTY_CYCLE_FULL  = (uint16)0x8000U    //!< duty cycle equals 100%

} Pwm_DutyCycleValueType;

/**
 * @brief    macro definition about pwm channel class type
 */
typedef enum
{
    PWM_VARIABLE_PERIOD       = 0x00U,   //!< both period and duty cycle can be changed

    PWM_FIXED_PERIOD          = 0x01U,   //!< only duty cycle can be changed

    PWM_FIXED_PERIOD_SHIFTED  = 0x02U    //!< only duty cycle can be changed

} Pwm_ChannelClassType;

/**
 * @brief   API Service ID definition according to AUTOSAR PWM Driver software spec.
 */
typedef enum
{
    PWM_INIT_SERVICE_ID                             = (uint8)0x00U,  //!< Service ID: Pwm_Init()

    PWM_DEINIT_SERVICE_ID                           = (uint8)0x01U,  //!< Service ID: Pwm_DeInit()

    PWM_SETDUTYCYCLE_SERVICE_ID                     = (uint8)0x02U,  //!< Service ID: Pwm_SetDutyCycle()

    PWM_SETPERIODANDDUTY_SERVICE_ID                 = (uint8)0x03U,  //!< Service ID: Pwm_SetPeriodAndDuty()

    PWM_SETOUTPUTTOIDLE_SERVICE_ID                  = (uint8)0x04U,  //!< Service ID: Pwm_SetOutputToIdle()

    PWM_GETOUTPUTSTATE_SERVICE_ID                   = (uint8)0x05U,  //!< Service ID: Pwm_GetOutputState()

    PWM_DISABLENOTIFICATION_SERVICE_ID              = (uint8)0x06U,  //!< Service ID: Pwm_DisableNotification()

    PWM_ENABLENOTIFICATION_SERVICE_ID               = (uint8)0x07U,  //!< Service ID: Pwm_EnableNotification()

    PWM_GETVERSIONINFO_SERVICE_ID                   = (uint8)0x08U,  //!< Service ID: Pwm_GetVersionInfo()

    PWM_SETPOWERSTATE_SERVICE_ID                    = (uint8)0x09U,  //!< Service ID: Pwm_SetPowerState()

    PWM_GETCURRENTPOWERSTATE_SERVICE_ID             = (uint8)0x0AU,  //!< Service ID: Pwm_GetCurrentPowerState()

    PWM_GETTARGETPOWERSTATE_SERVICE_ID              = (uint8)0x0BU,  //!< Service ID: Pwm_GetTargetPowerState()

    PWM_PREPAREPOWERSTATE_SERVICE_ID                = (uint8)0x0CU,  //!< Service ID: Pwm_PreparePowerState()

    PWM_MAIN_POWERTRANSITIONMANAGER_SERVICE_ID      = (uint8)0x0DU,  //!< Service ID: Pwm_Main_PowerTransitionManager()

    PWM_GETCHDUTYCYCLEVALUE_SERVICE_ID              = (uint8)0x0EU,  //!< Service ID: Pwm_GetChDutyCycleValue()

    PWM_SETOUTPUTTOACTIVE_SERVICE_ID                = (uint8)0x0FU,  //!< Service ID: Pwm_SetOutputToActive()

    PWM_SETCLKPRESCALER_SERVICE_ID                  = (uint8)0x10U,  //!< Service ID: Pwm_SetClkPrescaler()

    PWM_SOFTWARERESETCOUNTER_SERVICE_ID             = (uint8)0x11U,   //!< Service ID: Pwm_SoftwareResetCounter()

    PWM_TURNONOFFCHANNEL_SERVICE_ID                 = (uint8)0x12U   //!< Service ID: Pwm_TurnOnOffChannel()

} Pwm_ServiceIdType;

/**
 * @brief   Defines PWM module development and runtime errors.
 */
typedef enum
{
    PWM_E_INIT_FAILED                  = (uint8)0x10U,  //!< Pwm_Init() called with parameter is NULL_PTR

    PWM_E_UNINIT                       = (uint8)0x11U,  //!< Pwm module API called while Pwm module has not been initialized

    PWM_E_PARAM_CHANNEL                = (uint8)0x12U,  //!< Pwm module API called with undefined channel ID

    PWM_E_PERIOD_UNCHANGEABLE          = (uint8)0x13U,  //!< Pwm_SetPeriodAndDuty() or Pwm_SetPeriodAndDuty_SwSync()
                                                        //!< are used to change channel's period while channel's class is
                                                        //!< PWM_FIXED_PERIOD

    PWM_E_ALREADY_INITIALIZED          = (uint8)0x14U,  //!< Pwm_Init() called two times

    PWM_E_PARAM_POINTER                = (uint8)0x15U,  //!< Pwm_GetVersionInfo() or power control APIs called with
                                                        //!< parameter is NULL_PTR

    PWM_E_NOT_DISENGAGED               = (uint8)0x16U,  //!< Pwm_SetPowerState() called while Pwm channel is running

    PWM_E_POWER_STATE_NOT_SUPPORTED    = (uint8)0x17U,  //!< Pwm_PreparePowerState() called with undefined parameter

    PWM_E_TRANSITION_NOT_POSSIBLE      = (uint8)0x18U,  //!< The requested power state is not reachable from the current one

    PWM_E_PERIPHERAL_NOT_PREPARED      = (uint8)0x19U,  //!< Called Pwm_SetPowerState() but not called Pwm_PreparePowerState() before

    PWM_E_NOTIFICATION_POINTER_IS_NULL = (uint8)0x20U,  //!< pwm channel notification function pointer is NULL_PTR

    PWM_E_DUTYCYCLE_BEYOND_SCOPE       = (uint8)0x21U,  //!< duty cycle parameter bigger than 0x8000

    PWM_E_INSTANCE_ID                  = (uint8)0x22U,  //!< API hardware instance parameter is more than the
                                                        //!< maxmium number of configured

    PWM_E_PERIOD_ID                    = (uint8)0x23U  //!< To indicate the period det error

} Pwm_ErrorIdType;

/**
 * @brief    PWM module state
 */
typedef enum
{
    PWM_MODULE_STATE_UNINIT = 0x0U,    //!< pwm has not been initialized

    PWM_MODULE_STATE_IDLE   = 0x1U     //!< pwm is in idle

} Pwm_ModuleStateType;

/**@} end of group PWM_Enumerations */

/**************************************************************************
                    STRUCT DEFINITION
**************************************************************************/
/** @defgroup PWM_Structure
  @{
*/

/**
 * @brief    indicate pwm channel class type and notification function point
 */
typedef struct 
{
    CONST(Pwm_ChannelClassType, PWM_CONST) pwmChClass;    //!< indicate pwm channel class type

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
    CONST(Pwm_ChNotifyType, PWM_CONST)  pwmChNotifyPtr;   //!< point to pwm channel notification function
#endif

} Pwm_ChClassAndNotifyType;

/**
 * @brief     used for pwm module initialization
 */
typedef struct 
{
    CONST(Pwm_ChannelType, PWM_CONST) cfgChNumber;  //!< indicate total number of pwm channel

    CONST(Pwm_ChClassAndNotifyType, PWM_CONST) (*pChClassNotifyPtr)[];  //!< indicate pwm channel class type
                                                                        //!< and notification function point

    CONST(Pwm_IpCfgType, PWM_CONST) pwmIpCfg;  //!< indicate pwm channel achieve way

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
    CONST(Pwm_ChannelType, PWM_CONST) logicChMapToHwCh[PWM_HW_CHANNELS_NUM];  //!< map logic channel to HW channel
#endif

} Pwm_ConfigType;

/**@} end of group PWM_Structure */

/**************************************************************************
                    GLOBAL VARIABLE
**************************************************************************/
#define PWM_START_SEC_CONFIG_DATA_UNSPECIFIED
#include "Pwm_MemMap.h"

/** @defgroup PWM_Variable
  @{
*/

extern CONST(Pwm_ConfigType, PWM_CONST) Pwm_Config;

/**@} end of group PWM_Variable */

#define PWM_STOP_SEC_CONFIG_DATA_UNSPECIFIED
#include "Pwm_MemMap.h"

/**************************************************************************
                    FUNCTION DECLARATION
**************************************************************************/
#define PWM_START_SEC_CODE
#include "Pwm_MemMap.h"

/** @defgroup PWM_Fuctions
  @{
*/

FUNC(void, PWM_CODE) Pwm_Init(P2CONST(Pwm_ConfigType, AUTOMATIC, PWM_APPL_CONST) ConfigPtr);

#if (STD_ON == PWM_DE_INIT_API)
FUNC(void, PWM_CODE) Pwm_DeInit(void);
#endif

#if (STD_ON == PWM_SET_DUTY_CYCLE_API)
FUNC(void, PWM_CODE) Pwm_SetDutyCycle(VAR(Pwm_ChannelType,AUTOMATIC) ChannelNumber, VAR(uint16,AUTOMATIC) DutyCycle);
#endif

#if (STD_ON == PWM_SET_PERIOD_AND_DUTY_API)
FUNC(void, PWM_CODE) Pwm_SetPeriodAndDuty(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber,
                                          VAR(Pwm_PeriodType, AUTOMATIC) Period,
                                          VAR(uint16, AUTOMATIC) DutyCycle);
#endif

#if (STD_ON == PWM_SET_OUTPUT_TO_IDLE_API)
FUNC(void, PWM_CODE) Pwm_SetOutputToIdle(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber);
#endif

#if (STD_ON == PWM_GET_OUTPUT_STATE_API)
FUNC(Pwm_OutputStateType, PWM_CODE) Pwm_GetOutputState(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber);
#endif

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
FUNC(void, PWM_CODE) Pwm_DisableNotification(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber);
FUNC(void, PWM_CODE) Pwm_EnableNotification (VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber,
                                             VAR(Pwm_EdgeNotificationType, AUTOMATIC) Notification);
#endif

#if (STD_ON == PWM_LOW_POWER_STATE_ENABLE)
FUNC(Std_ReturnType, PWM_CODE) Pwm_GetCurrentPowerState
                               (P2VAR(Pwm_PowerStateType, AUTOMATIC, PWM_APPL_DATA) CurrentPowerState,
                                P2VAR(Pwm_PowerStateRequestResultType, AUTOMATIC, PWM_APPL_DATA) Result);

FUNC(Std_ReturnType, PWM_CODE) Pwm_GetTargetPowerState
                               (P2VAR(Pwm_PowerStateType, AUTOMATIC, PWM_APPL_DATA) TargetPowerState,
                                P2VAR(Pwm_PowerStateRequestResultType, AUTOMATIC, PWM_APPL_DATA) Result);

FUNC(Std_ReturnType, PWM_CODE) Pwm_PreparePowerState
                               (VAR(Pwm_PowerStateType, AUTOMATIC) PowerState,
                              P2VAR(Pwm_PowerStateRequestResultType, AUTOMATIC, PWM_APPL_DATA) Result);

FUNC(Std_ReturnType, PWM_CODE) Pwm_SetPowerState
                               (P2VAR(Pwm_PowerStateRequestResultType, AUTOMATIC, PWM_APPL_DATA) Result);

FUNC(void, PWM_CODE) Pwm_Main_PowerTransitionManager(void);
#endif

#if (STD_ON == PWM_GET_VERSION_INFO)
FUNC(void, PWM_CODE) Pwm_GetVersionInfo(P2VAR(Std_VersionInfoType, AUTOMATIC, PWM_APPL_DATA) versioninfo);
#endif

#ifdef PWM_DUAL_CLOCK_MODE_SUPPORTED
#if (STD_ON == PWM_DUAL_CLOCK_MODE_SUPPORTED)
FUNC(void, PWM_CODE) Pwm_SetClkPrescaler(VAR(Pwm_ClockDivisionType, AUTOMATIC) ClkPscMode);
#endif
#endif

#if (STD_ON == PWM_SET_OUTPUT_TO_ACTIVE)
FUNC (void, PWM_CODE) Pwm_SetOutputToActive(VAR(uint8, AUTOMATIC) ChannelNumber);
#endif

#if (STD_ON == PWM_SOFTWARE_RESET_COUNTER)
FUNC(void, PWM_CODE) Pwm_SoftwareResetCounter (VAR(uint8, AUTOMATIC) InstanceId);
#endif

#if (STD_ON == PWM_GET_CHANNEL_DUTYCYCLE)
FUNC(uint16, PWM_CODE) Pwm_GetChDutyCycleValue(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber);
#endif

#if (STD_ON == PWM_TURN_ON_OFF_CHANNEL)
FUNC(void, PWM_CODE) Pwm_TurnOnOffChannel(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber, VAR(boolean, AUTOMATIC) operaFlag);
#endif

/**@} end of group PWM_Fuctions */

#define PWM_STOP_SEC_CODE
#include "Pwm_MemMap.h"

#ifdef __cplusplus
}
#endif

#endif

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