/**************************************************************************
 * @file     pan_lp.h
 * @version  V1.00
 * $Revision: 3 $
 * $Date:    2023/11/08 $  
 * @brief    Panchip series lowpower driver header file
 *
 * @note
 * Copyright (C) 2025 Panchip Technology Corp. All rights reserved.
 *****************************************************************************/
#ifndef		__PAN_LP_H__
#define		__PAN_LP_H__

/**
 * @brief Lowpower Interface
 * @defgroup lowpower_interface Lowpower Interface
 * @{
 */
#ifdef __cplusplus
extern "C"
{
#endif

#include "pan271x.h"

#define	LP_EXT_P56_WK_EN								(1)		/*!< Gpio p56 wake up enable */
#define	LP_EXT_P56_WK_DISABLE							(0)		/*!< Gpio p56 wake up disable */

/**@defgroup LP_GPIO_WK_EDGE_FLAG Lowpower gpio wake up edge 
 * @brief       Lowpower gpio wake up edge select definitions
 * @{ */
#define	LP_EXT_P56_WK_EDGE_LOW							(0)		/*!< Gpio p56 wake up by falling edge */
#define	LP_EXT_P56_WK_EDGE_HIGH							(1)		/*!< Gpio p56 wake up by rising edge */
/**@} */

/**@defgroup LP_WK_SOURCE_FLAG Lowpower wakeup source select
 * @brief       Lowpower wakeup source select definitions
 * @{ */
#define LP_WKUP_MODE_SEL_EXT_GPIO                       (0)
#define LP_WKUP_MODE_SEL_32K                            (1)
#define LP_WKUP_MODE_SEL_GPIO                       	(2)
#define LP_WKUP_MODE_SEL_WDT                            (3)
#define LP_WKUP_MODE_SEL_TIMER                      	(4)
#define LP_WKUP_MODE_SEL_BOD                      		(5)
#define LP_WKUP_MODE_SEL_LVR	                      	(6)
#define LP_WKUP_MODE_SEL_KSCAN	                      	(7)

/**@} */


#define LP_MODE_SEL_SLEEP_MODE			(0)
#define LP_MODE_SEL_DEEPSLEEP_MODE		(1)
#define LP_MODE_SEL_STANDBY_M1_MODE		(2)
#define LP_MODE_SEL_STANDBY_M0_MODE		(3)

#define LP_DEEPSLEEP_MODE_SEL	LP_DEEPSLEEP_MODE1
#define LP_DEEPSLEEP_MODE1		(1)
#define LP_DEEPSLEEP_MODE2		(2)

#define LP_STANDBY_M1_MODE_SEL	LP_STANDBY_M1_MODE1
#define LP_STANDBY_M1_MODE1		(1)
#define LP_STANDBY_M1_MODE2		(2)

/**@defgroup LP_OTP_MODE Lowpower sram mode
 * @brief       Lowpower sram mode definitions
 * @{ */
typedef enum _LP_OtpModeDef
{
    OTP_MODE_PSD_CE_REEN_EN         = 0x0,  /*!< PSD\CE\REEN enable */
    OTP_MODE_PSD_CE_EN_REEN_DIS     = 0x1,  /*!< PSD\CE enable, REEN disable */
    OTP_MODE_PSD_CE_REEN_DIS        = 0x2,  /*!< PSD\CE\REEN disable */
    OTP_MODE_INVALID                = 0x3   /*!< no use */
} LP_OtpModeDef;
/**@} */


/**
* @brief  This function set otp ce delay time at low power mode
* @param[in]  pmu: where pmu is pmu module
* @param[in] delay: where delay is otp(TCRU) ce delay time, unit 1us
* @return   none
*/
__STATIC_INLINE void LP_SetOtpCeDelayTime(PMU_T *pmu, uint8_t delay)
{
	pmu->LP_CTRL0 = (pmu->LP_CTRL0 & ~LP_CTRL0_DLY3_TIME_Msk) | (delay << LP_CTRL0_DLY3_TIME_Pos);
}

/**
* @brief  This function set otp power delay time at low power mode
* @param[in]  pmu: where pmu is pmu module
* @param[in] delay: where delay is otp power(TVDC, TVCD) delay time, unit 1us
* @return   none
*/
__STATIC_INLINE void LP_SetOtpPowerDelayTime(PMU_T *pmu, uint8_t delay)
{
	pmu->LP_CTRL0 = (pmu->LP_CTRL0 & ~LP_CTRL0_DLY2_TIME_Msk) | (delay << LP_CTRL0_DLY2_TIME_Pos);
}

/**
* @brief  This function control analog module at low power mode
* @param[in]  pmu: where pmu is pmu module
* @param[in] mask: analog module control, including:
* 					\ref LP_CTRL0_SW0_LP_CTRL_Msk
* 					\ref LP_CTRL0_SW1_LP_CTRL_Msk
* 					\ref LP_CTRL0_SLOW_CLK_LP_CTRL_Msk
* 					\ref LP_CTRL0_HPLDO_LP_CTRL_Msk
* 					\ref LP_CTRL0_DEBUGREQ_LP_EN_Msk
* 					\ref LP_CTRL0_PMU_ISOLATE_EN_Msk
* 					\ref LP_CTRL0_CPU_LP_RET_EN_Msk
* @param[in] newState: new state of analog switch
* @return   none
*/
__STATIC_INLINE void LP_SetAnalogConfig(PMU_T *pmu, uint32_t mask, FunctionalState newState)
{
	(newState) ? (pmu->LP_CTRL0 |= mask):(pmu->LP_CTRL0 &= ~mask);
}

/**
* @brief  This function control otp config at low power mode
* @param[in]  pmu: where pmu is pmu module
* @param[in] otpCfg: otp config \ref LP_OTP_MODE
* @return   none
*/
__STATIC_INLINE void LP_SetOtpConfig(PMU_T *pmu, LP_OtpModeDef otpCfg)
{
	pmu->LP_CTRL0 = (pmu->LP_CTRL0 & ~LP_CTRL0_OTP_LP_CTRL_Msk) | (otpCfg << LP_CTRL0_OTP_LP_CTRL_Pos);
}

/**
* @brief  This function enable lowpower intterrupt
* @param[in]  ana: where ana is analog module
* @param[in] NewState: new state of interrupt mask
*					ANAC_INT_LP_INT_EN_Msk
* @return   none
*/
__STATIC_INLINE void LP_EnableInt(PMU_T *pmu,FunctionalState newState)
{
	(newState == ENABLE)?(pmu->LP_CTRL0 |= LP_CTRL0_LP_INT_EN_Msk):(pmu->LP_CTRL0 &= ~LP_CTRL0_LP_INT_EN_Msk);
}

/**
* @brief  This function wait to clear wake up flag
* @param[in]  pmu: where pmu is pmu module
* @param[in]  mask: bit need to be cleared
* @return   none
*/
__STATIC_INLINE void LP_ClearWakeFlag(PMU_T *pmu,uint32_t mask)
{
    uint32_t tmp = pmu->LP_FLAG_CTRL;
    tmp &= ~LP_FLAG_CTRL_INT_FLAG_MASK;
    pmu->LP_FLAG_CTRL = mask | tmp;
}


/**
* @brief  This function set sleep timer config at low power mode
* @param[in]  pmu: where pmu is pmu module
* @param[in] mask: peripheral selection, including:
* 					\ref SLPTMR_CTRL_SLPTMR_CMP1_EN_Msk
* 					\ref SLPTMR_CTRL_SLPTMR_CMP0_EN_Msk
* 					\ref SLPTMR_CTRL_SLPTMR_WK_EN_Msk
* 					\ref SLPTMR_CTRL_SLPTMR_INT_EN_Msk
* 					\ref SLPTMR_CTRL_SLPTMR_EN_Msk
* @param[in] newState: new state of sleep timer
* @return   none
*/
__STATIC_INLINE void LP_SetSleepTimerConfig(PMU_T *pmu, uint32_t mask, FunctionalState newState)
{
    (newState == ENABLE)?(pmu->SLPTMR_CTRL |= mask):(pmu->SLPTMR_CTRL &= ~mask);
}


/**
* @brief  This function get sleep timer current value
* @param[in]  pmu: where pmu is pmu module
* @return   none
*/
__STATIC_INLINE uint32_t LP_GetCurrentSleepTimerCnt(PMU_T *pmu)
{
	return pmu->SLPTMR_CURR;
}

/**
* @brief  This function get sleep timer current value
* @param[in]  pmu: where pmu is pmu module
* @return   current sleep timer current count
*/
__STATIC_INLINE void LP_UpdateSleepTimerLoad(PMU_T *pmu, uint32_t u32ClkCnt)
{
	pmu->SLPTMR_LOAD = u32ClkCnt;
}


/**
  * @brief  This function set sleep time
  * @param[in]  pmu: where pmu is pmu module base address
  * @param[in]  u32ClkCnt: where u32ClkCnt is 32k clock cnt num
  * @return   none
  */
void LP_SetSleepTime(PMU_T *pmu,uint32_t u32ClkCnt,uint8_t idx);

/**
  * @brief  This function used to set digital reset time
  * @param[in]  pmu: where pmu is pmu module base address
  * @param[in]  u8Clk32Cnt: where u8Clk32Cnt is 32k clock period cnt
  * @return   none
  */
void LP_SetWakeDelay(PMU_T *pmu,uint16_t u16Clk32Cnt);
/**
 * @brief  This function sets the sleep mode for the specified pmu module.
 * @param[in]  pmu: Analog module base address
 * @param[in]  mode: Sleep mode configuration
 * @return   None
 */
void LP_SetSleepMode(PMU_T *pmu,uint8_t mode);
	
/**
  * @brief  This function set sleep mode config
  * @param[in]  pmu: where pmu is pmu module base address
  * @param[in]  ahbClkDiv: where ahbClkDiv is ahb clock divider at wfi mode,
  *                        hardware restored after wake up.
  * @return   none
  */
void LP_SetSleepModeConfig(PMU_T *pmu, uint16_t ahbClkDiv);
/**
 * @brief  This function sets the deep sleep mode configuration.
 * @param[in]  pmu: Analog module base address
 * @param[in]  wkMode: Wakeup mode selection
 * @param[in]  enterCyclically: Determines whether to cycle into low power
 * @param[in]  dp_mode: Deep sleep mode configuration
 * @return   None
 */

void LP_SetDeepSleepConfig(PMU_T *pmu,
							uint32_t wkMode,
							uint8_t dp_mode);
/**
 * @brief  This function sets the Standby Mode 0 configuration.
 */
void LP_SetStandbyMode0Config(uint32_t wkMode);
/**
 * @brief  This function sets the Standby Mode 0 configuration with BOD and LVR.
 */
void LP_SetStandbyMode0BodLvrConfig(void);
/**
 * @brief  This function sets the Standby Mode 1 configuration.
 * @param[in]  pmu: Analog module base address
 * @param[in]  wkMode: Wakeup mode selection
 * @param[in]  PowerCtrl: Power control configuration
 * @param[in]  slpTimer: Sleep timer value
 * @param[in]  spaceIdx: Space index
 * @param[in]  stdy_mode: Standby mode configuration
 */
void LP_SetStandbyMode1Config(PMU_T *pmu,
							uint32_t wkMode,
							uint8_t stdy_mode);
/**@} */
#ifdef __cplusplus
}
#endif
#endif /* __PAN_LP_H__ */

