/****************************************************************************
/*  F i l e   D a t a                                                        
/*                                                                           
/*  Module       :  SRAMManager                                                
/*  C.I. No.     :                                                           
/*  $Revision: 1.1.1.1 $
/*  $Date: 2006/04/25 09:00:21 $
/*  Belonging to :                                                           
/*               :                                                           
/*  $RCSfile: SM_SRAMPageManager_op.c,v $
/*  Program Type :                                                           
/*  Sub-modules  :                                                           
/*                                                                           
/****************************************************************************
/*  S W   D e v e l o p m e n t   E n v i r o n m e n t                      
/*                                                                           
/*  Host system  :                                                           
/*  SW Compiler  :                                                           
/*  $Author: kusanagi $
/*               :                                                           
/****************************************************************************
/*  U p d a t i n g                                                          
/*                                                                           
/*  $Log: SM_SRAMPageManager_op.c,v $
/*  Revision 1.1.1.1  2006/04/25 09:00:21  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.55  2005/03/20 18:30:38  sebastiani
/*  *** empty log message ***
/*
/*  Revision 1.54  2005/02/21 08:58:29  sebastiani
/*  all log comments completed
/*
/*  Revision 1.53  2005/02/19 10:20:16  sebastiani
/*  accept all MCMC in all mode
/*
/*  Revision 1.52  2005/01/26 18:46:56  sebastiani
/*  new bug fixes for WS
/*
/*  Revision 1.51  2005/01/07 15:42:53  sebastiani
/*  add exp 64 mode delay patch
/*
/*  Revision 1.50  2004/11/19 15:14:55  sebastiani
/*  PRH_EXTERN_{VAR,ARR,TABLE} removed and put them on the autogenerated parameter heeader file
/*
/*  Revision 1.49  2004/11/05 16:43:08  sebastiani
/*  *** empty log message ***
/*
/*  Revision 1.48  2004/09/17 15:01:00  faber
/*  LU_INFN_LOG flags fixing
/*
/*  Revision 1.47  2004/09/09 14:53:58  sebastiani
/*  fix prepare page to send cmd
/*
/*  Revision 1.46  2004/08/26 16:54:41  sebastiani
/*  version work fine
/*
/*  Revision 1.45  2004/08/13 14:42:22  sebastiani
/*  Add Neutron detector!
/*  need add file ND_READ_ACQ.dat on site ...
/*
/*  Revision 1.44  2004/08/09 08:30:29  sebastiani
/*  fix calo alarm procedure
/*
/*  Revision 1.43  2004/08/02 12:17:26  sebastiani
/*  fix little
/*
/*  Revision 1.42  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.41  2004/07/27 13:27:18  sebastiani
/*  SM_EXPERIMENT cancelled
/*
/*  Revision 1.40  2004/07/21 14:09:22  sebastiani
/*  Fix PacketCounter
/*
/*  Revision 1.39  2004/07/16 16:13:05  sebastiani
/*  important fix
/*
/*  Revision 1.38  2004/07/15 13:46:01  sebastiani
/*  fix some bugs
/*
/*  Revision 1.37  2004/06/15 08:25:01  sebastiani
/*  *** empty log message ***
/*
/*  Revision 1.36  2004/06/04 14:24:40  sebastiani
/*  clear some files
/*
/*  Revision 1.35  2004/06/01 16:41:24  sebastiani
/*  EventReceive ANY
/*
/*  Revision 1.34  2004/05/26 17:48:30  sebastiani
/*  *** empty log message ***
/*
/*  Revision 1.33  2004/05/25 14:07:18  faber
/*  *** empty log message ***
/*
/*  Revision 1.32  2004/05/24 10:25:28  faber
/*  OS_EVENT_UNCOMPLETED_CMDIF introduced
/*
/*  Revision 1.31  2004/05/20 12:51:58  sebastiani
/*  nee
/*
/*  Revision 1.30  2004/05/20 09:04:23  sebastiani
/*  ok
/*
/*  Revision 1.29  2004/05/19 08:45:05  sebastiani
/*  fix bug
/*
/*  Revision 1.28  2004/05/10 12:59:17  faber
/*  __FILEID__ right value fixed: many .c files had the wrong value!
/*
/*  Revision 1.27  2004/04/29 16:13:59  alfarano
/*  update cal
/*
/*  Revision 1.25  2004/02/13 10:11:30  alfarano
/*  calorimeter initialization func and more
/*
/*  Revision 1.24  2004/02/05 15:38:50  sebastiani
/*  PM_WAIT_TRIGEVENT managed as a parametrized macro
/*
/*  Revision 1.23  2004/02/05 14:45:13  sebastiani
/*  unlock acq in PageWasSaved DAQ_SETUP case
/*
/*  Revision 1.22  2004/02/02 08:34:40  sebastiani
/*  change Macro to write packet header
/*
/*  Revision 1.21  2004/01/22 08:58:54  sebastiani
/*  WAIT time introduced between DAQ and CMD/IF DMA programming
/*
/*  Revision 1.20  2004/01/13 15:07:38  tassa
/*  add send forced idaq cmd!
/*
/*  Revision 1.19  2003/12/30 14:22:44  sebastiani
/*  change crc function: 8 => 16
/*
/*  Revision 1.18  2003/11/18 09:01:15  alfarano
/*  laben patch fixes some problems
/*
/*  Revision 1.17  2003/11/13 16:15:06  sebastiani
/*  PM_opUnLockAcquisition added to SM_DAQSETUP in PageWasSaved, as suggested in the new laben versione released in these days
/*
/*  Revision 1.16  2003/11/10 12:13:25  sebastiani
/*  PM_pi_SetPktType and SM_PktType global variable introdused
/*
/*  Revision 1.15  2003/10/31 17:21:29  sebastiani
/*  bug fix on read and write function in TM_TMTCManager: added busy flag control on each read & write
/*  CRC functions updated in the SRAMPageManager
/*
/*  Revision 1.14  2003/10/30 15:34:04  faber
/*  CRC debug fixed 2
/*
/*  Revision 1.13  2003/10/30 14:55:52  faber
/*  CRC function debuggin (some fixes)
/*
/*  Revision 1.12  2003/10/30 10:09:36  sebastiani
/*  *** empty log message ***
/*
/*  Revision 1.11  2003/10/29 17:41:48  sebastiani
/*  *** empty log message ***
/*
/*  Revision 1.10  2003/10/27 19:03:10  sebastiani
/*  PM_WRITE_* macros introduced: new header format/management.
/*  length,pktsize,crc
/*
/*  Revision 1.9  2003/10/21 16:09:12  alfarano
/*  LU_LOG_INFN replacement for all remaining original log functions
/*
/*  Revision 1.8  2003/10/17 09:16:43  sebastiani
/*  SKETCHBOARD_FREE event introduced
/*
/*  Revision 1.7  2003/09/17 16:38:53  faber
/*  PM_pi_ExpPageAvail() introduced
/*
/*  Revision 1.6  2003/09/10 13:44:52  laben
/*  delete reference to FILE2 ( new File System Model).
/*
/*  Revision 1.5  2003/09/10 10:30:43  faber
/*  -introduced:
/*  	void PM_pi_DisableStore_In_DataTimeOut(),
/*  	void PM_pi_EnableStore_In_DataTimeOut(),
/*  	UINT32 PM_pi_GetDataLength(SM_PAGEID page);
/*  - fixed: Bug in PreparePage, EXP64 mode "one page only use".
/*  the fixing consist of the subsitution
/*  of the istruction
/*      	    SM_SelectedPage <<= 2;
/*  with
/*  	    SM_SelectedPage += 4;
/*
/*  Revision 1.4  2003/08/26 07:44:56  faber
/*  events introduced
/*
/*  Revision 1.3  2003/08/08 11:02:20  sebastiani
/*  introduced SM_DIRECT mode
/*
/*  Revision 1.2  2003/08/07 08:46:55  wizard
/*  SIMULATOR bugfix ifdef/ifndef
/*  SM_PktSize update bug fix in SM_op_PageHasData in order to fix the laben bug of SM_pi_GetPacket
/*  introduced the notification to a task from the PageHasData
/*
/*  Revision 1.1.1.1  2003/08/04 09:40:21  sebastiani
/*  Imported sources laben rel. 19.06.2003 integrated with pam2
/*
/*  Revision 1.21  2003/06/13 09:04:15  aurora
/*  removed a debug comment
/*
/*  Revision 1.20  2003/06/09 10:20:34  aurora
/*  improved the management of data acquisition.
/*  Fixed the dalay when copy the data in to ERC32 memory
/*
/*  Revision 1.19  2003/05/12 16:05:20  aurora
/*  fixed the last modify
/*
/*  Revision 1.18  2003/05/12 15:48:24  aurora
/*  Increase the lostpkt counter on ETO interrupt
/*
/*  Revision 1.17  2003/04/29 13:31:34  aurora
/*  management of page overrun every 64 Kbyte
/*
/*  Revision 1.16  2003/03/24 11:06:11  aurora
/*  management for interrupt on page overrun at 128KByte in DAQSetup mode
/*
/*  Revision 1.15  2003/01/30 10:17:54  aurora
/*  correct the routine for share HBUS
/*
/*  Revision 1.14  2003/01/22 14:03:52  aurora
/*  improved management of HBUS
/*
/*  Revision 1.13  2002/11/14 09:55:02  zulia
/*  correct the size of data send through CMD I/F
/*  improved the management of ET ISR
/*
/*  Revision 1.12  2002/10/17 10:08:21  zulia
/*  fixed PIFReset
/*
/*  Revision 1.11  2002/10/17 08:38:57  zulia
/*  - added counters for distinguish the cause of lost packets
/*  - added a flag (SM_EnableStoreET) for enable or disable the
/*     storage of a packet when rises a ET
/*  - fixed the clear of page_overrun interrupt
/*
/*  Revision 1.10  2002/09/02 12:55:18  zulia
/*  reset of PIF on boot
/*
/*  Revision 1.9  2002/07/31 14:34:09  zulia
/*  send data to CMD I/F after Event Trigger
/*  set header to 12 Bytes
/*  packet counter to 32 bits
/*  provided interface for copy buffer from micro to PIF sram
/*
/*  Revision 1.8  2002/06/25 09:17:03  zulia
/*  Disable reset of packet counter after change state mode
/*
/*  Revision 1.7  2002/06/19 08:25:31  zulia
/*  added provided interface PM_pi_GetAndIncrPckCnt that
/*  get and increase the packet counter
/*
/*  Revision 1.6  2002/05/09 08:16:35  zulia
/*  *  acceptance release
/*
/*                                                                           
/*****************************************************************************/


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

#include <src/INFN/LU_SourceFileID_INFN.h>
#define __FILEID__ _SM_SRAMPageManager_op__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/SRAMManager/SRAMPageManager/SM_SRAMPageManager_op.h>
#include <src/SRAMManager/SRAMPageManager/SM_SRAMPageManager_int.h>
#include <src/HKManager/HistoryArea/HA_HistoryArea_p.h>
#include <src/SRAMManager/SRAMDriver/SD_SRAMDriver_p.h>
#include <src/BasicSW/TimingInfo/TI_TimingInfo_p.h>
#include <src/FileManager/MMSUManager/FT_MMSUManager_p.h>
#include <src/INFN/CM_Common_INFN.h>
#include <src/INFN/HB_HKBuffer_INFN.h>

/*============================== local define ===============================*/



/*======================== Object Internal variables ========================*/

/*****************************************************************************/
/* @Variable: SM_AcqMode                                                     */
/* @Purpose :                                                                */
/*  PIF Acquisition mode                                                     */
/* @@                                                                        */
/*****************************************************************************/
static SM_ACQMODE SM_AcqMode;

/*****************************************************************************/
/* @Variable: SM_EmptyPage                                                   */
/* @Purpose :                                                                */
/*  Flag to mark a SRAM "page empty" after an EVENT T.O.                     */
/* @@                                                                        */
/*****************************************************************************/
static BOOL SM_EmptyPage;

/*****************************************************************************/
/* @Variable: SM_TrashFlag                                                   */
/* @Purpose :                                                                */
/* Flag to mark the use of the SRAM trash page                               */
/* @@                                                                        */
/*****************************************************************************/
//static BOOL SM_TrashFlag;

/*****************************************************************************/
/* @Variable: SM_SavingSkatchboard                                           */
/* @Purpose :                                                                */
/*  Flag to mark that the sketchboard page storage is in progress            */
/* @@                                                                        */
/*****************************************************************************/
static BOOL SM_SavingSkatchboard;

/*****************************************************************************/
/* @Variable: SM_SelectedPage                                                */
/* @Purpose :                                                                */
/*  Current SRAM page used to hold incoming experiment packets               */
/* @@                                                                        */
/*****************************************************************************/
static UINT32 SM_SelectedPage;

/*****************************************************************************/
/* @Variable: SM_PacketCounter                                               */
/* @Purpose :                                                                */
/*  Header packet counter                                                    */
/* @@                                                                        */
/*****************************************************************************/
static UINT32 SM_PacketCounter;

/*****************************************************************************/
/* @Variable: SM_LostPackets                                                 */
/* @Purpose :                                                                */
/*  Lost packet counter                                                      */
/* @@                                                                        */
/*****************************************************************************/
static UINT32 SM_LostPackets;

/*****************************************************************************/
/* @Variable: SM_ETOLostPackets                                              */
/* @Purpose :                                                                */
/*  Lost packet counter due to ETO                                           */
/* @@                                                                        */
/*****************************************************************************/
static UINT32 SM_ETOLostPackets;

/*****************************************************************************/
/* @Variable: SM_MMSULostPackets                                             */
/* @Purpose :                                                                */
/*  Lost packet counter                                                      */
/* @@                                                                        */
/*****************************************************************************/
static UINT32 SM_MMSULostPackets;

/*****************************************************************************/
/* @Variable: SM_ERC32LostPackets                                            */
/* @Purpose :                                                                */
/*  Counter for packets lost during the transfer in ERC32 memory             */
/* @@                                                                        */
/*****************************************************************************/
static UINT32 SM_ERC32LostPackets;

/*****************************************************************************/
/* @Variable: SM_LostTriggers                                                */
/* @Purpose :                                                                */
/*  Lost Event Trigger counter                                               */
/* @@                                                                        */
/*****************************************************************************/
static UINT32 SM_LostTriggers;

/*****************************************************************************/
/* @Variable: SM_ExpPageCounter                                              */
/* @Purpose :                                                                */
/*  Counter of the free SRAM pages for the experiment pkts caching           */
/* @@                                                                        */
/*****************************************************************************/
static UINT32 SM_ExpPageCounter;

/*****************************************************************************/
/* @Variable: SM_PktRamCpyFlag                                               */
/* @Purpose :                                                                */
/*  Experiment pkt RAM copy flag                                             */
/* @@                                                                        */
/*****************************************************************************/
static BOOL SM_PktRamCpyFlag;

/*****************************************************************************/
/* @Variable: SM_PktSize                                                     */
/* @Purpose :                                                                */
/*  Size of the last recieved packet                                         */
/* @@                                                                        */
/*****************************************************************************/
static UINT32 SM_PktSize;

/*****************************************************************************/
/* @Variable: SM_PktStatus                                                   */
/* @Purpose :                                                                */
/*  Status of the last recieved packet                                       */
/* @@                                                                        */
/*****************************************************************************/
static SM_PKTSTAT SM_PktStatus;

/*****************************************************************************/
/* @Variable: SM_PktLock                                                     */
/* @Purpose :                                                                */
/*  Flag used to avoid concurrency in R/W on PktBuf during exp. acquisition  */
/* @@                                                                        */
/*****************************************************************************/
static BOOL SM_PktLock;

/*****************************************************************************/
/* @Variable: SM_PIFTrOk                                                     */
/* @Purpose :                                                                */
/*  PIF Tranfer status flag                                                  */
/* @@                                                                        */
/*****************************************************************************/
static SD_TRANSFERSTAT SM_PIFTrOk;

/*****************************************************************************/
/* @Variable: SM_CalDataLenght[16]                                           */
/* @Purpose :                                                                */
/*  Number of data to write after ET for initialise intruments               */
/*  These values are significatives only for SM_CALEXPx pages                */
/* @@                                                                        */
/*****************************************************************************/
static UINT32 SM_CalDataLenght[16];

/*****************************************************************************/
/* @Variable: SM_CalPageSelected                                             */
/* @Purpose :                                                                */
/*  page used for initialise instruments                                     */
/* @@                                                                        */
/*****************************************************************************/
static SM_PAGEID SM_CalPageSelected;

/*****************************************************************************/
/* @Variable: SM_PacketStoreIsOngoing                                        */
/* @Purpose :                                                                */
/*    Flag to mark that the store of scientific packet is ongoing            */
/* @@                                                                        */
/*****************************************************************************/
static BOOL SM_PacketStoreIsOngoing;
static BOOL SM_ERC32IsOngoing;

/*****************************************************************************/
/* @Variable: SM_HBUSIsLocked                                                */
/* @Purpose :                                                                */
/*    Flag to mark that HBUS is in use from an other function                */
/* @@                                                                        */
/*****************************************************************************/
static BOOL SM_HBUSIsLocked;

/*****************************************************************************/
/* @Variable: SM_NotifyTask (INFN)                                           */
/* @Purpose :                                                                */
/*    Task to notify the Event to                                            */
/* @@                                                                        */
/*****************************************************************************/
static UINT32 SM_NotifyTask_PKT_READY;
static UINT32 SM_NotifyTask_SKETCHBOARD_FREE;


/*****************************************************************************/
/* @Variable: SM_EnableStore                                                 */
/* @Purpose :                                                                */
/*    Enable/Disable the storing of the packed in the File Sistem (FILE1)    */
/* @@                                                                        */
/*****************************************************************************/
static BOOL SM_EnableStore;

/*****************************************************************************/
/* @Variable: SM_PktType                                                     */
/* @Purpose :                                                                */
/*    Enable/Disable the storing of the packed in the File Sistem (FILE1)    */
/* @@                                                                        */
/*****************************************************************************/
static BOOL SM_PktType;



static TI_TIME SM_exp64_t1=0;



/*****************************************************************************/
/*===== S R A M P a g e M a n a g e r P R O V I D E D    I N T E R F A C E ==*/

/*****************************************************************************/
/* @Function: SM_opSRAMPageManagerInit                                       */
/* @Purpose :                                                                */
/*  This function initializes the SRAM Page Manager object (its variables).  */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  SM_EXITCODE          OUT     Return code                                 */
/*  RstPktCounter        IN      Flag used to enable the lost packets        */
/*                               counter reset                               */
/* @@                                                                        */
/*****************************************************************************/

SM_EXITCODE PM_opSRAMPageManagerInit(BOOL RstPktCounter)
{
SM_EXITCODE status = SM_SUCCESS;
unsigned int intLevel;
unsigned int i;

  /* Init the lost packet counter only at startup  */
  if(RstPktCounter) 
  {
    SD_piPIFReset();
    SM_LostPackets      = 0;
    SM_ETOLostPackets   = 0;
    SM_MMSULostPackets  = 0;
    SM_ERC32LostPackets = 0;    
    SM_LostTriggers     = 0;
    SM_PacketCounter    = 0;    
    /* Init the timeout timers                          */
    SD_piSetEventTimeout(SM_ETO_TICS);
    SD_piSetDataTimeout(SM_DTO_TICS);
    /* Init the Header length registers                 */
    SD_piSetDataHeaderLength(SM_PKTHEADER_LEN);
    SD_piSetCalibrationHeaderLength(SM_PKTHEADER_LEN);
    /* Init the length of data in all calibration pages */
    for (i = 0; i < SM_MAXPAGE; SM_CalDataLenght[i++] = 0);
    /* select first page for initialise intruments      */
    SM_CalPageSelected = SM_CALEXP0;
  }

  /* Mask all interrupt related to PIF acquisition */
  OS_piInterDisable(&intLevel);
  SD_piMaskInt(SD_EVT_TO | SD_DATA_TO | SD_PAGE_OVR);
  OS_piInterEnable(intLevel);
  ERC32_Mask_interrupt(ETIRQ);
  /* Set the acquisition mode to IDLE              */
  FT_piChangeAcqMode(SM_IDLE);
  SM_ExpPageCounter = DIRECTPAGES;
  //  console_outbyte_polled( 0, 'J' );
  //  console_outbyte_polled( 0, '\n' );
  SM_PktLock = FALSE;
  SM_PktRamCpyFlag = FALSE;
  SM_NotifyTask_PKT_READY = RM_INFN_TASK;
  SM_NotifyTask_SKETCHBOARD_FREE = RM_INFN_TASK;
  SM_PktType = 0;
  SM_PIFTrOk = SD_TRANSFERFAIL;
  
  // Skratchboard
  SM_SavingSkatchboard = FALSE;

  return (status);
}

/*****************************************************************************/
/* @MACRO: SM_WRITE_PACKET_HEADER                                            */
/* @Purpose :                                                                */
/*  Write in the PIF the header for an incaming event. Must be used only     */
/*  inside the PreparePage                                                   */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* @@                                                                        */
/*****************************************************************************/


static BYTE PM_WRITE_PKT_HEADER_Pkt_Header[SM_PKTHEADER_LEN];
static UINT32 PM_WRITE_PKT_HEADER_index;


#define PM_WRITE_PKT_HEADER_BYTE(byte) do {   \
 PM_WRITE_PKT_HEADER_Pkt_Header[PM_WRITE_PKT_HEADER_index]=(BYTE)(byte); \
 SD_piWriteSRAM(PM_WRITE_PKT_HEADER_Pkt_Header[PM_WRITE_PKT_HEADER_index]); \
 PM_WRITE_PKT_HEADER_index++; \
} while(0)

#define PM_INC_PKT_COUNTER() do { \
  if(SM_EnableStore) \
      SM_PacketCounter++; \
} while(0)

#define PM_WRITE_PKT_HEADER(page,pkt_size,crc) do { \
          /* Retrive OBT */                                                   \
          TI_TIME obt;                                                        \
          TI_piGetTimeInfo_ms(&obt);                                             \
          /* Set the SRAM R/W register to the first byte of the Cal page */   \
          PM_WRITE_PKT_HEADER_index=0;                                        \
          SD_piSetSRAMRWAddress((UINT32)(page) * SM_SRAMPAGESIZE);            \
          /* The HBUS is locked by PM_opPreparePage */                        \
          PM_WRITE_PKT_HEADER_BYTE(PM_HEADER_1);                                           \
          PM_WRITE_PKT_HEADER_BYTE(PM_HEADER_2);                                           \
          PM_WRITE_PKT_HEADER_BYTE(PM_HEADER_3);                                           \
          /* write packet type */                                             \
          PM_WRITE_PKT_HEADER_BYTE(SM_PktType | ((SM_PktStatus == SM_PKT_BAD)<<7) );   \
          PM_WRITE_PKT_HEADER_BYTE(SM_PktType | ((SM_PktStatus == SM_PKT_BAD)<<7) );   \
          /* Write the packet counter */                                      \
          PM_WRITE_PKT_HEADER_BYTE(((SM_PacketCounter>>16) & 0x000000FF));        \
          PM_WRITE_PKT_HEADER_BYTE(((SM_PacketCounter>>8 ) & 0x000000FF));        \
          PM_WRITE_PKT_HEADER_BYTE(( SM_PacketCounter      & 0x000000FF));        \
          /* Write the OBT            */                                      \
          PM_WRITE_PKT_HEADER_BYTE(((obt>>24) & 0x000000FF));                     \
          PM_WRITE_PKT_HEADER_BYTE(((obt>>16) & 0x000000FF));                     \
          PM_WRITE_PKT_HEADER_BYTE(((obt>>8 ) & 0x000000FF));                     \
          PM_WRITE_PKT_HEADER_BYTE(( obt      & 0x000000FF));                     \
          /* Write the pkt lenght */                                   \
          PM_WRITE_PKT_HEADER_BYTE((( (pkt_size)-SM_PKTHEADER_LEN)>>16) & 0x000000FF);     \
          PM_WRITE_PKT_HEADER_BYTE((( (pkt_size)-SM_PKTHEADER_LEN)>>8 ) & 0x000000FF);     \
          PM_WRITE_PKT_HEADER_BYTE( ( (pkt_size)-SM_PKTHEADER_LEN)      & 0x000000FF);      \
          crc=CM_Compute_CRC16(0,&PM_WRITE_PKT_HEADER_Pkt_Header[0],PM_WRITE_PKT_HEADER_index); \
          /*crc=CM_Compute_CRC8_8(0,&PM_WRITE_PKT_HEADER_Pkt_Header[0],PM_WRITE_PKT_HEADER_index); */\
          PM_WRITE_PKT_HEADER_BYTE(crc & 0xff);     \
          PM_WRITE_PKT_HEADER_index=0;                                          \
} while(0)



/********************************************************g*********************/
/* @Function: SM_opPreparePage                                               */
/* @Purpose :                                                                */
/*  The function selects a new SRAM page to hold the new data coming from    */
/*  the DAQ I/F and write the page header.                                   */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code PM_opPreparePage(BOOL daq_dmain)
{
#ifdef SIMULATOR
  return;
#else
  unsigned int intLevel;
  status_code status=CM_RC_SUCCESSFUL;

  /* Mask any further Event Trigger */
  ERC32_Mask_interrupt(ETIRQ);

#if 0
  {
    static TI_TIME SM_exp64_t0=0;
    TI_TIME delay=0;
    TI_piGetTimeInfo_ms(&SM_exp64_t0);      
    if(SM_exp64_t0>SM_exp64_t1){
      if((SM_exp64_t0-SM_exp64_t1)<PRH_VAR_EXP64_MODE_DELAY)
	delay=SM_exp64_t1+PRH_VAR_EXP64_MODE_DELAY-SM_exp64_t0;
    }
    else
      /* Timing info is over 41 uptime ! days :) */
      delay=PRH_VAR_EXP64_MODE_DELAY;
    if(delay)
      OS_piTaskSuspend(delay);
    SM_exp64_t1=SM_exp64_t0;
  }
#endif

  if ((PM_opLockHBUS()         == SM_SUCCESS))
    {      
      OS_piInterDisable(&intLevel);	  
      switch(SM_AcqMode) 
	{
	case SM_DIRECT:
	case SM_DAQSETUP: {
	  if(SM_ExpPageCounter > 0 || !daq_dmain) {	 

	    if (SM_CalDataLenght[SM_CalPageSelected] > 0) 
	      {	      
		/* Set the selected SRAM page where take data for	 */
		/*   initialise instrument  			 */
		SD_piSetCMDBUSReadPage(SM_CalPageSelected);
		/* Set end of data of selected page 		 */
		SD_piSetCMDBUSReadParams(
					 (UINT32)(SM_CalPageSelected * SM_SRAMPAGESIZE +
						  SM_CalDataLenght[SM_CalPageSelected]-1));
		
		/* Start the acquisition and timeouts */
		if (daq_dmain) 
		  {
		    SM_ExpPageCounter--;
		    /* Set the fix SRAM page to hold the incoming pkt */
		    SD_piSetDAQWritePage(SM_CALPAGE);

		    SD_piTrigCalibrationEvent();
		  }		
		/* start transfer to CMD I/F*/
		SD_piStartTransferToCMD();
		//console_outbyte_polled( 0, 'X' );
		//console_outbyte_polled( 0, '\n' );
	      }
	    else{
	      status=CM_RC_CALPAGEEMPTY;
	    }
	  }else{
	    status=CM_RC_NOPAGEAVAILABLE;
	  }  
	} break;	
#if 0 
	/*       /\* Actions performed after an ET in Experiment acq. mode *\/ */
	/*       case SM_EXPERIMENT:  */
	/*       { */
	/*     	/\* Check if a new SRAM cache page has to be selected:		    *\/ */
	/*     	/\* - The last acquisition was good and need to be saved 	    *\/ */
	/*     	/\* - In the last acquisition the trash page was selected	    *\/ */
	/*     	if((SM_PIFTrOk == TRUE && */
	/*     	    SM_EmptyPage == FALSE ) || */
	/*     	    SM_TrashFlag == TRUE)  */
	/*       { */
	/*     	  /\* Check if there is any free SRAM page left *\/ */
	/*     	  if(SM_ExpPageCounter > 0)  */
	/*         { */
	/*     	    SM_ExpPageCounter--; */
	/*     	    /\* Select the next SRAM page number in a circular buffer of *\/ */
	/*     	    /\* EXPPAGES pages						*\/ */
	/*     	    SM_SelectedPage++; */
	/*     	    SM_SelectedPage &= 0x00000007; */
	/*     	    /\* Set the SRAM page to hold the incoming pkt *\/ */
	/*     	    SD_piSetDAQWritePage(SM_SelectedPage); */
	/*     	    /\* The selected page is not the trash one *\/ */
	/*     	    SM_TrashFlag = FALSE; */
	/*     	  } */
	/*     	  else  */
	/*         { */
	/*     	    /\* No more free cache SRAM page left. The Trash one must be selected *\/ */
	/*     	    SD_piSetDAQWritePage(TRASHPAGE); */
	/*     	    SM_TrashFlag = TRUE; */
	/*     	  } */
	/*     	} */
	/*     	/\* If the last acquisition was not good then reselect the same SRAM page *\/ */
	/*     	else */
	/*     	  SD_piSetDAQWritePage(SM_SelectedPage); */
	
	/*     	if (SM_CalDataLenght[SM_CalPageSelected] > 0)	   */
	/*     	{ */

	/*     	    /\* Set the selected SRAM page where take data for	 *\/ */
	/*     	    /\*   initialise instrument  			 *\/ */
	/*     	    SD_piSetCMDBUSReadPage(SM_CalPageSelected); */
	/*     	    /\* Set end of data of selected page 		 *\/	    */
	/*     	    SD_piSetCMDBUSReadParams( */
	/*     		  (UINT32)(SM_CalPageSelected * SM_SRAMPAGESIZE + */
	/*     			       SM_CalDataLenght[SM_CalPageSelected]-1)); */
	/*     	    /\* Start the acquisition *\/ */
	/* 	    if (daq_dmain) */
	/* 	      { */
	/* 		SD_piTrigDataEvent(); */
	/* 	      } */
	/*     	    /\* start transfer to CMD I/F			 *\/		       */
	/*     	    SD_piStartTransferToCMD(); */
	    
	    
	/* 	    // PM_WRITE_PKT_HEADER_BEFORE(SM_SelectedPage); */


	/*         }      */
	/*       } break; */
#endif
	/* Actions performed after an ET in Exp64 acq. mode                   */
	case SM_EXP64: {
	  if(SM_ExpPageCounter > 0) {	 
	    SM_ExpPageCounter--;
	    SM_SelectedPage += 4;
	    SM_SelectedPage &= 0x00000007;
	    /* Set the SRAM page to hold the incoming pkt */
	    SD_piSetDAQWritePage(SM_SelectedPage);
	    if (SM_CalDataLenght[SM_CalPageSelected] > 0)	  
	      {
		/* Set the selected SRAM page where take data for	 */
		/*   initialise instrument  			 */
		SD_piSetCMDBUSReadPage(SM_CalPageSelected);
		/* Set end of data of selected page 		 */	   
		SD_piSetCMDBUSReadParams(
					 (UINT32)(SM_CalPageSelected * SM_SRAMPAGESIZE +
						  SM_CalDataLenght[SM_CalPageSelected]-1));	      
		/* Start the acquisition */
		SD_piTrigData64Event();
		/* start transfer to CMD I/F			 */		      
		SD_piStartTransferToCMD();	    
		// PM_WRITE_PKT_HEADER_BEFORE(SM_SelectedPage);
	      }
	    else{
	      status=CM_RC_CALPAGEEMPTY;
	    }
	  }
	  else{
	    status=CM_RC_NOPAGEAVAILABLE;	    
	  }
#if 0 
	  /*     	/\* Check if a new SRAM cache page has to be selected:		    *\/ */
	  /*     	/\* - The last acquisition was good and need to be saved 	    *\/ */
	  /*     	/\* - In the last acquisition the trash page was selected	    *\/ */
	  /*     	if((SM_PIFTrOk == TRUE && */
	  /*     	    SM_EmptyPage == FALSE ) || */
	  /* 	   SM_TrashFlag == TRUE) { */
	  /*     	  /\* Check if there is any free SRAM page left *\/ */
	  /*     	  if(SM_ExpPageCounter > 0) { */
	  /*     	    SM_ExpPageCounter--; */
	  /*     	    /\* Select the page 0 and the page 3 in a circulat buffer of     *\/ */
	  /*     	    /\* page 0 and page 3                                            *\/ */
	  /*     	    SM_SelectedPage += 4; */
	  /*     	    SM_SelectedPage &= 0x00000007; */
	  /*     	    /\* Set the SRAM page to hold the incoming pkt *\/ */
	  /*     	    SD_piSetDAQWritePage(SM_SelectedPage); */
	  /*     	    /\* The selected page is not the trash one *\/ */
	  /*     	    SM_TrashFlag = FALSE; */
	  /*     	  } */
	  /*     	  else { */
	  /*     	    /\* No more free cache SRAM page left. The Trash one must be selected *\/ */
	  /*     	    SD_piSetDAQWritePage(TRASHPAGE); */
	  /*     	    SM_TrashFlag = TRUE; */
	  /*     	  } */
	  /*     	} */
	  /*     	/\* If the last acquisition was not good then reselect the same SRAM page *\/ */
	  /*     	else */
	  /*     	  SD_piSetDAQWritePage(SM_SelectedPage); */

	  /*     	if (SM_CalDataLenght[SM_CalPageSelected] > 0)	   */
	  /* 	  { */

	  /*     	    /\* Set the selected SRAM page where take data for	 *\/ */
	  /*     	    /\*   initialise instrument  			 *\/ */
	  /*     	    SD_piSetCMDBUSReadPage(SM_CalPageSelected); */
	  /*     	    /\* Set end of data of selected page 		 *\/	    */
	  /*     	    SD_piSetCMDBUSReadParams( */
	  /*     		  (UINT32)(SM_CalPageSelected * SM_SRAMPAGESIZE + */
	  /*     			       SM_CalDataLenght[SM_CalPageSelected]-1)); */
    	
	  /*     	    /\* Start the acquisition *\/ */
	  /*     	    SD_piTrigData64Event(); */
	  /*     	    /\* start transfer to CMD I/F			 *\/		       */
	  /*     	    SD_piStartTransferToCMD(); */

	  /* 	    // PM_WRITE_PKT_HEADER_BEFORE(SM_SelectedPage); */
	  /* 	  }      */
#endif // 0

	}break;
      	}
      OS_piInterEnable(intLevel);	
    }
  else
    {
      /* HBUS is locked or an other storage is ongoing */
      SM_LostTriggers++;
      status=CM_RC_BUSY;
    }
  /* Release the HBUS for an other transfer */
  PM_opReleaseHBUS();
  /* Clear ERC32 interrupt					 */  

  OS_piInterDisable(&intLevel);
  ERC32_Clear_interrupt(ETIRQ);		     
  ERC32_Unmask_interrupt(ETIRQ);				     
  OS_piInterEnable(intLevel);
  return status;
#endif  // SIMULATOR
}

void PM_opDisableStore_In_DataTimeOut() {
  SM_EnableStore = FALSE;
}
void PM_opEnableStore_In_DataTimeOut() {
  SM_EnableStore = TRUE;
}

BYTE PM_opSetPktType(BYTE pkttype) {
  BYTE old=SM_PktType;
  SM_PktType = pkttype;
  return old;
}

BYTE PM_opGetPktType() {
  return SM_PktType;
}


/*****************************************************************************/
/* @Function: PM_opPageHasData                                               */
/* @Purpose :                                                                */
/*  The function is used to tell the Page Manager that the last selected page*/
/*  contains data written by the DAQ I/F. The Page Manager checks the data   */
/*   and send a "store" request to the MMSUManager.                          */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* @@                                                                        */
/*****************************************************************************/

static UINT32 counterleft=~0x00;
void PM_opPageHasData(void)
{
#ifdef SIMULATOR
  return;
#else

  SD_DAQ_WRESULT pageInfo;
  unsigned int intLevel;
  static BYTE crc_pkt;
  unsigned int pkt_size;
  BOOL savepagecalled=FALSE;

  OS_piInterDisable(&intLevel);
  SD_piClearInt(SD_DATA_TO);
  OS_piInterEnable(intLevel);

  ERC32_Clear_interrupt(ERC32_INTERRUPT_EXTERNAL_2);

  counterleft=SD_piGetCMDCounterLeft();

  switch(SM_AcqMode) {
    
  case SM_DIRECT: {
    /* Check if the packet buffer is not locked for read operation */
    if(!SM_PktLock &&
       !SD_piIsIntPending(SD_PAGE_OVR))
      {

        /* Evaluate the packet size in bytes */
        SM_PktSize = pageInfo = SD_piGetDAQWriteResult();
	SM_PktSize++;

        if (FT_piSavePage(SM_CALPAGE, SM_PktSize, FS_ERC32) != FT_SUCCESS)
	  { 
	    SM_ExpPageCounter=DIRECTPAGES;
	    SM_ERC32LostPackets++;
	  }
	else
	  SM_ERC32IsOngoing=TRUE;
        /* Check if the packet is good */
        if(SD_piIsDAQWriteOk() == SD_TRANSFEROK) 
          SM_PktStatus = SM_PKT_GOOD;
        else 
	  {
	    SM_LostPackets++;
	    SM_PktStatus = SM_PKT_BAD;
	  }
        // TBD:Post to INFN: DAQPkt READY !!!
        /* Enable again the Event Trigger Interrupt*/
	if(counterleft){
	  /*@LOG PageHasData: counterleft != 0 - counterleft*/
	  LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,counterleft);
	  if(SM_NotifyTask_PKT_READY != NULL_TASK)
	    OS_piEventSend(SM_NotifyTask_PKT_READY,OS_EVENT_UNCOMPLETED_CMDIF);
	}else
	  if(SM_NotifyTask_PKT_READY != NULL_TASK)
	    OS_piEventSend(SM_NotifyTask_PKT_READY,OS_EVENT_PKT_READY);
      }
    else
      {
        /* Clear the Page Overrun pending interrupt*/
        if(SD_piIsIntPending(SD_PAGE_OVR))
	  {
	    SD_piClearInt(SD_PAGE_OVR);
	    SM_EmptyPage = TRUE; 
	  }
	SM_PktStatus = SM_PKT_BAD;
	SM_ExpPageCounter=DIRECTPAGES;
	//	console_outbyte_polled( 0, '@' );
	//	console_outbyte_polled( 0, '\n' );
      }
  } break;
  
  /* Actions performed after an DTO in DAQSetup acq. mode */
  case SM_DAQSETUP: {
    /* Check if the packet buffer is not locked for read operation */
    if(!SM_PktLock &&
       !SD_piIsIntPending(SD_PAGE_OVR))
      {
        /* Increase the packet counter */

        /* Evaluate the packet size in bytes */
        SM_PktSize = pageInfo = SD_piGetDAQWriteResult();
	SM_PktSize++;	
	
	/* Check if the packet is good */
        if(SD_piIsDAQWriteOk() == SD_TRANSFEROK) 
          SM_PktStatus = SM_PKT_GOOD;
        else 
	  {
	    SM_LostPackets++;
	    SM_PktStatus = SM_PKT_BAD;
	  }
        
	
	PM_WRITE_PKT_HEADER(SM_CALPAGE,SM_PktSize,crc_pkt);	
	PM_INC_PKT_COUNTER();
	
	savepagecalled=FALSE;
	/* Put a save request for the selected SRAM page in the save queue*/
	if(SM_PktRamCpyFlag)
	  if (FT_piSavePage(SM_CALPAGE, pageInfo, FS_ERC32) != FT_SUCCESS)
	    SM_ERC32LostPackets++;
	  else{
	    SM_ERC32IsOngoing=TRUE;
	    savepagecalled=TRUE;
	  }

	if(SM_EnableStore)
	  if (FT_piSavePage(SM_CALPAGE, pageInfo, FS_FILE1) != FT_SUCCESS)
	    SM_MMSULostPackets++;
      	  else{
	    SM_PacketStoreIsOngoing=TRUE;
	    savepagecalled=TRUE;
	  }
	        
	if(!savepagecalled){
	  SM_ExpPageCounter=DAQSETUPPAGES;
	  //	  console_outbyte_polled( 0, '@' );
	  //	  console_outbyte_polled( 0, '\n' );
	}
	// console_outbyte_polled( 0, 'y' );
	// console_outbyte_polled( 0, '\n' );	

	if(counterleft){
	  /*@LOG PageHasData: counterleft != 0 - counterleft*/
	  LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,counterleft);
	  if(SM_NotifyTask_PKT_READY != NULL_TASK)
	    OS_piEventSend(SM_NotifyTask_PKT_READY,OS_EVENT_UNCOMPLETED_CMDIF);
	}else
	  if(SM_NotifyTask_PKT_READY != NULL_TASK)
	    OS_piEventSend(SM_NotifyTask_PKT_READY,OS_EVENT_PKT_READY);
      }
    else
      {
        /* Clear the Page Overrun pending interrupt*/
        if(SD_piIsIntPending(SD_PAGE_OVR))
	  {
	    SD_piClearInt(SD_PAGE_OVR);
	    SM_EmptyPage = TRUE; 
	  }
        SM_LostPackets++;
        /* this counter is increased only because is reported in RTF */
        SM_LostTriggers++;
	/* The transfer is complete then enalble an other acquisition */	
	SM_ExpPageCounter=DAQSETUPPAGES;
	//	console_outbyte_polled( 0, '@' );
	//	console_outbyte_polled( 0, '\n' );
      }
  } break;

  case SM_EXP64:
    {
      // SM_exp64_t2=SM_exp64_t1;
      /* Actions performed after an DTO in experiment acq. mode */
      SM_EmptyPage = FALSE;
      /* Check if the packet is good */
      /*
	SM_PIFTrOk = SD_piIsDAQWriteOk();
	if(SM_TrashFlag == FALSE &&
	SM_PIFTrOk == SD_TRANSFEROK &&
	!SD_piIsIntPending(SD_PAGE_OVR))
      */
      if(!SD_piIsIntPending(SD_PAGE_OVR))
	{
	  /* Get the paket end address in SRAM */
	  SM_PktSize = pageInfo = SD_piGetDAQWriteResult() ;
	  SM_PktSize++;
	  SM_PktSize -= (SM_SelectedPage * SM_SRAMPAGESIZE);
	  /* Increase the packet counter */
#if 0
	  if(PRH_VAR_RM_IDAQONLYACQ_ADDON_SIZE) {
	    SM_PktSize += CM_RAND(PRH_VAR_RM_IDAQONLYACQ_ADDON_SIZE);
	    if(SM_PktSize > SM_SRAMPAGESIZE64)
	      SM_PktSize=SM_SRAMPAGESIZE64;
	    pageInfo = SM_PktSize + (SM_SelectedPage * SM_SRAMPAGESIZE) -1;
	  }
#endif
	  /* Check if the packet is good */
	  if(SD_piIsDAQWriteOk() == SD_TRANSFEROK) 
	    SM_PktStatus = SM_PKT_GOOD;
	  else 
	    {
	      SM_LostPackets++;
	      SM_PktStatus = SM_PKT_BAD;
	    }
        
	  PM_WRITE_PKT_HEADER(SM_SelectedPage,SM_PktSize,crc_pkt);	
	  PM_INC_PKT_COUNTER();

	  savepagecalled=FALSE;


	  /* Check if it's time to copy the packet into RAM */
	  if(SM_PktRamCpyFlag)
	    {
	      if(FT_piSavePage(SM_SelectedPage, pageInfo, FS_ERC32) != FT_SUCCESS)
		SM_ERC32LostPackets++;
	      else
		{
		  SM_ERC32IsOngoing=TRUE;
		  savepagecalled=TRUE;	      
		}
	    }
	  /* Put a save request for the selected SRAM page in the save queue*/
	  if(SM_EnableStore)
	    if(FT_piSavePage(SM_SelectedPage, pageInfo, FS_FILE1) != FT_SUCCESS)
	      {
		/* The save request was refused so the current page can be immediatly */
		/* reused                                                             */
		SM_EmptyPage = TRUE;
		/* A packet was lost                                                  */
		SM_MMSULostPackets++;
	      }
	    else
	      {
		savepagecalled=TRUE;
		SM_PacketStoreIsOngoing=TRUE;
	      }	  

	  if(!savepagecalled)
	    if(++SM_ExpPageCounter > EXP64PAGES) 
	      {
		SM_ExpPageCounter = EXP64PAGES;
	      }	  
	  
	  
	  if(counterleft){
	    /*@LOG PageHasData: counterleft != 0 - counterleft*/
	    LU_INFN_LOG(LU_DEBUG_TRACE,LU_MASK(__FILEID__),__FILEID__,__LINE__,counterleft);
	    if(SM_NotifyTask_PKT_READY != NULL_TASK)
	      OS_piEventSend(SM_NotifyTask_PKT_READY,OS_EVENT_UNCOMPLETED_CMDIF);
	  }else
	    if(SM_NotifyTask_PKT_READY != NULL_TASK)
	      OS_piEventSend(SM_NotifyTask_PKT_READY,OS_EVENT_PKT_READY);
	}
      else
	/* The packet is not good */
	{
	  /* Clear the Page Overrun pending interrupt*/
	  if(SD_piIsIntPending(SD_PAGE_OVR))
	    {
	      SD_piClearInt(SD_PAGE_OVR);
	      SM_EmptyPage = TRUE;
	    }
	  SM_LostPackets++;
	  SM_LostTriggers++;
          if(++SM_ExpPageCounter > EXP64PAGES) 
	    {
	      SM_ExpPageCounter = EXP64PAGES;
	    }
	}      
    } break;
  default:{
    /*@LOG Unespected Data Timeout          LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_SM,HA_E10_UNESPECTED_DTO,HA_E10_REP2_NULL); */
    LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,HA_E10_REP2_NULL);
  }
  }
#endif // SIMULATOR
}





#ifdef DEBUG
status_code PM_opPreparePage_dummy()
{
  unsigned int intLevel;
  status_code status=CM_RC_SUCCESSFUL;
  OS_piInterDisable(&intLevel);
  SD_piSetDAQWritePage(SM_CALPAGE);
  if(SM_ExpPageCounter > 0) {
    SM_ExpPageCounter--;
    SM_SelectedPage =0;
  }
  else{
    status=CM_RC_NOPAGEAVAILABLE;
  }
  OS_piInterEnable(intLevel);
  return status;
}
#endif // DEBUG




/*****************************************************************************/
/* @Function: PM_opPageIsEmpty                                               */
/* @Purpose :                                                                */
/*  The function is used to tell the Page Manager that the last selected page*/
/*  was not written by the DAQ I/F.                                          */
/*  selected                                                                 */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* @@                                                                        */
/*****************************************************************************/

void PM_opPageIsEmpty(void)
{
unsigned int intLevel;

  /* The packet was lost*/
  SM_ETOLostPackets++;
  SM_LostTriggers++;

  if(SM_NotifyTask_PKT_READY != NULL_TASK)
    OS_piEventSend(SM_NotifyTask_PKT_READY,OS_EVENT_ETO);
  
  switch(SM_AcqMode) {
    /* Actions performed after an ETO in DAQSetup acq. mode */    
  case SM_DIRECT: 
  case SM_DAQSETUP:
    SM_ExpPageCounter=DIRECTPAGES;
    //    console_outbyte_polled( 0, '@' );
    //    console_outbyte_polled( 0, '\n' );
    break;
  case SM_EXP64: 
    if(++SM_ExpPageCounter > EXP64PAGES) 
      {
	SM_ExpPageCounter = EXP64PAGES;
      }
    break;
  }
  
  /* Clear the Event Timeout interrupt */
  OS_piInterDisable(&intLevel);
  SD_piClearInt(SD_EVT_TO);
  OS_piInterEnable(intLevel);
}

/*****************************************************************************/
/* @Function: PM_opPageWasSaved                                              */
/* @Purpose :                                                                */
/*  The function tels the Page Manager that a SRAM page was saved in MMSU and*/
/*  can be reused                                                            */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* @@                                                                        */
/*****************************************************************************/

void PM_opPageWasSaved(FS_FILEID FileId)
{
  unsigned int intLevel;
  switch (FileId)
    {  
    case FS_FILE1:
      {
	switch(SM_AcqMode) 
	  {
	  case SM_EXP64: 
	    {
	      OS_piInterDisable(&intLevel);
	      SM_PacketStoreIsOngoing=FALSE;
	      /* Increment the number free available SRAM page */
	      if(SM_ERC32IsOngoing==FALSE){
		SM_ExpPageCounter++;
		if(SM_ExpPageCounter > EXP64PAGES) 
		  {
		    SM_ExpPageCounter = EXP64PAGES;
		  }
	      }
	      OS_piInterEnable(intLevel);
	    } break;
	  case SM_DAQSETUP:
	    {
	      OS_piInterDisable(&intLevel);
	      SM_PacketStoreIsOngoing=FALSE;
	      /* Increment the number free available SRAM page */
	      if(SM_ERC32IsOngoing==FALSE){		
		SM_ExpPageCounter=DAQSETUPPAGES;
		//		console_outbyte_polled( 0, 'Y' );
		//		console_outbyte_polled( 0, '\n' );
	      }
	      OS_piInterEnable(intLevel);
	    } break;
	  case SM_DIRECT:
	    break;
	  default:
	    break;
	  }
      } break;
    case FS_HK:
      {
	/* Unlock the schetchboard page as soon as it is saved*/
	SM_SavingSkatchboard = FALSE;
	if(SM_NotifyTask_SKETCHBOARD_FREE != NULL_TASK)
	  OS_piEventSend(SM_NotifyTask_SKETCHBOARD_FREE,OS_EVENT_SKETCHBOARD_FREE);
      } break;      
    case FS_ERC32:
      {
	switch(SM_AcqMode) 
	  {
	  case SM_DIRECT:
	  case SM_DAQSETUP:
	    OS_piInterDisable(&intLevel);
	    SM_ERC32IsOngoing=FALSE;
	    if(SM_PacketStoreIsOngoing==FALSE){
	      SM_ExpPageCounter=DIRECTPAGES;
	      //	      console_outbyte_polled( 0, 'Z' );
	      //	      console_outbyte_polled( 0, '\n' );
	    }
	    OS_piInterEnable(intLevel);
	    break;
	  case SM_EXP64:
	    OS_piInterDisable(&intLevel);
	    SM_ERC32IsOngoing=FALSE;
	    if(SM_PacketStoreIsOngoing==FALSE){
	      SM_ExpPageCounter++;
	      if(SM_ExpPageCounter > EXP64PAGES) 
		{
		  SM_ExpPageCounter = EXP64PAGES;
		}
	    }
	    OS_piInterEnable(intLevel);
	    break;	  
	  }
      } break;
    case FS_CMD:
      break;
    default:
      break;
    }
}

/*****************************************************************************/
/* @Function: PM_op_SetAcqMode                                               */
/* @Purpose :                                                                */
/*  The function selects the operational mode for the Page Manager:          */
/*  science data or calibration. The transition is possible only if in the   */
/*  curent mode there are no more SRAM page to store into MMSU              */
/*  Due to the fact that the SRAM is a shared resource between the           */
/*  acquisition and the mass memory store automas, this function highly      */
/*  coupled with the MMSUManager Enable/Disable store functions.             */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* SM_EXITCODE          OUT     Return code                                  */
/* @@                                                                        */
/*****************************************************************************/

SM_EXITCODE PM_op_SetAcqMode(SM_ACQMODE mode)
{
  SM_EXITCODE status = SM_SUCCESS;
  UINT32 idx;
  unsigned int intLevel;

      /* Mask any interrupt related to acquisition activity */
      OS_piInterDisable(&intLevel);
      SD_piMaskInt(SD_EVT_TO | SD_DATA_TO | SD_PAGE_OVR);
      ERC32_Mask_interrupt(ETIRQ);
      OS_piInterEnable(intLevel);
      PM_opReleaseHBUS();
      SM_ERC32IsOngoing=FALSE;
      SM_PacketStoreIsOngoing = FALSE;
      
      switch(mode) {
        /* Enter the Direct Mode mode */
        case SM_DIRECT: 
        {
	  SD_piSetCalibrationHeaderLength(0);
          SM_AcqMode = SM_DIRECT;
          /* Init the last recieved packet status to a  */
          /* "to be acquired" condition                 */
          SM_PktStatus = SM_PKT_ACQ;
          /* Enable the skatchboard usage */
          SM_SavingSkatchboard = FALSE;
	  /**/
	  SM_ExpPageCounter = DIRECTPAGES;
	  if(SM_NotifyTask_SKETCHBOARD_FREE != NULL_TASK)
	    OS_piEventSend(SM_NotifyTask_SKETCHBOARD_FREE,OS_EVENT_SKETCHBOARD_FREE);
          /* Clear and unmask all the acquisition related interrupts */
          ERC32_Clear_interrupt(ETIRQ);
          OS_piInterDisable(&intLevel);
          SD_piClearInt(SD_EVT_TO | SD_DATA_TO | SD_PAGE_OVR);
          SD_piUnMaskInt(SD_EVT_TO | SD_DATA_TO);
          OS_piInterEnable(intLevel);
          ERC32_Unmask_interrupt(ETIRQ);
        } break;

        /* Enter the DAQSetup mode */
        case SM_DAQSETUP: 
        {
	  SD_piSetCalibrationHeaderLength(SM_PKTHEADER_LEN);
          SM_AcqMode = SM_DAQSETUP;
          /* Init the last recieved packet status to a  */
          /* "to be acquired" condition                 */
          SM_PktStatus = SM_PKT_ACQ;
          /* Enable the skatchboard usage */
          SM_SavingSkatchboard = FALSE;
	  SM_ExpPageCounter = DAQSETUPPAGES;
	  //	  console_outbyte_polled( 0, '9' );
	  //	  console_outbyte_polled( 0, '\n' );
	  if(SM_NotifyTask_SKETCHBOARD_FREE != NULL_TASK)
	    OS_piEventSend(SM_NotifyTask_SKETCHBOARD_FREE,OS_EVENT_SKETCHBOARD_FREE);
          /* Clear and unmask all the acquisition related interrupts */
          ERC32_Clear_interrupt(ETIRQ);
          OS_piInterDisable(&intLevel);
          SD_piClearInt(SD_EVT_TO | SD_DATA_TO | SD_PAGE_OVR);
          SD_piUnMaskInt(SD_EVT_TO | SD_DATA_TO);
          OS_piInterEnable(intLevel);
          ERC32_Unmask_interrupt(ETIRQ);
        } break;

#if 0
        /* Enter the Experiment mode */
        case SM_EXPERIMENT: 
        {
	  SD_piSetCalibrationHeaderLength(SM_PKTHEADER_LEN);
          SM_AcqMode = SM_EXPERIMENT;
          /* Force the Caching automa to select a brand new SRAM page */
          SM_TrashFlag = TRUE;
          SM_SelectedPage = 0;
          SM_EmptyPage = TRUE;
          SM_ExpPageCounter = EXPPAGES;
          /* Init the last recieved packet status to a  */
          /* "to be acquired" condition                 */
          SM_PktStatus = SM_PKT_ACQ;
          /* Reset the SRAM to RAM triggrer counter */
          /* Enable the skatchboard usage */
          SM_SavingSkatchboard = FALSE;
	  if(SM_NotifyTask_SKETCHBOARD_FREE != NULL_TASK)
	    OS_piEventSend(SM_NotifyTask_SKETCHBOARD_FREE,OS_EVENT_SKETCHBOARD_FREE);
          /* Clear and unmask all the acquisition related interrupts */
          OS_piInterDisable(&intLevel);
          SD_piClearInt(SD_EVT_TO | SD_DATA_TO | SD_PAGE_OVR);
          SD_piUnMaskInt(SD_EVT_TO | SD_DATA_TO);
          OS_piInterEnable(intLevel);
          ERC32_Clear_interrupt(ETIRQ);
          ERC32_Unmask_interrupt(ETIRQ);
        } break;
#endif
        /* Enter the Experiment mode */
        case SM_EXP64: 
        {
	  SD_piSetCalibrationHeaderLength(SM_PKTHEADER_LEN);
          SM_AcqMode = SM_EXP64;
          /* Force the Caching automa to select a brand new SRAM page */
	  SM_SelectedPage = 0;
          SM_EmptyPage = TRUE;
          SM_ExpPageCounter = EXP64PAGES;
          /* Init the last recieved packet status to a  */
          /* "to be acquired" condition                 */
          SM_PktStatus = SM_PKT_ACQ;
          /* Reset the SRAM to RAM triggrer counter */
          /* Enable the skatchboard usage */
          SM_SavingSkatchboard = FALSE;
	  if(SM_NotifyTask_SKETCHBOARD_FREE != NULL_TASK)
	    OS_piEventSend(SM_NotifyTask_SKETCHBOARD_FREE,OS_EVENT_SKETCHBOARD_FREE);
          /* Clear and unmask all the acquisition related interrupts */
          OS_piInterDisable(&intLevel);
          SD_piClearInt(SD_EVT_TO | SD_DATA_TO | SD_PAGE_OVR);
          SD_piUnMaskInt(SD_EVT_TO | SD_DATA_TO);
          OS_piInterEnable(intLevel);
          ERC32_Clear_interrupt(ETIRQ);
          ERC32_Unmask_interrupt(ETIRQ);
        } break;

        /* Enter the Idle mode */
        case SM_IDLE: 
        {
          SM_AcqMode = SM_IDLE;
        } break;
        default:{
          status = SM_WRONGACQMODE;
        }
      }
  return (status);
}

/*****************************************************************************/
/* @Function: PM_op_GetAcqMode                                               */
/* @Purpose :                                                                */
/*  The function return the current acquisition mode                         */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* SM_ACQMODE           OUT     acquisition mode                             */
/* @@                                                                        */
/*****************************************************************************/

SM_ACQMODE PM_op_GetAcqMode(void)
{
  /* Return the current acquisition mode */
  return (SM_AcqMode);
}

/*****************************************************************************/
/* @Function: PM_op_GetLostPktCounter                                        */
/* @Purpose :                                                                */
/*  The function return the lost Event Trigger counter                       */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* @@                                                                        */
/*****************************************************************************/

void PM_op_GetLostPktCounter(UINT32* Counter)
{
unsigned int intLevel;

  /* Return the lost packets counter */
  OS_piInterDisable(&intLevel);
  *Counter = SM_LostTriggers;
  OS_piInterEnable(intLevel);
}

/*****************************************************************************/
/* @Function: PM_op_GetPacket                                                */
/* @Purpose :                                                                */
/*  The function return a packet from PIF SRAM Memory                        */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  SM_PKTSTAT           OUT     acquisition result                          */
/*  PtrPkt               OUT      Pointer to the caller packet buffer        */
/*  Size                 OUT     Size of the packet copied into buffer       */
/* @@                                                                        */
/*****************************************************************************/

SM_PKTSTAT PM_op_GetPacket(UINT32* Size, void* PtrPkt)
{
SM_PKTSTAT pktStat;
unsigned int intLevel;
FS_FILE_DESCR fd;

  if (PM_opLockHBUS() == SM_SUCCESS)
  {
    /* Lock the buffer in read mode */
    OS_piInterDisable(&intLevel);
    SM_PktLock = TRUE;
    OS_piInterEnable(intLevel);
    /* return the packet status */
    pktStat = SM_PktStatus;
 
    FS_piGetFileInfo(FS_ERC32, &fd);
    /* If the paket is good then copy it to the provided destination */
    if(SM_PktStatus == SM_PKT_GOOD)
    {
      memcpy(PtrPkt, (void*)fd.WriteAddr, SM_PktSize);
      *Size = SM_PktSize;
    }
    /* Unlock the buffer */
    OS_piInterDisable(&intLevel);
    SM_PktLock = FALSE;
    OS_piInterEnable(intLevel);
    PM_opReleaseHBUS();
  }
  else
    pktStat = SM_PKT_ACQ;
  return (pktStat);
}

/*****************************************************************************/
/* @Function: PM_op_StorePacket                                              */
/* @Purpose :                                                                */
/*  The function starts all the operations needed to store the given packet  */
/*  in the selected file. If the result is good it means that the store      */
/*  request was successfuly accepted. The store of the packet can still fail */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  SM_STRSTAT           OUT     Store request result                        */
/*  PtrPkt               IN      Pointer to the caller packet buffer         */
/*  Size                 IN      Size of the packet to be copied into FileId */
/*                                in bytes                                   */
/*  FileID               IN      Destination file                            */
/* @@                                                                        */
/*****************************************************************************/

SM_STRSTAT  PM_op_StorePacket(UINT32 Size, void* PtrPkt, FS_FILEID FileId)
{
SM_STRSTAT strStat = SM_STR_OK;
SD_DAQ_WRESULT pageInfo;

  /* Check the FileID */
  if(FileId == FS_REGFILES || FileId == FS_MAXID)
  {
    strStat = SM_STR_WRONGFILE;
  }
  /* Check the packet size */
  if(Size == 0 || Size > SM_SKETCHSIZE)
  {
    strStat = SM_STR_WRIONGSIZE;
  }
  /* Check if the skatchboard is in use */
  if(SM_SavingSkatchboard == TRUE)
  {
    strStat = SM_STR_BUSY;
  }

  if (strStat == SM_STR_OK)
  {
    /* Copy the provided packet into SRAM skatchboard       */
    if(PtrPkt != NULL)
      SM_ifCopyToSRAM((UINT32)(SM_SKETCHBOARD * SM_SRAMPAGESIZE),
		      (void*)PtrPkt, Size);

    /* Put a save request for the skatchboard SRAM page in the save queue*/
    pageInfo = (UINT32)(SM_SKETCHBOARD * SM_SRAMPAGESIZE) + Size - 1;
    /* The save request was accepted */
    /* so lock the skatchboard page: assume here that it will have success  */
    SM_SavingSkatchboard = TRUE;
    if(FT_piSavePage(SM_SKETCHBOARD, pageInfo, FileId) != FT_SUCCESS)
      {
	/* The save request was refused */
	strStat = SM_STR_FAILED;
	
	SM_SavingSkatchboard = FALSE;
	if(SM_NotifyTask_SKETCHBOARD_FREE != NULL_TASK)
	  OS_piEventSend(SM_NotifyTask_SKETCHBOARD_FREE,OS_EVENT_SKETCHBOARD_FREE);
	
      }
    
  }

  return (strStat);
}

/*****************************************************************************/
/* @Function: PM_op_SetExpPktCpyFlag                                         */
/* @Purpose :                                                                */
/*  This function sets the experiment pkt RAM copy flag                      */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  Flag                 IN      Flag                                        */
/* @@                                                                        */
/*****************************************************************************/

void PM_op_SetExpPktCpyFlag(BOOL Flag)
{
  /* Set the trigger counter for the experiment pkt RAM copy */
  SM_PktRamCpyFlag = Flag;
}

/*****************************************************************************/
/* @Function: PM_op_GetAndIncrPckCnt                                         */
/* @Purpose :                                                                */
/*  This function get and increase the packet counter                        */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* UINT32                OUT    return the packet counter                    */
/* @@                                                                        */
/*****************************************************************************/
UINT32 PM_op_GetAndIncrPckCnt (void)
{
  return (SM_PacketCounter++);
}

/*****************************************************************************/
/* @Function: PM_op_CopyToSRAM                                               */
/* @Purpose :                                                                */
/*  This function copy from RAMStartAddr "Size" bytes to Page selected in    */
/*  in SRAM Memory.                                                          */
/*  this function update the value of SM_CalDataLenght for the page selected */
/*  with the "size"                                                          */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* SM_STRSTAT           OUT     Store request result                         */
/* Page                 IN      Page to store data buffer                    */
/* RAMStartAddr         IN      Pointer to the caller data buffer            */
/* Size                 IN      Size of the packet to be copied into FileId  */
/*                                in bytes                                   */
/* @@                                                                        */
/*****************************************************************************/
SM_STRSTAT PM_op_CopyToSRAM (SM_PAGEID Page, void* RAMStartAddr, UINT32 Size)
{
SM_STRSTAT strStat = SM_STR_OK;
unsigned int intLevel;

  
  /* Check the packet size */
  if(Size == 0 || Size > SM_SKETCHSIZE)
  {
    strStat = SM_STR_WRIONGSIZE;
  }
  /* check that page selected is valid page                         */
  if ((Page < SM_CALEXP0) || (Page > SM_CALEXP3))
  {
    strStat = SM_STR_WRONGFILE;
  }

  if (strStat == SM_STR_OK)
  {
    if (PM_opLockHBUS() == SM_SUCCESS)
    {
      /* Copy the provided data into SRAM Page Selected               */

      SM_ifCopyToSRAM((UINT32)(Page * SM_SRAMPAGESIZE), RAMStartAddr, Size);
      SM_CalDataLenght[Page] = Size;

      PM_opReleaseHBUS();
    }
    else
      strStat = SM_STR_BUSY;
   }
   return strStat;
}

/*****************************************************************************/
/* @Function: PM_op_UseCalibrationPage                                       */
/* @Purpose :                                                                */
/*  This function select the page that must be used for next acquisition     */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* Page                 IN      Page to store data buffer                    */
/* @@                                                                        */
/*****************************************************************************/
void PM_op_UseCalibrationPage (SM_PAGEID Page)
{
    SM_CalPageSelected = Page;
}

/*****************************************************************************/
/* @Function: PM_opLockHBUS                                                  */
/* @Purpose :                                                                */
/*  This function lock the HW HBUS shared resource                           */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* SM_EXITCODE          OUT     Lock HBUS request result                     */
/* @@                                                                        */
/*****************************************************************************/
SM_EXITCODE PM_opLockHBUS()
{
SM_EXITCODE status = SM_SUCCESS;    
unsigned int intLevel;
    
    OS_piInterDisable(&intLevel);
    if (SM_HBUSIsLocked)
        status = SM_FAIL;
    else
        SM_HBUSIsLocked = TRUE;
    OS_piInterEnable(intLevel);
    return status;
}

/*****************************************************************************/
/* @Function: PM_opReleaseHBUS                                               */
/* @Purpose :                                                                */
/*  This function release the HW HBUS shared resource                        */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* @@                                                                        */
/*****************************************************************************/
void PM_opReleaseHBUS()
{
unsigned int intLevel;
    
    OS_piInterDisable(&intLevel);
    SM_HBUSIsLocked = FALSE;
    OS_piInterEnable(intLevel);
}

/*****************************************************************************/
/* @Function: PM_opGetDataLen                                                */
/* @Purpose :                                                                */
/*  Returns the length of a page                                             */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* @@                                                                        */
/*****************************************************************************/
UINT32 SM_opGetDataLength(SM_PAGEID page)
{
  return SM_CalDataLenght[page];
}

/*****************************************************************************/
/* @Function: PM_opFullExp                                                   */
/* @Purpose :                                                                */
/*  Returns wheather or not the is at least one page available on the PIF    */
/*  (exp page)                                                               */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* @@                                                                        */
/*****************************************************************************/
BOOL SM_opExpPageAvail()
{
  BOOL ret = FALSE;
  unsigned int intLevel;
  OS_piInterDisable(&intLevel);
  switch(SM_AcqMode) 
    {
    case SM_DIRECT:
    case SM_DAQSETUP:
      //      ret = !SM_PacketStoreIsOngoing;   
      ret = SM_ExpPageCounter > 0;
      break;
    case SM_EXP64:
      //    case SM_EXPERIMENT:
      ret = SM_ExpPageCounter > 0;
      break;
    }
  OS_piInterEnable(intLevel);
  return ret;
}


BOOL SM_opAllExpPageAvail()
{
  BOOL ret = FALSE;
  unsigned int intLevel;
  OS_piInterDisable(&intLevel);
  switch(SM_AcqMode) 
    {
    case SM_DIRECT:
    case SM_DAQSETUP:
      ret = SM_ExpPageCounter == DAQSETUPPAGES;
      break;
    case SM_EXP64:
      ret = SM_ExpPageCounter == EXP64PAGES;
      break;
    }
  OS_piInterEnable(intLevel);
  return ret;
}

