/*******************************************************************************
* Project:      Amped'RF Bluetooth
* File name:    GKI_sleep.c
* Description:  Sleep abstraction layer
*
* Copyright (c) 2013 Amped'RF Inc., AR Technology  All rights reserved.
*******************************************************************************/
#include "Common.h"
#include "TM_FlashManager.h"
#include "GKI_lib.h"
#include "btm_int.h"
#include "TargetManagerAPI.h"
#include "AT_pvt.h"
extern tBTM_CB     btm_cb;
#ifndef TI2564
u32 GKI_PowerModeStat_wfe_count=0;
#endif
u32 GKI_PowerModeStat_low_power_count=0;
u32 GKI_PowerModeStat_sleep_count=0;

extern void RDA5876LDOoff(void);
extern void RDA5876EnableAutoSleep(void);
extern void RDA5876DisableAutoSleep(void);
extern void RDA5876WakeUp(void);

#ifdef CUSTOM_POWER_OFF_STATE
void StandbyMode(void)
{
  PWR_EnterSTANDBYMode();
}
#endif

#if defined(STM32F10x)
void GKI_sleep(void)
{
    bool MainIsHSE=TM_MainClockUsesHSE();

#if defined(BT24)
    RDA5876EnableAutoSleep();
#endif

    ENTER_CRITICAL();

    // (perhaps redundant)
    TM_BTControllerSleep();
    // Shut off HSE if it is not main clock
#if !defined(BT31) && !defined(BT33)
    if (!MainIsHSE) {
        MAIN_HSE_OFF();
    }
#endif

    if (TM_USE_EXT_LPO)
    {
        GKI_exti_Cmd(ENABLE);
        NVIC_SystemLPConfig(NVIC_LP_SEVONPEND,   ENABLE);
        NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,   ENABLE);
        NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT, DISABLE);
        PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);
        SU_SetCpuMHz(TM_CpuMHz);
        GKI_exti_Cmd(DISABLE);
        TM_BTControllerWake();
    }
    else {
#ifdef DSM_KHZ
        SU_SetCpuHz(DSM_KHZ*1000);
#else
        SU_SetCpuMHz(1);                    // Slow CPU to X MHz: determines HSI or HSE
#endif
        GKI_exti_Cmd(ENABLE);
        NVIC_SystemLPConfig(NVIC_LP_SEVONPEND,   ENABLE);
        NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,   DISABLE);
        NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT, DISABLE);
        RCC_PCLK2Config(RCC_HCLK_Div16);
        __WFE();


#if defined(BT24)

    BT24WakeUp();
    TM_WaitMS(30);

    BT24DisableAutoSleep();
#endif
        RCC_PCLK2Config(RCC_HCLK_Div1);
        GKI_exti_Cmd(DISABLE);
        TM_BTControllerWake();
        SU_SetCpuMHz(TM_CpuMHz);            // Speed up cpu clock: determines HSI or HSE
    }

    // Turn on HSE if it is not main clock
#if !defined(BT31) && !defined(BT33)
    if (!MainIsHSE) {
        MAIN_HSE_ON();
    }
#endif

    // Wait if HSE is main clock
    if (MainIsHSE) {
        TM_WaitMS(5);                       // wait for stable clock
    }

//#endif // CUSTOM_POWER_OFF_STATE
    EXIT_CRITICAL();

#ifdef DEVKIT
    read current
    Targ_DSM_WakeUp_Callback(past, current);
#endif

#if 1  //lkl 2012.12.13
    //init again to fix the issue: stopbits back to 1 bit, because of the set of MCH frequency :SU_SetCpuMHz(1);  ,SU_SetCpuMHz(TM_CpuMHz);
        tTM_UartDev *pUart = &TM_UartDev[eTM_MainUart];
        TM_SetupUart(eTM_MainUart,
        pUart->Config.DataBits,
        pUart->Config.StopBits,
        pUart->Config.Parity,
        pUart->Config.Baudrate);

        TM_WaitMS(5);//Wait new UART config to work
#endif
}
#endif

#ifdef DEBUG_SLEEP
u32 dbg_sleep_cts=0;
#endif

//----------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------
bool gbMcuDsmFlag = false;
extern bool gbRTC_Working;
#if defined(BT43) || defined(BT31) || defined(BT24)

void GKI_Sleep(void)
{
	if(!gbRTC_Working){
		GKI_F4_LSI_Disable();  
	}
#ifdef TI2564
	if (TM_USE_EXT_LPO){ 	
        GKI_exti_Cmd(ENABLE);	
		NVIC_SystemLPConfig(NVIC_LP_SEVONPEND,	 ENABLE);
		NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,	 ENABLE);
		NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT, DISABLE);
		PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);		
        GKI_rcc_SetSysClock(TM_CpuMHz);
        GKI_uart_ReSetup(eTM_MainUart);
        GKI_exti_Cmd(DISABLE);	
		
		if(btm_cb.devcb.DsmBleEnable == false){
			tBP_Signal    *pSignal = NULL;
			pSignal = BP_AllocSignal(SIG_AT_ENABLE_BLE_ADV, 0);	
			if(pSignal){
				BP_Send(BP_AT, pSignal);
			}
		}		
	}
	
#elif defined(BT24)	//#ifdef TI2564
	
	#ifdef USE_HSE_CLOCK
    bool MainIsHSE=true;
	#else
    bool MainIsHSE=false;
	#endif
	
	RDA5876EnableAutoSleep();
	#ifdef DEBUG_SLEEP
    dbg_sleep_cts = GKI_io_ReadBit(IO_HCI_CTS);
	#endif
	
	if(!MainIsHSE){
       	 MAIN_HSE_OFF();
	}
	
	if (TM_USE_EXT_LPO){
        GKI_exti_Cmd(ENABLE);
        NVIC_SystemLPConfig(NVIC_LP_SEVONPEND,   ENABLE);
        NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,   ENABLE);
        NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT, DISABLE);
		PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);
		RDA5876WakeUp();
        TM_WaitMS(30);
        RDA5876DisableAutoSleep();      	
        GKI_exti_Cmd(DISABLE);
		GKI_rcc_SetSysClock(TM_CpuMHz);	
        GKI_exti_Cmd(DISABLE);		
	}
	else{
		GKI_PowerModeStat_wfe_count++;
        //============================================= Slow down
        //USART_Cmd(USART1, DISABLE);       
        GKI_rcc_SetSysClock(DSM_CPU_CLK);
        GKI_rtc_ReConfig();  
		
		GKI_exti_Cmd(ENABLE);               
		if(GKI_io_ReadBit(IO_HCI_HOST_WAKE)==0)
		{
			 NVIC_SystemLPConfig(NVIC_LP_SEVONPEND,   ENABLE);
			 NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,   DISABLE);
			 NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT, DISABLE);
			 //----------------------------------
			 __WFE(); 
		}
		RDA5876WakeUp();
        TM_WaitMS(30);
        RDA5876DisableAutoSleep();      	
        GKI_exti_Cmd(DISABLE);
		
		GKI_rcc_SetSysClock(TM_CpuMHz);
		GKI_rtc_ReConfig();
		
		if (!MainIsHSE) {
			MAIN_HSE_ON();
		} 
	}
	//EXIT_CRITICAL();
	// init again to fix the issue: stopbits back to 1 bit,
	// because of the set of MCH frequency :SU_SetCpuMHz(1);
	GKI_uart_ReSetup(eTM_MainUart);
	TM_WaitMS(1);
#else //defined(BT24)
    
#ifdef USE_HSE_CLOCK
    bool MainIsHSE=true;
#else
    bool MainIsHSE=false;
#endif

#if defined(BT24)
    RDA5876EnableAutoSleep();
#endif
    
#if  defined(BT43) && !defined(GPS)
	 bool BtchipIs2905=TM_USE_EXT_LPO? false : true;
#else
     bool BtchipIs2905=false;
#endif
	
    ENTER_CRITICAL();


#ifdef DEBUG_SLEEP
    dbg_sleep_cts = GKI_io_ReadBit(IO_HCI_CTS);
#endif

    // (perhaps redundant)
    TM_BTControllerSleep();
    if(BtchipIs2905!=true)
       {
    // Shut off HSE if it is not main clock
    	if (!MainIsHSE) {
       	 	MAIN_HSE_OFF();
    		}

	}
    
    if (TM_USE_EXT_LPO)
    {
        GKI_exti_Cmd(ENABLE);
        NVIC_SystemLPConfig(NVIC_LP_SEVONPEND,   ENABLE);
        NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,   ENABLE);
        NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT, DISABLE);
        PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);
#ifndef TI2564
#if  defined(BT43) && !defined(GPS)
	if((GKI_io_ReadBit(IO_HCI_HOST_WAKE)==0)&&(GKI_io_ReadBit(io_HOST_WAKEUP)==0))
	    {
		PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);
	    }
#endif
#endif
        GKI_rcc_SetSysClock(TM_CpuMHz);
        GKI_exti_Cmd(DISABLE);
        TM_BTControllerWake();
		#if  defined(BT43) && !defined(GPS)
		if(btm_cb.devcb.DsmBleEnable == false){
		  	tBP_Signal    *pSignal = NULL;
			pSignal = BP_AllocSignal(SIG_AT_ENABLE_BLE_ADV, 0);	
			if(pSignal){
				BP_Send(BP_AT, pSignal);
			}
		}
		#endif
    }
    else
    {   
        GKI_PowerModeStat_wfe_count++;
        //============================================= Slow down
        //USART_Cmd(USART1, DISABLE);       
        GKI_rcc_SetSysClock(DSM_CPU_CLK);
        GKI_rtc_ReConfig();
		if(BtchipIs2905==true){
			// Shut off HSE if it is not main clock
		    if (!MainIsHSE) {
		        MAIN_HSE_OFF();
		    }
		}
        GKI_exti_Cmd(ENABLE);
                
		if(GKI_io_ReadBit(IO_HCI_HOST_WAKE)==0)
		{
			 NVIC_SystemLPConfig(NVIC_LP_SEVONPEND,   ENABLE);
			 NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,   DISABLE);
			 NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT, DISABLE);
			 //----------------------------------
			 __WFE();              
			#if  defined(BT43) && !defined(GPS)
					if((GKI_io_ReadBit(IO_HCI_HOST_WAKE)==0)&&(GKI_io_ReadBit(io_HOST_WAKEUP)==0))
					{
						__WFE(); 
					}
			#endif
		}
        //---------------------------------
#if defined(BT24)
        RDA5876WakeUp();
        TM_WaitMS(30);
        RDA5876DisableAutoSleep();
#endif        
		
        GKI_exti_Cmd(DISABLE);
        TM_BTControllerWake();
		
		if(BtchipIs2905==true){
            // Shut off HSE if it is not main clock
			if (!MainIsHSE) {
				MAIN_HSE_ON();
            }
		}
		GKI_rcc_SetSysClock(TM_CpuMHz);
		GKI_rtc_ReConfig();
        //USART_Cmd(USART1, ENABLE);
        //============================================= Speed up
	}

	
    if(BtchipIs2905!=true){
		// Turn on HSE if it is not main clock
		if (!MainIsHSE) {
			MAIN_HSE_ON();
		}
	}  
    // Wait if HSE is main clock
    if (MainIsHSE) {
        TM_WaitMS(15);                       // wait for stable clock
    }

//#endif // CUSTOM_POWER_OFF_STATE
    EXIT_CRITICAL();

#if 1   // lkl 2012.12.13
        // init again to fix the issue: stopbits back to 1 bit,
        // because of the set of MCH frequency :SU_SetCpuMHz(1);
		GKI_uart_ReSetup(eTM_MainUart);
        TM_WaitMS(1);//Wait new UART config to work
#endif

#endif
}
#endif




//--------------------------------------------------------------
//