/*******************************************************************************
*
* power.c
*
* Purpose: This file contains the functions used for power on and off 
*          management of the board.
*          In case of RVM_PWR_SWE, this file contains also the 
*          functions used for charger plug and unplug management. 
*          They are all called after the occurence of the ABB interrupt.
*																			
* Author:  Candice Bazanegue (c-brille@ti.com)						
*																			
*																			
* (C) Texas Instruments 2001
*
******************************************************************************/

#ifndef _WINDOWS
  #include "rv.cfg"
#endif

#include "abb/abb.h"
#include "rvm/rvm_use_id_list.h"
#include "spi/spi_env.h"
#include "power/power.h"
#include "rv/rv_defined_swe.h"	   // for RVM_PWR_SWE

#ifndef _WINDOWS
  #include "kpd/kpd_power_api.h"
  #include "ffs/ffs.h"
#endif  // _WINDOWS

#ifdef RVM_PWR_SWE
  #include "spi/spi_task.h"
  #ifndef _WINDOWS
    #include "l1sw.cfg" 
    #include "chipset.cfg" 
  #endif  // _WINDOWS
  #include "pwr/pwr_messages.h"
  #include "pwr/pwr_liion_cha.h"
  #include "pwr/pwr_disch.h"
#endif /* #ifdef RVM_PWR_SWE */



#ifndef _WINDOWS
  /* Declare the variable containing pressed and released callback.  */
  extern T_KPD_KEYPAD Kp;

  extern effs_t ffs_exit(void);
#endif  // _WINDOWS


/// The ABB status used to know the cause of the Switch ON event.
static SYS_UWORD16 Power_abb_status = 0;


/*******************************************************************************
**
** Function      Power_ON_Button
**
** Description:  Informs the Protocol Stack that the Power ON key has been  
**				 pressed, and thus allows it to start.
**
*******************************************************************************/
void Power_ON_Button(void)
{
#ifndef _WINDOWS
   SPI_GBL_INFO_PTR->is_gsm_on = TRUE;

   /*
     When we build for ACI, we have no MMI, so there's no point waiting 
      for a keypress.  See CR 17958.
   */
#if (MMI == 0)
   return;
#endif

#if (OP_WCP == 0)

   /* Wait until the pointers initialization by the SMI */
   while(!(Kp.pressed && Kp.released))
     rvf_delay(1);

#if (TEST==0)
   (Kp.pressed)(KPD_PWR);  /* tell key is pressed */
   rvf_delay(5);
   (Kp.released)();        /* allow protocol stack to start */
#endif

#endif // OP_WCP == 0

#else
  rvf_send_trace("Start from button", 17, NULL_PARAM, RV_TRACE_LEVEL_WARNING, LCC_USE_ID);
  SPI_GBL_INFO_PTR->is_gsm_on = TRUE;
#endif  // _WINDOWS
}



/*******************************************************************************
**
** Function      Power_OFF_Button
**
** Description:  Informs the Protocol Stack that the Power OFF key has been  
**				 pressed, and thus allows it to stop.
**
*******************************************************************************/
void Power_OFF_Button(void)
{
#ifndef _WINDOWS
   ffs_exit ();
#endif  // _WINDOWS
   rvf_send_trace("Power off button", 16, NULL_PARAM, RV_TRACE_LEVEL_WARNING, LCC_USE_ID);
   SPI_GBL_INFO_PTR->is_gsm_on = FALSE;
#ifndef _WINDOWS
  #if (OP_WCP == 0)
   (Kp.pressed)(KPD_PWR);  /* tell key is pressed */
   rvf_delay(5);
   (Kp.released)();        /* tell key is released */
  #endif
#endif  // _WINDOWS
}


/**
 * @brief Sets the cause of the swith ON event.
 *
 * This function get the ABB status register and stores it into the
 * global variable Power_abb_status.
 *
 * @noparam
 *
 * @noreturn
 */
void Set_Switch_ON_Cause(void)
{
   Power_abb_status = ABB_Read_Status();
}


/*******************************************************************************
**
** Function      Switch_ON
**
** Description   This function is called by the spi task after the board is  
**               switched ON. It calls the appropriate function according
**               to the ABB status register.
**
** Warning       The Set_Switch_ON_Cause() function has to be called prior.
**
*******************************************************************************/
void Switch_ON(void)
{
#if ((ANLG_FAM == 1) || (ANLG_FAM == 2))
   if (Power_abb_status & ONBSTS)
#elif (ANLG_FAM == 3)
   if (Power_abb_status & PWONBSTS)
#endif
   {
      /* Switch on Condition on ON BUTTON Push */
      rvf_send_trace("Push Button from OFF to ON",26, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, LCC_USE_ID);
      Power_ON_Button();
      #ifdef RVM_PWR_SWE
      pwr_handle_discharge();
      #endif
   }

#if ((ANLG_FAM == 1) || (ANLG_FAM == 2))
   else if (Power_abb_status & ONRSTS) 
#elif (ANLG_FAM == 3)
   else if (Power_abb_status & RPSTS)
#endif
   {
      /* Switch on Condition on ON REM transition 0->1 */
      rvf_send_trace("ON Remote",9, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, LCC_USE_ID); 
      Power_ON_Remote();
      #ifdef RVM_PWR_SWE
      pwr_handle_discharge();
      #endif
   }

#ifdef RVM_PWR_SWE
   else if (Power_abb_status & CHGSTS)
   {
      /* Switch on Condition on CHARGER IC PLUG */
      rvf_send_trace("PWR: Charger Plug",17, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, LCC_USE_ID); 
      if (Power_abb_status & CHGPRES)
      {
         /* charger still present */
         PWR_Charger_Plug();
      }
   }
#endif /* #ifdef RVM_PWR_SWE */

   else
   {
      // The reset should run the SW in the same way than a Power ON
      rvf_send_trace("Start from reset",16, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, LCC_USE_ID); 
      Power_ON_Button();
      #ifdef RVM_PWR_SWE
      pwr_handle_discharge();
      #endif
   }
}



/*******************************************************************************
**
** Function         Power_ON_Remote
**
** Description      
**
**
*******************************************************************************/
void Power_ON_Remote(void)
{
}



/*******************************************************************************
**
** Function         Power_OFF_Remote
**
** Description      
**
**
*******************************************************************************/
void Power_OFF_Remote(void)
{
}



/*******************************************************************************
**
** Function         Power_IT_WakeUp
**
** Description      
**
**
*******************************************************************************/
void Power_IT_WakeUp(void)
{
}



#ifdef RVM_PWR_SWE
/*******************************************************************************
**
** Function         PWR_Charger_Plug
**
** Description      
**
**
*******************************************************************************/
void PWR_Charger_Plug(void)
{

  /* Start the fast charging cycle */

  /* Since this function is called from the SPI task
   it can't be interrupt by another task
   so we can directly access the SPI through the low-level driver */

   if (SPI_GBL_INFO_PTR->is_gsm_on == FALSE) /* GSM OFF */
   {
      rvf_delay(RVF_MS_TO_TICKS(2000));
   }

   rvf_stop_timer(SPI_TIMER3);

   /* informs the upper layer that the charger has been plugged */
   pwr_send_charger_plug_event();

   /* get the type of the battery */
   pwr_get_battery_type();
}



/*******************************************************************************
**
** Function         PWR_Charger_Unplug
**
** Description      
**
**
*******************************************************************************/
void PWR_Charger_Unplug(void)
{
   /* informs the upper layer that the charger has been unplugged */
   pwr_send_charger_unplug_event(); 

   rvf_send_trace("Charger unplug", 14, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, LCC_USE_ID );
   pwr_stop_charging();
   if (SPI_GBL_INFO_PTR->is_gsm_on == FALSE) /* GSM OFF */
   {
    #ifndef _WINDOWS
      #if (ANLG_FAM == 1) 
      ABB_Write_Register_on_page(PAGE0, VRPCCTL2, 0x00EE);
      #elif ((ANLG_FAM == 2) || (ANLG_FAM == 3))
      ABB_Write_Register_on_page(PAGE0, VRPCDEV, 0x0001);
      #endif
    #else
      ABB_Write_Register_on_page(PAGE0, VRPCDEV, 0x00EE);
    #endif  // _WINDOWS
   }
   else
   {
      pwr_handle_discharge();
   }
}
#endif /* #ifdef RVM_PWR_SWE */





