/**
  **********************************************************************************
  * @file    lowpower_hal.c
  * @author  Product application department
  * @version V1.0
  * @date    2020.03.30
  * @brief   LOWPOWER模块HAL层驱动.
  * @note 这个文件为应用层提供了操作LOWPOWER的接口:
  *
  @verbatim
  ===================================================================================
                                  ##### 更新 #####
  ===================================================================================
  [..] 更新时间:
  [..] 更新人:
  [..] 更新内容:
        1. nothing.
  @endverbatim
  */
#include "lowpower_hal.h"

/*** 全局变量定义 ***************************************************************/
/** @
  * @{volatile
  */
/** @ 
  * @}
  */
/** @ 
  * @{static
  */
/** @ 
  * @}
  */
/*** 常量定义 *******************************************************************/
/** @
  * @{const
  */
/** @ 
  * @}
  */

/*** 函数定义 *******************************************************************/
/**
 * @brief 芯片进入Hiber低功耗（poweroff 2 mode）
 *
 * @param[in] NONE
 * @return @ref NONE
 */
void LOWPOWER_Hiber(void)
{
	_cpm_eport_all_module_clk_sleep_dis;
	_cpm_sleep_mode_sel(2);//enter hibermation mode
	
	_cpm_set_vddpd_power_domain_retention_off;//VDD_PD power domain switch off
	_cpm_set_vddwk_power_domain_switch_off;//VDD_WK power domain switch off
	_cpm_set_cpm_ips_clk_sleep_dis;//Specify if the IPS Clock is enabled in system sleep mode
	
	//sdclk/sddat[0:3] swap enable
//	_ioctrl_swapcr_swap2_en;
//	_ioctrl_swapcr_swap7_en;
	
	_cpm_write_power_saving_mode_register(0x0028DF13);
	
	//overwrite OSCL STABLE/OSCH STABLE/VCC/CARDLDO TRIM.
	DRV_CPM_VccCoreTestModeSet(0x01860000);
	_cpm_set_sleep_counter_val(0x00000080);
	_cpm_set_wakeup_counter_val(0x00000080);
	_cpm_set_wakeup_filter_val(0x00000040);
	
	_cpm_set_oscl_stable_time_value(0x0);
	_cpm_set_osch_stable_time_value(0x001001FF);
	
	//wake-up digit filter enable, analog filter bypass.
	_cpm_wakeup_filter_en;
	_cpm_wakeup_filter_clk_gate_en;
	_cpm_wakeup_analog_filter_bypass_en;
	_cpm_wakeup_filter_bypass_dis;
	
	//limit peri_clk_en = 30us
	_eflash_set_tnvh_cnt(0x40);
	
	NVIC_Init(3, 3, PCI_IRQn, 2);
//*(u32 *) 0x40004030 &= ~(0x3<<2);
//*(u32 *) 0x40004000 &= ~(0xfff7ffff);
//*(u32 *) 0x40004000 |= 0x3<<26;
	Sys_Standby();
}

/**
 * @brief 芯片进入Deep Sleep低功耗（poweroff 1.5 mode）
 *
 * @param[in] NONE
 * @return @ref NONE
 */
void LOWPOWER_DeepSleep(void)
{
	_cpm_eport_all_module_clk_sleep_dis;
	_cpm_pmu128k_sleep_dis;
	_cpm_sleep_mode_sel(1);//Enter Retention mode
	
	_cpm_set_vddpd_power_domain_retention_off;//VDD_PD power domain switch off
	_cpm_set_vddwk_power_domain_switch_on;//VDD_WK power domain switch on
	_cpm_set_cpm_ips_clk_sleep_dis;//Specify if the IPS Clock is enabled in system sleep mode
	
	//sdclk/sddat[0:3] swap enable
//	_ioctrl_swapcr_swap2_en;
//	_ioctrl_swapcr_swap7_en;
	
	_cpm_write_power_saving_mode_register(0x0);
	
	//overwrite OSCL STABLE/OSCH STABLE/VCC/CARDLDO TRIM.
	DRV_CPM_VccCoreTestModeSet(0x01860000);
	_cpm_set_sleep_counter_val(0x000F0080);
	_cpm_set_wakeup_counter_val(0x00000080);
	_cpm_set_wakeup_filter_val(0x00000040);
	
	_cpm_set_oscl_stable_time_value(0x0);
	_cpm_set_osch_stable_time_value(0x001001FF);
	
	//wake-up digit filter enable, analog filter bypass.
	_cpm_wakeup_filter_en;
	_cpm_wakeup_filter_clk_gate_en;
	_cpm_wakeup_analog_filter_bypass_en;
	_cpm_wakeup_filter_bypass_dis;
	
	//limit peri_clk_en = 30us
	_eflash_set_tnvh_cnt(0x40);
	
#ifdef TSI_DEMO
	_cpm_write_wakeup_src(0x000303FF);
#else
  _cpm_write_wakeup_src(0x001313FF);
#endif

	_cpm_set_vcc_latch_auto_set_on;//VCC auto Set IO latch when system enter sleep mode
	_cpm_set_vcc_latch_auto_clr_on;//VCC auto clear IO latch when system exit sleep mode.
	
	NVIC_Init(3, 3, PCI_IRQn, 2);
	Sys_Standby();
}

/**
 * @brief 芯片进入Retention低功耗（poweroff 1 mode）
 *
 * @param[in] NONE
 * @return @ref NONE
 */
void LOWPOWER_Retention(void)
{
	_cpm_eport_all_module_clk_sleep_dis;
	_cpm_pmu128k_sleep_dis;
	_cpm_sleep_mode_sel(1);//Enter Low Power mode
	
	_cpm_set_vddpd_power_domain_retention_on;//VDD_PD power domain switch on
	_cpm_set_vddwk_power_domain_switch_off;//VDD_WK power domain switch off
	_cpm_set_cpm_ips_clk_sleep_dis;//Specify if the IPS Clock is enabled in system sleep mode
	
	//sdclk/sddat[0:3] swap enable
//	_ioctrl_swapcr_swap2_en;
//	_ioctrl_swapcr_swap7_en;
	
	_cpm_write_power_saving_mode_register(0x00001000);
	
	//overwrite OSCL STABLE/OSCH STABLE/VCC/CARDLDO TRIM.
	DRV_CPM_VccCoreTestModeSet(0x01860000);
	_cpm_set_sleep_counter_val(0x000F0080);
	_cpm_set_wakeup_counter_val(0x00000080);
	_cpm_set_wakeup_filter_val(0x00000040);
	
	_cpm_set_oscl_stable_time_value(0x0);
	_cpm_set_osch_stable_time_value(0x001001FF);
	
	//wake-up digit filter enable, analog filter bypass.
	_cpm_wakeup_filter_en;
	_cpm_wakeup_filter_clk_gate_en;
	_cpm_wakeup_analog_filter_bypass_en;
	_cpm_wakeup_filter_bypass_dis;

	//limit peri_clk_en = 30us
	_eflash_set_tnvh_cnt(0x40);
	
#if 0
	_cpm_write_wakeup_src(0x000202FF);
#else
  _cpm_write_wakeup_src(0x001212FF);
#endif

	_cpm_set_vcc_latch_auto_set_on;
	_cpm_set_vcc_latch_auto_clr_on;
		
	NVIC_Init(2, 2, PCI_IRQn, 1);
	Sys_Standby();
}

/**
 * @brief 芯片进入Lowpower低功耗（sleep mode）
 *
 * @param[in] NONE
 * @return @ref NONE
 */
void LOWPOWER_Lowpower(void)
{
	_cpm_eport_all_module_clk_sleep_dis;
	_cpm_sleep_mode_sel(0);//Enter Low Power mode
	
	_cpm_set_vddpd_power_domain_retention_off;
	_cpm_set_vddwk_power_domain_switch_off;
	_cpm_set_cpm_ips_clk_sleep_dis;//Specify if the IPS Clock is enabled in system sleep mode
	
	//sdclk/sddat[0:3] swap enable
//	_ioctrl_swapcr_swap2_en;
//	_ioctrl_swapcr_swap7_en;
	
	_cpm_write_power_saving_mode_register(0x0028DF13);
	
	//overwrite OSCL STABLE/OSCH STABLE/VCC/CARDLDO TRIM.
	DRV_CPM_VccCoreTestModeSet(0x01860000);
	_cpm_set_sleep_counter_val(0x00000080);
	_cpm_set_wakeup_counter_val(0x00000080);
	_cpm_set_wakeup_filter_val(0x00000040);
	
	_cpm_set_oscl_stable_time_value(0x0);
	_cpm_set_osch_stable_time_value(0x001001FF);
	
	//wake-up digit filter enable, analog filter bypass.
	_cpm_wakeup_filter_en;
	_cpm_wakeup_filter_clk_gate_en;
	_cpm_wakeup_analog_filter_bypass_en;
	_cpm_wakeup_filter_bypass_dis;
	
	//limit peri_clk_en = 30us
	_eflash_set_tnvh_cnt(0x40);
	
#ifdef TSI_DEMO
	_cpm_write_wakeup_src(0x000303FF);
#else
  _cpm_write_wakeup_src(0x001313FF);
#endif
	
	NVIC_Init(3, 3, PCI_IRQn, 2);
	Sys_Standby();
}

