/****************************************************************************
 *  F i l e   D a t a                                                        
 *  $Id: PWR_PowerHandler_INFN.c,v 1.52 2005/03/23 10:21:42 sebastiani Exp $
 *  $Revision: 1.52 $
 *  $Date: 2005/03/23 10:21:42 $
 *  $RCSfile: PWR_PowerHandler_INFN.c,v $
 *                                                                           
 ****************************************************************************
 *  S W   D e v e l o p m e n t   E n v i r o n m e n t                      
 *                                                                           
 *  $Author: sebastiani $
 *               :                                                           
 ****************************************************************************
 *  U p d a t i n g                                                          

 *  $Log: PWR_PowerHandler_INFN.c,v $
 *  Revision 1.52  2005/03/23 10:21:42  sebastiani
 *  PWR_HVSetting always return successful; PWR_PSBforTOFSetting introduced
 *
 *  Revision 1.51  2005/03/20 18:24:07  sebastiani
 *  OS_piTaskSuspend(PRH_VAR_PWR_CMD2PSB_DELAY) introduced at starto of PSB commands
 *
 *  Revision 1.50  2005/03/06 14:54:46  sebastiani
 *  version running on 06 03 2005
 *
 *  Revision 1.49  2005/02/24 17:47:11  sebastiani
 *  (1) more logging comments (2) IF_CMD2TOFHV PWR_output_values_ipm updated at end of PWR_CheckIPM_Voltage (3) PWR_IF_CMD2PSB accepts 2 params (4) IF_CMD2PSB is now a funciont, not a macro and accepts 2 params (5) PWR_IF_CALO_FE introduced as a wrapper of IF_CMD2PSB (6) OS_piTaskSuspend(500) introduced in CUSTOM mode between  PWR_SendTC(TM_PS_RESET) and  PWR_PSBSetting()
 *
 *  Revision 1.48  2005/02/21 08:58:29  sebastiani
 *  all log comments completed
 *
 *  Revision 1.47  2005/01/26 18:46:48  sebastiani
 *  new bug fixes for WS
 *
 *  Revision 1.46  2005/01/10 14:54:16  faber
 *  bugfix des force
 *
 *  Revision 1.44  2004/12/23 13:54:34  faber
 *  PWR_HVSetting() introduced
 *
 *  Revision 1.43  2004/12/20 14:02:04  faber
 *  @LOG entry introduced in all ALM_WriteLog occurrences
 *
 *  Revision 1.42  2004/12/15 09:25:19  sebastiani
 *  PWR_TRB_On introduced, TRBSetting accept a mask parameter and called 3 times,
 *  and many other patches
 *
 *  Revision 1.41  2004/12/03 10:08:11  faber
 *  PWR_TRB_MOSFET_MASK introduced
 *  and IF_CMD2PSB(PRH_VAR_PSB_TRB_S9004_34_ON)
 *  into TRB Settings procedure
 *
 *  Revision 1.40  2004/11/25 09:20:17  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.39  2004/11/23 22:54:06  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.38  2004/11/23 15:53:26  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.37  2004/11/23 15:16:51  faber
 *  *** empty log message ***
 *
 *  Revision 1.36  2004/11/23 12:24:57  sebastiani
 *  fixed dcdcon procedure
 *
 *  Revision 1.35  2004/11/19 15:14:52  sebastiani
 *  PRH_EXTERN_{VAR,ARR,TABLE} removed and put them on the autogenerated parameter heeader file
 *
 *  Revision 1.34  2004/11/18 16:02:34  sebastiani
 *  GAS/TRD removed
 *
 *  Revision 1.33  2004/11/16 18:22:18  sebastiani
 *  change power on off precedure on dcdc
 *  fix psb commands
 *  ecc.ecc.
 *
 *  Revision 1.32  2004/11/05 09:36:35  sebastiani
 *  first version of the PM state machine. tried but not deeply tested
 *
 *  Revision 1.31  2004/11/02 15:41:39  faber
 *  *** empty log message ***
 *
 *  Revision 1.30  2004/10/22 16:05:06  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.29  2004/10/19 16:59:27  sebastiani
 *  first text for IPM/ciclyc
 *
 *  Revision 1.28  2004/10/18 14:11:37  faber
 *  *** empty log message ***
 *
 *  Revision 1.27  2004/10/18 10:43:02  faber
 *  Power check new fligh mode
 *
 *  Revision 1.26  2004/10/08 15:57:51  sebastiani
 *  fix power hot cold variables settings.
 *  fix ws
 *  added function to set khb hot or cold
 *
 *  Revision 1.25  2004/09/17 15:01:00  faber
 *  LU_INFN_LOG flags fixing
 *
 *  Revision 1.24  2004/09/14 14:47:05  sebastiani
 *  PSB reply one word everytime
 *
 *  Revision 1.23  2004/09/14 13:05:37  alfarano
 *  update TM constants and definitions
 *
 *  Revision 1.22  2004/09/13 16:07:46  alfarano
 *  *** empty log message ***
 *
 *  Revision 1.21  2004/09/10 15:27:28  sebastiani
 *  added PWR dcdc procedures
 *
 *  Revision 1.20  2004/08/02 15:49:47  alfarano
 *  alarm handling , scm & pm communication rewrite
 *
 *  Revision 1.19  2004/07/13 14:35:54  alfarano
 *  *** empty log message ***
 *
 *  Revision 1.18  2004/07/12 09:19:33  sebastiani
 *  some fixing about alamrs
 *
 *  Revision 1.17  2004/04/26 10:56:04  faber
 *  imported diffs from TM branch (PWR_ module)
 *
 *  Revision 1.14.2.5  2004/04/08 14:40:49  sebastiani
 *  various bugfixes
 *
 *  Revision 1.14.2.4  2004/04/06 16:14:46  sebastiani
 *  update
 *
 *  Revision 1.14.2.3  2004/04/06 16:01:20  sebastiani
 *  various bugfixes (voltage,errors,CCA infos)
 *
 *  Revision 1.14.2.2  2004/04/06 13:55:29  sebastiani
 *  new updates:put check voltage out of the ipm check cycle; special management for space chain (enable ipm); bugfix in the PWR_CheckIPM_VoltageRange
 *
 *  Revision 1.15  2004/03/08 15:49:09  alfarano
 *  improved handling functions for FE
 *
 *  Revision 1.14  2003/12/11 18:10:18  sebastiani
 *  Full buffer in HB not logged any more
 *  and bug fix in PWR_PowerOn
 *
 *  Revision 1.13  2003/12/11 17:19:59  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.12  2003/12/11 11:35:47  sebastiani
 *  IPM error bit managerment
 *
 *  Revision 1.11  2003/12/08 10:22:29  sebastiani
 *  voltage check inside ipm check, error_status for CCA better provided and implemented
 *
 *  Revision 1.10  2003/12/07 12:12:13  sebastiani
 *  update
 *
 *  Revision 1.9  2003/12/06 08:32:38  faber
 *  startup procedure tuned. TMTC sampling storing  at startup
 *
 *  Revision 1.8  2003/12/04 17:16:08  sebastiani
 *  GS debug/tests, and other
 *
 *  Revision 1.7  2003/12/03 14:36:51  faber
 *  more action definition about mcmd (setmode/purge_trd).
 *  SSt word better defined
 *
 *  Revision 1.6  2003/12/02 11:05:33  faber
 *  first CCA info for IPMs
 *  first technologica model's SELECT MODE management
 *
 *  Revision 1.5  2003/12/01 09:27:16  sebastiani
 *  CCA info for Gas Module and first implementation of IPM infos.
 *
 *  Revision 1.4  2003/11/28 14:42:48  faber
 *  *** empty log message ***
 *
 *  Revision 1.3  2003/11/27 17:53:23  faber
 *  -Power management poweron procedure done and some tested in the simulator
 *  -history entry 5 now takes OBT
 *
 *  Revision 1.2  2003/11/26 16:39:33  faber
 *  advancing development for power management
 *
 *  Revision 1.1  2003/11/19 15:47:03  faber
dq1t4 *  System Control Manager (SCM) and Power Handler (PWR) modules introduced
 *
 *  Revision 1.1  2003/10/03 16:12:26  faber
 *  *** empty log message ***
 *
 *                                                                           
 *****************************************************************************/



/*============================= Include File ================================*/
  
#include <src/INFN/LU_SourceFileID_INFN.h>
#define __FILEID__ _PWR_PowerHandler_INFN__c
#include <src/INFN/PRH_ParamHandler_INFN.h>
#include <src/INFN/LU_LogUtility_INFN.h>
#include <src/INFN/PRH_ParamHandler_INFN_auto.h>
#include <src/INFN/ALM_Alarm_INFN.h>

LU_DECL_MASK();

#include <src/TM_TCManager/TMTCManager/TM_TMTCManager_p.h>
#include <src/INFN/KHB_Driver_INFN.h>
#include <src/INFN/PWR_PowerHandler_INFN.h>
#include <src/INFN/CM_Common_INFN.h>
#include <src/INFN/HK_Manager_INFN.h>

//#define PWR_IPM_CHECK(var,ipm)  (var &   (1 << ipm))
#define PWR_KHB_33_CHECK_RETRY 3

#define PWR_IPMSTATUS_INIT 0x00FC
/*****************************************************************************/
/*============================= Object variables ============================*/


static  CM_ON_OFF   PWR_output_values_ipm[PWR_IPM6_MAX];

static  CM_HOT_COLD PWR_ipm_hot_cold[PWR_IPM3_MAX];

static BOOL      PWR_Check_IPM_Timeout = TRUE;

static  PWR_IPM6  PWR_IPM_TWIN[6] = {PWR_IPM_2,PWR_IPM_1,PWR_IPM_4,PWR_IPM_3,PWR_IPM_6,PWR_IPM_5};
static  CM_ON_OFF PWR_real_values_ipm_cc[PWR_IPM6_MAX];
static  CM_ON_OFF PWR_mask_ipm_hl_status[PWR_IPM6_MAX];
static  CM_ON_OFF PWR_masked_ipm_hl_status[PWR_IPM6_MAX];
static  CM_ON_OFF PWR_tab_ipm[PWR_IPM6_MAX];
static  BOOL      PWR_error_voltage_status_ipm[PWR_IPM6_MAX];
static  BOOL      PWR_error_voltage_ool_ipm[PWR_IPM6_MAX];
static  BOOL      PWR_error_status_ipm[PWR_IPM6_MAX];
static  CM_HOT_COLD PWR_KHB_hc;

/* status word (SW) IPM  for the CCA: */

/* BIT 1 */
#define PWR_IPM_SW_EMERGENCY_SIGNAL_IPM_SPARE (1<<0)
static  BOOL PWR_ipm_emergency_signal_spare;

/* BIT 2 */
#define PWR_IPM_SW_EMERGENCY_SIGNAL_IPM_MAIN  (1<<1)
static  BOOL PWR_ipm_emergency_signal_main;

static  UINT16 PWR_IPM_SW_ERROR[6]={
  (1<<7) /* IPM1: bit 8 */,
  (1<<4) /* IPM2: bit 5 */,
  (1<<6) /* IPM3: bit 7 */,
  (1<<3) /* IPM4: bit 4 */,
  (1<<5) /* IPM5: bit 6 */,
  (1<<2) /* IPM6: bit 3 */
};

/* BIT 9 */
#define PWR_IPM_SW_ERROR_HISTORY_SPARE  (1<<8)
static  BOOL PWR_ipm_error_history_spare;

/* BIT 10 */
#define PWR_IPM_SW_ERROR_HISTORY_MAIN  (1<<9)
static  BOOL PWR_ipm_error_history_main;

static UINT16 PWR_IPM_SW_POWER_OK[6]={
  (1<<15) /* IPM1: bit 16 */,
  (1<<12) /* IPM2: bit 13 */,
  (1<<14) /* IPM3: bit 15 */,
  (1<<11) /* IPM4: bit 12 */,
  (1<<13) /* IPM5: bit 14 */,
  (1<<10) /* IPM6: bit 11 */
};




status_code PWR_GetIPMStatus(UINT16* IPMStatus)
{
  PWR_IPM6 ipm;
  UINT16 result=0;
  if(PWR_ipm_emergency_signal_spare)
    result |= PWR_IPM_SW_EMERGENCY_SIGNAL_IPM_SPARE;

  if(PWR_ipm_emergency_signal_main)
    result |= PWR_IPM_SW_EMERGENCY_SIGNAL_IPM_MAIN;

  if(PWR_ipm_error_history_spare)
    result |= PWR_IPM_SW_ERROR_HISTORY_SPARE;
  if(PWR_ipm_error_history_main)
    result |= PWR_IPM_SW_ERROR_HISTORY_MAIN;

  for(ipm=PWR_IPM_1;ipm<=PWR_IPM_6;ipm++) {  
    if(PWR_error_voltage_ool_ipm[ipm])
      result |= PWR_IPM_SW_POWER_OK[ipm];
    if(!PWR_error_status_ipm[ipm])
      result |= PWR_IPM_SW_ERROR[ipm];
  }

  *IPMStatus=result;
  return CM_RC_SUCCESSFUL;
}



/*****************************************************************************/

/*       P a y l o a d s   O P E R A T I O N A L  F U N C T I O N S          */

/*****************************************************************************/
/* @Function: PWR_InitHKManager                                               */
/* @Purpose :                                                                */
/*  Initialialization function of the HK component.                          */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code PWR_Init(void)  {
  PWR_IPM6 ipm;
  
  PWR_ipm_emergency_signal_spare=FALSE;
  PWR_ipm_emergency_signal_main=FALSE;
  PWR_ipm_error_history_main=FALSE;
  PWR_ipm_error_history_spare=FALSE;
  
  PWR_output_values_ipm[PWR_IPM_1]=CM_ON;
  PWR_output_values_ipm[PWR_IPM_2]=CM_OFF;
  PWR_output_values_ipm[PWR_IPM_3]=CM_ON;
  PWR_output_values_ipm[PWR_IPM_4]=CM_OFF;
  PWR_output_values_ipm[PWR_IPM_5]=CM_ON;
  PWR_output_values_ipm[PWR_IPM_6]=CM_OFF;
  
  for(ipm=PWR_IPM_1;ipm<=PWR_IPM_6;ipm++) {
    PWR_error_status_ipm[ipm]=FALSE;
    PWR_real_values_ipm_cc[ipm]=CM_OFF;
    PWR_error_voltage_ool_ipm[ipm]=FALSE;
    PWR_error_voltage_status_ipm[ipm]=FALSE;    
  }
  return SUCCESSFUL;
}


status_code PWR_KRB_IPM(PWR_IPM6 ipm,CM_ON_OFF *oo) {
  status_code s;
  TM_INFN_TELEMETRY id;
  switch(ipm) {
  case PWR_IPM_1:
    id=TM_KRB_IPM1;
    break;
  case PWR_IPM_2:
    id=TM_KRB_IPM2;
    break;
  case PWR_IPM_3:
    id=TM_KRB_IPM3;
    break;
  case PWR_IPM_4:
    id=TM_KRB_IPM4;
    break;
  case PWR_IPM_5:
    id=TM_KRB_IPM5;
    break;
  case PWR_IPM_6:
    id=TM_KRB_IPM6;
    break;
  default:
    // INT 
    break;
  }
#ifndef SIMULATOR
  return PWR_ReadCC(id,CM_ON,CM_OFF,oo);
#else
  return CM_RC_SUCCESSFUL;
#endif
}

status_code PWR_ReadCC(TM_INFN_TELEMETRY id,CM_ON_OFF ifzero,CM_ON_OFF ifnonzero,CM_ON_OFF *oo) {
  unsigned int v;
  status_code s;
#ifndef SIMULATOR
  s=HK_GetTMValue(id,&v);
#else
  s=CM_RC_SUCCESSFUL;
  v=0;
#endif
  if(s == CM_RC_SUCCESSFUL) {
    if(v)
      * oo = ifnonzero;
    else
      * oo = ifzero;
  }
  return s;
}

status_code PWR_SendTC(TM_INFN_TELECOMMANDS id) {
#ifndef SIMULATOR
  return HK_SendTC(id,TM_HL_DUMMYVALUE);
#else
  return CM_RC_SUCCESSFUL;
#endif
}

status_code PWR_SendTC_PS(TM_INFN_TELECOMMANDS id) {
  status_code status = PWR_SendTC(id);
  OS_piTaskSuspend(500);
  return status;
}


status_code PWR_SwitchOn_IPM(PWR_IPM6 ipm) {
  unsigned int v;
  status_code s;
  TM_INFN_TELECOMMANDS id;
  switch(ipm) {
  case PWR_IPM_1:
    id=TM_IPM1_ON;
    break;
  case PWR_IPM_2:
    id=TM_IPM2_ON;
    break;
  case PWR_IPM_3:
    id=TM_IPM3_ON;
    break;
  case PWR_IPM_4:
    id=TM_IPM4_ON;
    break;
  case PWR_IPM_5:
    id=TM_IPM5_ON;
    break;
  case PWR_IPM_6:
    id=TM_IPM6_ON;
    break;
  default:
    // INT 
    break;
  }
  PWR_output_values_ipm[ipm]=CM_ON;
  PWR_mask_ipm_hl_status[ipm]=CM_ON;  
  return PWR_SendTC(id);
}

status_code PWR_SwitchOff_IPM(PWR_IPM3 couple) {
  TM_INFN_TELECOMMANDS id;
  PWR_IPM6 ipm1,ipm2;
  switch(couple) {
  case PWR_IPM_12:
    id=TM_IPM12_OFF;
    ipm1=PWR_IPM_1;
    ipm2=PWR_IPM_2;
    break;
  case PWR_IPM_34:
    id=TM_IPM34_OFF;
    ipm1=PWR_IPM_3;
    ipm2=PWR_IPM_4;
    break;
  case PWR_IPM_56:
    id=TM_IPM56_OFF;
    ipm1=PWR_IPM_5;
    ipm2=PWR_IPM_6;
    break;
  default:
    // INT 
    break;
  }
  PWR_output_values_ipm[ipm1]=CM_OFF;
  PWR_output_values_ipm[ipm2]=CM_OFF;
  
  PWR_mask_ipm_hl_status[ipm1]=CM_OFF;  
  PWR_mask_ipm_hl_status[ipm2]=CM_OFF;
#ifndef SIMULATOR
  return PWR_SendTC(id);
#endif
}

#if 0
status_code PWR_KHB_33_Check(CM_HOT_COLD hc) {
  CM_ON_OFF oo;
  UINT32 i;
  status_code s;
  #warning "QUESTA FUNZIONE VA ELIMINATA!!!"
#warning "there's no reference for  TM_KHB_HOT_33DC TM_KHB_COLD_33D  TM_KHB_PWR_33_HOT_ON TM_KHB_PWR_33_COLD_ON on the docs j8,j9"

  //  TM_INFN_TELEMETRY    id_tm = hc == CM_HOT ? TM_KHB_HOT_33DC       : TM_KHB_COLD_33DC;
  // TM_INFN_TELECOMMANDS id_hl = hc == CM_HOT ? TM_KHB_PWR_33_HOT_ON : TM_KHB_PWR_33_COLD_ON;
  // TBD: this is only for the TM tests:
  // KHB_SetSerialLine(hc);
  //  PWR_KHB_hc = hc;
  return CM_RC_SUCCESSFUL;
#if 0
#define PWR_KHB_READ_CC PWR_ReadCC(id_tm,CM_OFF,CM_ON,&oo)
  PWR_KHB_READ_CC;
  if(oo == CM_ON)
    s=CM_RC_SUCCESSFUL;
  else {
    for(i=0;i<PWR_KHB_33_CHECK_RETRY;i++) {
      PWR_SendTC(id_hl);
    }
    PWR_KHB_READ_CC;
    PWR_ReadCC(id_tm,CM_OFF,CM_ON,&oo);
    if(oo == CM_ON)
      s=CM_RC_SUCCESSFUL;
    else 
      s=CM_RC_NO_POWER;
  }
#undef PWR_KHB_READ_CC
  if(s==CM_RC_SUCCESSFUL) {
    KHB_SetSerialLine(hc);
    PWR_KHB_hc = hc;
  }
#endif
}
#endif

rtems_timer_service_routine PWR_Check_IPM_Timeout_ISR(
  rtems_id   timer_id,
  void      *run_counter
  ) {
  PWR_Check_IPM_Timeout = TRUE;
}



status_code PWR_ReadVoltage(PWR_IPM6 ipm,UINT32 *voltage) {
  status_code s;
  TM_INFN_TELECOMMANDS id;
  switch(ipm) {
  case PWR_IPM_1:
    id=TM_IPM_MOV_IPM1;
    break;
  case PWR_IPM_2:
    id=TM_IPM_MOV_IPM2;
    break;
  case PWR_IPM_3:
    id=TM_IPM_MOV_IPM3;
    break;
  case PWR_IPM_4:
    id=TM_IPM_MOV_IPM4;
    break;
  case PWR_IPM_5:
    id=TM_IPM_MOV_IPM5;
    break;
  case PWR_IPM_6:
    id=TM_IPM_MOV_IPM6;
    break;
  default:
    // INT 
    break;
  }  
#ifndef SIMULATOR
  return HK_GetTMValue(id,voltage);
  //return TM_piGetTMValue(id,TM_CURRENT_VAL,voltage);
#else
  return CM_RC_SUCCESSFUL;
#endif
}

status_code PWR_CheckIPM_VoltageRange(PWR_IPM6 ipm,CM_ON_OFF *on_off) {
  status_code s=CM_RC_SUCCESSFUL;
  UINT32 voltage;
  UINT32 *min,*max;
  if((s=PWR_ReadVoltage(ipm,&voltage))==CM_RC_SUCCESSFUL) {
    PWR_error_voltage_ool_ipm[ipm]=FALSE;
    s=CM_RC_SUCCESSFUL;
    if(voltage >= PRH_ARR_PWR_VOLTAGE_IPM_RANGE_ON_MIN[ipm] &&
       voltage <= PRH_ARR_PWR_VOLTAGE_IPM_RANGE_ON_MAX[ipm])
      *on_off=CM_ON;
    else if(voltage >= PRH_ARR_PWR_VOLTAGE_IPM_RANGE_OFF_MIN[ipm] &&
	    voltage <= PRH_ARR_PWR_VOLTAGE_IPM_RANGE_OFF_MAX[ipm])
      *on_off=CM_OFF;
    else {
      PWR_error_voltage_ool_ipm[ipm]=TRUE;

      *on_off=CM_ON;

      s=CM_RC_VALUE_OUT_OFF_RANGE;
    }
  }
  return s;
}



status_code PWR_CheckIPM_Voltage(BOOL do_action) {

  CM_ON_OFF oo_voltage,oo_cc;
  status_code s;
  status_code status=CM_RC_SUCCESSFUL;
  BOOL time_out;
  UINT16 n=0;
  PWR_IPM3 couple;
  PWR_IPM6 ipm1,ipm2;
  /* initialize at hot : */
  PWR_IPM6 toggle[PWR_IPM3_MAX]={PWR_IPM_1,PWR_IPM_3,PWR_IPM_5};
  CM_ON_OFF cc_oo[PWR_IPM6_MAX];
  CM_ON_OFF adc_oo[PWR_IPM6_MAX];
  CM_ON_OFF wanted1,wanted2;
  volatile UINT16 i=0;
  PWR_IPM_ACTION action[PWR_IPM3_MAX];
  PWR_IPM_TO_ACTION timeout_action[PWR_IPM3_MAX];
  status_code s1,s2;
  do {
    if(PRH_VAR_VERBOSE_DEBUG)
      /*@LOG PWR_CheckIPM_Voltage: sten no. */
      LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,n);    
    for(couple=PWR_IPM_12;couple<PWR_IPM3_MAX;couple++) {
      switch(couple) {
      case PWR_IPM_12:
	ipm1=PWR_IPM_1;
	ipm2=PWR_IPM_2;
	break;
      case PWR_IPM_34:
	ipm1=PWR_IPM_3;
	ipm2=PWR_IPM_4;
	break;
      case PWR_IPM_56:
	ipm1=PWR_IPM_5;
	ipm2=PWR_IPM_6;
	break;
      }
      wanted1=PRH_ARR_PWR_IPM_CONF[ipm1]==0 ? CM_OFF:CM_ON;
      wanted2=PRH_ARR_PWR_IPM_CONF[ipm2]==0 ? CM_OFF:CM_ON;
      /* read cc: */
      PWR_KRB_IPM(ipm1,&cc_oo[ipm1]);
      PWR_KRB_IPM(ipm2,&cc_oo[ipm2]);
      /* read adc */
      s1=PWR_CheckIPM_VoltageRange(ipm1,&adc_oo[ipm1]);
      s2=PWR_CheckIPM_VoltageRange(ipm2,&adc_oo[ipm2]);

      if( s1 != CM_RC_SUCCESSFUL){
	/*@LOG PWR_CheckIPM_Voltage: error reading voltage range ipm hot - ipm1 << 16 | s1 */
	LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,ipm1 << 16 | s1);
	adc_oo[ipm1]= wanted1 == CM_ON ? CM_OFF : CM_ON;
      }
      if( s2 != CM_RC_SUCCESSFUL){
	/*@LOG PWR_CheckIPM_Voltage: error reading voltage range ipm cold - ipm2 << 16 | s2*/
	LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,ipm2 << 16 | s2);
	adc_oo[ipm2]= wanted2== CM_ON ? CM_OFF : CM_ON;
      }

      i=
	((cc_oo[ipm1]==CM_ON)<<5) |
	((cc_oo[ipm2]==CM_ON)<<4) |
	((adc_oo[ipm1]==CM_ON)<<3) |
	((adc_oo[ipm2]==CM_ON)<<2) |
	((wanted1==CM_ON)<<1) |
	( wanted2==CM_ON);

      action[couple]=(PWR_IPM_ACTION)((PRH_TAB_PWR_IPM_ACTION[couple][i]>>4) & 0xF);
      timeout_action[couple]=(PWR_IPM_TO_ACTION)(PRH_TAB_PWR_IPM_ACTION[couple][i] & 0xF);
      PWR_ipm_hot_cold[couple]=(CM_HOT_COLD)((PRH_TAB_PWR_IPM_ACTION[couple][i] >> 8) & 0x1);
      if(do_action) {
	switch(action[couple]) {
	case PWR_IPM_ACTION_ON_HOT:
	  PWR_SwitchOff_IPM(couple);
	  PWR_SwitchOn_IPM(ipm1);
	  break;
	case PWR_IPM_ACTION_ON_COLD:
	  PWR_SwitchOff_IPM(couple);
	  PWR_SwitchOn_IPM(ipm2);
	  break;
	case PWR_IPM_ACTION_ON_TOGGLED:
	  PWR_SwitchOff_IPM(couple);
	  PWR_SwitchOn_IPM(toggle[couple]);
	  toggle[couple]=PWR_IPM_TWIN[toggle[couple]];
	  break;
	case PWR_IPM_ACTION_OFF:
	  PWR_SwitchOff_IPM(couple);
	  break;  
	}

      }
    }
    if(do_action)
      OS_piTaskSuspend(PRH_VAR_PWR_VOLTAGE_DELAY_ATTEMPT);
    n++;
    time_out=n > PRH_VAR_PWR_VOLTAGE_N_ATTEMPT;

  } while(do_action                 &&
	  !time_out                 &&
	  !
	  (
	   (
	    action[PWR_IPM_12] == PWR_IPM_ACTION_EXIT_BAD ||
	    action[PWR_IPM_12] == PWR_IPM_ACTION_EXIT_OK 
	    ) &&
	   (
	    action[PWR_IPM_34] == PWR_IPM_ACTION_EXIT_BAD ||
	    action[PWR_IPM_34] == PWR_IPM_ACTION_EXIT_OK 
	    ) &&
	   (
	    action[PWR_IPM_56] == PWR_IPM_ACTION_EXIT_BAD || 
	    action[PWR_IPM_56] == PWR_IPM_ACTION_EXIT_OK 
	    )
	   )
	  );
  status=CM_RC_SUCCESSFUL;
  if(timeout_action[PWR_IPM_12] ==   PWR_IPM_TO_ACTION_STOP ||
     timeout_action[PWR_IPM_34] ==   PWR_IPM_TO_ACTION_STOP ||
     timeout_action[PWR_IPM_56] ==   PWR_IPM_TO_ACTION_STOP 
     ) {
    if(do_action) {
      PWR_DcdcOFF(TRUE);
    }
    status=CM_RC_DO_STOP_WAIT;
  }
  if(PRH_VAR_VERBOSE_DEBUG) {
    for(couple=PWR_IPM_12;couple<PWR_IPM3_MAX;couple++) {
      /*@LOG PWR_CheckIPM_Voltage: end of function - couple */
      LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,couple);
      /*@LOG PWR_CheckIPM_Voltage: end of function - action[couple] */
      LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,action[couple]);
      /*@LOG PWR_CheckIPM_Voltage: end of function - timeout_action[couple] */
      LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,timeout_action[couple]);
    }
    /*@LOG PWR_CheckIPM_Voltage: end of function - status */
    LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
  }
  if(status == CM_RC_SUCCESSFUL) {
    /* update the real ipm status according to the ACD values . we decide to trust in adc_oo read above */
    for(ipm1=PWR_IPM_1;ipm1<PWR_IPM6_MAX;ipm1++)
      PWR_output_values_ipm[ipm1]=adc_oo[ipm1];
  }
  return status;
}




status_code PWR_IPM_WaitOK() {

  CM_ON_OFF oo_cc;
  status_code s;
  status_code status=CM_RC_SUCCESSFUL;
  BOOL time_out;
  UINT16 n=0;
  PWR_IPM3 couple;
  PWR_IPM6 ipm1,ipm2;
  /* initialize at hot : */
  CM_ON_OFF cc_oo[PWR_IPM6_MAX];
  BOOL exit[PWR_IPM3_MAX];
  CM_ON_OFF wanted1,wanted2;
  volatile UINT16 i=0;
  status_code s1,s2;
  do {
    /*@LOG PWR_IPM_WaitOK: step no. */
    LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,n);    
    for(couple=PWR_IPM_12;couple<PWR_IPM3_MAX;couple++) {
      switch(couple) {
      case PWR_IPM_12:
	ipm1=PWR_IPM_1;
	ipm2=PWR_IPM_2;
	break;
      case PWR_IPM_34:
	ipm1=PWR_IPM_3;
	ipm2=PWR_IPM_4;
	break;
      case PWR_IPM_56:
	ipm1=PWR_IPM_5;
	ipm2=PWR_IPM_6;
	break;
      }
      wanted1=PRH_ARR_PWR_IPM_CONF[ipm1]==0 ? CM_OFF:CM_ON;
      wanted2=PRH_ARR_PWR_IPM_CONF[ipm2]==0 ? CM_OFF:CM_ON;
      /* read cc: */
      PWR_KRB_IPM(ipm1,&cc_oo[ipm1]);
      PWR_KRB_IPM(ipm2,&cc_oo[ipm2]);
      /* read adc */
      i=
	((cc_oo[ipm1]==CM_ON)<<3) |
	((cc_oo[ipm2]==CM_ON)<<2) |
	((wanted1==CM_ON)<<1) |
	( wanted2==CM_ON);
      /*                   CC1 CC2 WANT1 WANT2 */
      exit[couple]
	= (i == 0x00 || /*  0   0    0      0   */
	   i == 0x5  || /*  0   1    0      1   */
	   i == 0x7  || /*  0   1    1      1   */
	   i == 0xA  || /*  1   0    1      0   */
	   i == 0xB     /*  1   0    1      1   */
	   );
      /*@LOG PWR_IPM_WaitOK loop - couple << 16 | exit[couple] */
      LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,couple << 16 | exit[couple]);  
    }
    
    OS_piTaskSuspend(PRH_VAR_PWR_IPM_WAIT_OK_DELAY_ATTEMPT);
    n++;
    time_out=n > PRH_VAR_PWR_IPM_WAIT_OK_N_ATTEMPT;
  } while(!time_out                 &&
	  !
	  (
	   exit[PWR_IPM_12] && exit[PWR_IPM_34] && exit[PWR_IPM_56] 
	   )
	  );
  /*@LOG PWR_IPM_WaitOK end of function - time_out */
  LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,time_out);  
  return CM_RC_SUCCESSFUL;
}


status_code PWR_PowerCheck(BOOL do_action) {
  status_code ps;

  ps = PWR_CheckIPM_Voltage(do_action);
  if(ps == CM_RC_SUCCESSFUL) {
    
  }
  return ps;
}



#define PWR_PSB_HK_TIMEOUT 10
#define PWR_TRB_HK_TIMEOUT 10


status_code PWR_CMD2PSB(UINT16 psbcmd,
			TM_INFN_TELEMETRY tm_cc_id,
			CM_ON_OFF expected_cc,
			ALM_VAR_ID alm_id1,
			ALM_VAR_ID alm_id2,
			UINT16 expected_answer)
{
  status_code status;
  UINT16 outbuf;
  int i;
  CM_ON_OFF psb_ccalm;
  OS_piTaskSuspend(PRH_VAR_PWR_CMD2PSB_DELAY);
  for(i=0;i<3;i++){
    status = HK_KHB_Cmd2FE(KHB_POWER_SUPPLY,1,1,&psbcmd,&outbuf,PWR_PSB_HK_TIMEOUT);
    if(status!=CM_RC_SUCCESSFUL){
      /*@LOG PSBCommand: KHB Error on PSB Command */
      ALM_WriteLog(ALM_TRACE_ID,alm_id1);
      /*@LOG PSBCommand: KHB Error on PSB Command - psbcmd << 16 | status */
      LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,psbcmd << 16 | status);
      return status;
    }
    if(outbuf == expected_answer){
      status = PWR_ReadCC(tm_cc_id,CM_OFF,CM_ON,&psb_ccalm);
      if(status!=CM_RC_SUCCESSFUL){
	/*@LOG PSBCommand: PSB Alarm */
	ALM_WriteLog(ALM_TRACE_ID,alm_id1);
	/*@LOG PSBCommand: PSB Alarm - psbcmd << 16 | status */
	LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,psbcmd << 16 | status);
	return status;
      }
      if(psb_ccalm==expected_cc)
	return CM_RC_SUCCESSFUL;
    }    
  }
  /*@LOG PSBCommand: PSB Alarm: too many failed attempts */
  ALM_WriteLog(ALM_TRACE_ID,alm_id2);
  /*@LOG PSBCommand: PSB Alarm: too many failed attempts - psbcmd */
  LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,psbcmd);
  return CM_RC_PSB_ERROR;
}

static UINT16 PWR_TRB_COMMAND_SET[PWR_TRB_MAX][CM_HOT_COLD_MAX][PWR_TRB_FE_MAX][16] = {
#include "PWR_TRB_Commands.include"
};
/*
  trb_cmd(0,0,0,0,0x3F00,"$trb_dir/TRB_1_READ_COLD.mcs");
  trb_cmd(0,0,0,0,0x3C00,"$trb_dir/TRB_1_READ_HOT.mcs");
  trb_cmd(0,0,0,0,0x5F00,"$trb_dir/TRB_2_READ_COLD.mcs");
  trb_cmd(0,0,0,0,0x5C00,"$trb_dir/TRB_2_READ_HOT.mcs");
*/
static UINT16 PWR_TRB_COMMAND_READ[PWR_TRB_MAX][CM_HOT_COLD_MAX]={{0x3C00,0x3F00},{0x5C00,0x5F00}};


status_code PWR_CMD2TRB_SET(
			    PWR_TRB trb,
			    CM_HOT_COLD hc,
			    PWR_TRB_FE fe,
			    UINT16 cmd)
{
  
  //  PRH_VAR_TYPE trbcmd,ALM_VAR_ID alm_id){
  status_code status;
  UINT16 unused;
  UINT16 combuf=PWR_TRB_COMMAND_SET[trb][hc][fe][cmd];
  status = HK_KHB_Cmd2FE(KHB_TRACKER_RELAYS,1,0,&combuf,&unused,PWR_TRB_HK_TIMEOUT);
  if(status!=CM_RC_SUCCESSFUL){

    /*@LOG KHB command failed on TRB Set */
    ALM_WriteLog(ALM_TRACE_ID,cmd | (fe<<4) | (hc<<5) | (trb<<6));
  }
  else
    OS_piTaskSuspend(PRH_VAR_PWR_TRB_SET_DELAY);
  return status;
}

status_code PWR_CMD2TRB_READ(PWR_TRB trb,CM_HOT_COLD hc,UINT16* outbuf) 
{
  // PRH_VAR_TYPE trbcmd,ALM_VAR_ID alm_id,int expetcted,UINT16 *outbuf){
  status_code status=~CM_RC_SUCCESSFUL;
  UINT16 combuf=PWR_TRB_COMMAND_READ[trb][hc];
  int i;
  for(i=0;i<PRH_VAR_PWR_TRB_READ_ATTEMPTS && status != CM_RC_SUCCESSFUL ;i++) {
    status = HK_KHB_Cmd2FE(KHB_TRACKER_RELAYS,1,2,&combuf,outbuf,PWR_TRB_HK_TIMEOUT);
    if(status!=CM_RC_SUCCESSFUL){

      /*@LOG PWR_CMD2TRB_READ: KHB command failed on TRB Read */
      ALM_WriteLog(ALM_TRACE_ID,hc | (trb << 1));
      HK_KHB_Cmd2FE(KHB_TRACKER_RELAYS,1,0,&combuf,outbuf,PWR_TRB_HK_TIMEOUT);
      OS_piTaskSuspend(PRH_VAR_PWR_TRB_READ_DELAY);
    }
    else {
      OS_piTaskSuspend(PRH_VAR_PWR_TRB_READ_DELAY);
      status = outbuf[0] == PWR_TRB_COMMAND_READ[trb][hc] + 1 ?  CM_RC_SUCCESSFUL : CM_RC_TIMEOUT;
      if (status != CM_RC_SUCCESSFUL)
	/*@LOG PWR_CMD2TRB_READ: KHB answer error - outbuf[0] << 16 | status  */
	LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,outbuf[0] << 16 | status);
    }
  }

  return status;
}


status_code PWR_CheckTRB(PRH_VAR_TYPE trbcmd,UINT32 expected_outbuf,ALM_VAR_ID alm_id1,ALM_VAR_ID alm_id2){
  status_code status;
  UINT16 combuf=(UINT16)trbcmd;
  UINT32 outbuf;
  status = HK_KHB_Cmd2FE(KHB_TRACKER_RELAYS,1,sizeof(outbuf)/2,&combuf,(UINT16*)&outbuf,PWR_TRB_HK_TIMEOUT);
  if(status!=CM_RC_SUCCESSFUL){
    /*@LOG KHB command failed on CheckTRB */
    ALM_WriteLog(ALM_TRACE_ID,alm_id1);
    return status;
  }
  if(expected_outbuf!=outbuf)
    {
      /*@LOG CheckTRB: answer is not the same as 'expected' */
      ALM_WriteLog(ALM_TRACE_ID,alm_id2);
      status=CM_RC_TRB_ERROR;
    }
  return status;
}




status_code PWR_IF_CMD2PSB(UINT16 cmd,ALM_VAR_ID *psb_almid) {
  return PWR_CMD2PSB(cmd,TM_PSB_ALARM,CM_OFF,(*psb_almid)++,(*psb_almid)++,PWR_PSB_STANDARD_ANSWER) == CM_RC_SUCCESSFUL;
}

status_code PWR_IF_CMD2TOFHV(BYTE idx,BOOL isipm1,ALM_VAR_ID *psb_almid) {
  status_code s = PWR_CMD2PSB(PRH_ARR_HVB_COMMANDS[idx],
			    isipm1?TM_TOFHV_HOT_ALARM:TM_TOFHV_COLD_ALARM,CM_ON,
			    (*psb_almid)++,(*psb_almid)++,0xFECE);
  if(s!=CM_RC_SUCCESSFUL) {
    /*@LOG PWR_HVSetting: failed cmd to HV board - idx of HVB_COMMANDS*/
    LU_INFN_LOG(LU_WARNING|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,idx);
  }
  return (s==CM_RC_SUCCESSFUL);
}
     
status_code PWR_IF_CALO_FE(BYTE idx,ALM_VAR_ID *psb_almid) {
return   PWR_CMD2PSB(PRH_ARR_PSB_CALO_FE[idx],
		     TM_PSB_ALARM,CM_OFF,
		     (*psb_almid)++,(*psb_almid)++,
		     PWR_PSB_STANDARD_ANSWER) == CM_RC_SUCCESSFUL;
}

status_code PWR_IF_CALO_FE_ON(BYTE idx,ALM_VAR_ID *psb_almid) {
return   PWR_CMD2PSB(PRH_ARR_PSB_CALO_FE_ON[idx],
		     TM_PSB_ALARM,CM_OFF,
		     (*psb_almid)++,(*psb_almid)++,
		     PWR_PSB_STANDARD_ANSWER) == CM_RC_SUCCESSFUL;
}



#define IF_CHKTRB(cmd,rep) (PWR_CheckTRB(cmd,rep,trb_almid++,trb_almid++) == CM_RC_SUCCESSFUL) 

#define PWR_TRB_MOSFET_MASK 0x0447

status_code PWR_TRBSetting(UINT16 trk_bias_mask){
  CM_HOT_COLD ipm_trb;
  status_code status=CM_RC_DO_POWER_OFF_ON,s;
  ALM_VAR_ID trb_almid=ALM_TRBSET_FIRSTERROR;
  UINT16 unused;
  
  PWR_TRB trb;
  CM_HOT_COLD hc;
  PWR_TRB_FE fe;

  UINT16 ans[PWR_TRB_MAX][CM_HOT_COLD_MAX][2];
  UINT16 action[PWR_TRB_MAX][CM_HOT_COLD_MAX] = {{0,0},{0,0}};
  UINT16 onoff[PWR_TRB_MAX][CM_HOT_COLD_MAX] = {{0,0},{0,0}};
  static UINT16 MASK[PWR_TRB_FE_MAX] = {0x0003,0x003C,0x03C0,0x3C00};
  UINT16 x;
  UINT16 action_flag=0;
#warning deve essere dichiarata qui questa var ?
  ALM_VAR_ID psb_almid=0;
  UINT16 trb1_set = PRH_VAR_PWR_TRB1_SET & trk_bias_mask;
  UINT16 trb2_set = PRH_VAR_PWR_TRB2_SET & trk_bias_mask;

  UINT16 des[PWR_TRB_MAX][CM_HOT_COLD_MAX] = {
    {PWR_TRB_MOSFET_MASK & trb1_set,
     PWR_TRB_MOSFET_MASK & trb2_set},
    {PWR_TRB_MOSFET_MASK & trb1_set,
     PWR_TRB_MOSFET_MASK & trb2_set}
  };


  ipm_trb = PWR_ipm_hot_cold[PWR_IPM_34];

  if(! PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TRB_S9004_34_ON],&psb_almid))
     return status;
     
  /*
    // fix the TRB board communication error

    for(trb=PWR_TRB_MIN;trb<PWR_TRB_MAX;trb++)
    for(hc=CM_HOT;hc<CM_HOT_COLD_MAX;hc++) {
    if(PWR_CMD2TRB_READ(trb,hc,ans[trb][hc])!=CM_RC_SUCCESSFUL)
    return status;
    }
  */

  des[PWR_TRB1][ipm_trb]=trb1_set;
  des[PWR_TRB2][ipm_trb]=trb2_set;
  
  // fix the TRB board communication error
  for(trb=PWR_TRB_MIN;trb<PWR_TRB_MAX;trb++)
    for(hc=CM_HOT;hc<CM_HOT_COLD_MAX;hc++) 
      ans[trb][hc][1]= 0x3FFF & (~des[trb][hc]);
      

  /*
    by the diagram the table is:
    
    ANS   DES   ACTION   ONOFF
    0     0      0        0     
    0     1      1        1 
    1     0      1        0
    1     1      0        1
  */
  
  for(trb=PWR_TRB_MIN;trb<PWR_TRB_MAX;trb++)
    for(hc=CM_HOT;hc<CM_HOT_COLD_MAX;hc++) {
      action[trb][hc] = (ans[trb][hc][1] ^ des[trb][hc]) & 0x3FFF;
      onoff [trb][hc] =  des[trb][hc] & 0x3FFF;
      action_flag |= action[trb][hc];
    }

  if(action_flag) {
    if(! PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TRB_S9004_ALL_ON],&psb_almid))
      return status;
    
    OS_piTaskSuspend(PRH_VAR_PSB_TRB_S9004_ALL_ON_DELAY);
    
    for(trb=PWR_TRB_MIN;trb<PWR_TRB_MAX;trb++)
      for(hc=CM_HOT;hc<CM_HOT_COLD_MAX;hc++)
	for(fe=PWR_TRB_FE_MIN;fe<PWR_TRB_FE_MAX;fe++) 
	  if(action[trb][hc] & MASK[fe]) {
	    x=(onoff[trb][hc] & MASK[fe]) >> (fe==0 ? 0 : (2*(2*fe-1) ));
	    if(PWR_CMD2TRB_SET(trb,hc,fe,x) != CM_RC_SUCCESSFUL)
	      return status;
	  }
  }

  if( ( (PWR_TRB_MOSFET_MASK & trb1_set) != PWR_TRB_MOSFET_MASK) ||
      ( (PWR_TRB_MOSFET_MASK & trb2_set) != PWR_TRB_MOSFET_MASK)
      ) 
    {
      if(! PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TRB_S9004_34_ON],&psb_almid))
	return status;
    }
  else if(! PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TRB_S9004_OFF],&psb_almid))
    return status;
  
  return CM_RC_SUCCESSFUL;
}








void PWR_DcdcOFF(BOOL do_12_any_case){
  status_code status;
  PRH_VAR_PAMELA_ON=0;
  status = PWR_SendTC(TM_PS_OFF);
  // status = PWR_CMD2PSB(PRH_VAR_PSB_OFF,TM_PSB_ALARM,ALM_DCDC_PWROFF_KHBERROR,ALM_DCDC_PWROFF_CCERROR);
  if(do_12_any_case || status!=CM_RC_SUCCESSFUL)
    PWR_SwitchOff_IPM(PWR_IPM_12);
  PWR_SwitchOff_IPM(PWR_IPM_34);
  PWR_SwitchOff_IPM(PWR_IPM_56);
}

status_code PWR_HLSetting(){
  status_code status;
  status = PWR_SendTC_PS(TM_KHB_PWR_33_OFF);
  
  if (status == CM_RC_SUCCESSFUL)
    {
      if(PRH_VAR_POWER_KHB==CM_HOT){//HOT
	status = PWR_SendTC_PS(TM_KHB_PWR_33_HOT_ON);
	if (status != CM_RC_SUCCESSFUL) 
	  /*@LOG PWR_HLSetting: error sendiing TM_KHB_PWR_33_HOT_ON - status */
	  LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
	status = HK_KHB_SetHotCold(CM_HOT);
	if (status != CM_RC_SUCCESSFUL)
	  /*@LOG PWR_HLSetting: error setting HK_KHB_SetHotCold(CM_HOT) - status */
	  LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
      }
      else{//COLD
	status = PWR_SendTC_PS(TM_KHB_PWR_33_COLD_ON);
	if (status != CM_RC_SUCCESSFUL)
	  /*@LOG PWR_HLSetting: error sendiing TM_KHB_PWR_33_COLD_ON - status */
	  LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
	status = HK_KHB_SetHotCold(CM_COLD);
	if (status != CM_RC_SUCCESSFUL)
	  /*@LOG PWR_HLSetting: error setting HK_KHB_SetHotCold(CM_COLD) - status */
	  LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
      }
    }
  return status;
}



status_code PWR_HVSetting()
{
  status_code status=CM_RC_DO_POWER_OFF_ON;
  ALM_VAR_ID psb_almid=ALM_HV_FIRSTERROR;
  BOOL isipm1 = ( PWR_output_values_ipm[PWR_IPM_1] == CM_ON );
  
  if(!(
     PWR_IF_CMD2TOFHV(0,isipm1,&psb_almid) &&
     PWR_IF_CMD2TOFHV(1,isipm1,&psb_almid) &&
     PWR_IF_CMD2TOFHV(2,isipm1,&psb_almid) &&
     PWR_IF_CMD2TOFHV(3,isipm1,&psb_almid) &&
     PWR_IF_CMD2TOFHV(4,isipm1,&psb_almid) &&
     PWR_IF_CMD2TOFHV(5,isipm1,&psb_almid) &&
     PWR_IF_CMD2TOFHV(6,isipm1,&psb_almid) &&
     PWR_IF_CMD2TOFHV(7,isipm1,&psb_almid) &&
     PWR_IF_CMD2TOFHV(8,isipm1,&psb_almid) &&
     PWR_IF_CMD2TOFHV(9,isipm1,&psb_almid) &&
     PWR_IF_CMD2TOFHV(10,isipm1,&psb_almid) &&
     PWR_IF_CMD2TOFHV(11,isipm1,&psb_almid) 
     ))
    /* some of them get error successful */
    {
      /*@LOG PWR_HVSetting: failed first reset, retry - status */
      LU_INFN_LOG(LU_WARNING|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,0xBABE);
    }
  return CM_RC_SUCCESSFUL;
}


#define TOF_FE56_OFF 0x0000
#define TOF_FE12_OFF 0x1418
#define TOF_FE34_OFF 0x150B
#define TOF_FE56_ON 0x00C5
#define TOF_FE12_ON 0x14DD
#define TOF_FE34_ON 0x15CE

status_code PWR_PSBforTOFSetting(BOOL switchon){
  
  status_code status = CM_RC_SUCCESSFUL;
  ALM_VAR_ID psb_almid=ALM_PSBTOFSET_FIRSTERROR;  
  PWR_IF_CMD2PSB(TOF_FE56_OFF,&psb_almid);
  PWR_IF_CMD2PSB(TOF_FE12_OFF,&psb_almid);
  PWR_IF_CMD2PSB(TOF_FE34_OFF,&psb_almid);

  if(switchon){
    if( 
       PWR_IF_CMD2PSB(TOF_FE56_ON,&psb_almid) &&
       PWR_IF_CMD2PSB(TOF_FE12_ON,&psb_almid) &&
       PWR_IF_CMD2PSB(TOF_FE34_ON,&psb_almid)
       )
      status =  CM_RC_SUCCESSFUL;
    else
      status = CM_RC_DO_POWER_OFF_ON;
  }
  return status; 
  
}
     
status_code PWR_PSBSetting(){
  status_code status=CM_RC_DO_POWER_OFF_ON;
  ALM_VAR_ID psb_almid=ALM_PSBSET_FIRSTERROR;
  BOOL isipm1;
  isipm1 = ( PWR_output_values_ipm[PWR_IPM_1] == CM_ON );
  


  if(
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TRIGGER_OFF],&psb_almid)    &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TOF_5_6_S9004],&psb_almid)  &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_S4],&psb_almid)             &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_ANTI],&psb_almid)           &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_HV_CONT_PB],&psb_almid)     &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_PULSER],&psb_almid)         &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TRB_S9004],&psb_almid)      &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_CALO_DSP_1_2],&psb_almid)   &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_CALO_DSP_3_4],&psb_almid)   &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TOF_1_2_S9006],&psb_almid)  &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TOF_3_4_S9006],&psb_almid)  &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TOF_5_6_S9006],&psb_almid)  &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TRACKER_DSP_1],&psb_almid)  &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TRACKER_DSP_2],&psb_almid)  &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_S4_ADC],&psb_almid)         &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TOF_DSP],&psb_almid)        &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TRIGGER],&psb_almid)        &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_IDAQ],&psb_almid)           &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TRACKER_SENSOR],&psb_almid) &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TOF_1_2_S9004],&psb_almid)  &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_TOF_3_4_S9004],&psb_almid)  &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_PMT_1],&psb_almid)          &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_PMT_2],&psb_almid)          &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_COMMANDS[PWR_PSB_PMT_3],&psb_almid)          &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_CALO_FE_OFF[0],&psb_almid)  &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_CALO_FE_OFF[1],&psb_almid)  &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_CALO_FE_OFF[2],&psb_almid)  &&
     PWR_IF_CMD2PSB(PRH_ARR_PSB_CALO_FE_OFF[3],&psb_almid)  
     )
    /* all of them were successful */
    status=CM_RC_SUCCESSFUL;
  else
    /* some of functions have failed */
    status=CM_RC_DO_POWER_OFF_ON;
  return status;
}

status_code PWR_CalFe57(BOOL iscustom){
  status_code status=CM_RC_SUCCESSFUL;
  ALM_VAR_ID psb_almid;
  if(PRH_VAR_CAL_OK){
    status=CM_RC_DO_POWER_OFF_ON;
    OS_piTaskSuspend(PRH_VAR_PSB_CALOFE_DELAY);
    if(iscustom){
      psb_almid=ALM_PSBSETCALCUSTOM_FIRSTERROR;
      
      /*       if(PWR_CMD2PSB(PRH_VAR_PSB_CALO_FE_1,TM_PSB_ALARM,psb_almid++,psb_almid++,PWR_PSB_STANDARD_ANSWER) == CM_RC_SUCCESSFUL) */
      /* 	if(PWR_CMD2PSB(PRH_VAR_PSB_CALO_FE_2,TM_PSB_ALARM,psb_almid++,psb_almid++,PWR_PSB_STANDARD_ANSWER) == CM_RC_SUCCESSFUL) */
      /* 	  if(PWR_CMD2PSB(PRH_VAR_PSB_CALO_FE_3,TM_PSB_ALARM,psb_almid++,psb_almid++,PWR_PSB_STANDARD_ANSWER) == CM_RC_SUCCESSFUL) */
      /* 	    if(PWR_CMD2PSB(PRH_VAR_PSB_CALO_FE_4,TM_PSB_ALARM,psb_almid++,psb_almid++,PWR_PSB_STANDARD_ANSWER) == CM_RC_SUCCESSFUL) */
      /* 	      status=CM_RC_SUCCESSFUL; */
      
      if(
	 PWR_IF_CALO_FE(0,&psb_almid) && 
	 PWR_IF_CALO_FE(1,&psb_almid) && 
	 PWR_IF_CALO_FE(2,&psb_almid) && 
	 PWR_IF_CALO_FE(3,&psb_almid)
	 )
	status=CM_RC_SUCCESSFUL;
      
    }

    else{
      psb_almid=ALM_PSBSETCAL_FIRSTERROR;

      if(
	 PWR_IF_CALO_FE_ON(0,&psb_almid) && 
	 PWR_IF_CALO_FE_ON(1,&psb_almid) && 
	 PWR_IF_CALO_FE_ON(2,&psb_almid) && 
	 PWR_IF_CALO_FE_ON(3,&psb_almid)
	 )
	status=CM_RC_SUCCESSFUL;

/*       if(PWR_CMD2PSB(PRH_VAR_PSB_CALO_FE_1_ON,TM_PSB_ALARM,psb_almid++,psb_almid++,PWR_PSB_STANDARD_ANSWER) == CM_RC_SUCCESSFUL) */
/* 	if(PWR_CMD2PSB(PRH_VAR_PSB_CALO_FE_2_ON,TM_PSB_ALARM,psb_almid++,psb_almid++,PWR_PSB_STANDARD_ANSWER) == CM_RC_SUCCESSFUL) */
/* 	  if(PWR_CMD2PSB(PRH_VAR_PSB_CALO_FE_3_ON,TM_PSB_ALARM,psb_almid++,psb_almid++,PWR_PSB_STANDARD_ANSWER) == CM_RC_SUCCESSFUL) */
/* 	    if(PWR_CMD2PSB(PRH_VAR_PSB_CALO_FE_4_ON,TM_PSB_ALARM,psb_almid++,psb_almid++,PWR_PSB_STANDARD_ANSWER) == CM_RC_SUCCESSFUL) */
/* 	      status=CM_RC_SUCCESSFUL; */

    }
   }
  return status;
}


status_code PWR_InitBoard_twice() {
  status_code s=HK_KHB_InitBoard();
  if(s) {
    /*@LOG PWR_InitBoard_twice: failed first reset, retry - status */
    LU_INFN_LOG(LU_WARNING|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,s);
    if(PRH_VAR_PWR_KHB_INITBOARD_TWICE_DELAY)
      OS_piTaskSuspend(PRH_VAR_PWR_KHB_INITBOARD_TWICE_DELAY);    
    s=HK_KHB_InitBoard();
    if(s) {
      /*@LOG PWR_InitBoard_twice: failed second attempt: error in reset! - s */
      LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,s);
    }
  }
  return s;
}

status_code PWR_DcdcON(){
  status_code status = CM_RC_SUCCESSFUL;

  /*@LOG PWR_DcdcON ...*/
  LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,PRH_VAR_POWER_MODE);  

  switch(PRH_VAR_POWER_MODE){
  case PWRMODE_HOT:
    status = PWR_SendTC_PS(TM_PS_HOT);
    if(status == CM_RC_SUCCESSFUL) {
      status = HK_KHB_SetHotCold(CM_HOT);
      if (status == CM_RC_SUCCESSFUL)
	{
	  status = PWR_InitBoard_twice();
	  if(status == CM_RC_SUCCESSFUL)
	    {
	      status = PWR_SendTC_PS(TM_PS_RESET);
	      if(status == CM_RC_SUCCESSFUL) {
		status=PWR_CalFe57(FALSE);	    
		if (status == CM_RC_SUCCESSFUL)
		  {
		    // Setting Parameters for HOT MODE
		    PRH_VAR_TB_LINK=1; //HOT
		  }
	      }
	    }
	}
    }
    if(status!=CM_RC_SUCCESSFUL) {
      /*@LOG PWR_DcdcON - PWRMODE_HOT : - status */
      LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
      status=CM_RC_DO_POWER_OFF_ON;
    }
    break;
  case PWRMODE_COLD:
    status = PWR_SendTC_PS(TM_PS_HOT);			
    if (status == CM_RC_SUCCESSFUL)
      {	
	status = PWR_SendTC_PS(TM_PS_COLD);			
	if (status == CM_RC_SUCCESSFUL)
	  {
	    status = HK_KHB_SetHotCold(CM_COLD);
	    if (status == CM_RC_SUCCESSFUL)
	      {
		status = PWR_InitBoard_twice();
		if(status == CM_RC_SUCCESSFUL)
		  {
		    status = PWR_SendTC_PS(TM_PS_RESET);
		    if (status == CM_RC_SUCCESSFUL) {
		      status=PWR_CalFe57(FALSE);	  
		      if (status == CM_RC_SUCCESSFUL)
			{
			  status=PWR_PSBforTOFSetting(TRUE);
			  PRH_VAR_TB_LINK=2; //COLD
			}
		    }
		  }
	      }
	  }
      }
    if(status!=CM_RC_SUCCESSFUL) {	
      /*@LOG PWR_DcdcON - PWRMODE_COLD : - status */
      LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
      status=CM_RC_DO_POWER_OFF_ON;
    }
    break;
  default:
    // CUSTOM
    status = PWR_HLSetting();
    if (status == CM_RC_SUCCESSFUL)
      {
	status = PWR_InitBoard_twice();
	if (status == CM_RC_SUCCESSFUL)
	  {
	    status = PWR_SendTC_PS(TM_PS_RESET);
	    if(status == CM_RC_SUCCESSFUL) {
	      PWR_PSBforTOFSetting(FALSE);
	      status = PWR_PSBSetting();
	      if (status == CM_RC_SUCCESSFUL)
		{
		  status= PWR_CalFe57(TRUE);
		  PRH_VAR_TB_LINK=PRH_VAR_TB_LINK_CUSTOM; //CUSTOM
		}
	    }
	    
	    
	  }
      }
  
    
    if(status!=CM_RC_SUCCESSFUL) {
        /*@LOG PWR_DcdcON - PWRMODE_CUSTOM : - status */
	LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
	status=CM_RC_DO_POWER_OFF_ON;
    }
    break;
  }
  /*@LOG PWR_DcdcON end of function - status */
  LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
  return status;
}




status_code PWR_TRB_On() 
{
  status_code status;

  PWR_SwitchOff_IPM(PWR_IPM_34);

  OS_piTaskSuspend(PRH_VAR_PSB_TRB_BIAS_WAIT);
		  
  status = PWR_TRBSetting(0x0003); // ALL OFF
  /*@LOG TRB Setting 0x0003 All Off - status */
  LU_INFN_LOG (LU_DEBUG_TRACE|LU_HA, LU_MASK(__FILEID__), __FILEID__, __LINE__, status);
  if(status == CM_RC_SUCCESSFUL) {
    
    if(PWR_ipm_hot_cold[PWR_IPM_34] == CM_HOT)
      PWR_SwitchOn_IPM(PWR_IPM_3);
    else
      PWR_SwitchOn_IPM(PWR_IPM_4);
    
    OS_piTaskSuspend(PRH_VAR_PSB_TRB_BIAS_WAIT);
    status = PWR_TRBSetting(0x3BBB); // BIAS OFF
    /*@LOG TRB Setting 0x3BBB Bias Off - status */    
    LU_INFN_LOG (LU_DEBUG_TRACE|LU_HA, LU_MASK(__FILEID__), __FILEID__, __LINE__, status);
    if(status == CM_RC_SUCCESSFUL) {
      OS_piTaskSuspend(PRH_VAR_PSB_TRB_BIAS_WAIT);
      status = PWR_TRBSetting(0x3FFF); // ALL ON
      /*@LOG TRB Setting 0x3FFF All On - status */    
      LU_INFN_LOG (LU_DEBUG_TRACE|LU_HA, LU_MASK(__FILEID__), __FILEID__, __LINE__, status);
    }
  }
  /*@LOG PWR_TrbOn end of function - status */
  LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
  return status;
}
