/****************************************************************************
 *  F i l e   D a t a                                                        
 *  $Id: PM_PamManager_INFN.c,v 1.102 2005/03/23 10:22:14 sebastiani Exp $
 *  $Revision: 1.102 $ 
 *  $Date: 2005/03/23 10:22:14 $     
 *  $RCSfile: PM_PamManager_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: PM_PamManager_INFN.c,v $
 *  Revision 1.102  2005/03/23 10:22:14  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.101  2005/03/20 18:23:04  sebastiani
 *  old code for timers calcelled an Gas system
 *
 *  Revision 1.100  2005/03/13 18:12:46  sebastiani
 *  better logging in status, SetActiveState in correct position
 *
 *  Revision 1.99  2005/03/06 14:54:46  sebastiani
 *  version running on 06 03 2005
 *
 *  Revision 1.98  2005/02/21 14:26:01  sebastiani
 *  TSB bugfixes.
 *
 *  Revision 1.97  2005/02/21 08:58:29  sebastiani
 *  all log comments completed
 *
 *  Revision 1.96  2005/02/19 10:19:38  sebastiani
 *  ALM_S4_CALIB_00_HARD,ALM_S4_CALIB_00_SOFT,ALM_S4_128TRIGGER_0 added
 *
 *  Revision 1.95  2005/01/28 11:27:11  sebastiani
 *  CM_RC_DO_AGAINACQ added in the DecodeCode
 *
 *  Revision 1.94  2005/01/26 18:46:48  sebastiani
 *  new bug fixes for WS
 *
 *  Revision 1.93  2005/01/10 09:48:34  sebastiani
 *  fix warning
 *
 *  Revision 1.92  2004/12/20 14:02:04  faber
 *  @LOG entry introduced in all ALM_WriteLog occurrences
 *
 *  Revision 1.91  2004/12/17 12:46:40  faber
 *  ALARM REGISTER aligned to be 32 bit. memory aling core dump (should be) fixed
 *
 *  Revision 1.90  2004/12/15 09:26:40  sebastiani
 *  better use of PRH_VAR_AUTO_SCM_MODE and new log entry PAMELA_STATUS, shows
 *  all status of PM,RM,SCM
 *
 *  Revision 1.89  2004/11/23 22:54:06  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.88  2004/11/23 15:42:31  faber
 *  *** empty log message ***
 *
 *  Revision 1.87  2004/11/23 12:24:57  sebastiani
 *  fixed dcdcon procedure
 *
 *  Revision 1.86  2004/11/19 15:14:52  sebastiani
 *  PRH_EXTERN_{VAR,ARR,TABLE} removed and put them on the autogenerated parameter heeader file
 *
 *  Revision 1.85  2004/11/18 17:51:53  sebastiani
 *  added CAL_WRITE_FPGA_REG_I341_x
 *
 *  Revision 1.84  2004/11/18 16:02:34  sebastiani
 *  GAS/TRD removed
 *
 *  Revision 1.83  2004/11/10 17:00:00  sebastiani
 *  - GS_COMPILE directive introduced and be undef by default
 *  - automatic flush mechanism by run manager mailbox timeout
 *
 *  Revision 1.82  2004/11/05 16:43:07  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.81  2004/11/05 09:36:35  sebastiani
 *  first version of the PM state machine. tried but not deeply tested
 *
 *  Revision 1.80  2004/11/02 15:41:39  faber
 *  *** empty log message ***
 *
 *  Revision 1.79  2004/10/22 16:05:06  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.78  2004/10/19 16:59:27  sebastiani
 *  first text for IPM/ciclyc
 *
 *  Revision 1.77  2004/10/18 15:09:24  faber
 *  *** empty log message ***
 *
 *  Revision 1.76  2004/10/18 14:11:37  faber
 *  *** empty log message ***
 *
 *  Revision 1.75  2004/10/15 11:19:36  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.74  2004/10/04 13:59:05  alfarano
 *  fixed some return code in run manager
 *
 *  Revision 1.73  2004/09/28 15:36:25  sebastiani
 *  interrupt manager fix
 *
 *  Revision 1.72  2004/09/28 08:52:04  alfarano
 *  disabletmtc/savetmtc funciont call fix
 *
 *  Revision 1.71  2004/09/27 15:42:43  alfarano
 *  tracker sensor board functions
 *
 *  Revision 1.70  2004/09/17 15:01:00  faber
 *  LU_INFN_LOG flags fixing
 *
 *  Revision 1.69  2004/09/14 13:05:37  alfarano
 *  update TM constants and definitions
 *
 *  Revision 1.68  2004/09/13 16:07:46  alfarano
 *  *** empty log message ***
 *
 *  Revision 1.67  2004/09/09 14:52:55  sebastiani
 *  using PreparePage to send cmd to idaq/FE
 *  added some test
 *  added trigger param
 *  added/tested Force Send KHB_to_FE
 *  added/tested Send Cmd to IDAQ/FE
 *
 *  Revision 1.66  2004/09/08 10:39:12  faber
 *  *** empty log message ***
 *
 *  Revision 1.65  2004/08/31 09:08:35  sebastiani
 *  fix warning
 *
 *  Revision 1.64  2004/08/30 07:08:18  sebastiani
 *  little modify
 *
 *  Revision 1.63  2004/08/27 13:13:49  alfarano
 *  High voltage functions
 *
 *  Revision 1.62  2004/08/26 16:54:34  sebastiani
 *  version work fine
 *
 *  Revision 1.61  2004/08/05 16:19:07  sebastiani
 *  fix close run
 *  add cal handler error
 *  fix tmtc
 *  ok protocol betwen pm-rm-scm
 *
 *  Revision 1.60  2004/08/04 13:25:21  sebastiani
 *  first fix allarm procedure
 *
 *  Revision 1.59  2004/08/02 15:49:47  alfarano
 *  alarm handling , scm & pm communication rewrite
 *
 *  Revision 1.58  2004/08/02 12:20:24  sebastiani
 *  re-engeenering sw
 *
 *  Revision 1.57  2004/08/02 09:28:29  faber
 *  Stamp management into SMH_SetParam
 *  TS_PamManger TM_RMTest moved respectively into PM and RM as PM_MCMDTest and
 *  RM_MCMDTEst. TS_Test_INFN.c will be deleted soon.
 *
 *  Revision 1.56  2004/07/28 17:19:01  sebastiani
 *  better loggin status
 *
 *  Revision 1.55  2004/07/27 17:30:17  faber
 *  OBT can be now in second or milliseconds, depending of the situazion.
 *  OBT_s is used for FM compatibility, OBT_ms basically for MM infos
 *
 *  Revision 1.54  2004/07/21 14:08:32  sebastiani
 *  Fix close RUN we wait a event to close the run
 *  PM send Sint and don't wait for SintOK
 *  Header'Trailer Initialization
 *  FixPacketCounter
 *
 *  Revision 1.53  2004/07/20 14:36:26  sebastiani
 *  AC/CAL/TRK/TOF/TRG unmaksed all KHB alarms
 *  RM: Close Run before RunTrailer (send page 2)
 *
 *  Revision 1.52  2004/07/15 10:39:42  faber
 *  *** empty log message ***
 *
 *  Revision 1.51  2004/07/14 13:02:35  alfarano
 *  update calorimeter func
 *
 *  Revision 1.50  2004/07/12 09:51:49  faber
 *  external_data dir added with all commands inside. tgz creation rules remove.
 *  AUTO mode introduced:
 *
 *  Revision 1.49  2004/07/06 15:21:49  sebastiani
 *  some daq_reply inserted, MAX_TEMP_.... from 16K to 32K
 *
 *  Revision 1.48  2004/07/02 11:58:48  faber
 *  implemented intellingent http from the web: update_http_from_web.tgz added to the repository.
 *   update_commands_from_web.sh works now in 2 modes.
 *
 *  Revision 1.47  2004/06/22 08:57:01  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.46  2004/06/15 08:24:37  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.45  2004/06/04 14:24:38  sebastiani
 *  clear some files
 *
 *  Revision 1.44  2004/06/01 16:41:19  sebastiani
 *  EventReceive ANY
 *
 *  Revision 1.43  2004/05/26 17:48:25  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.42  2004/05/25 14:07:18  faber
 *  *** empty log message ***
 *
 *  Revision 1.41  2004/05/20 16:03:52  faber
 *  ACQ flow dev continuing
 *
 *  Revision 1.40  2004/05/12 14:46:14  faber
 *  *** empty log message ***
 *
 *  Revision 1.39  2004/04/29 07:46:29  sebastiani
 *  compilation ok
 *
 *  Revision 1.38  2004/04/26 10:56:04  faber
 *  imported diffs from TM branch (PWR_ module)
 *
 *  Revision 1.37  2004/04/23 14:37:30  tassa
 *  ops fix compilation!
 *
 *  Revision 1.36  2004/04/22 14:50:30  faber
 *  Purge TRD bad pointer bug fix
 *
 *  Revision 1.35  2004/03/08 15:49:09  alfarano
 *  improved handling functions for FE
 *
 *  Revision 1.34  2004/03/03 11:13:18  sebastiani
 *  gen_mcmd.pl bugfixes,other bugfixes
 *
 *  Revision 1.33  2004/03/01 17:46:45  tassa
 *  Non testato:
 *  TMTC sample e STORE in SCM
 *  send FECMD bloccante
 *  aggiunto MCMD to send FECMD
 *
 *  Revision 1.32  2004/02/27 15:40:46  tassa
 *  TMTC function moved in SCM MANAGER
 *  add function blocking to send FE command in HK MANAGER
 *
 *  Revision 1.31  2004/02/13 10:11:30  alfarano
 *  calorimeter initialization func and more
 *
 *  Revision 1.30  2004/01/28 12:50:26  alfarano
 *  *** empty log message ***
 *
 *  Revision 1.29  2004/01/22 08:58:30  sebastiani
 *  WAIT time introduced between DAQ and CMD/IF DMA programming
 *
 *  Revision 1.28  2003/12/19 11:05:37  faber
 *  TS_PamManager invoked from the PAM Manager
 *
 *  Revision 1.27  2003/12/11 18:39:37  alfarano
 *  bug fix GS_GasResume
 *
 *  Revision 1.26  2003/12/07 15:07:11  sebastiani
 *  GAS_TEST renamed to GAS_CONTAINER_PURGE
 *
 *  Revision 1.25  2003/12/06 10:53:41  alfarano
 *  update
 *
 *  Revision 1.24  2003/12/06 08:32:38  faber
 *  startup procedure tuned. TMTC sampling storing  at startup
 *
 *  Revision 1.23  2003/12/05 17:14:34  alfarano
 *  update
 *
 *  Revision 1.22  2003/12/03 14:36:51  faber
 *  more action definition about mcmd (setmode/purge_trd).
 *  SSt word better defined
 *
 *  Revision 1.21  2003/11/26 16:39:33  faber
 *  advancing development for power management
 *
 *  Revision 1.20  2003/11/21 11:15:54  faber
 *  bugfixes:
 *  SELECT_MODE min length is 8, not 7
 *  CALIBRATE length is 6, not 15
 *
 *  Revision 1.19  2003/11/19 15:48:37  faber
 *  *** empty log message ***
 *
 *  Revision 1.18  2003/11/18 17:13:15  sebastiani
 *  GPT enabled to print a "\n" every 60s directly on UART, only to check if the CPU is
 *  alive
 *
 *  Revision 1.17  2003/11/18 09:01:14  alfarano
 *  laben patch fixes some problems
 *
 *  Revision 1.16  2003/11/13 16:13:55  sebastiani
 *  dump_parameters flag added to WriteHBInfos(); Important bugfixed and better management with ChangeAcqMode and SetNotifyTask_SKETCHBOARD()
 *
 *  Revision 1.15  2003/11/06 10:27:12  faber
 *  HB_HKBuffer now implemented as multibuffer (as specified in the
 *  mass memory format). Only compilation, not tested
 *
 *  Revision 1.14  2003/11/04 11:36:35  alfarano
 *  deleted task in TM_TMTC manager and added to HK_Manager, added KHB buffer read task
 *
 *  Revision 1.13  2003/10/27 18:57:25  sebastiani
 *  Enable/Disable sampling/stoting of the TMTC introduced
 *
 *  Revision 1.12  2003/10/17 10:04:36  sebastiani
 *  allowed the pam manager to send a MCMDS inside itself
 *
 *  Revision 1.11  2003/09/22 09:59:35  faber
 *  new select mode definitions
 *
 *  Revision 1.10  2003/09/19 15:57:35  faber
 *  Large development update INFN software
 *
 *  Revision 1.9  2003/09/16 08:42:05  faber
 *  StoreOrb/Incl done / new LOG initialization
 *
 *  Revision 1.8  2003/09/15 17:46:27  faber
 *  HB_HKBuffer_INFN module introduced.
 *
 *  Revision 1.7  2003/09/12 10:57:41  faber
 *  development in proress (Working schedule module)
 *
 *  Revision 1.6  2003/09/10 16:15:52  faber
 *  PRH_EXTERN_VAR(XX_LOGMASK) removed (not needed any more)
 *
 *  Revision 1.5  2003/09/10 11:55:07  faber
 *  LU_MASK introduced. Log mask for module is now an unique array (PRH_ARR_LOG_MASK) indexed by __FILEID__
 *
 *  Revision 1.4  2003/09/10 10:32:37  faber
 *  Large implementation of PamManager/RunManager Pam Sowfare. (compiled,never run)
 *
 *  Revision 1.3  2003/08/29 11:34:09  faber
 *   PM_GetDownlinkIntervalTime and PM_GetDownlinkStartTime introduced (dummy
 *
 *  Revision 1.2  2003/08/22 07:57:08  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.1.1.1  2003/08/04 09:40:22  sebastiani
 *  Imported sources laben rel. 19.06.2003 integrated with pam2
 *
 *  Revision 1.3  2003/06/18 16:53:19  sebastiani
 *  Pam/Run Manager development update. ExpSeq sequence is receiven from the RunManager (simulator mode)
 *
 *  Revision 1.2  2003/06/12 15:15:55  sebastiani
 *  LogUtility support added
 *
 *  Revision 1.1  2003/06/09 16:39:50  sebastiani
 *  Moved pammanager Module (it's a task) in its own directory.
 *  fix directory path.
 *
 *  Revision 1.1  2003/06/05 10:31:12  wizard
 *  added PamMnager (empty skeleton),and other main dirs on INFN
 *
 *                                                                           
 *****************************************************************************/


/*============================= Include File ================================*/


#include <src/INFN/LU_SourceFileID_INFN.h>
#define __FILEID__ _PM_PamManager_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/PM_PamManager_INFN.h>
#include <src/BasicSW/RTEMSInterface/OS_rtems_p.h>
#include <src/INFN/SMH_SelectModeHandler_INFN.h>

#include <src/INFN/PWR_PowerHandler_INFN.h>

#ifdef TEST_I
//#include <src/INFN/TS_Test_INFN.h>
#endif // TEST_I


#include <src/INFN/OS_rtems_INFN_p.h>

#include <src/INFN/PM_PamManager_INFN.h>
#include <src/INFN/WS_WorkingSchedule_INFN.h>
#include <src/BasicSW/RTEMSInterface/OS_rtems_p.h>
#include <src/INFN/OS_rtems_INFN_p.h>
#include <src/MCMDManager/MCMDArea/MA_MCMDArea_p.h>

//#include <src/TM_TCManager/TMTCManager/TM_TMTCManager_p.h>
//#include <src/FileManager/FileSystem/FS_FileSystem_p.h>

#include <src/HKManager/HistoryArea/HA_HistoryArea_p.h>
#include <src/INFN/SMH_SelectModeHandler_INFN.h>
#include <src/INFN/MH_ModeHandler_INFN.h>
#include <src/INFN/HB_HKBuffer_INFN.h>
#include <src/INFN/HK_Manager_INFN.h>
#include <src/INFN/SCM_Manager_INFN.h>
#include <src/INFN/GS_Gas_INFN.h>
#include <src/INFN/MH_ModeHandler_INFN.h>
#include <src/INFN/PWR_PowerHandler_INFN.h>
#include <src/INFN/HV_INFN.h>
#include <src/SRAMManager/SRAMPageManager/SM_SRAMPageManager_p.h>
#include <src/FileManager/MMSUManager/FT_MMSUManager_p.h>
#include <src/BasicSW/CrimeaDriver/CD_CrimeaDriver_p.h>
#include <src/INFN/ALM_Alarm_INFN.h>

// for test procedures
#include <src/INFN/KHB_Driver_INFN.h>
#include <src/QualitySystem/DiagSupervisor/QS_DiagSupervisor_p.h>


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



/*============================== global types  ==============================*/



/*****************************************************************************/
/*=========================== Structure define ==============================*/


/*****************************************************************************/
/*============================ Enumerate define =============================*/

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

/*=== P A M   M A N A G E R   P R O V I D E D    I N T E R F A C E ==*/

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




/* the current ACQ Setting mode */
static RM_ACQ_SETTING  PM_AcqSetting;
static PM_INFN_STATUS PM_CurrentStatus; 
static PM_INFN_STATUS PM_Status_BeforeDownload; 
static PM_INFN_COMMAND PM_CurrentCommand;

/* counter of the ascending node since Pamela boot */
static UINT32 PM_AscendingNode_Counter;
static BOOL PM_PendingCalibration = FALSE;

static char *PM_Compilation_DATE;
static char *PM_Compilation_TIME;
static UINT32 *PM_ExternalTimeStamp;

static RM_OPCODES rm_saved_opcode;
static status_code rm_saved_code;
static BOOL rm_saved_flag;
static UINT32 pm_scm_action=0;
/* Automatic Mode: in automatic mode we have an utomatic (in flight) behavoir (automatic restart for ACQ after Downling, EEPROM read at startup, as in fligh mode.
   if AutoMode is off, no action are taken, (useful for testing ad debuggin) */

/* Periodic Actions translations: */
static TIM_INFN_ADDR   PM_Periodic_TIM[PM_INFN_COMMAND_MAX];
static PM_INFN_COMMAND PM_Periodic_Action[PM_INFN_COMMAND_MAX];
static SCM_ACTION      PM_Periodic_SCMAction[PM_INFN_COMMAND_MAX];
/* Periodic global variables: */
static BOOL PM_Periodic_DoFlag[PM_INFN_COMMAND_MAX];


void PM_ForceRunning_CallBack(rtems_id timer_id, void *action_ptr)
{
  PM_SendCommand(PM_FORCE_RUNNING);
}


void PM_Periodic_CallBack(rtems_id timer_id, void *action_ptr)
{
  PM_INFN_COMMAND action = *(PM_INFN_COMMAND*)action_ptr;
  if (PM_Periodic_DoFlag[action]) 
    PM_SendCommand(action);
}

#if 0
void PM_SaveTMTCValue_CallBack(rtems_id timer_id, void *suspend)
{
  if (PM_SaveTMTCFlag) 
    PM_SendCommand(PM_SAVE_TMTC_VALUES);
}

void PM_TSB_B_Start_CallBack(rtems_id timer_id, void *suspend)
{
  if (PM_DoTSB_B_Flag)
    PM_SendCommand(PM_TSB_B_CHECK);
}

void PM_TSB_T_Start_CallBack(rtems_id timer_id, void *suspend)
{
  if (PM_DoTSB_T_Flag)
    PM_SendCommand(PM_TSB_T_CHECK);
}
#endif

#ifdef SIMULATOR

/* use this variabile to send a simulated MCMD */
task PM_SIM_tkMCMDSender(task_argument unused) {
  void *arg;
  rtems_device_driver d;
  static unsigned char buf[50];
  int len=0;
  int c;
  while(1) {
    if( (c=console_inbyte_nonblocking(1)) != -1) {
	LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,c);

	/*
	  if(len<sizeof(buf)-1) {
	  buf[len++] = (unsigned char)c;
	  if(len == sizeof(buf)-1) {
	  while(len) {
	  console_outbyte_polled(0,buf[--len]);
	  }
	}
	}
	else {
      
	}
	*/
      //console_outbyte_polled(0,(char)c);
    }else
      OS_piTaskSuspend(200);
  }
}


rtems_name PM_SIM_name;
rtems_id   PM_SIM_id;
void PM_SIM_Init() {
  status_code status;
  unsigned int  OldPriority;

  status  =SUCCESSFUL;
  PM_SIM_name = rtems_build_name( 'M', 'C', 'M', 'S' );
  
  status =rtems_task_create(PM_SIM_name,3, 
			    RTEMS_MINIMUM_STACK_SIZE, 
			    RTEMS_DEFAULT_MODES,
			    RTEMS_DEFAULT_ATTRIBUTES,
			    &PM_SIM_id);
  if(status != SUCCESSFUL)
    LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);

  //  status = rtems_task_start(PM_SIM_id,(rtems_task_entry)PM_SIM_tkMCMDSender ,0);
  if(status != SUCCESSFUL)
    LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);

}

#endif // SIMULATOR

#ifdef DEBUG
unsigned short simulMCMD[PM_MCMD_MAX_WORD_SIZE];
char* simul_sm_body_p;
MA_HEADER_MCMD simul_headerMcmd;
static unsigned short int simul_mcmd_seqid=0;

void PM_SIM_FormatHeader(unsigned short int seqid,
		      unsigned char timetag,
		      unsigned char id,
		      unsigned char len,
		      unsigned short TT_MSW,
		      unsigned short TT_LSW) {
  simulMCMD[0]=seqid;
  simulMCMD[1]=(timetag?1:0)<<15 | (id & 0x00FF);
  simulMCMD[2]=len & 0x0FFF;
  simulMCMD[3]=TT_MSW;
  simulMCMD[4]=TT_LSW;
}

void PM_SIM_FormatHeaderSM(unsigned char bodylen) {
  PM_SIM_FormatHeader(simul_mcmd_seqid++,0,0x33,bodylen+8,0,0);
}


void PM_SIM_FormatSM(char mode,
		  unsigned short pnumber) {
  simulMCMD[5]=mode;
  simulMCMD[6]=pnumber;
  simul_sm_body_p=(char*)&simulMCMD[7];
}

void PM_SIM_Load_uc(unsigned char  x) { memcpy(simul_sm_body_p,&x,sizeof(x)); simul_sm_body_p+=sizeof(x); }
void PM_SIM_Load_us(unsigned short x) { memcpy(simul_sm_body_p,&x,sizeof(x)); simul_sm_body_p+=sizeof(x); }
void PM_SIM_Load_ui(unsigned int   x) { memcpy(simul_sm_body_p,&x,sizeof(x)); simul_sm_body_p+=sizeof(x); }

void PM_SIM_Send() {
  unsigned short id=simulMCMD[1] & 0x00FF;
  switch(id) {
  case ID_SELECT_MODE: 
    simul_headerMcmd.Type=SELECT_MODE; 
    break;
  default:
    simul_headerMcmd.Type=0xFFFFFFFF;
    break;
  }
  simul_headerMcmd.TimeTag = simulMCMD[1] >> 15;
  simul_headerMcmd.PtrMCMD = simulMCMD;
  simul_headerMcmd.Length  = simulMCMD[2] & 0x0FFF;
  PM_SubmitMCMD(&simul_headerMcmd);
}

void PM_SIM_send_sm() {
  PM_SIM_FormatHeaderSM(20);
  PM_SIM_FormatSM(0x10,10);
  PM_SIM_Send();
}

void PM_SIM_send_testdebug(unsigned short code) {
  PM_SIM_FormatHeaderSM(4);
  PM_SIM_FormatSM( SMH_FAMILY_TEST << 4 | SMH_TEST_DEBUG,1);
  PM_SIM_Load_us(code);
  PM_SIM_Send();
}

#endif // DEBUG


/*****************************************************************************/
/* @Function: PM_opInitPamManager_INFN                                       */
/* @Purpose :                                                                */
/*  Operation initialize the PamManager object.                              */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

void PM_PeriodicInit() {
  PM_INFN_COMMAND c;
  PM_Periodic_TIM[PM_CYCLIC_ACQUISITION]=PM_DOCYCLIC_TIM;
  PM_Periodic_TIM[PM_SAVE_TMTC_VALUES]  =PM_SAVETMTC_TIM;
  PM_Periodic_TIM[PM_TSB_T_CHECK]       =PM_TSB_T_TIM;
  PM_Periodic_TIM[PM_TSB_B_CHECK]       =PM_TSB_B_TIM;

  PM_Periodic_SCMAction[PM_CYCLIC_ACQUISITION] = SCM_CYCLIC_ACQUISITION;
  PM_Periodic_SCMAction[PM_SAVE_TMTC_VALUES]   = SCM_SAVE_TMTC_VALUES;    
  PM_Periodic_SCMAction[PM_TSB_T_CHECK]        = SCM_TSB_T_CHECK;    
  PM_Periodic_SCMAction[PM_TSB_B_CHECK]        = SCM_TSB_B_CHECK; 

  for(c=PM_PERIODIC_BASE;c<PM_PERIODIC_NO;c++) {
    PM_Periodic_DoFlag[c] = FALSE;    
    PM_Periodic_Action[c] = c;
  }
}

status_code PM_InitPamManager_INFN(void)
{
  status_code status;
  unsigned int  OldPriority;
    
    status  =SUCCESSFUL;


    /* Task initialization                           */
    if ((status=OS_piTaskReady_INFN(PM_INFN_TASK,PM_tkPamManager_INFN)) != SUCCESSFUL) {
      /* Task is not correctly started             */
      //HA_piLogHistoryEntry10(HA_E10_SW_MD,HA_E10_TSK_READY_ERR,status);    
      /*@LOG Task is not correctly started - status */
      LU_INFN_LOG(LU_FATAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);      
      status  =UNSATISFIED;
    }

    if ((status=OS_piTaskPriority_INFN(PM_INFN_TASK,PM_INFN_PRIORITY,&OldPriority)) != SUCCESSFUL)  {
      /* Task priority is not correctly updated    */
      //HA_piLogHistoryEntry10(HA_E10_SW_MD,HA_E10_TSK_PRIORITY_ERR,status);    
      /*@LOG Task priority is not correctly updated - status */
      LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);      
      status  =UNSATISFIED;
    }

    PM_AscendingNode_Counter = 0;
    PM_AcqSetting = RM_ACQ_SETTING_NULL;    
    /* store che compilation timestamps: */
    // PM_Compilation_DATE = __DATE__;
    // PM_Compilation_TIME = __TIME__;


    PM_PeriodicInit();


    return (status);

}

/*****************************************************************************/
/* @Function: PM_SendSINT_OK                                                 */
/* @Purpose :                                                                */
/*  send a SINT_OK event to the PAM Manager. sent to notify that the run     */
/*  manager received the SINT and goes to IDLEOperation initialize the       */
/*  PamManager object.                                                       */
/*  By design, this routine should be invoked only by the PamManager         */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

void PM_SendSINT_OK() {
  status_code status;
  if( (status = OS_piEventSend(PM_INFN_TASK,OS_EVENT_SINT_OK)) != SUCCESSFUL)
    /*@LOG PM:fatal error receiving SINT_OK signal - status */
    LU_INFN_LOG(LU_FATAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
}

/*****************************************************************************/
/* @Function: PM_CheckSint_OK()                                              */
/* @Purpose :                                                                */
/* return true if a SINT event had been received (also clear the event)      */ 
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

BOOL PM_CheckSINT_OK() {
  rtems_event_set unused;
  return OS_piEventReceive(OS_EVENT_SINT_OK,RTEMS_NO_WAIT,0,&unused) == RTEMS_SUCCESSFUL;
}




/*****************************************************************************/
/* @Function: PM_opSndMsgPamManager_INFN                                     */
/* @Purpose :                                                                */
/*  Put message in PamManager MailBox.                                       */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name       @Message                                             */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code PM_SndMsgPamManager_INFN(MsgTsk* SndMsg) {
  rtems_status_code status;

  /* Send message to PamManager  task mailbox                */
  status =OS_piMsgQueueSend_INFN(PM_INFN_MAILBOX,(void*)SndMsg,sizeof(MsgTsk));
  if (status != SUCCESSFUL)
    {
      /*@LOG Fail during the send message to PamManager mailbox - status */
      LU_INFN_LOG(LU_FATAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    }
  return (status);
}

/*****************************************************************************/
/* @Function: PM_SendCommand                                                 */
/* @Purpose :                                                                */
/*  A wrapper of the PM_SndMsgPamManager_INFN to send only a command code    */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name       @Message                                            */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/


status_code PM_SendCommand(PM_INFN_COMMAND command) {
  MsgTsk SndMsg;
  SndMsg.Code = command;
  SndMsg.LlInfo = 0;
  return PM_SndMsgPamManager_INFN(&SndMsg);
}

status_code PM_SendTestCommand(UINT16 code,
			       UINT16 value1,UINT16 value2,
			       UINT16 value3,UINT16 value4) 
{
  MsgTsk SndMsg;
  BYTE *p = SndMsg.Info;
  SndMsg.Code = PM_INFN_TEST_PAM_MANAGER;
  CM_WRITE_BE_UINT16(p,code);
  CM_WRITE_BE_UINT16(p,value1);
  CM_WRITE_BE_UINT16(p,value2);
  CM_WRITE_BE_UINT16(p,value3);
  CM_WRITE_BE_UINT16(p,value4);
  return PM_SndMsgPamManager_INFN(&SndMsg);
}

#ifdef DEBUG
/* this funcion is used to force break point in case of message timeout */
unsigned int PM_FORCE_BREAKPOINT() {
  unsigned int s=SUCCESSFUL;
  return s;
}
#endif


/*****************************************************************************/
/* @Function: PM_tkPamManger_INFN                                            */
/* @Purpose :                                                                */
/*  The Pamela Manager task                                                  */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name       @Message                                            */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/


task PM_tkPamManager_INFN (task_argument unused) {
  MsgTsk        RxMsg;
  MsgTsk        SndMsg;
  status_code   mboxstatus;
  status_code   storestatus;
  unsigned int  MsgSize,fid;
  unsigned short ashort;
  status_code    status;
  BYTE *p;
  BYTE tmp;
  UINT16 code_tmp,value1,value2,value3,value4;
  MA_HEADER_MCMD* headerMcmd;
  UINT32 bootinfo;


  SCM_ACTION opcode;
  status_code code;

  unsigned char *pc;
  
  /*@LOG PAM Manager Started - PRH_VAR_N_BOOT */
  LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,PRH_VAR_N_BOOT);
  /*@LOG Esoteric info */
  LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,0xFAB9B151 ^ 0x060E605A ^ 0x4D9B0);

#if 0
#warning remove this in flight:!!!!
  for(fid=0;fid<LU_FILEID_N;fid++)
    LU_MASK(fid) |= LU_DEBUG_TRACE;
#endif

  /* power on Pamela: */
  PM_SetGom(PM_BOOTED,SCM_NO_ACTION);
 
  PRH_VAR_N_BOOT++;
  status = PRH_var_write2eeprom(PRH_EEPROM_CURRENT,PRH_VAR_N_BOOT_IDX);
  if (status)
    /*@LOG Error updating N_BOOT parameter at startup - status */
    LU_INFN_LOG(LU_INTERNAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
  
  status = PRH_ReadEEPROMBootinfo(&bootinfo);
  if(status == CM_RC_SUCCESSFUL) 
    /*@LOG Boot Info successfully read - bootinfo */
    LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,bootinfo);
  else
    /*@LOG Error reading bootinfo - status */
    LU_INFN_LOG(LU_FATAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);

  /* write PANIC state, in order to store valid boot info 
     in case PSCU is unintentionally  reset/power down */
  status = PRH_WriteEEPROMBootinfo(PRH_BOOTINFO_PANIC);
  if(status != CM_RC_SUCCESSFUL)
    /*@LOG Error writing bootinfo PANIC state - status */
    LU_INFN_LOG(LU_FATAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
  else
  /*@LOG PANIC state successfully write at startup, in order to store valid boot info in case PSCU is unintentionally  reset/power down */
    LU_INFN_LOG(LU_FATAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,0xbabe);

  status=OS_piStartTimer_INFN(PM_FORCERUNNING_TIM,
			 PRH_VAR_PM_FORCE_RUNNING_TIMEOUT,
			 PM_ForceRunning_CallBack,NULL); 

  PM_SetGom(PM_CPU_START_UP,SCM_POWER_ON);

  RM_SendCodeRunManager(RM_OP_DOWNLOAD_HEADER);

  while( FOREVER ) 
    {
      if ((mboxstatus =OS_piMsgQueueReceive_INFN (PM_INFN_MAILBOX,(void*)&RxMsg,
						  &MsgSize,WAIT, NO_TIMEOUT)) == SUCCESSFUL)
	{
	  switch (PM_CurrentCommand = RxMsg.Code)
	    {
	    case PM_FORCE_RUNNING:
	      PRH_VAR_AUTO_RM_MODE=1;
	      PM_SetGom(PM_RUNNING,SCM_NO_ACTION);		
	      /*@LOG PM_FORCE_RUNNING called  */
	      LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,0xbabe);
	      break;
	    case PM_INFN_MCMD_SELECTMODE:
	      headerMcmd=(MA_HEADER_MCMD*)RxMsg.Info;
	      SMH_MCMDSelectMode(headerMcmd);
	      break;
	    case PM_INFN_MCMD_STOREINCLINATIONINFO:
	      headerMcmd=(MA_HEADER_MCMD*)RxMsg.Info;
	      PM_MCMDStoreOrbitalInfo(headerMcmd);
	      break;
	    case PM_INFN_MCMD_STOREORBITALINFO:
	      headerMcmd=(MA_HEADER_MCMD*)RxMsg.Info;
	      PM_MCMDStoreInclinationInfo(headerMcmd);
	      break;
	    case PM_INFN_MCMD_NEUTRONDETECTOR:
	      headerMcmd=(MA_HEADER_MCMD*)RxMsg.Info;
	      PM_MCMDNeutronDetector(headerMcmd);
	      break;
	    case PM_INFN_MCMD_GASCONTAINERPURGE:
	      headerMcmd=(MA_HEADER_MCMD*)RxMsg.Info;
	      // ignore this 
	      PM_RemoveMCMDInPartition(headerMcmd->PtrMCMD);
	      break;
	    case PM_INFN_MCMD_CALIBRATE:
	      headerMcmd=(MA_HEADER_MCMD*)RxMsg.Info;
	      PM_MCMDCalibrate(headerMcmd);
	      break;
	    case PM_INFN_MCMD_PURGE_TRD:
	      headerMcmd=(MA_HEADER_MCMD*)RxMsg.Info;
	      PM_MCMDPurgeTRD(headerMcmd);
	      break;
	    case PM_INFN_RUNMANAGER_MSG:
	      {
		pc = RxMsg.Info;
		opcode = *(RM_OPCODES*)(pc); pc += sizeof(RM_OPCODES);
		code   = *(status_code*)(pc); pc += sizeof(status_code);

		if(pm_scm_action) {
		  /* if SCManager is doing something... save codes and exit */
		  rm_saved_flag=TRUE;
		  rm_saved_opcode=opcode;
		  rm_saved_code=code;
		}else{
		  PM_DecodeCode(opcode,code);		 
		}		
	      }
	      break;
	    case PM_INFN_SCMMANAGER_MSG:
	      {
		pc = RxMsg.Info;
		opcode = *(SCM_ACTION*)(pc);  pc += sizeof(RM_OPCODES);
		code   = *(status_code*)(pc); pc += sizeof(status_code);
		pm_scm_action--;
		PM_DecodeCode(opcode,code);
	      }
	      break;
	    case PM_INFN_NEXTRUN:
	      if (PM_CurrentStatus == PM_RUNNING)
		PM_DoNextRun();
	      break;
	    case PM_INFN_END_OF_DOWNLINK:
	      RM_SendCodeRunManager(RM_OP_DOWNLOAD_HEADER);
	      if(PRH_VAR_AUTO_RM_MODE)
		if (PM_CurrentStatus == PM_RUNNING)
		  MH_SetGOM(MH_GetLastIgnoredOpDuringDownload());
	      MH_EndOfDownload();
	      break;
	   
	    case PM_INFN_TEST_PAM_MANAGER:
#ifdef DEBUG
	      p=RxMsg.Info;
	      CM_READ_BE_UINT16(p,code_tmp,tmp);
	      CM_READ_BE_UINT16(p,value1,tmp);
	      CM_READ_BE_UINT16(p,value2,tmp);
	      CM_READ_BE_UINT16(p,value3,tmp);
	      CM_READ_BE_UINT16(p,value4,tmp);
	      PM_MCMDTest(code_tmp,value1,value2,value3,value4);
#endif // DEBUG 
	      break;
	    case PM_SAVE_TMTC_VALUES:
	    case PM_CYCLIC_ACQUISITION:
	    case PM_TSB_T_CHECK:
	    case PM_TSB_B_CHECK:
	      PM_Periodic_DoFlag[PM_CurrentCommand]=TRUE;
	      pm_scm_action++;
	      SCM_SendCode(PM_Periodic_SCMAction[PM_CurrentCommand]);
	      break;
	    default :
	      /*@LOG PamManager: Bad operation - storestatus */
	      LU_INFN_LOG(LU_INTERNAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,storestatus);
	      break;
	    }
	}
    }
}

/*
    switch(opcode) {
    case RM_OP_INITIALIZATION:
      break;
    case RM_OP_CALIBRATION:
      break;
    case RM_OP_ACQUISITION:
      break;
    case RM_OP_FLUSH_HB:
      break;      
    case RM_OP_FORCE_IDAQCMD:
      break;
    case RM_OP_TEST:
      break;
    case RM_OP_SINT:
      break;
    case SCM_SAVE_TMTC_VALUES:
      break;
    case SCM_CYCLIC_ACQUISITION:
      break;
    case SCM_POWER_ON:
      break;
    case SCM_POWEROFF_ON:
      break;
    case SCM_TSB_CHECK:
      break;
    }

      switch(code) {
      case CM_RC_SUCCESSFUL:
        break;
      case CM_RC_DO_AGAINACQ:
	break;
      case CM_RC_DO_INIT:
	break;
      case CM_RC_DO_RESET_IF_ALM:
	break;
      case CM_RC_DO_POWER_ON:
	break;
      case CM_RC_DO_POWER_OFF_ON:
	break;
      case CM_RC_DO_STOP_WAIT:
	break;
      }

*/



status_code PM_DecodeCode(UINT32 opcode,status_code code)
{
  if(PRH_VAR_VERBOSE_DEBUG) {
    /*@LOG PamManager State Machine - DecodeCode - opcode */
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,opcode);	
    /*@LOG PamManager State Machine - DecodeCode - code */
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);	
  }

  switch(PM_CurrentStatus) {
  case PM_BOOTED:
    /*@LOG PamManager State Machine - DecodeCode - in PM_BOOTED status receved  - PM_CurrentStatus */
    LU_INFN_LOG(LU_INTERNAL,LU_MASK(__FILEID__),__FILEID__,__LINE__,PM_CurrentStatus);
    break;
  case PM_CPU_START_UP:
    switch(opcode) {
    case SCM_POWER_ON:
      switch(code) {
      case CM_RC_SUCCESSFUL:
	PM_SetGom(PM_RUNNING,SCM_NO_ACTION);
        break;
      case CM_RC_DO_POWER_OFF_ON:
	if(PRH_VAR_AUTO_SCM_MODE)
	  PM_SetGom(PM_ALARM_HANDLER,SCM_POWEROFF_ON);
	break;
      case CM_RC_DO_STOP_WAIT:
	PM_SetGom(PM_STOP_AND_WAIT,SCM_NO_ACTION);
	break;
      case CM_RC_DO_AGAINACQ:
      case CM_RC_DO_INIT:
      case CM_RC_DO_RESET_IF_ALM:
      case CM_RC_DO_POWER_ON:
	/*@LOG PamManager State Machine - DecodeCode - in PM_CPU_STARTUP status receves this 'code' */
	LU_INFN_LOG(LU_INTERNAL,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);
	break;
      }
      break;
    case SCM_CYCLIC_ACQUISITION:
      PM_Periodic_ProgramTimer(PM_CYCLIC_ACQUISITION);
      break;
    case SCM_SAVE_TMTC_VALUES:
      PM_Periodic_ProgramTimer(PM_SAVE_TMTC_VALUES);
      break;
    case RM_OP_DOWNLOAD_HEADER:
      /*@LOG PM: StartUp->Download_Header  */      
      LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);	
      break;
    case SCM_POWEROFF_ON:
    case SCM_TSB_T_CHECK:
    case SCM_TSB_B_CHECK:
    case SCM_POWEROFF:
    case RM_OP_INITIALIZATION:
    case RM_OP_CALIBRATION:
    case RM_OP_ACQUISITION:
    case RM_OP_FLUSH_HB:
    case RM_OP_FORCE_IDAQCMD:
    case RM_OP_TEST:
    case RM_OP_SINT:
      /*@LOG PamManager State Machine - DecodeCode - in PM_CPU_STARTUP status receves this 'opcode' */
      LU_INFN_LOG(LU_INTERNAL,LU_MASK(__FILEID__),__FILEID__,__LINE__,opcode);
      break;
    }
    break;
  case PM_RUNNING:    
    switch(opcode) {
    case RM_OP_INITIALIZATION: // CurrentStatus==RUNNING
      switch(code) {
      case CM_RC_SUCCESSFUL:
	if(PRH_VAR_AUTO_RM_MODE)
	  {
	    if (PM_PendingCalibration)
	      MH_SetGOM(MH_GOM_CALIBRATION);
	    else
	      MH_SetGOM(MH_GOM_ACQUISITION);
	  }
	break;
      case CM_RC_DO_AGAINACQ:
	if (PM_PendingCalibration)
	  MH_SetGOM(MH_GOM_CALIBRATION);
	else
	  MH_SetGOM(MH_GOM_ACQUISITION);
	break;
      case CM_RC_DO_RESET_IF_ALM:
	if(PRH_VAR_AUTO_SCM_MODE) {
	  if (PRH_VAR_RES < PRH_VAR_NRES)
	    {
	      PRH_VAR_RES++;
	      /*@LOG PM: Running->Initialization->ResetIFAlarm PRH_VAR_RES<PRH_VAR_NRES, Redo Initialization */
	      ALM_WriteLog(ALM_OFF,PRH_VAR_OFF);
	      /*@LOG PM: Running->Initialization->ResetIFAlarm PRH_VAR_RES<PRH_VAR_NRES, Redo Initialization */
	      ALM_WriteLog(ALM_RES,PRH_VAR_RES);
	      
	      MH_SetGOM(MH_GOM_INITIALIZATION);
	  }
	  else
	    PM_SetGom(PM_ALARM_HANDLER,SCM_POWEROFF_ON);
	}
	break;
      case CM_RC_DO_POWER_OFF_ON:
	if(PRH_VAR_AUTO_SCM_MODE)
	  PM_SetGom(PM_ALARM_HANDLER,SCM_POWEROFF_ON);
	break;
      case CM_RC_DO_STOP_WAIT:
      case CM_RC_DO_POWER_ON:
      case CM_RC_DO_INIT:
	/*@LOG PamManager State Machine - DecodeCode - in PM_RUNNIGN status receves this 'code' */
	LU_INFN_LOG(LU_INTERNAL,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);
	break;
      }
      break;
    case RM_OP_CALIBRATION:// CurrentStatus==RUNNING
      switch(code) {
      case CM_RC_SUCCESSFUL:
	PM_PendingCalibration = FALSE;
	if(PRH_VAR_AUTO_RM_MODE)
	  MH_SetGOM(MH_GOM_ACQUISITION);
	break;
      case CM_RC_DO_RESET_IF_ALM:
	if(PRH_VAR_AUTO_SCM_MODE) {
	  if (PRH_VAR_RES < PRH_VAR_NRES)
	    {
	      PRH_VAR_RES++;
	      /*@LOG PM: Running->Calibration->ResetIFAlarm PRH_VAR_RES<PRH_VAR_NRES, Redo Initialization */
	      ALM_WriteLog(ALM_OFF,PRH_VAR_OFF);
	      /*@LOG PM: Running->Calibration->ResetIFAlarm PRH_VAR_RES<PRH_VAR_NRES, Redo Initialization */
	      ALM_WriteLog(ALM_RES,PRH_VAR_RES);
	      MH_SetGOM(MH_GOM_INITIALIZATION);
	    }
	  else
	    PM_SetGom(PM_ALARM_HANDLER,SCM_POWEROFF_ON);
	}
	break;
      case CM_RC_DO_POWER_OFF_ON:
	if(PRH_VAR_AUTO_SCM_MODE)
	  PM_SetGom(PM_ALARM_HANDLER,SCM_POWEROFF_ON);
	break;
      case CM_RC_DO_STOP_WAIT:
      case CM_RC_DO_AGAINACQ:
      case CM_RC_DO_POWER_ON:
      case CM_RC_DO_INIT:
	/*@LOG PamManager State Machine - DecodeCode - in PM_RUNNING status receves this 'code' */
	LU_INFN_LOG(LU_INTERNAL,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);
	break;
      }      
      break;

    case RM_OP_ACQUISITION:// CurrentStatus==RUNNING
      switch(code) {
      case CM_RC_SUCCESSFUL:
	// ???
	break;
      case CM_RC_DO_AGAINACQ:
	if (PM_PendingCalibration)
	  MH_SetGOM(MH_GOM_CALIBRATION);
	else
	  MH_SetGOM(MH_GOM_ACQUISITION);
	break;
      case CM_RC_DO_RESET_IF_ALM:
	if(PRH_VAR_AUTO_SCM_MODE) {
	  if (PRH_VAR_RES < PRH_VAR_NRES)
	    {
	      PRH_VAR_RES++;
	      /*@LOG PM: Running->Acquisition->ResetIFAlarm PRH_VAR_RES<PRH_VAR_NRES, Redo Initialization */
	      ALM_WriteLog(ALM_OFF,PRH_VAR_OFF);
	      /*@LOG PM: Running->Acquisition->ResetIFAlarm PRH_VAR_RES<PRH_VAR_NRES, Redo Initialization */
	      ALM_WriteLog(ALM_RES,PRH_VAR_RES);
	      MH_SetGOM(MH_GOM_INITIALIZATION);
	    }
	  else
	    PM_SetGom(PM_ALARM_HANDLER,SCM_POWEROFF_ON);
	}
	break;
      case CM_RC_DO_POWER_OFF_ON:
	if(PRH_VAR_AUTO_SCM_MODE)
	  PM_SetGom(PM_ALARM_HANDLER,SCM_POWEROFF_ON);
	break;
      case CM_RC_DO_INIT:
	/*@LOG No Trigger during 4.6sec (IDAQ ETO during ACQ) */
	LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,0xc1cc10);
	MH_SetGOM(MH_GOM_INITIALIZATION);
	break;
      case CM_RC_DO_STOP_WAIT:
      case CM_RC_DO_POWER_ON:
	LU_INFN_LOG(LU_INTERNAL,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);
	break;
      }            
      break;
    case RM_OP_FLUSH_HB:// CurrentStatus==RUNNING
      //
      break;      
    case RM_OP_FORCE_IDAQCMD:// CurrentStatus==RUNNING
      //
      break;
    case RM_OP_DOWNLOAD_HEADER:
      /*@LOG PM: Running->Download_Header  */      
      LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);	
      break;
    case RM_OP_TEST:// CurrentStatus==RUNNING
      //
      break;
    case RM_OP_SINT:// CurrentStatus==RUNNING
      //
      break;
    case SCM_SAVE_TMTC_VALUES:// CurrentStatus==RUNNING
      if(rm_saved_flag)
	PM_DecodeCode(rm_saved_opcode,rm_saved_code);
      PM_Periodic_ProgramTimer(PM_SAVE_TMTC_VALUES);
      break;
    case SCM_CYCLIC_ACQUISITION:// CurrentStatus==RUNNING
      switch(code) {
      case CM_RC_SUCCESSFUL:
	if(rm_saved_flag)
	  PM_DecodeCode(rm_saved_opcode,rm_saved_code);
	break;
      case CM_RC_DO_POWER_OFF_ON:
	if(PRH_VAR_AUTO_SCM_MODE) 
	  {
	    if(rm_saved_flag && 
	       rm_saved_code == CM_RC_DO_STOP_WAIT)
	      PM_SetGom(PM_STOP_AND_WAIT,SCM_NO_ACTION); // no possible
	    else
	      PM_SetGom(PM_ALARM_HANDLER,SCM_POWEROFF_ON);
	  }
	break;
      case CM_RC_DO_STOP_WAIT:
	// go in stop and wait for termistor check!!!
	// but in this case reenable cycliccheck
	// waiting for termistors give me ok for power_on
	PM_SetGom(PM_STOP_AND_WAIT,SCM_POWEROFF);
	SCM_SetCyclicCheck(CM_ENABLED);
	break;
      case CM_RC_DO_INIT:
      case CM_RC_DO_POWER_ON:
      case CM_RC_DO_AGAINACQ:
      case CM_RC_DO_RESET_IF_ALM:
	LU_INFN_LOG(LU_INTERNAL,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);	
	break;
      }
      PM_Periodic_ProgramTimer(PM_CYCLIC_ACQUISITION);
      break;
    case SCM_TSB_T_CHECK:// CurrentStatus==RUNNING
    case SCM_TSB_B_CHECK:
      if(code != CM_RC_SUCCESSFUL && 
	 PRH_VAR_AUTO_SCM_MODE)
	{
	  PM_SetGom(PM_ALARM_HANDLER,SCM_POWEROFF_ON);
	}
      else {
	if(rm_saved_flag) 
	  PM_DecodeCode(rm_saved_opcode,rm_saved_code);
	opcode == SCM_TSB_T_CHECK ? 
	  PM_Periodic_ProgramTimer(PM_TSB_T_CHECK) :
	  PM_Periodic_ProgramTimer(PM_TSB_B_CHECK) ;
      }
      break;
    case SCM_POWER_ON:// CurrentStatus==RUNNING
    case SCM_POWEROFF_ON:// CurrentStatus==RUNNING
    case SCM_POWEROFF:// CurrentStatus==RUNNING
      /*@LOG Unhandled opcode in PM State Machine - PM_RUNNING/Acquistition status */
      LU_INFN_LOG(LU_INTERNAL,LU_MASK(__FILEID__),__FILEID__,__LINE__,opcode);
      break;
    }    
    break;
  case PM_STOP_AND_WAIT:    
    
    switch(opcode) {
    case SCM_SAVE_TMTC_VALUES:
      PM_Periodic_ProgramTimer(PM_SAVE_TMTC_VALUES);
      break;
    case SCM_CYCLIC_ACQUISITION:
      switch(code) {
      case CM_RC_DO_POWER_ON:
	if(PRH_VAR_AUTO_SCM_MODE)
	  PM_SetGom(PM_CPU_START_UP,SCM_POWER_ON);
	break;
      case CM_RC_SUCCESSFUL:
	if(PRH_VAR_VERBOSE_DEBUG)
	  LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);
	break;
      case CM_RC_DO_POWER_OFF_ON:
      case CM_RC_DO_STOP_WAIT:
      case CM_RC_DO_INIT:
      case CM_RC_DO_AGAINACQ:
      case CM_RC_DO_RESET_IF_ALM:
	LU_INFN_LOG(LU_INTERNAL,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);
	break;
      }
      PM_Periodic_ProgramTimer(PM_CYCLIC_ACQUISITION);
      break;
    case RM_OP_DOWNLOAD_HEADER:
      /*@LOG PM: Stop&Wait->Download_Header  */      
      LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);	
      break;
    case RM_OP_INITIALIZATION:
    case RM_OP_CALIBRATION:
    case RM_OP_ACQUISITION:
    case RM_OP_FLUSH_HB:
    case RM_OP_FORCE_IDAQCMD:
    case RM_OP_TEST:
    case RM_OP_SINT:
    case SCM_TSB_T_CHECK:
    case SCM_TSB_B_CHECK:
    case SCM_POWEROFF:
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,opcode);
      break;
    case SCM_POWEROFF_ON:
    case SCM_POWER_ON:
      LU_INFN_LOG(LU_INTERNAL,LU_MASK(__FILEID__),__FILEID__,__LINE__,opcode);
      break;
    }
    break;
  case PM_ALARM_HANDLER:
    switch(opcode) {
    case SCM_POWEROFF_ON:
      switch(code) {
      case CM_RC_DO_POWER_ON:
	PM_SetGom(PM_CPU_START_UP,SCM_POWER_ON);
	break;
      case CM_RC_DO_STOP_WAIT:
	PM_SetGom(PM_STOP_AND_WAIT,SCM_NO_ACTION);
	break;
      case CM_RC_DO_POWER_OFF_ON:
      case CM_RC_SUCCESSFUL:
      case CM_RC_DO_AGAINACQ:
      case CM_RC_DO_INIT:
      case CM_RC_DO_RESET_IF_ALM:
	break;      
      }
      break;
    case SCM_SAVE_TMTC_VALUES:
      PM_Periodic_ProgramTimer(PM_SAVE_TMTC_VALUES);      
      break;    
    case SCM_CYCLIC_ACQUISITION:
#warning to investigate
      PM_Periodic_ProgramTimer(PM_CYCLIC_ACQUISITION);
      break;
    case RM_OP_DOWNLOAD_HEADER:
      /*@LOG PM: AlarmHandler->Download_Header  */      
      LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);	
      break;
    case RM_OP_INITIALIZATION:
    case RM_OP_CALIBRATION:
    case RM_OP_ACQUISITION:
    case RM_OP_FLUSH_HB:
    case RM_OP_FORCE_IDAQCMD:
    case RM_OP_TEST:
    case RM_OP_SINT:
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,opcode);
      break;
    case SCM_POWEROFF:
    case SCM_POWER_ON:
    case SCM_TSB_B_CHECK:
    case SCM_TSB_T_CHECK:
      LU_INFN_LOG(LU_INTERNAL,LU_MASK(__FILEID__),__FILEID__,__LINE__,opcode);
      break;
    }
    break;
  }
  rm_saved_flag=FALSE;
  return SUCCESSFUL;
}






/*****************************************************************************/
/* @Function: PM_StopRunManager                                              */
/* @Purpose :                                                                */
/*  stop che Run Manager, wait for the SINT_OK back                          */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name       @Message                                            */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code PM_StopRunManager() {
  status_code status=CM_RC_SUCCESSFUL;
  RM_SendSINT();
  RM_CancelACQTimers();

  return status;
}



/*****************************************************************************/
/* @Function: PM_StoreMCMDInPartition                                      */
/* @Purpose :                                                                */
/*  Put message in PamManager private space for MCMD                         */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name       @Message                                            */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code PM_StoreMCMDInPartition(MA_HEADER_MCMD* mcmd,void** new_location) {
  void* p;
  status_code status;
  /* try to gen a new buffer */
  status=OS_piPartGetBuffer_INFN(MCMD_INFN_PART,&p);
  *new_location=NULL;
  if (status!=SUCCESSFUL) {
    /*@LOG StoreMCMDInPartition: buffer not available, notify to history area and do nothing: the MCMD is lost */
    LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
  }else{
    /* if buffer available, store the MCMD in it 
       no length control because buffer size should be greater then the
       biggest mcmd->length 
    */
    memcpy(p,mcmd->PtrMCMD,mcmd->Length*sizeof(unsigned short int));
    /* now update the PtrMCMD to the new location , so the mcmd points to the right location */
    *new_location=p;
  }
  return status;
}


/*****************************************************************************/
/* @Function: PM_RemoveMCMDInPartition                                       */
/* @Purpose :                                                                */
/*  Remove message in PamManager private space for MCMD                      */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name       @Message                                            */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code PM_RemoveMCMDInPartition(void *McmdPtr) {
  status_code status;
  /* try to gen a new buffer */
  status=OS_piPartReturnBuffer_INFN(MCMD_INFN_PART,McmdPtr);
  if (status!=SUCCESSFUL) {
    /*@LOG RemoveMCMDInPartition error - status */
    LU_INFN_LOG(LU_FATAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
  }
  return status;
}



/*****************************************************************************/
/* @Function: PM_SubmitMCMD                                                */
/* @Purpose :                                                                */
/*  Submit the MCMD to PamManager.                                           */
/*  This is the unique function of this module executed directly from the    */
/*  higher priority laben task, not by INFN tasks.                           */
/*  the caller is in the laben MCMD Dispather                                *a
    /* @@                                                                        */
/* @Parameter Name       @MA_HEADER_MCMD*                                    */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/


status_code PM_SubmitMCMD(MA_HEADER_MCMD* headerMcmd) {
  status_code  status=SUCCESSFUL;
  MsgTsk sndMsg;
  unsigned int    code=0,istimetag;
  void            *newPtr;
  unsigned short* pMcmdInfo;
  /* copy the MCMD in the INFN privte partition: */
  status=PM_StoreMCMDInPartition(headerMcmd,&newPtr);
  /* As laben-SW requested, delete the MCMD from the area. deleting of the MCMD must be done in any case,even if not
     stored in the INFN private partition */

#ifndef SIMULATOR
  istimetag =( *(((unsigned short*)headerMcmd->PtrMCMD)+1)&TIMETAG_MASK ) ? TIMETAG_MCMD : IMMEDIATE_MCMD;
  MA_piDelBufferMCMD(headerMcmd->PtrMCMD,istimetag);
#endif // SIMULATOR

  if(status==SUCCESSFUL) {
    /* update the new MCMD location pointer */
    headerMcmd->PtrMCMD=newPtr;
    
    switch(headerMcmd->Type)
      {
      case ORBITAL_INFORMATION:
	code=PM_INFN_MCMD_STOREORBITALINFO;
	break;
      case INCLINATION_INFORMATION:
	code=PM_INFN_MCMD_STOREINCLINATIONINFO;
	break;     
      case SELECT_MODE:
	code=PM_INFN_MCMD_SELECTMODE;
	break;
      case CALIBRATE:
	code=PM_INFN_MCMD_CALIBRATE;
	break;
      case NEUTRON_DETECTOR:
	code = PM_INFN_MCMD_NEUTRONDETECTOR;
	break;
      case GAS_CONTAINER_PURGE:
	code = PM_INFN_MCMD_GASCONTAINERPURGE;
	break;
      case PURGE_TRD:
	/*At the moment unused*/
	// code = PM_INFN_MCMD_NEUTRONDETECTOR, PM_INFN_MCMD_GASTEST, PM_INFN_MCMD_CALIBRATE, PM_INFN_MCMD_PURGE_TRD, PM_INFN_MCMD_TEST,
	// break;
	code=PM_INFN_MCMD_PURGE_TRD;
	break;
      case TEST:
	code=PM_INFN_MCMD_TEST;
	break;
      default :
	PM_RemoveMCMDInPartition(headerMcmd->PtrMCMD);
	/*@LOG MCMD not identified:  */
	LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,0);
	status =HA_E10_MCMD_ERR;
	break;
	
      }
    
    if (status==SUCCESSFUL)  {
      /*==================== MCMD dispatched ======================*/
      /* Send message to the object executor                       */
      sndMsg.Code   =code;
      *(MA_HEADER_MCMD* )sndMsg.Info =*headerMcmd;
      sndMsg.LlInfo =sizeof(MA_HEADER_MCMD);
      status=PM_SndMsgPamManager_INFN(&sndMsg);   
    }
    
  }else{
    /*@LOG error storing MCMD in partition - status */
    LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
  }
  return status;
}





/*****************************************************************************/
/* @Function: PM_MCMDStoreOrbitalInfo                                        */
/* @Purpose :                                                                */
/*  Manage the Store Orbinal Info                                            */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name       @Message                                            */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code PM_MCMDStoreOrbitalInfo(MA_HEADER_MCMD* headerMcmd) {
  /*
    Dont store now because storing is done in low level for all MCMDs 
  
    HB_Store(HB_MCMD,
    headerMcmd->Length*sizeof(unsigned short int),
    headerMcmd->PtrMCMD);
  */
  PM_RemoveMCMDInPartition(headerMcmd->PtrMCMD);
}


/*****************************************************************************/
/* @Function: PM_StoreMCMDInclinationInfo                                    */
/* @Purpose :                                                                */
/*  manage the store inclination info.                                       */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name       @Message                                            */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code PM_MCMDStoreInclinationInfo(MA_HEADER_MCMD* headerMcmd) {
  /*
    Dont store now because storing is done in low level for all MCMDs 
  
    HB_Store(HB_MCMD,
    headerMcmd->Length*sizeof(unsigned short int),
    headerMcmd->PtrMCMD);
  */
  PM_RemoveMCMDInPartition(headerMcmd->PtrMCMD);
}


/*****************************************************************************/
/* @Function: PM_MCMDCalibrate                                               */
/* @Purpose :                                                                */
/*  manage the calibrate MCMD                                                */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name       @Message                                            */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code PM_MCMDCalibrate(MA_HEADER_MCMD* headerMcmd) {
  PM_RemoveMCMDInPartition(headerMcmd->PtrMCMD);
  PM_ActionForTheAscendingNode();
}

/*****************************************************************************/
/* @Function: PM_ActionForTheAscendingNode                                   */
/* @Purpose :                                                                */
/*  do     the Calibrate/AScending Node actions                              */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name       @Message                                            */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code PM_ActionForTheAscendingNode() {
  status_code status;
  PM_AscendingNode_Counter++;
  // Every ascending node we reset value of these counter.
  PRH_VAR_RES=0;
  PRH_VAR_OFF=0;
  PRH_VAR_TRIG=0;
  TI_piSetObtOrbit_s();
  if(PRH_VAR_PM_N_ORBIT_CALIB != 0 && PM_AscendingNode_Counter % PRH_VAR_PM_N_ORBIT_CALIB == 0) {
    /* TBD: what to do in in download mode ? */
    if(PM_CurrentStatus == PM_RUNNING && RM_RunIsInProgress())
      MH_SetGOM(MH_GOM_CALIBRATION);
    else
      PM_PendingCalibration = TRUE;
  }
}



/*****************************************************************************/
/* @Function: PM_DoNextRun                                                   */
/* @Purpose :                                                                */
/*  this is what to do when Pam Manager receives a Next Run Message          */
/* @@                                                                        */
/* @Parameter Name       @Message                                            */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code PM_DoNextRun() {

  if(MH_GetGOM() == MH_GOM_ACQUISITION)
    {
      return MH_SetGOM(MH_GOM_ACQUISITION);
    }
  
  return CM_RC_SUCCESSFUL;
}


status_code PM_MCMDPurgeTRD(MA_HEADER_MCMD *headerMcmd) {
  UINT16 *id=SMH_GETPTR_BODYAREA(headerMcmd->PtrMCMD);
  switch(*id) {
  case 0xCAFE:
    // TBD: Call the GasFunction "gas purge"
    break;
  case 0xCBFE:
    // TBD: Call the GasFunction "one valve"
    break;
  default:
    LU_INFN_LOG(LU_WARNING,LU_MASK(__FILEID__),__FILEID__,__LINE__,*id);    
    break;
  }
  PM_RemoveMCMDInPartition(headerMcmd->PtrMCMD);  
}


status_code PM_MCMDNeutronDetector(MA_HEADER_MCMD *headerMcmd)
{
  PM_RemoveMCMDInPartition(headerMcmd->PtrMCMD);
}

status_code PM_GetCurrentAcqSetting(RM_ACQ_SETTING *mode)
{
  *mode = PM_AcqSetting;
}

PM_INFN_STATUS PM_GetStatus()
{
  return(PM_CurrentStatus);
}

void PM_SetGom(PM_INFN_STATUS new_status,SCM_ACTION scm_action)
{ 

  switch(new_status)
    {
    case PM_BOOTED:
      SCM_SetCyclicCheck(CM_DISABLED);
      PM_PeriodicEnable(PM_CYCLIC_ACQUISITION);
      PM_PeriodicEnable(PM_SAVE_TMTC_VALUES);
      PM_PeriodicDisable(PM_TSB_T_CHECK);
      PM_PeriodicDisable(PM_TSB_B_CHECK);
      // This calls FT_ChangeOpMode
      // MH_SetGOM(MH_GOM_MAINTENANCE);
      break;
    case PM_CPU_START_UP:
      // scm_action = SCM_POWER_ON;
      SCM_SetCyclicCheck(CM_DISABLED);
      PM_PeriodicDisable(PM_TSB_T_CHECK);
      break;
    case PM_RUNNING:
      if(PRH_VAR_AUTO_RM_MODE)
	MH_SetGOM(MH_GOM_INITIALIZATION);
      if (PRH_VAR_AUTO_SCM_MODE){
	PM_PeriodicEnable(PM_TSB_T_CHECK);
	PM_PeriodicEnable(PM_TSB_B_CHECK);
	SCM_SetCyclicCheck(CM_ENABLED);
      }
      break;
    case PM_STOP_AND_WAIT:
      MH_SetGOM(MH_GOM_MAINTENANCE);
      SCM_SetCyclicCheck(CM_DISABLED);
      PM_PeriodicDisable(PM_TSB_T_CHECK);
      break;
    case PM_ALARM_HANDLER:
      MH_SetGOM(MH_GOM_MAINTENANCE);
      SCM_SetCyclicCheck(CM_DISABLED);
      PM_PeriodicDisable(PM_TSB_T_CHECK);
      break;
    default:
    }
  if(scm_action != SCM_NO_ACTION){
    pm_scm_action++;
    //
    SCM_SendCode(scm_action);
  }
  PM_CurrentStatus = new_status;
}

PM_INFN_STATUS PM_GetGOM() {
  return PM_CurrentStatus;
}

static status_code PM_PeriodicEnable(PM_INFN_COMMAND action)
{
  PM_SendCommand(action);
  return CM_RC_SUCCESSFUL;
}
static status_code PM_PeriodicDisable(PM_INFN_COMMAND action)
{
  
  OS_piCancelTimer_INFN(PM_Periodic_TIM[action]);
  PM_Periodic_DoFlag[action] = FALSE;
  return CM_RC_SUCCESSFUL;
}

status_code PM_Periodic_ProgramTimer(PM_INFN_COMMAND action) 
{
  status_code s=CM_RC_SUCCESSFUL;
  if(PM_Periodic_DoFlag[action])
    s=OS_piStartTimer_INFN(PM_Periodic_TIM[action],
			   PRH_ARR_PM_PERIODIC_DELAY[action],
			   PM_Periodic_CallBack,&(PM_Periodic_Action[action])); 
  return s;
}


/* this function is executed directly, not by the Pam Manager: */
status_code PM_CPU_Reboot(BOOL do_reset) {
  unsigned int    reset; 
  /* Switch off the Memory Module 1              */
  FT_piMemModuleOFF(FT_MEM_MOD_1);
  /* Switch off the Memory Module 2              */
  FT_piMemModuleOFF(FT_MEM_MOD_2);
  /* PDHT hardware reset is performed by programming       */
  /* PCMCIA B RESET register (0x10000144)                  */
  CD_PCMCIA_B_RESET_PROGRAM;
  if(do_reset) {
    /* Enable software reset                                 */            
    reset = ERC32_MEC.Control;
    reset |=ERC32_CONFIGURATION_SOFTWARE_RESET_ALLOWED;
    ERC32_MEC.Control = reset;	
    /* Write software reset                                  */
    ERC32_MEC.Software_Reset =0;
  }
}

status_code PM_SysInitialization()
{
  if (PRH_VAR_AUTO_SCM_MODE)
    {
      PM_PeriodicEnable(PM_CYCLIC_ACQUISITION);
      PM_PeriodicEnable(PM_SAVE_TMTC_VALUES);
    }
  
  
  if(PRH_VAR_AUTO_RM_MODE)
    PM_SetGom(PM_RUNNING,SCM_NO_ACTION);

  return CM_RC_SUCCESSFUL;
}




status_code PM_LogStatus()
{
  TI_TIME obt_ts,ts,t;
  status_code s;
  /*@LOG PamManager CurrentStatus */
  LU_INFN_LOG(LU_NORMAL_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,PM_CurrentStatus);
  /*@LOG SCMManager CurrentAction */
  LU_INFN_LOG(LU_NORMAL_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,SCM_GetCurrentAction());
  s=TI_piGetTimeSyncInfo_s(&obt_ts,&ts);
  if(s) 
    /*@LOG error getting GetTimeSyncInfo_s - status */
    LU_INFN_LOG(LU_NORMAL_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,0xAAAA0000 | s);
  else {
    /*@LOG OBT at the last time sync information - s */
    LU_INFN_LOG(LU_NORMAL_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,obt_ts);
    /*@LOG TimeSync info - s */
    LU_INFN_LOG(LU_NORMAL_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,ts);
  }
  s=TI_piGetTimeSyncOffset_s(&t);
  if(s) 
    /*@LOG error getting GetTimeSyncOffset_s - status */
    LU_INFN_LOG(LU_NORMAL_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,0xAAAA0000 | s);
  else {
    /*@LOG TimeSyncOffset - seconds */
    LU_INFN_LOG(LU_NORMAL_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,t);
  }
  s=TI_piGetCurrentMoscowTime_s(&t);
  if(s) 
    /*@LOG error getting GetCurrentMoscowTime_s - seconds */
    LU_INFN_LOG(LU_NORMAL_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,0xAAAA0000 | s);
  else {
    /*@LOG CurrentMoscowTime_s - seconds */
    LU_INFN_LOG(LU_NORMAL_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,t);
  }
  s=TI_piGetOrbitOffset_s(&t);
  if(s) 
    /*@LOG error GetOrbitOffset_s - status */
    LU_INFN_LOG(LU_NORMAL_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,0xAAAA0000 | s);
  else {
    /*@LOG OrbitOffset_s - seconds */
    LU_INFN_LOG(LU_NORMAL_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,t);
  }
  RM_LogStatus();
}




#if DEBUG
/* this function is executed by PamManager */
void PM_MCMDTest(unsigned short code,
		 unsigned short value1,
		 unsigned short value2,
		 unsigned short value3,
		 unsigned short value4) {
  UINT32 i;
  static UINT32 blen = 24*1024;
  UINT32 fid,v;
  static UINT32 pattern = 0xCAFECAFE;
  status_code status,s;
  PWR_IPM6 ipm;
  CM_ON_OFF oo;
  UINT16 sw;
#ifdef GS_COMPILE
  GS_REPLY_STRUCT gas_status;
  UINT16 *gas_word=(UINT16*)&gas_status;
#endif


  int n;
  int sleep;
  // LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,code);
  switch(code) {
  case 0:
    MH_SetGOM(MH_GOM_FLUSH_HB);
    break;
  case 1:
    MH_SetGOM(MH_GOM_ACQUISITION);
    break;
  case 2:
    MH_SetGOM(MH_GOM_MAINTENANCE);
    break;
#ifdef DURTY_MODE
  case 3:
    TS_SndTestCode_INFN(value1);
    break;
#endif // DURTY_MODE
  case 4:
    PM_pi_EnableStore_In_DataTimeOut();
    break;
  case 5:
    PM_pi_DisableStore_In_DataTimeOut();
    break;
  case 6:
    // bufsel=value1;
    break;
  case 7:
    RM_LogStatus();
    break;
  case 8:
    //LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,HB_SpaceLeft());
    break;
    /*
  case 9:
    PM_pi_SetNotifyTask_SKETCHBOARD_FREE(TS_INFN_TASK);
    PM_piPageWasSaved(FS_HK);
    break;
    */
  case 10:
    RM_SendHBStoreRequest();
   break;
  case 11:
    PM_PeriodicEnable(PM_SAVE_TMTC_VALUES);
    break;
  case 12:
    PM_PeriodicDisable(PM_SAVE_TMTC_VALUES);
    break;
  case 13:
    PM_PeriodicEnable(PM_CYCLIC_ACQUISITION);
    break;
  case 14:
    PM_PeriodicDisable(PM_CYCLIC_ACQUISITION);
    break;
  case 15:
    SD_piPIFReset();
    break;
  case 16:
    HK_KHB_InitBoard();
    // KHB_InitBoard();
    break;
  case 17:
    FS_piLogInfo();
    break;
  case 18:
    PM_PeriodicDisable(PM_TSB_T_CHECK);
    break;
  case 19:
    {
      unsigned int DataValue;
      int i;
      static int min=0,max=4;
      for(i = min ; i < max; i++){
	HK_GetTMValue (TM_DEA_ANA_1+min, &DataValue);
	LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,DataValue>>16);
	LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,DataValue);
      }
    }
    break;
  case 20:
    // KHB_Log();
    break;
  case 21:
    for(fid=0;fid<LU_FILEID_N;fid++)
      LU_MASK(fid) |= LU_DEBUG_TRACE;
    break;
  case 22:
    for(fid=0;fid<LU_FILEID_N;fid++)
      if(LU_MASK(fid) & LU_DEBUG_TRACE)
	LU_MASK(fid) &= ~LU_DEBUG_TRACE;
    break;
  case 23:
    PM_PeriodicEnable(PM_TSB_T_CHECK);
    break;
  case 24:
    PM_PeriodicEnable(PM_TSB_B_CHECK);
    break;
  case 25:
    PM_PeriodicDisable(PM_TSB_B_CHECK);
    
  case 41:
    PWR_SwitchOn_IPM(TM_KRB_IPM1);
    break;
  case 42:
    PWR_SwitchOn_IPM(TM_KRB_IPM2);
    break;
  case 43:
    PWR_SwitchOn_IPM(TM_KRB_IPM3);
    break;
  case 44:
    PWR_SwitchOn_IPM(TM_KRB_IPM4);
    break;
  case 45:
    PWR_SwitchOn_IPM(TM_KRB_IPM5);
    break;
  case 46:
    PWR_SwitchOn_IPM(TM_KRB_IPM6);
    break;
  case 47:
    PWR_SwitchOff_IPM(TM_IPM12_OFF);
    break;
  case 48:
    PWR_SwitchOff_IPM(TM_IPM34_OFF);
    break;
  case 49:
    PWR_SwitchOff_IPM(TM_IPM56_OFF);
    break;
  case 60:
    for(ipm=PWR_IPM_1;ipm<=PWR_IPM_6;ipm++) {
      PWR_KRB_IPM(ipm,&oo);
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,oo);
    }
  case 66:
    HK_SendTC(TM_KHB_PWR_33_HOT_ON,1);
    break;
  case 67:
    HK_SendTC(TM_KHB_PWR_33_COLD_ON,1);
    break;
  case 68:
    HK_SendTC(TM_KHB_PWR_33_OFF,1);
    break;
  case 69:

#define LOG_TM(id,line) do { \
    HK_GetTMValue(id,&v); \
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,line,v); \
} while(0)
    break;
  case 80:
    s=PRH_var_write2eeprom(PRH_EEPROM_CURRENT,value1);
    break;
  case 81:
    s=PRH_var_write2eeprom(PRH_EEPROM_CURRENT,value1);
    break;
  case 82:
    s=PRH_var_read_eeprom(PRH_EEPROM_CURRENT,value1);
    break;
  case 83:
    s=PRH_arr_write2eeprom(PRH_EEPROM_CURRENT,value1);
    break;
  case 84:
    s=PRH_arr_read_eeprom(PRH_EEPROM_CURRENT,value1);
    break;
  case 85:
    s=PRH_tab_write2eeprom(PRH_EEPROM_CURRENT,value1);
    break;
  case 86:
    s=PRH_tab_read_eeprom(PRH_EEPROM_CURRENT,value1);
    break;
  case 87:
    HK_KHB_HardReset();
    break;
  case 89:
    MH_SetTestParam(value1,value2,value3);
    MH_SetGOM(MH_GOM_TEST);
    break;
  case 90:
    HK_KHBSend128Trigger();
    break;
  case 91:
    MH_SetGOM(MH_GOM_INITIALIZATION);
    break;
  case 92:
    MH_SetGOM(MH_GOM_CALIBRATION);
    break;
  case 93:
    MH_SetGOM(MH_GOM_ACQUISITION);
    break;
  case 94:
    FT_piInitFileSystem();
    break;
  case 95:
    status=DAQ_ReadStatusWord(&sw);
    if(status)
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    else
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,sw);
    break;
  case 96:
    QS_piCounterCalibration(value1);
    break;
  case 97:
    QS_piUsageStart();
    break;
  case 98:
    {
      UINT16 usage;
      QS_piUsageStop(&usage);
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,usage);
    }
    break;
  case 99:
    {
      static UINT16 usage;
      static UINT32 i,j;
      static UINT32 susp=2,n=1000,ncrc=1000;
      static BYTE B[100];
      UINT16 oldcrc=0x17,crc=0x33;
      
      n=value1;
      ncrc=sizeof(B);
      QS_piUsageStart();
      for(i=0;i<n;i++) {
	OS_piTaskSuspend(susp);
	for(j=0;j<ncrc;j++) {
	  B[j]=(BYTE)(oldcrc+B[j]+j+crc);
	  crc=CM_Compute_CRC16(oldcrc,B,sizeof(B));
	}
      }
      QS_piUsageStop(&usage);
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,usage);
    }
    break;
  case 100:
    {
      UINT32 ar=0xf1c0f1c0;
      UINT16 sr=0xf1c0;
      status_code s;

      s=HK_ReadKHBStatusRegister(&sr);
      if(s)
	LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,s);
      else
	LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,sr);

      s=HK_ReadKHBAlarmRegister(&ar);
      if(s)
	LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,s);
      else
	LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,ar);
    }
    break;
  case 101:
    {
      PM_SetGom(PM_RUNNING,SCM_NO_ACTION);
    }
    break;
  case 102:
    {
      status_code status;
      BYTE channel = value1;
      BYTE value = value2;      
      status = HV_Write(channel,value);
    }
    break;
  case 103:
    MC_piSetState(MC_ACTIVE_STATE);
    break;
  case 104:
    MC_piSetState(MC_MAINTENANCE_STATE);
    break;
  case 105:
    status = OS_piResourceRelease_INFN (TEST_RES);
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    break;
  case 106:
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,0xffff);
    status = OS_piResourceObtain_INFN(TEST_RES,WAIT,NO_TIMEOUT);
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    break;
  case 107:
    PM_FORCE_BREAKPOINT();
    break;
  case 108:
    /* CM_dummy_loop test */
    {
      TI_TIME t1,t2;
      UINT32 n= value3 ? value3*1000 : ((value1 << 16) | value2) ;
      TI_piGetTimeInfo_ms (&t1);
      CM_Suspend_Dummy_Loop(n);
      TI_piGetTimeInfo_ms (&t2);
      LU_INFN_LOG(LU_DEBUG_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,t2-t1);
    }
    break;
  case 109:                                        // formatta eprom quando sto in default mode 
    status = PRH_FormatEEPROM();
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    break;
  case 110:                                        // legge i valori correnti della eeprom e li mette in mem 
    status = PRH_ReadCurrentParam();
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    break;
  case 111:
    status = PRH_ReadDefaultParam();
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    break;
  case 112:
    status = PRH_WriteCurrentParam();
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    break;
  case 113:
    status = PRH_WriteEEPROMBootinfo( (value1 << 16) | value2 );
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    break;
  case 114:
    {
      UINT32 bi=0xFFFFFFFF;
      status = PRH_ReadEEPROMBootinfo(&bi);
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,bi);
    }
    break;
  case 115:
    {
      unsigned int DataValue;
      HK_GetTMValue (value1, &DataValue); 
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,value1);
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,DataValue);
    }
    break;
  case 116:
    {
      unsigned int DataValue;
      HK_SendTC (value1, value2); 
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,value1);
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,value2);
    }
    break;
  case 117:
    // KHB_TestBoard(1);
    // HK_UpdateKHBMaskRegister(KHB_MASK_ALL,KHB_PRESET);
    break;
  case 118:
    PM_SetGom(PM_RUNNING,SCM_NO_ACTION);    
    break;
  case 119:
    PM_SetGom(PM_CPU_START_UP,SCM_POWER_ON);    
    break;
  case 120: 
    PM_LogStatus();
    break;
  case 121:
    PM_SetGom(PM_STOP_AND_WAIT,SCM_NO_ACTION);    
    break;
  case 122:
    status = HK_KHB_SetHotCold(CM_HOT);
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    break;
  case 123:
    status = HK_KHB_SetHotCold(CM_COLD);
    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    break;
  case 124:
    {
      UINT16 x[2];
      status = PWR_CMD2TRB_READ(value1,value2,x);
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,x[0]);
      LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,x[1]);
    }
  case 125:
    WS_2_Log();
    break;
  case 126:
    WS_2_LogTable(value1,WS_2_FULL);
    break;
  }
}
#endif // DEBUG



