/****************************************************************************
 *  F i l e   D a t a                                                        
 *  $Id: ALM_Alarm_INFN.c,v 1.1.1.1 2006/04/25 09:00:20 kusanagi Exp $
 *  $Revision: 1.1.1.1 $
 *  $Date: 2006/04/25 09:00:20 $
 *  $RCSfile: ALM_Alarm_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: kusanagi $
 *               :                                                           
 ****************************************************************************
 *  U p d a t i n g                                                          

 *  $Log: ALM_Alarm_INFN.c,v $
 *  Revision 1.1.1.1  2006/04/25 09:00:20  kusanagi
 *  These program extract in an XML format the info contained into the ROOT files generated by YODA from the PAMELA data. To visualize the XML files in a more human readable format a collection of XSL files are given in the Data subfolder.
 *
 *  Revision 1.24  2005/03/13 18:10:23  sebastiani
 *  fix:correct logging khb_reg
 *
 *  Revision 1.23  2005/03/06 14:54:46  sebastiani
 *  version running on 06 03 2005
 *
 *  Revision 1.22  2005/02/22 18:09:25  sebastiani
 *  various bugfixes
 *
 *  Revision 1.21  2005/02/21 14:26:01  sebastiani
 *  TSB bugfixes.
 *
 *  Revision 1.20  2005/01/10 14:02:12  faber
 *  TRG,AC_1,AC_2,TOF Error Handler reviewed
 *
 *  Revision 1.19  2005/01/07 15:41:51  sebastiani
 *  fix alarm precedure
 *  add exp 64 delay patch
 *  removed unused sleep
 *
 *  Revision 1.18  2004/12/20 14:02:04  faber
 *  @LOG entry introduced in all ALM_WriteLog occurrences
 *
 *  Revision 1.17  2004/12/15 09:12:50  sebastiani
 *  maks contruction well defined in
 *  ALM_FE_Acquisition_Check
 *
 *  Revision 1.16  2004/12/02 10:43:38  sebastiani
 *  fix AC
 *  fix CAL
 *  fix HK BUFTYPE
 *
 *  Revision 1.15  2004/11/30 11:51:53  faber
 *  AC+AC2 software moved into AC_1 AC_2
 *  new calibration and initialization for AC
 *  first version,never run
 *
 *  Revision 1.14  2004/11/19 15:14:52  sebastiani
 *  PRH_EXTERN_{VAR,ARR,TABLE} removed and put them on the autogenerated parameter heeader file
 *
 *  Revision 1.13  2004/10/18 15:09:24  faber
 *  *** empty log message ***
 *
 *  Revision 1.12  2004/10/04 13:59:05  alfarano
 *  fixed some return code in run manager
 *
 *  Revision 1.11  2004/10/01 11:13:21  sebastiani
 *  TIMEOUT S4 calib fix
 *
 *  Revision 1.10  2004/10/01 08:48:10  sebastiani
 *  TRD alarma renamed TRD_S4  - S4 Alarm renamed S4_POWER
 *  Callback function into DAQ_SendCmd2PIFWaitDAQReply_internal
 *
 *  Revision 1.9  2004/09/22 15:54:54  alfarano
 *  S4 functions
 *
 *  Revision 1.8  2004/09/13 14:16:53  faber
 *  ErrorHandler for TOF/TRG + Test function TOF/TRG
 *
 *  Revision 1.7  2004/08/31 09:08:35  sebastiani
 *  fix warning
 *
 *  Revision 1.6  2004/08/27 13:30:39  alfarano
 *  cvs header
 *
 *  Revision 1.1  2003/10/03 16:12:26  faber
 *  *** empty log message ***
 *
 *                                                                           
 *****************************************************************************/
/*============================= Include File ================================*/
#include <src/INFN/LU_SourceFileID_INFN.h>
#define __FILEID__ _ALM_Alarm_INFN__c

#include <src/INFN/PRH_ParamHandler_INFN.h>
#include <src/INFN/LU_LogUtility_INFN.h>
#include <src/INFN/PRH_ParamHandler_INFN_auto.h>
LU_DECL_MASK();

#include <src/INFN/DAQ_IDAQ_INFN.h>
#include <src/INFN/CM_Common_INFN.h>
#include <src/INFN/KHB_Driver_INFN.h>
#include <src/INFN/CH_CommandHandler_INFN.h>
#include <src/INFN/HK_Manager_INFN.h>
#include <src/INFN/HB_HKBuffer_INFN.h>
#include <src/INFN/ALM_Alarm_INFN.h>
#include <src/INFN/MH_ModeHandler_INFN.h>
#include <src/INFN/CAL_Calorimeter_INFN.h>
#include <src/INFN/TRK_Tracker_INFN.h>
#include <src/INFN/TRD_TransRadDetector_INFN.h>
#include <src/INFN/S4_INFN.h>
#include <src/INFN/AC_Anticoincidence_INFN.h>
#include <src/INFN/TRG_Trigger_INFN.h>
#include <src/INFN/TOF_TimeOfFlight_INFN.h>
#include <src/INFN/SCM_Manager_INFN.h>

/*============================ Global define ================================*/






UINT16 ALM_FE_Acquisition_Check()
{
  status_code status;
  UINT16 mask = KHB_STS_ALARM_IDAQ  | KHB_STS_ALARM_TRG;
  UINT16 status_reg;

  if(PRH_VAR_TOF_OK)
     mask|=KHB_STS_ALARM_TOF;

  if (PRH_VAR_AC_1_OK)
    mask|=KHB_STS_ALARM_AC_1;

  if(PRH_VAR_AC_2_OK)
    mask|=KHB_STS_ALARM_S4_ADC_AC_2;

  if (PRH_VAR_CAL_OK)
    mask|=KHB_STS_ALARM_CALO;
  
  if (PRH_VAR_TRK_OK)
    mask|=KHB_STS_ALARM_TRK;

  if(PRH_VAR_S4_OK && (PRH_VAR_S4_WORKING || PRH_VAR_S4_ATTEMPT ))
    mask |= KHB_STS_ALARM_S4_ADC_AC_2 | KHB_STS_ALARM_S4_FE;  

  mask &= PRH_VAR_MASK_ACQ_ALARM;

  status = HK_ReadKHBStatusRegister(&status_reg);

  if (status/* == CM_RC_KHB_ERROR*/)
    status_reg = ALM_KHB_INVALID_REGISTER;
  
  status_reg &=mask;
  PRH_VAR_GOM_DURING_ALARM = MH_GetGOM();	
  return status_reg;  
}

status_code ALM_FE_Alarm_Check(UINT16 loc_mask,ALM_VAR_ID trace_id) {
  return ALM_FE_Alarm_Check_general(loc_mask,trace_id,KHB_ALARM_MASK_ALL);
}

status_code ALM_FE_Alarm_Check_general(UINT16 loc_mask,ALM_VAR_ID trace_id,UINT32 alarm_mask)
{
  UINT16 status_reg;
  status_code status;
 
  status = HK_ReadKHBStatusRegister(&status_reg);

  if (status == CM_RC_KHB_ERROR)
    {
      /*@LOG ALM_FE_Alarm_Check: error reading KHB status register */
      ALM_WriteLog(ALM_KHB_REGISTER,status_reg);
      status_reg = ALM_KHB_INVALID_REGISTER;
    }
  
  status_reg &= ((KHB_STS_ALARM_IDAQ | loc_mask) & PRH_VAR_MASK_ACQ_ALARM);
  
  if (status_reg)
    {
      PRH_VAR_GOM_DURING_ALARM = MH_GetGOM();
      /*@LOG ALM_FE_Alarm_Check: KHB - trace */
      ALM_WriteLog(ALM_TRACE_ID,trace_id);
      status = ALM_FE_AlarmAction_general(status_reg,alarm_mask);
    }
  else
    status = CM_RC_SUCCESSFUL;
  return(status);
}

status_code ALM_FE_AlarmAction(UINT16 khb_reg) {
  return ALM_FE_AlarmAction_general(khb_reg,KHB_ALARM_MASK_ALL);
}

status_code ALM_FE_AlarmAction_general(UINT16 khb_reg,UINT32 alarm_mask)
{
  status_code status=CM_RC_SUCCESSFUL;
  int n;
  UINT16 idaq_status;
  BOOL idaq_ok = FALSE;
  BOOL do_power_off_on = FALSE;
  BOOL do_reset = FALSE;
  BYTE old_pkt_type;
  UINT32 khb_alarm;
  /*@LOG Alarm Action ALM_KHB_REGISTER - khb_status_reg */
  ALM_WriteLog(ALM_KHB_REGISTER,khb_reg);

  if (khb_reg & KHB_STS_ALARM_IDAQ)
    {
      n=0;
      do 
      	{
	  status = DAQ_ReadStatusWord(&idaq_status);

	  if (status == CM_RC_KHB_ERROR)
	    {
	      /*@LOG Error reading  IDAQ Status Word - status */
	      ALM_WriteLog(ALM_KHB_REGISTER,status);
	      idaq_status = ALM_KHB_INVALID_REGISTER;
	      break;
	    }
	  
	  idaq_ok = ((idaq_status & DAQ_IDAQ_OK) != DAQ_IDAQ_OK);
	  n++;
	} while ((n < 3) && !idaq_ok);
      /*@LOG idaq_status register (trace) */
      ALM_WriteLog(ALM_IDAQ_REGISTER,idaq_status);
      
      if (!idaq_ok || status)
	{
	  status = CM_RC_DO_RESET_IF_ALM;
	  return(status);
	}  
      
      if (!( 
	    ((idaq_status & (  
			     (1<<DAQ_SW_CMD_ERR) |
			     (1<<DAQ_SW_IF_ERR) |
			     (1<<DAQ_SW_ETO) |
			     (1<<DAQ_SW_ATO)
			     )) == (1<<DAQ_SW_ATO)
	      ) 
	    && 
	    (khb_reg & KHB_STS_ALARM_ALL_FE)   
	    )
	  )
	{
	  status = CM_RC_DO_RESET_IF_ALM;
	  return status;
	}
    }


  if (khb_reg & KHB_STS_ALARM_TRG) {
    old_pkt_type=PM_pi_SetPktType(HB_PKTTYPE_TRG_ALARM);
    status = TRG_Error_Handler();
    do_power_off_on |= status == CM_RC_DO_POWER_OFF_ON;
    do_reset        |= status == CM_RC_DO_RESET_IF_ALM;
    
    PM_pi_SetPktType(old_pkt_type);
  }

  if ((khb_reg & KHB_STS_ALARM_AC_1)) {
    old_pkt_type=PM_pi_SetPktType(HB_PKTTYPE_AC_1_ALARM);
    status = AC_Error_Handler(DAQ_FE_AC_1);
    do_power_off_on |= status == CM_RC_DO_POWER_OFF_ON;
    do_reset        |= status == CM_RC_DO_RESET_IF_ALM;
    PM_pi_SetPktType(old_pkt_type);
  }

  if ((khb_reg & KHB_STS_ALARM_S4_ADC_AC_2 ))
    {
      status = HK_ReadKHBAlarmRegister(&khb_alarm);

      if(status != CM_RC_SUCCESSFUL)
	return CM_RC_DO_POWER_OFF_ON;

      khb_alarm &= alarm_mask;

      if((khb_alarm & KHB_ALARM_AC_2) && PRH_VAR_AC_2_OK){
	old_pkt_type=PM_pi_SetPktType(HB_PKTTYPE_AC_2_ALARM);
	status = AC_Error_Handler(DAQ_FE_AC_2);
	do_power_off_on |= status == CM_RC_DO_POWER_OFF_ON;
	do_reset        |= status == CM_RC_DO_RESET_IF_ALM;
	PM_pi_SetPktType(old_pkt_type);
      }

      if((khb_alarm & KHB_ALARM_S4_ADC) && PRH_VAR_S4_OK) {
	old_pkt_type=PM_pi_SetPktType(HB_PKTTYPE_S4_ALARM);
	status = S4_Error_Handler();
	do_power_off_on |= status == CM_RC_DO_POWER_OFF_ON;
	do_reset        |= status == CM_RC_DO_RESET_IF_ALM;
	PM_pi_SetPktType(old_pkt_type);	
      }

    }
  
  if (khb_reg & KHB_STS_ALARM_S4_FE) {
    PRH_VAR_S4_WORKING = 0;
    /*@LOG S4_FE alarm: dont use S4 - khb_reg */
    LU_INFN_LOG(LU_WARNING|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,khb_reg);
  }

  if ((khb_reg & KHB_STS_ALARM_TOF)) {
    old_pkt_type=PM_pi_SetPktType(HB_PKTTYPE_TOF_ALARM);
    status = TOF_Error_Handler();
    do_power_off_on |= status == CM_RC_DO_POWER_OFF_ON;
    do_reset        |= status == CM_RC_DO_RESET_IF_ALM;

    PM_pi_SetPktType(old_pkt_type);
  }
  
  if ((khb_reg & KHB_STS_ALARM_CALO)) {
    old_pkt_type=PM_pi_SetPktType(HB_PKTTYPE_CAL_ALARM);

    status = CAL_Error_Handler();
    do_power_off_on |= status == CM_RC_DO_POWER_OFF_ON;
    do_reset        |= status == CM_RC_DO_RESET_IF_ALM;
    
    PM_pi_SetPktType(old_pkt_type);
  }
  
  if ((khb_reg & KHB_STS_ALARM_TRK)) {
    old_pkt_type=PM_pi_SetPktType(HB_PKTTYPE_TRK_ALARM);
    
    status = TRK_Error_Handler();
    do_power_off_on |= status == CM_RC_DO_POWER_OFF_ON;
    do_reset        |= status == CM_RC_DO_RESET_IF_ALM;
    
    PM_pi_SetPktType(old_pkt_type);
  }
  if(do_power_off_on)
    return CM_RC_DO_POWER_OFF_ON;
  if(do_reset)
    return CM_RC_DO_RESET_IF_ALM;

  return CM_RC_SUCCESSFUL;
}

status_code ALM_Eto_Reset()
{
  UINT16 status_reg,n,idaq_status;
  status_code status;
  BOOL idaq_ok;
  
  status = HK_ReadKHBStatusRegister(&status_reg);

  if (status == CM_RC_KHB_ERROR)
    {
      /*@LOG ALM_Eto_Reset(): KHB Status Register reading error - status_reg */
      ALM_WriteLog(ALM_KHB_REGISTER,status_reg);
      status_reg = ALM_KHB_INVALID_REGISTER;
    }
  /*@LOG ALM_Eto_Reset(): KHB Status Register - status_reg */
  ALM_WriteLog(ALM_KHB_REGISTER,status_reg);
  
  n=0;
  do 
    {
      status = DAQ_ReadStatusWord(&idaq_status);
      
      if (status == CM_RC_KHB_ERROR)
	{
	  /*@LOG ALM_Eto_Reset(): error reading IDAQ status word - status */
	  ALM_WriteLog(ALM_KHB_REGISTER,status);
	  idaq_status = ALM_KHB_INVALID_REGISTER;
	  break;
	}
      idaq_ok = ((idaq_status & DAQ_IDAQ_OK) != DAQ_IDAQ_OK);
      n++;
    } while ((n < 3) && !idaq_ok);
  /*@LOG ALM_Eto_Reset(): idaq_status */
  ALM_WriteLog(ALM_IDAQ_REGISTER,idaq_status);
  
  return(CM_RC_DO_RESET_IF_ALM);
}

status_code ALM_Eto_Acquisition()
{
  UINT16 status_reg,n,idaq_status;
  status_code status=CM_RC_DO_RESET_IF_ALM;
  BOOL idaq_ok;
  
  n=0;
  do 
    {
      status = DAQ_ReadStatusWord(&idaq_status);

      if (status == CM_RC_KHB_ERROR)
	{
	  /*@LOG ALM_Eto_Reset(): error reading IDAQ status word - status */
	  ALM_WriteLog(ALM_KHB_REGISTER,status);
	  idaq_status = ALM_KHB_INVALID_REGISTER;
	  break;
	}
      
      idaq_ok = ((idaq_status & DAQ_IDAQ_OK) != DAQ_IDAQ_OK);
      
      n++;
    } while ((n < 3) && !idaq_ok);
  /*@LOG ALM_Eto_Reset(): idaq_status */  
  ALM_WriteLog(ALM_IDAQ_REGISTER,idaq_status);

  if(!idaq_ok || status) 
    status = CM_RC_DO_RESET_IF_ALM;
  else 
    {
      if ((idaq_status & 0x1109) != 0x9)
	status = CM_RC_DO_RESET_IF_ALM;
      else
	{
	  if (++PRH_VAR_TRIG > PRH_VAR_NTRIG) 
	    status = CM_RC_DO_POWER_OFF_ON; 
	  else
	    status = CM_RC_DO_INIT;
	}
    }
  return(status);
}
