/****************************************************************************
 *  F i l e   D a t a                                                        
 *  $Id: MH_ModeHandler_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: MH_ModeHandler_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: MH_ModeHandler_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.34  2005/03/21 13:46:49  faber
 *  TRIG_II software introeduces as emtpy commands.
 *  DNLK_TIM started at start downlink in order to be sure end of download.
 *
 *  Revision 1.33  2005/03/06 14:54:46  sebastiani
 *  version running on 06 03 2005
 *
 *  Revision 1.32  2005/02/21 08:58:29  sebastiani
 *  all log comments completed
 *
 *  Revision 1.31  2004/12/02 10:43:38  sebastiani
 *  fix AC
 *  fix CAL
 *  fix HK BUFTYPE
 *
 *  Revision 1.30  2004/11/19 15:14:52  sebastiani
 *  PRH_EXTERN_{VAR,ARR,TABLE} removed and put them on the autogenerated parameter heeader file
 *
 *  Revision 1.29  2004/11/05 16:43:07  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.28  2004/11/05 09:36:35  sebastiani
 *  first version of the PM state machine. tried but not deeply tested
 *
 *  Revision 1.27  2004/09/17 15:01:00  faber
 *  LU_INFN_LOG flags fixing
 *
 *  Revision 1.26  2004/08/26 16:54:34  sebastiani
 *  version work fine
 *
 *  Revision 1.25  2004/07/27 10:13:48  faber
 *  LU_ALARM macro introduced,
 *  LU_XXXX bit field "logtype" redefined.
 *  HistoryArea 5 now log a 32 bit word as "info1"
 *  and logging is reformatted.
 *
 *  Revision 1.24  2004/07/01 14:47:44  sebastiani
 *  add crc_c
 *
 *  Revision 1.23  2004/06/22 08:57:01  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.22  2004/06/15 08:24:37  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.21  2004/06/08 14:02:43  alfarano
 *  eeprom functions
 *
 *  Revision 1.20  2004/06/01 16:41:19  sebastiani
 *  EventReceive ANY
 *
 *  Revision 1.19  2004/05/20 16:03:52  faber
 *  ACQ flow dev continuing
 *
 *  Revision 1.18  2004/05/04 17:20:51  sebastiani
 *  new GOM TEST mode introduced. Entry point in TS_RM_Test(c1,c2)
 *
 *  Revision 1.17  2004/01/12 17:51:28  tassa
 *  manca solo la parte di invio e ricezione sulla/dalla IDAQ
 *
 *  Revision 1.16  2003/12/15 10:57:16  sebastiani
 *  last changes for the acceptance of TM tests in Rome of 9-12/Dec/2003
 *
 *  Revision 1.15  2003/12/06 08:32:38  faber
 *  startup procedure tuned. TMTC sampling storing  at startup
 *
 *  Revision 1.14  2003/12/03 14:36:51  faber
 *  more action definition about mcmd (setmode/purge_trd).
 *  SSt word better defined
 *
 *  Revision 1.13  2003/12/01 15:44:09  faber
 *  Donwlink duration field is a 16 bit word, not 32 (only HSB)
 *
 *  Revision 1.12  2003/11/19 15:48:37  faber
 *  *** empty log message ***
 *
 *  Revision 1.11  2003/10/17 10:01:55  sebastiani
 *  MC_piSetState introduced in all cases of MH_SetGOM
 *
 *  Revision 1.10  2003/09/25 09:47:20  faber
 *  donwlink time/duration *= --> /=
 *
 *  Revision 1.9  2003/09/24 14:52:59  carota
 *  bug fix again (like before)
 *
 *  Revision 1.8  2003/09/24 14:06:43  faber
 *  fix: 2 words mcmcd scanning skippend
 *
 *  Revision 1.7  2003/09/22 09:59:35  faber
 *  new select mode definitions
 *
 *  Revision 1.6  2003/09/19 15:57:35  faber
 *  Large development update INFN software
 *
 *  Revision 1.5  2003/09/12 10:57:41  faber
 *  development in proress (Working schedule module)
 *
 *  Revision 1.4  2003/09/10 16:15:52  faber
 *  PRH_EXTERN_VAR(XX_LOGMASK) removed (not needed any more)
 *
 *  Revision 1.3  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.2  2003/09/10 10:32:37  faber
 *  Large implementation of PamManager/RunManager Pam Sowfare. (compiled,never run)
 *
 *  Revision 1.1.1.1  2003/08/04 09:40:22  sebastiani
 *  Imported sources laben rel. 19.06.2003 integrated with pam2
 *
 *  Revision 1.4  2003/07/17 11:15:52  sebastiani
 *  idaq manager
 *  new print for logging in minicom
 *
 *  Revision 1.3  2003/07/03 12:39:29  sebastiani
 *  *** empty log message ***
 *
 *  Revision 1.2  2003/06/18 16:53:19  sebastiani
 *  Pam/Run Manager development update. ExpSeq sequence is receiven from the RunManager (simulator mode)
 *
 *  Revision 1.1  2003/06/12 15:17:21  sebastiani
 *  first ModeHandler update
 *
 *                                                                           
 *****************************************************************************/


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

#include <src/INFN/LU_SourceFileID_INFN.h>
#define __FILEID__ _MH_ModeHandler_INFN__c


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

#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/INFN/RM_RunManager_INFN.h>

#include <src/BasicSW/RTEMSInterface/OS_rtems_p.h>
#include <src/INFN/MH_ModeHandler_INFN.h>
#include <src/INFN/SMH_SelectModeHandler_INFN.h>

#include <src/ModeManager/ModeCoordinator/MC_ModeCoordinator_p.h>
#include <src/HKManager/HistoryArea/HA_HistoryArea_p.h>
#include <src/FileManager/MMSUManager/FT_MMSUManager_p.h>
#include <src/FileManager/MMSUManager/FT_MMSUManager_int.h>
#include <src/INFN/WS_WorkingSchedule_INFN.h>

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


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



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


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

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

/*=== Mode Handler   O P E R A T I O N   E N V I R O N M  ==*/

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

/* the General Operation Mode of Pamela. What pamela is doing */
static MH_GOM MH_GOM_Mode,MH_Saved_GOM_Mode;
static RM_OPCODES MH_LastIgnoredOpDuringDownload;
static UINT32 MH_test_c1,MH_test_c2,MH_test_c3;
static UINT32 MH_SubMode;

/* annouce donwload infos: (B1 MCMD) */
static TI_TIME MH_DownlinkStart;
static TI_TIME MH_DownlinkDuration;
static BOOL MH_DownlinkInfo=FALSE;
static BOOL MH_DownloadIsInProgress_flag=FALSE;


UINT32 MH_GetSubMode() {
  return MH_SubMode;
}

status_code MH_Init() {
  MH_SubMode = 0;
  MH_Saved_GOM_Mode=MH_GOM_NULL;
  MH_GOM_Mode=MH_GOM_NULL;
  MH_test_c1=0;
  MH_test_c2=0;
  MH_test_c3=0;
  MH_DownlinkInfo = FALSE;
  return SUCCESSFUL;
}

MH_GOM MH_GetGOM() {
  MH_GOM m;
  UINT32 level;
  OS_PROTECTED_INT(level,m=MH_GOM_Mode);
  return m;
}

MH_GOM MH_GetSavedGOM() {
  MH_GOM m;
  UINT32 level;
  OS_PROTECTED_INT(level,m=MH_Saved_GOM_Mode);
  return m;
}

/* 
   MH_GetDownlinkInfo.

   the function return the downlink start time and duration. 
   times are in 1/8 of seconds.
   if DownlinkInfo is not available (B1 not called) it returns
   an error.
   the function also automatically clear the DownlinkInfo, so
   another successfull call of the function must wait for another
   downlink info to come.
*/
status_code MH_GetDownlinkInfo(TI_TIME* start,TI_TIME* duration) {
  status_code status;
  if(MH_DownlinkInfo) {
    /* return infos: */
    *start = MH_DownlinkStart;
    *duration = MH_DownlinkDuration;
    /* clean information flag */
    MH_DownlinkInfo=FALSE;
    status=SUCCESSFUL;
  }else
    status=MH_INFN_NODOWNLINKINFO;
  return status;
}

status_code MH_SetModeFromMCMD(BYTE Mode,MA_HEADER_MCMD *headerMcmd) {
  status_code  status=CM_RC_SUCCESSFUL;
  static MsgTsk       ActiveMsg;
  unsigned int    code;
  unsigned int    timetagFlag;
  unsigned short* pMcmdInfo;
  unsigned int CurrentState;
  

  MsgTsk   SndMsg;

  

  //MC_piSetState(MC_ACTIVE_STATE); 
  // Delete MCMD from partition
  
  
  switch(Mode)
       {
       case SMH_SUBMODEA0:
	 // MH_SetGOM(MH_GOM_MAINTENANCE);
	 PM_SetGom(PM_STOP_AND_WAIT,SCM_NO_ACTION);    
	 MH_SubMode = Mode;
	 break;       
       case SMH_SUBMODEB1:
	 MH_PrepareDownlink(headerMcmd);
	 MH_SubMode = Mode;
	 break;       
       case SMH_SUBMODEB2:  
	 WS_SetFavouriteWorkingSchedule(WS_3);
	 MH_SubMode = Mode;
	 break;       
       case SMH_SUBMODEB3:  
	 WS_SetFavouriteWorkingSchedule(WS_0);
	 MH_SubMode = Mode;
	 break;       
       case SMH_SUBMODEB41:  
	 WS_SetFavouriteWorkingSchedule(WS_1);
	 MH_SubMode = Mode;
	 break;
       case SMH_SUBMODEB42:
	 WS_SetFavouriteWorkingSchedule(WS_2);
	 MH_SubMode = Mode;
	 break;
       default :
	 /*@LOG unrecognized SUBMODE in SetModeFromMCMD - Mode */
	 LU_INFN_LOG(LU_INTERNAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,Mode);
	 break;
       }
  /*@LOG Trace: SubMode */
  LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,Mode);
  return (status);

}

status_code MH_PrepareDownlink(MA_HEADER_MCMD* headerMcmd) {
  UINT16 start_l,start_h,duration_l,duration_h;
  UINT16 *usp;
  MC_STATE CurrentState;
  /* prepare DOWNLINK */
  MC_piGetState(&CurrentState);
  /* get information from the MCMD: */
  usp = SMH_GETPTR_BODYAREA(headerMcmd->PtrMCMD);
  /* skip select mode info: SUBMODE & LEN */
  usp+=2;
  /* get the start time info: */
  start_h = *usp;
  usp++;
  start_l = *usp;
  usp++;
  /* get the duration info: */
  duration_h = *usp;
  usp++;
  duration_l = *usp;
  /* TBD: stop acq here */
  MH_DownlinkStart = 
    (unsigned int)start_h << 16 |
    (unsigned int)start_l;
  /*
  MH_DownlinkDuration =
    (unsigned int)duration_h << 16 |
    (unsigned int)duration_l;
  */
  MH_DownlinkDuration =
    (unsigned int)duration_h;
  
  /* because we have times in units of 0.125 seconds in the MCMDs,
     we multiply the value by 8
  */
  
  MH_DownlinkInfo=TRUE;

  MH_DownlinkStart    /= 8;
  MH_DownlinkDuration /= 8;
  /*@LOG Downlink Start */
  LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,MH_DownlinkStart);
  /*@LOG Downlink Dowlink Duration */
  LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,MH_DownlinkDuration);  

  MH_SetGOM(MH_GOM_DOWNLOAD);
}

status_code MH_SetTestParam(UINT32 c1,UINT32 c2,UINT32 c3) {
  MH_test_c1=c1;
  MH_test_c2=c2;
  MH_test_c3=c3;
}

void MH_SetLastIgnoredOpDuringDownload(RM_OPCODES m) {
  UINT32 level;
  OS_PROTECTED_INT(level,MH_LastIgnoredOpDuringDownload=m);
}


MH_GOM MH_GetLastIgnoredOpDuringDownload() {

  static MH_GOM MH_RMOPCODES_2_GOM [RM_OP_MAX] = {
    /* RM_OP_NULL           -> */   MH_GOM_MAINTENANCE ,
    /* RM_OP_IDLE           -> */   MH_GOM_MAINTENANCE ,
    /* RM_OP_INITIALIZATION -> */   MH_GOM_INITIALIZATION ,
    /* RM_OP_CALIBRATION    -> */   MH_GOM_CALIBRATION,
    /* RM_OP_ACQUISITION    -> */   MH_GOM_ACQUISITION,
    /* RM_OP_FLUSH_HB       -> */   MH_GOM_FLUSH_HB, // not sure here!
    /* RM_OP_FORCE_IDAQCMD  -> */   MH_GOM_FORCE_IDAQCMD,
    /* RM_OP_TEST           -> */   MH_GOM_TEST,
    /* RM_OP_SINT           -> */   MH_GOM_NULL
  };
  
  UINT32 level;
  RM_OPCODES m;
  OS_PROTECTED_INT(level,m=MH_LastIgnoredOpDuringDownload);
  return MH_RMOPCODES_2_GOM[m];
}

void MH_EndOfDownload() {
  UINT32 level;
  OS_PROTECTED_INT(level,MH_DownloadIsInProgress_flag=FALSE);
}

BOOL MH_DownloadIsInProgress() {
  UINT32 level;
  BOOL b;
  OS_PROTECTED_INT(level,b=MH_DownloadIsInProgress_flag);
  return b;
}

status_code MH_SetGOM(MH_GOM newmode) {
  rtems_event_set unused;
  status_code status;
  PM_INFN_STATUS s;
  UINT32 level;
  /* stop the run manager: */
  status = PM_StopRunManager();
  if(status == SUCCESSFUL) {
    switch(newmode) {
    case MH_GOM_INITIALIZATION:
      MH_Saved_GOM_Mode = MH_GOM_Mode;
      RM_SendCodeRunManager(RM_OP_INITIALIZATION);
      break;
    case MH_GOM_CALIBRATION:
      MH_Saved_GOM_Mode = MH_GOM_Mode;
      RM_SendCodeRunManager(RM_OP_CALIBRATION);
      break;
    case MH_GOM_ACQUISITION:
      MH_Saved_GOM_Mode = MH_GOM_Mode;
      RM_SendCodeRunManager(RM_OP_ACQUISITION);
      break;
    case MH_GOM_DOWNLOAD:

      {
	RM_OPCODES rmopcode=RM_OP_NULL;
        OS_PROTECTED_INT(level,MH_DownloadIsInProgress_flag=TRUE);
        switch(MH_GOM_Mode) {
        case MH_GOM_INITIALIZATION:
          rmopcode=RM_OP_INITIALIZATION;
	  break;
        case MH_GOM_CALIBRATION:
          rmopcode=RM_OP_CALIBRATION ;
	  break;
        case MH_GOM_ACQUISITION:
          rmopcode=RM_OP_ACQUISITION;
	  break;
        }
	if(rmopcode!=RM_OP_NULL)
	  RM_SendCodeRunManager(rmopcode);

	/* this is to be sure a stop downlink will occur in case no download MCMD arrive. Timeout one minute */
	status = OS_piStartTimer_INFN(DNLK_TIM,PRH_VAR_MH_END_OF_DOWNLOAD_TIMEOUT,
				      FT_ifStopDownLink_CallBack, NULL);
      }

      // OS_PROTECTED_INT(level,MH_DownloadIsInProgress_flag=TRUE);
      // RM_SendCodeRunManager(MH_GOM_Mode); /* make the RM remember what is doing */
      break;
    case MH_GOM_MAINTENANCE:
      MH_Saved_GOM_Mode = MH_GOM_Mode;
      break;
    case MH_GOM_FLUSH_HB:
      RM_SendCodeRunManager(RM_OP_FLUSH_HB); /*  */
      break;
    case MH_GOM_FORCE_IDAQCMD:
      RM_SendCodeRunManager(RM_OP_FORCE_IDAQCMD);
      break; 
    case MH_GOM_TEST:
      RM_SendTest(MH_test_c1,MH_test_c2,MH_test_c3);
      break;
    default:
      /*@LOG MH_SetGOM: unrecognized newmode - newmode */
      LU_INFN_LOG(LU_INTERNAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,newmode);
      MH_GOM_Mode=MH_GOM_MAINTENANCE;
      break;
    }
    MH_GOM_Mode = newmode;
  }else {
    /*@LOG MH_SetGOM: error in stopping run manager - status */
    LU_INFN_LOG(LU_FATAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
  }

}



